1 /*
2 * Copyright 2012-2025 CodeLibs Project and the Others.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13 * either express or implied. See the License for the specific language
14 * governing permissions and limitations under the License.
15 */
16 package org.codelibs.fess.helper;
17
18 import java.util.LinkedHashMap;
19 import java.util.Map;
20
21 import org.apache.commons.lang3.StringUtils;
22 import org.apache.logging.log4j.LogManager;
23 import org.apache.logging.log4j.Logger;
24 import org.codelibs.core.lang.StringUtil;
25 import org.codelibs.core.stream.StreamUtil;
26 import org.codelibs.fess.util.ComponentUtil;
27
28 import jakarta.annotation.PostConstruct;
29
30 /**
31 * Helper class for managing file type mappings based on MIME types.
32 * This class provides functionality to map MIME types to file types and
33 * retrieve appropriate file type classifications for documents during indexing.
34 *
35 * The mappings are loaded from configuration and can be dynamically modified
36 * at runtime. When a MIME type is not found in the mapping, a default value
37 * is returned.
38 */
39 public class FileTypeHelper {
40 /** Logger instance for this class */
41 private static final Logger logger = LogManager.getLogger(FileTypeHelper.class);
42
43 /** Default file type value returned when MIME type is not found in mappings */
44 protected String defaultValue = "others";
45
46 /** Map storing MIME type to file type mappings */
47 protected Map<String, String> mimetypeMap = new LinkedHashMap<>();
48
49 /**
50 * Default constructor for file type helper.
51 * Creates a new instance with default values.
52 */
53 public FileTypeHelper() {
54 // Default constructor
55 }
56
57 /**
58 * Initializes the file type mappings by loading configuration from Fess settings.
59 * This method is called automatically after dependency injection is complete.
60 * The mappings are loaded from the index filetype configuration property,
61 * where each line contains a MIME type to file type mapping in the format "mimetype=filetype".
62 */
63 @PostConstruct
64 public void init() {
65 StreamUtil.split(ComponentUtil.getFessConfig().getIndexFiletype(), "\n")
66 .of(stream -> stream.filter(StringUtil::isNotBlank).forEach(s -> {
67 final String[] values = StringUtils.split(s, "=", 2);
68 if (values.length == 2) {
69 mimetypeMap.put(values[0], values[1]);
70 }
71 }));
72 if (logger.isDebugEnabled()) {
73 logger.debug("loaded filetype: {}", mimetypeMap);
74 }
75 }
76
77 /**
78 * Adds or updates a MIME type to file type mapping.
79 *
80 * @param mimetype the MIME type to map (e.g., "application/pdf")
81 * @param filetype the file type classification (e.g., "pdf")
82 */
83 public void add(final String mimetype, final String filetype) {
84 mimetypeMap.put(mimetype, filetype);
85 }
86
87 /**
88 * Retrieves the file type for a given MIME type.
89 *
90 * @param mimetype the MIME type to look up
91 * @return the corresponding file type, or the default value if not found
92 */
93 public String get(final String mimetype) {
94 final String filetype = mimetypeMap.get(mimetype);
95 if (StringUtil.isBlank(filetype)) {
96 return defaultValue;
97 }
98 return filetype;
99 }
100
101 /**
102 * Gets the default file type value used when MIME type is not found.
103 *
104 * @return the default file type value
105 */
106 public String getDefaultValue() {
107 return defaultValue;
108 }
109
110 /**
111 * Sets the default file type value to use when MIME type is not found.
112 *
113 * @param defaultValue the new default file type value
114 */
115 public void setDefaultValue(final String defaultValue) {
116 this.defaultValue = defaultValue;
117 }
118
119 /**
120 * Gets all distinct file types currently configured in the mappings.
121 *
122 * @return an array of all unique file type values
123 */
124 public String[] getTypes() {
125 return mimetypeMap.values().stream().distinct().toArray(n -> new String[n]);
126 }
127 }