1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.cms.beans.config;
35
36 import info.magnolia.cms.core.Content;
37 import info.magnolia.cms.core.HierarchyManager;
38 import info.magnolia.cms.core.ItemType;
39 import info.magnolia.cms.util.NodeDataUtil;
40 import info.magnolia.cms.util.ObservationUtil;
41 import info.magnolia.context.MgnlContext;
42 import info.magnolia.repository.RepositoryConstants;
43
44 import java.util.Collection;
45 import java.util.Hashtable;
46 import java.util.Iterator;
47 import java.util.Map;
48
49 import javax.jcr.PathNotFoundException;
50 import javax.jcr.RepositoryException;
51 import javax.jcr.observation.EventIterator;
52 import javax.jcr.observation.EventListener;
53
54 import org.apache.commons.lang.StringUtils;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57
58
59
60
61 public class MIMEMapping {
62 private static final Logger log = LoggerFactory.getLogger(MIMEMapping.class);
63
64 public static final String ICONS_PATH = "/.resources/file-icons/";
65 public static final String DEFAULT_ICON = ICONS_PATH + "general.png";
66 private static final String NODEPATH = "/server/MIMEMapping";
67 public static final String DEFAULT_ICON_STYLE = "icon-file";
68
69 private static Map<String, MIMEMappingItem> cachedContent = new Hashtable<String, MIMEMappingItem>();
70 private static final String DEFAULT_CHAR_ENCODING = "UTF-8";
71
72
73
74
75 protected static class MIMEMappingItem {
76
77 protected String ext;
78
79 protected String mime;
80
81 protected String icon;
82
83 protected String iconStyle;
84 }
85
86
87
88
89
90 private MIMEMapping() {
91
92 }
93
94
95
96
97 public static void init() {
98 log.info("Initializing MIMEMapping from {}", NODEPATH);
99 load();
100 registerEventListener();
101 }
102
103
104
105
106 public static void load() {
107 MIMEMapping.cachedContent.clear();
108 try {
109 final HierarchyManager hm = MgnlContext.getSystemContext().getHierarchyManager(RepositoryConstants.CONFIG);
110
111 Collection<Content> mimeList = hm.getContent(NODEPATH).getChildren(ItemType.CONTENTNODE);
112 MIMEMapping.cacheContent(mimeList);
113 log.debug("MIMEMapping loaded from {}", NODEPATH);
114 } catch (PathNotFoundException e) {
115 log.warn("No MIMEMapping info configured at {}", NODEPATH);
116 }catch (RepositoryException e) {
117 log.error("Failed to load MIMEMapping: " + e.getMessage(), e);
118 }
119 }
120
121 public static void reload() {
122 log.info("Reloading MIMEMapping from {}", NODEPATH);
123 MIMEMapping.load();
124 }
125
126
127
128
129 private static void registerEventListener() {
130 log.info("Registering event listener for MIMEMapping");
131
132 ObservationUtil.registerChangeListener(RepositoryConstants.CONFIG, NODEPATH, new EventListener() {
133 @Override
134 public void onEvent(EventIterator iterator) {
135
136 reload();
137 }
138 });
139 }
140
141
142
143
144 private static void cacheContent(Collection<Content> mimeList) {
145 Iterator<Content> iterator = mimeList.iterator();
146 while (iterator.hasNext()) {
147 Content c = iterator.next();
148 try {
149 MIMEMappingItem item = new MIMEMappingItem();
150 item.ext = NodeDataUtil.getString(c, "extension", c.getName());
151 item.mime = c.getNodeData("mime-type").getString();
152 item.icon = NodeDataUtil.getString(c, "icon");
153 item.iconStyle = NodeDataUtil.getString(c, "iconStyle");
154
155 MIMEMapping.cachedContent.put(item.ext, item);
156 }
157 catch (Exception e) {
158 log.error("Failed to cache MIMEMapping");
159 }
160 }
161 }
162
163
164
165
166
167
168 public static String getMIMEType(String key) {
169 if (StringUtils.isEmpty(key)) {
170 return StringUtils.EMPTY;
171 }
172
173 String loweredKey = key.toLowerCase();
174 if (MIMEMapping.cachedContent.containsKey(loweredKey)) {
175 return MIMEMapping.cachedContent.get(loweredKey).mime;
176 }
177
178
179 return null;
180
181 }
182
183
184
185
186 public static String getMIMETypeOrDefault(String extension) {
187 String mimeType = getMIMEType(extension);
188
189 if (StringUtils.isNotEmpty(mimeType)) {
190 return mimeType;
191 }
192
193 if (StringUtils.isNotEmpty(extension)) {
194 log.info("Cannot find MIME type for extension \"{}\"", extension);
195 }
196
197 String defaultExtension = ServerConfiguration.getInstance().getDefaultExtension();
198 if(StringUtils.isBlank(defaultExtension)){
199 defaultExtension = "html";
200 }
201 return getMIMEType(defaultExtension);
202 }
203
204 public static String getContentEncoding(String contentType) {
205 if (contentType != null) {
206 int index = contentType.lastIndexOf(";");
207 if (index > -1) {
208 String encoding = contentType.substring(index + 1).toLowerCase().trim();
209 encoding = encoding.replaceAll("charset=", StringUtils.EMPTY);
210 return encoding;
211 }
212 }
213 return StringUtils.EMPTY;
214 }
215
216 public static String getContentEncodingOrDefault(String contentType) {
217 final String characterEncoding = getContentEncoding(contentType);
218
219 return (StringUtils.isEmpty(characterEncoding)) ? DEFAULT_CHAR_ENCODING : characterEncoding;
220 }
221
222
223
224
225
226 public static String getMIMETypeIcon(String extension) {
227 MIMEMappingItem item = MIMEMapping.cachedContent.get(extension.toLowerCase());
228 if (item != null) {
229 return StringUtils.defaultIfEmpty(item.icon, DEFAULT_ICON);
230 }
231
232 return DEFAULT_ICON;
233
234 }
235
236
237
238
239
240 public static String getMIMETypeIconStyle(String mimeType) {
241 String genericMimeType = StringUtils.substringBefore(mimeType, "/");
242 MIMEMappingItem mimeMappingItem = null;
243 for (MIMEMappingItem item : cachedContent.values()) {
244 if (item.mime != null && item.mime.equals(mimeType) && StringUtils.isNotBlank(item.iconStyle)) {
245 mimeMappingItem = item;
246 break;
247 }
248 if (item.mime != null && item.mime.equals(genericMimeType) && StringUtils.isNotBlank(item.iconStyle)) {
249 mimeMappingItem = item;
250 }
251 }
252 if (mimeMappingItem != null && StringUtils.isNotBlank(mimeMappingItem.iconStyle)) {
253 return mimeMappingItem.iconStyle;
254 }
255 return DEFAULT_ICON_STYLE;
256 }
257 }