/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package javax.activation;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.StringReader;
import java.util.Map;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.Enumeration;
import java.net.URL;

/**
 * @version $Rev: 467742 $ $Date: 2006-10-25 21:30:38 +0200 (Wed, 25 Oct 2006) $
 */
public class MimetypesFileTypeMap extends FileTypeMap {
    private static final String DEFAULT_TYPE = "application/octet-stream";

    private final Map types = new HashMap();

    public MimetypesFileTypeMap() {
        // defaults from /META-INF/mimetypes.default
        try {
            InputStream is = MimetypesFileTypeMap.class.getResourceAsStream("/META-INF/mimetypes.default");
            if (is != null) {
                try {
                    loadStream(is);
                } finally {
                    is.close();
                }
            }
        } catch (IOException e) {
            // ignore
        }

        // defaults from resources called /META-INF/mime.types
        try {
            ClassLoader cl = MimetypesFileTypeMap.class.getClassLoader();
            if (cl != null) {
                Enumeration e = cl.getResources("/META-INF/mime.types");
                while (e.hasMoreElements()) {
                    URL url = (URL)e.nextElement();
                    try {
                        InputStream is = url.openStream();
                        try {
                            loadStream(is);
                        } finally {
                            is.close();
                        }
                    } catch (IOException e1) {
                        continue;
                    }
                }
            }
        } catch (SecurityException e) {
            // ignore
        } catch (IOException e) {
            // ignore
        }

        // defaults from ${java.home}/lib/mime.types
        try {
            File file = new File(System.getProperty("java.home"), "lib/mime.types");
            InputStream is = new FileInputStream(file);
            try {
                loadStream(is);
            } finally {
                is.close();
            }
        } catch (SecurityException e) {
            // ignore
        } catch (FileNotFoundException e) {
            // ignore
        } catch (IOException e) {
            // ignore
        }

        // defaults from ${user.home}/.mime.types
        try {
            File file = new File(System.getProperty("user.home"), ".mime.types");
            InputStream is = new FileInputStream(file);
            try {
                loadStream(is);
            } finally {
                is.close();
            }
        } catch (SecurityException e) {
            // ignore
        } catch (FileNotFoundException e) {
            // ignore
        } catch (IOException e) {
            // ignore
        }
    }

    public MimetypesFileTypeMap(String mimeTypeFileName) throws IOException {
        this();
        BufferedReader reader = new BufferedReader(new FileReader(mimeTypeFileName));
        try {
            String line;
            while ((line = reader.readLine()) != null) {
                addMimeTypesOneLine(line);
            }
            reader.close();
        } catch (IOException e) {
            try {
                reader.close();
            } catch (IOException e1) {
                // ignore to allow original cause through
            }
            throw e;
        }
    }

    public MimetypesFileTypeMap(InputStream is) {
        this();
        try {
            loadStream(is);
        } catch (IOException e) {
            // ignore as the spec's signature says we can't throw IOException - doh!
        }
    }

    private void loadStream(InputStream is) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        String line;
        while ((line = reader.readLine()) != null) {
            addMimeTypesOneLine(line);
        }
    }

    private synchronized void addMimeTypesOneLine(String mime_types) {
        int hashPos = mime_types.indexOf('#');
        if (hashPos != -1) {
            mime_types = mime_types.substring(0, hashPos);
        }
        StringTokenizer tok = new StringTokenizer(mime_types);
        if (!tok.hasMoreTokens()) {
            return;
        }
        String contentType = tok.nextToken();
        while (tok.hasMoreTokens()) {
            String fileType = tok.nextToken();
            types.put(fileType, contentType);
        }
    }
    
    public synchronized void addMimeTypes(String mime_types) {
        BufferedReader reader = new BufferedReader(new StringReader(mime_types));
        try {
            String line;
            while ((line = reader.readLine()) != null) {
                addMimeTypesOneLine(line);
            }
            reader.close();
        } catch (IOException e) {
            try {
                reader.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }


    public String getContentType(File f) {
        return getContentType(f.getName());
    }

    public synchronized String getContentType(String filename) {
        int index = filename.lastIndexOf('.');
        if (index == -1 || index == filename.length()-1) {
            return DEFAULT_TYPE;
        }
        String fileType = filename.substring(index + 1);
        String contentType = (String) types.get(fileType);
        return contentType == null ? DEFAULT_TYPE : contentType;
    }
}
