001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *  http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    
020    package javax.activation;
021    
022    import java.io.File;
023    import java.io.IOException;
024    import java.io.InputStream;
025    import java.io.BufferedReader;
026    import java.io.InputStreamReader;
027    import java.io.FileReader;
028    import java.io.FileInputStream;
029    import java.io.FileNotFoundException;
030    import java.util.Map;
031    import java.util.HashMap;
032    import java.util.StringTokenizer;
033    import java.util.Enumeration;
034    import java.net.URL;
035    
036    /**
037     * @version $Rev: 467553 $ $Date: 2006-10-25 06:01:51 +0200 (Mi, 25. Okt 2006) $
038     */
039    public class MimetypesFileTypeMap extends FileTypeMap {
040        private static final String DEFAULT_TYPE = "application/octet-stream";
041    
042        private final Map types = new HashMap();
043    
044        public MimetypesFileTypeMap() {
045            // defaults from /META-INF/mimetypes.default
046            try {
047                InputStream is = MimetypesFileTypeMap.class.getResourceAsStream("/META-INF/mimetypes.default");
048                if (is != null) {
049                    try {
050                        loadStream(is);
051                    } finally {
052                        is.close();
053                    }
054                }
055            } catch (IOException e) {
056                // ignore
057            }
058    
059            // defaults from resources called /META-INF/mime.types
060            try {
061                ClassLoader cl = MimetypesFileTypeMap.class.getClassLoader();
062                Enumeration e = cl.getResources("/META-INF/mime.types");
063                while (e.hasMoreElements()) {
064                    URL url = (URL) e.nextElement();
065                    try {
066                        InputStream is = url.openStream();
067                        try {
068                            loadStream(is);
069                        } finally {
070                            is.close();
071                        }
072                    } catch (IOException e1) {
073                        continue;
074                    }
075                }
076            } catch (SecurityException e) {
077                // ignore
078            } catch (IOException e) {
079                // ignore
080            }
081    
082            // defaults from ${java.home}/lib/mime.types
083            try {
084                File file = new File(System.getProperty("java.home"), "lib/mime.types");
085                InputStream is = new FileInputStream(file);
086                try {
087                    loadStream(is);
088                } finally {
089                    is.close();
090                }
091            } catch (SecurityException e) {
092                // ignore
093            } catch (FileNotFoundException e) {
094                // ignore
095            } catch (IOException e) {
096                // ignore
097            }
098    
099            // defaults from ${user.home}/.mime.types
100            try {
101                File file = new File(System.getProperty("user.home"), ".mime.types");
102                InputStream is = new FileInputStream(file);
103                try {
104                    loadStream(is);
105                } finally {
106                    is.close();
107                }
108            } catch (SecurityException e) {
109                // ignore
110            } catch (FileNotFoundException e) {
111                // ignore
112            } catch (IOException e) {
113                // ignore
114            }
115        }
116    
117        public MimetypesFileTypeMap(String mimeTypeFileName) throws IOException {
118            this();
119            BufferedReader reader = new BufferedReader(new FileReader(mimeTypeFileName));
120            try {
121                String line;
122                while ((line = reader.readLine()) != null) {
123                    addMimeTypes(line);
124                }
125                reader.close();
126            } catch (IOException e) {
127                try {
128                    reader.close();
129                } catch (IOException e1) {
130                    // ignore to allow original cause through
131                }
132                throw e;
133            }
134        }
135    
136        public MimetypesFileTypeMap(InputStream is) {
137            this();
138            try {
139                loadStream(is);
140            } catch (IOException e) {
141                // ignore as the spec's signature says we can't throw IOException - doh!
142            }
143        }
144    
145        private void loadStream(InputStream is) throws IOException {
146            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
147            String line;
148            while ((line = reader.readLine()) != null) {
149                addMimeTypes(line);
150            }
151        }
152    
153        public synchronized void addMimeTypes(String mime_types) {
154            int hashPos = mime_types.indexOf('#');
155            if (hashPos != -1) {
156                mime_types = mime_types.substring(0, hashPos);
157            }
158            StringTokenizer tok = new StringTokenizer(mime_types);
159            if (!tok.hasMoreTokens()) {
160                return;
161            }
162            String contentType = tok.nextToken();
163            while (tok.hasMoreTokens()) {
164                String fileType = tok.nextToken();
165                types.put(fileType, contentType);
166            }
167        }
168    
169        public String getContentType(File f) {
170            return getContentType(f.getName());
171        }
172    
173        public synchronized String getContentType(String filename) {
174            int index = filename.lastIndexOf('.');
175            if (index == -1 || index == filename.length()-1) {
176                return DEFAULT_TYPE;
177            }
178            String fileType = filename.substring(index + 1);
179            String contentType = (String) types.get(fileType);
180            return contentType == null ? DEFAULT_TYPE : contentType;
181        }
182    }