001: /*
002:
003: This software is OSI Certified Open Source Software.
004: OSI Certified is a certification mark of the Open Source Initiative.
005:
006: The license (Mozilla version 1.0) can be read at the MMBase site.
007: See http://www.MMBase.org/license
008:
009: */
010: package org.mmbase.util.magicfile;
011:
012: import java.io.File;
013: import java.io.FileInputStream;
014: import java.io.IOException;
015: import java.util.Iterator;
016: import java.util.List;
017: import org.mmbase.util.logging.*;
018:
019: /**
020: * Tries to determine the mime-type of a byte array (or a file).
021: *
022: * @author cjr@dds.nl
023: * @author Michiel Meeuwissen
024: * @version $Id: MagicFile.java,v 1.4 2007/03/02 21:04:16 nklasens Exp $
025: */
026: public class MagicFile {
027: private static final Logger log = Logging
028: .getLoggerInstance(MagicFile.class);
029:
030: public static final String FAILED = "Failed to determine type";
031: // application/octet-stream?
032:
033: protected static final int BUFSIZE = 4598;
034: // Read a string of maximally this length from the file
035: // Is this garanteed to be big enough?
036:
037: private static MagicFile instance;
038:
039: protected DetectorProvider detectors;
040:
041: /**
042: * Return the current instance of MagicFile. If no instance exists,
043: * one is created.
044: */
045: public static MagicFile getInstance() {
046: if (instance == null) {
047: instance = new MagicFile();
048: }
049: return instance;
050: }
051:
052: private MagicFile() {
053: DetectorProvider d = MagicXMLReader.getInstance();
054: // default, read from XML
055: if (d == null) {
056: d = new MagicParser();
057: }
058: detectors = d;
059: }
060:
061: /**
062: * Returns a list of detectors used by this MagicFile instance
063: */
064:
065: public List<Detector> getDetectors() {
066: return detectors.getDetectors();
067: }
068:
069: /*
070: * @deprecated use getMimeType(File)
071: */
072: protected String test(String path) {
073: try {
074: return getMimeType(new File(path));
075: } catch (IOException e) {
076: return "File not found " + path;
077: }
078: }
079:
080: /**
081: * @param file Location of file to be checked
082: * @return Type of the file as determined by the magic file
083: */
084: protected String getMimeType(File file) throws IOException {
085: FileInputStream fir = null;
086: try {
087: byte[] lithmus = new byte[BUFSIZE];
088: fir = new FileInputStream(file);
089: int res = fir.read(lithmus, 0, BUFSIZE);
090: log.debug("read " + res + " bytes from "
091: + file.getAbsolutePath());
092: return getMimeType(lithmus);
093: } catch (IOException ioe) {
094: throw ioe;
095: } finally {
096: if (fir != null) {
097: fir.close();
098: }
099: }
100: }
101:
102: /**
103: * Tests the byte[] array for the mime type.
104: *
105: * @return The found mime-type or FAILED
106: */
107: public String getMimeType(byte[] input) {
108: byte[] lithmus;
109:
110: if (input.length > BUFSIZE) {
111: lithmus = new byte[BUFSIZE];
112: System.arraycopy(input, 0, lithmus, 0, BUFSIZE);
113: log
114: .debug("getMimeType was called with big bytearray cutting to "
115: + BUFSIZE + " bytes");
116: } else {
117: lithmus = input;
118: }
119:
120: List<Detector> list = getDetectors();
121: if (list == null) {
122: log.warn("No detectors found");
123: return FAILED;
124: }
125: for (Detector detector : list) {
126: if (detector.test(lithmus)) {
127: log.debug("Trying " + detector.getMimeType());
128: return detector.getMimeType();
129: }
130: }
131: return FAILED;
132: }
133:
134: /**
135: * @javadoc
136: */
137: public String extensionToMimeType(String extension) {
138: for (Detector detector : getDetectors()) {
139: for (String ex : detector.getExtensions()) {
140: if (ex.equalsIgnoreCase(extension)) {
141: return detector.getMimeType();
142: }
143: }
144: }
145: return FAILED;
146: }
147:
148: /**
149: * Given a mime-type string, this function tries to create a common extension for it.
150: * @return An extension (without the dot), or an empty string if the mime-type is unknown.
151: * @since MMBase-1.7.1
152: */
153: public String mimeTypeToExtension(String mimeType) {
154: for (Detector detector : getDetectors()) {
155: if (mimeType.equalsIgnoreCase(detector.getMimeType())) {
156: Iterator<String> j = detector.getExtensions()
157: .iterator();
158: if (j.hasNext()) {
159: String ex = j.next();
160: return ex;
161: }
162: }
163: }
164: return "";
165: }
166:
167: /**
168: * @javadoc
169: */
170: public String getMimeType(byte[] data, String extension) {
171: String result;
172: result = getMimeType(data);
173: if (result.equals(FAILED)) {
174: result = extensionToMimeType(extension);
175: }
176: return result;
177: }
178:
179: /**
180: * e.g.: java -Dmmbase.config=/home/mmbase/mmbase-app/WEB-INF/config org.mmbase.util.MagicFile test.doc
181: * @javadoc
182: */
183: public static void main(String[] argv) {
184: MagicFile magicFile = MagicFile.getInstance();
185:
186: if (argv.length == 1) {
187: try {
188: // one argument possible: a file name. Return the mime-type
189: log.info(magicFile.getMimeType(new File(argv[0])));
190: } catch (IOException e) {
191: log.info(argv[0] + " cannot be opened or read: "
192: + e.toString());
193: }
194: } else {
195: // show the known Detectors;
196: for (Detector d : magicFile.getDetectors()) {
197: log.info(d.toString());
198: }
199: }
200: }
201: }
|