001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.util;
018:
019: import java.io.BufferedInputStream;
020: import java.io.BufferedReader;
021: import java.io.File;
022: import java.io.FileInputStream;
023: import java.io.FileNotFoundException;
024: import java.io.IOException;
025: import java.io.InputStream;
026: import java.io.InputStreamReader;
027: import java.io.Reader;
028: import java.util.HashMap;
029: import java.util.Map;
030: import java.util.StringTokenizer;
031:
032: /**
033: * A collection of <code>File</code>, <code>URL</code> and filename
034: * utility methods.
035: *
036: * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
037: * @author <a href="mailto:tk-cocoon@datas-world.de">Torsten Knodt</a>
038: * @author <a href="mailto:jefft@apache.org">Jeff Turner</a>
039: * @version CVS $Id: MIMEUtils.java 433543 2006-08-22 06:22:54Z crossley $
040: */
041: public class MIMEUtils {
042:
043: private static final String MIME_MAPPING_FILE = "org/apache/cocoon/util/mime.types";
044:
045: /** Default extensions for MIME types. */
046: final private static Map extMap = new HashMap();
047: /** MIME types for extensions. */
048: final private static Map mimeMap = new HashMap();
049:
050: /**
051: * Load the MIME type mapping
052: */
053: static {
054: try {
055: final InputStream is = MIMEUtils.class.getClassLoader()
056: .getResourceAsStream(MIME_MAPPING_FILE);
057: if (null == is) {
058: throw new RuntimeException(
059: "Cocoon cannot load MIME type mappings from "
060: + MIME_MAPPING_FILE);
061: }
062: loadMimeTypes(new InputStreamReader(is), extMap, mimeMap);
063: } catch (IOException ioe) {
064: throw new RuntimeException(
065: "Cocoon cannot load MIME type mappings from "
066: + MIME_MAPPING_FILE);
067: }
068: }
069:
070: /**
071: * Return the MIME type for a given file.
072: *
073: * @param file File.
074: * @return MIME type.
075: */
076: public static String getMIMEType(final File file)
077: throws FileNotFoundException, IOException {
078: BufferedInputStream in = null;
079:
080: try {
081: in = new BufferedInputStream(new FileInputStream(file));
082: byte[] buf = new byte[3];
083: int count = in.read(buf, 0, 3);
084:
085: if (count < 3) {
086: return (null);
087: }
088:
089: if ((buf[0]) == (byte) 'G' && (buf[1]) == (byte) 'I'
090: && (buf[2]) == (byte) 'F') {
091: return ("image/gif");
092: }
093:
094: if ((buf[0]) == (byte) 0xFF && (buf[1]) == (byte) 0xD8) {
095: return ("image/jpeg");
096: }
097:
098: } finally {
099: if (in != null) {
100: try {
101: in.close();
102: } catch (IOException e) {
103: }
104: }
105: }
106: final String name = file.getName();
107: int index = name.lastIndexOf(".");
108: String fileExt = ".";
109: if (index != -1) {
110: fileExt = name.substring(index);
111: }
112: return getMIMEType(fileExt);
113: }
114:
115: /**
116: * Return the MIME type for a given filename extension.
117: *
118: * @param ext Filename extension.
119: *
120: * @return MIME type.
121: */
122: public static String getMIMEType(final String ext) {
123: return (String) mimeMap.get(ext);
124: }
125:
126: /**
127: * Return the default filename extension for a given MIME type.
128: *
129: * @param type MIME type.
130: *
131: * @return Filename extension.
132: */
133: public static String getDefaultExtension(final String type) {
134: return (String) extMap.get(type);
135: }
136:
137: /**
138: * Parses a <code>mime.types</code> file, and generates mappings between
139: * MIME types and extensions.
140: * For example, if a line contains:
141: * <pre>text/html html htm</pre>
142: * Then 'html' will be the default extension for text/html, and both 'html'
143: * and 'htm' will have MIME type 'text/html'.
144: * Lines starting with '#' are treated as comments and ignored. If an
145: * extension is listed for two MIME types, the first will be chosen.
146: *
147: * @param in Reader of bytes from <code>mime.types</code> file content
148: * @param extMap Empty map of default extensions, keyed by MIME type. Will
149: * be filled in by this method.
150: * @param mimeMap Empty map of MIME types, keyed by extension. Will be
151: * filled in by this method.
152: */
153: public static void loadMimeTypes(Reader in, Map extMap, Map mimeMap)
154: throws IOException {
155: BufferedReader br = new BufferedReader(in);
156: String line;
157: while ((line = br.readLine()) != null) {
158: if (line.startsWith("#")) {
159: continue;
160: }
161: if (line.trim().length() == 0) {
162: continue;
163: }
164: StringTokenizer tok = new StringTokenizer(line, " \t");
165: String mimeType = tok.nextToken();
166: if (tok.hasMoreTokens()) {
167: String defaultExt = tok.nextToken();
168: if (!extMap.containsKey(mimeType)) {
169: extMap.put(mimeType, "." + defaultExt);
170: }
171: if (!mimeMap.containsKey("." + defaultExt)) {
172: mimeMap.put("." + defaultExt, mimeType);
173: }
174: while (tok.hasMoreTokens()) {
175: String ext = tok.nextToken();
176: if (!mimeMap.containsKey("." + ext)) {
177: mimeMap.put("." + ext, mimeType);
178: }
179: }
180: }
181: }
182: }
183: }
|