001    package org.apache.archiva.webdav.util;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *  http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.apache.commons.io.IOUtils;
023    import org.apache.commons.lang.StringUtils;
024    import org.slf4j.Logger;
025    import org.slf4j.LoggerFactory;
026    import org.springframework.stereotype.Service;
027    
028    import javax.annotation.PostConstruct;
029    import java.io.BufferedReader;
030    import java.io.File;
031    import java.io.FileInputStream;
032    import java.io.FileNotFoundException;
033    import java.io.IOException;
034    import java.io.InputStream;
035    import java.io.InputStreamReader;
036    import java.net.URL;
037    import java.util.HashMap;
038    import java.util.Map;
039    import java.util.StringTokenizer;
040    
041    /**
042     * MimeTypes
043     *
044     *
045     */
046    @Service( "mimeTpes" )
047    public class MimeTypes
048    {
049        private static final String DEFAULT_MIME_TYPE = "application/octet-stream";
050    
051        private String resource = "org/apache/archiva/webdav/util/mime.types";
052    
053        private Map<String, String> mimeMap = new HashMap<String, String>();
054    
055        private Logger log = LoggerFactory.getLogger( MimeTypes.class );
056    
057        /**
058         * Get the Mime Type for the provided filename.
059         *
060         * @param filename the filename to obtain the mime type for.
061         * @return a mime type String, or null if filename is null, has no extension, or no mime type is associated with it.
062         */
063        public String getMimeType( String filename )
064        {
065            String value = null;
066            if ( !StringUtils.isEmpty( filename ) )
067            {
068                int index = filename.lastIndexOf( '.' );
069    
070                if ( index >= 0 )
071                {
072                    value = (String) mimeMap.get( filename.substring( index + 1 ).toLowerCase() );
073                }
074            }
075    
076            if ( value == null )
077            {
078                value = DEFAULT_MIME_TYPE;
079            }
080    
081            return value;
082    
083        }
084    
085        @PostConstruct
086        public void initialize()
087        {
088            load( resource );
089        }
090    
091        public void load( File file )
092        {
093            if ( !file.exists() || !file.isFile() || !file.canRead() )
094            {
095                log.error( "Unable to load mime types from file " + file.getAbsolutePath() + " : not a readable file." );
096                return;
097            }
098    
099            FileInputStream fis = null;
100    
101            try
102            {
103                fis = new FileInputStream( file );
104            }
105            catch ( FileNotFoundException e )
106            {
107                log.error( "Unable to load mime types from file " + file.getAbsolutePath() + " : " + e.getMessage(), e );
108            }
109            finally
110            {
111                IOUtils.closeQuietly( fis );
112            }
113        }
114    
115        public void load( String resourceName )
116        {
117            ClassLoader cloader = this.getClass().getClassLoader();
118    
119            /* Load up the mime types table */
120            URL mimeURL = cloader.getResource( resourceName );
121    
122            if ( mimeURL == null )
123            {
124                throw new IllegalStateException( "Unable to find resource " + resourceName );
125            }
126    
127            InputStream mimeStream = null;
128    
129            try
130            {
131                mimeStream = mimeURL.openStream();
132                load( mimeStream );
133            }
134            catch ( IOException e )
135            {
136                log.error( "Unable to load mime map " + resourceName + " : " + e.getMessage(), e );
137            }
138            finally
139            {
140                IOUtils.closeQuietly( mimeStream );
141            }
142        }
143    
144        public void load( InputStream mimeStream )
145        {
146            mimeMap.clear();
147    
148            InputStreamReader reader = null;
149            BufferedReader buf = null;
150    
151            try
152            {
153                reader = new InputStreamReader( mimeStream );
154                buf = new BufferedReader( reader );
155                String line = null;
156    
157                while ( ( line = buf.readLine() ) != null )
158                {
159                    line = line.trim();
160    
161                    if ( line.length() == 0 )
162                    {
163                        // empty line. skip it
164                        continue;
165                    }
166    
167                    if ( line.startsWith( "#" ) )
168                    {
169                        // Comment. skip it
170                        continue;
171                    }
172    
173                    StringTokenizer tokenizer = new StringTokenizer( line );
174                    if ( tokenizer.countTokens() > 1 )
175                    {
176                        String type = tokenizer.nextToken();
177                        while ( tokenizer.hasMoreTokens() )
178                        {
179                            String extension = tokenizer.nextToken().toLowerCase();
180                            this.mimeMap.put( extension, type );
181                        }
182                    }
183                }
184            }
185            catch ( IOException e )
186            {
187                log.error( "Unable to read mime types from input stream : " + e.getMessage(), e );
188            }
189            finally
190            {
191                IOUtils.closeQuietly( buf );
192                IOUtils.closeQuietly( reader );
193            }
194        }
195    
196        public String getResource()
197        {
198            return resource;
199        }
200    
201        public void setResource( String resource )
202        {
203            this.resource = resource;
204        }
205    }