1 /*
2 * Copyright 2007-2009 Medsea Business Solutions S.L.
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, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package eu.medsea.mimeutil.detector;
17 import java.io.File;
18 import java.io.InputStream;
19 import java.net.URL;
20 import java.util.Collection;
21
22 /**
23 * ALL MimeDetector(s) must extend this class.
24 * @author Steven McArdle
25 *
26 */
27 public abstract class MimeDetector {
28 /**
29 * Gets the name of this MimeDetector
30 * @return name of MimeDetector as a fully qualified class name
31 */
32 public final String getName() {
33 return getClass().getName();
34 }
35
36 /**
37 * Called by MimeUtil.MimeDetectorRegistry.getMimeTypes(String fileName) {}
38 * @param fileName
39 * @return
40 * @throws UnsupportedOperationException
41 */
42 public final Collection getMimeTypes(final String fileName) throws UnsupportedOperationException {
43 return getMimeTypesFileName(fileName);
44 }
45
46 /**
47 * Called by MimeUtil.MimeDetectorRegistry.getMimeTypes(File file) {}
48 * @param fileName
49 * @return
50 * @throws UnsupportedOperationException
51 */
52 public final Collection getMimeTypes(final File file) throws UnsupportedOperationException {
53 return getMimeTypesFile(file);
54 }
55
56 /**
57 * Called by MimeUtil.MimeDetectorRegistry.getMimeTypes(URL url) {}
58 * @param fileName
59 * @return
60 * @throws UnsupportedOperationException
61 */
62 public final Collection getMimeTypes(final URL url) throws UnsupportedOperationException {
63 return getMimeTypesURL(url);
64 }
65
66 /**
67 * Called by MimeUtil.MimeDetectorRegistry.getMimeTypes(byte [] data) {}
68 * @param fileName
69 * @return
70 * @throws UnsupportedOperationException
71 */
72 public final Collection getMimeTypes(final byte [] data) throws UnsupportedOperationException {
73 return getMimeTypesByteArray(data);
74 }
75
76 /**
77 * Called by MimeUtil.MimeDetectorRegistry.getMimeTypes(InputStream in) {}
78 * The InputStream must support the mark() and reset() methods.
79 * @param fileName
80 * @return
81 * @throws UnsupportedOperationException
82 */
83 public final Collection getMimeTypes(final InputStream in) throws UnsupportedOperationException {
84 // Enforces that the InputStream supports the mark() and reset() methods
85 if(!in.markSupported()) {
86 throw new UnsupportedOperationException("The InputStream must support the mark() and reset() methods.");
87 }
88 return getMimeTypesInputStream(in);
89 }
90
91 /**
92 * You can override this method if you have any special one off initialisation to perform
93 * such as allocating resources etc.
94 */
95 public void init() {}
96
97 /**
98 * You can override this method if for instance you allocated any resources in the init() method
99 * that need to be closed or deallocated specially.
100 */
101 public void delete() {}
102
103 /**
104 * Abstract method to be implement by concrete MimeDetector(s).
105 * @return description of this MimeDetector
106 */
107 public abstract String getDescription();
108
109 /**
110 * Abstract method that must be implemented by concrete MimeDetector(s). This takes a file name and is
111 * called by the MimeUtil getMimeTypes(String fileName) getMimeTypes(File file) getMimeTypes(URL url) methods.
112 * If your MimeDetector does not handle file names then either throw an UnsupportedOperationException or return an
113 * empty collection.
114 *
115 * @param fileName
116 * @return Collection of matched MimeType(s)
117 * @throws UnsupportedOperationException
118 */
119 protected abstract Collection getMimeTypesFileName(final String fileName) throws UnsupportedOperationException;
120
121 /**
122 * Abstract method that must be implemented by concrete MimeDetector(s). This takes a file object and is
123 * called by the MimeUtil getMimeTypes(File file) method.
124 * If your MimeDetector does not handle file names then either throw an UnsupportedOperationException or return an
125 * empty collection.
126 *
127 * @param file
128 * @return Collection of matched MimeType(s)
129 * @throws UnsupportedOperationException
130 */
131 protected abstract Collection getMimeTypesFile(final File file) throws UnsupportedOperationException;
132
133 /**
134 * Abstract method that must be implemented by concrete MimeDetector(s). This takes a URL object and is
135 * called by the MimeUtil getMimeTypes(URL url) method.
136 * If your MimeDetector does not handle file names then either throw an UnsupportedOperationException or return an
137 * empty collection.
138 *
139 * @param file
140 * @return Collection of matched MimeType(s)
141 * @throws UnsupportedOperationException
142 */
143 protected abstract Collection getMimeTypesURL(final URL url) throws UnsupportedOperationException;
144
145 /**
146 * Abstract method that must be implemented by concrete MimeDetector(s). This takes an InputStream object and is
147 * called by the MimeUtil getMimeTypes(URL url), getMimeTypes(File file) and getMimeTypes(InputStream in) methods.
148 * If your MimeDetector does not handle InputStream objects then either throw an UnsupportedOperationException or return an
149 * empty collection.
150 * <p>
151 * If the InputStream passed in does not support the mark() and reset() methods a MimeException will be thrown
152 * before reaching this point. The implementation is responsible for the actual use of the mark() and reset() methods
153 * as the amount of data to retrieve from the stream is implementation and even call by call dependent.
154 * If you do not use the mark() and reset() methods on the Stream then the position in the Stream will have moved on when this method returns
155 * and the next MimeDetector that handles the stream will either fail or be incorrect.
156 * </p>
157 * <p>
158 * To allow the reuse of the Stream in other parts of your code and by further MimeDetector(s) in a way that it is unaware of
159 * any data read via this method i.e. the Stream position will be returned to where it was when this method was called,
160 * it is IMPORTANT to utilise the mark() and reset() methods within your implementing method.
161 * </p>
162 * @param in InputStream.
163 *
164 * @return Collection of matched MimeType(s)
165 * @throws UnsupportedOperationException
166 */
167 protected abstract Collection getMimeTypesInputStream(final InputStream in) throws UnsupportedOperationException;
168
169 /**
170 * Abstract method that must be implemented by concrete MimeDetector(s). This takes a byte [] object and is
171 * called by the MimeUtil getMimeTypes(byte []) method.
172 * If your MimeDetector does not handle byte [] objects then either throw an UnsupportedOperationException or return an
173 * empty collection.
174 *
175 * @param data byte []. Is a byte array that you want to parse for matching mime types.
176 * @return Collection of matched MimeType(s)
177 * @throws UnsupportedOperationException
178 */
179 protected abstract Collection getMimeTypesByteArray(final byte [] data) throws UnsupportedOperationException;
180
181 protected static InputStream closeStream(InputStream in) {
182 if(in == null) {
183 return null;
184 }
185 try {
186 in.close();
187 }catch(Exception ignore) {}
188 return null;
189 }
190 }
191
192