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 org.apache.james.mime4j.storage;
021    
022    import org.apache.commons.logging.Log;
023    import org.apache.commons.logging.LogFactory;
024    
025    /**
026     * Allows for a default {@link StorageProvider} instance to be configured on an
027     * application level.
028     * <p>
029     * The default instance can be set by either calling
030     * {@link #setInstance(StorageProvider)} when the application starts up or by
031     * setting the system property
032     * <code>org.apache.james.mime4j.defaultStorageProvider</code> to the class
033     * name of a <code>StorageProvider</code> implementation.
034     * <p>
035     * If neither option is used or if the class instantiation fails this class
036     * provides a pre-configured default instance.
037     */
038    public class DefaultStorageProvider {
039    
040        /** Value is <code>org.apache.james.mime4j.defaultStorageProvider</code> */
041        public static final String DEFAULT_STORAGE_PROVIDER_PROPERTY =
042            "org.apache.james.mime4j.defaultStorageProvider";
043    
044        private static Log log = LogFactory.getLog(DefaultStorageProvider.class);
045    
046        private static volatile StorageProvider instance = null;
047    
048        static {
049            initialize();
050        }
051    
052        private DefaultStorageProvider() {
053        }
054    
055        /**
056         * Returns the default {@link StorageProvider} instance.
057         *
058         * @return the default {@link StorageProvider} instance.
059         */
060        public static StorageProvider getInstance() {
061            return instance;
062        }
063    
064        /**
065         * Sets the default {@link StorageProvider} instance.
066         *
067         * @param instance
068         *            the default {@link StorageProvider} instance.
069         */
070        public static void setInstance(StorageProvider instance) {
071            if (instance == null) {
072                throw new IllegalArgumentException();
073            }
074    
075            DefaultStorageProvider.instance = instance;
076        }
077    
078        private static void initialize() {
079            String clazz = System.getProperty(DEFAULT_STORAGE_PROVIDER_PROPERTY);
080            try {
081                if (clazz != null) {
082                    instance = (StorageProvider) Class.forName(clazz).newInstance();
083                }
084            } catch (Exception e) {
085                log.warn("Unable to create or instantiate StorageProvider class '"
086                        + clazz + "'. Using default instead.", e);
087            }
088    
089            if (instance == null) {
090                StorageProvider backend = new TempFileStorageProvider();
091                instance = new ThresholdStorageProvider(backend, 1024);
092            }
093        }
094    
095        // for unit tests only
096        static void reset() {
097            instance = null;
098            initialize();
099        }
100    
101    }