001    package net.sf.logdistiller;
002    
003    /*
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    import java.util.*;
018    
019    import net.sf.logdistiller.logtypes.BaseLogTypes;
020    import net.sf.logdistiller.util.ExtensionHelper;
021    import net.sf.logdistiller.util.FormatUtil;
022    
023    /**
024     * Definition of available log types. By default, some log types come {@link net.sf.logdistiller.logtypes.BaseLogTypes
025     * predefined} with <b>LogDistiller</b>. You can add custom log types:
026     * <ul>
027     * <li>1. create a new <code>LogEvent</code> class, with corresponding <code>LogEvent.Factory</code> and
028     * <code>LogType</code></li>
029     * <li>2. create a new <code>LogTypes</code> class defining previous <code>LogType</code> with a default constructor</li>
030     * <li>3. create a <code>logdistiller.properties</code> resource file which <code>logtypes</code> property is the full
031     * <code>LogTypes</code> class name</li>
032     * </ul>
033     *
034     * @see LogType
035     */
036    public abstract class LogTypes
037    {
038        /**
039         * get the <code>LogType</code> instances defined by this extension.
040         *
041         * @return the list of logtypes
042         * @see LogType
043         */
044        public abstract List defineLogTypes();
045    
046        public static final List ALL;
047    
048        public static final Map MAP;
049        static
050        {
051            List all = new ArrayList( new BaseLogTypes().defineLogTypes() );
052            all.addAll( loadExtensionLogTypes() );
053            ALL = Collections.unmodifiableList( all );
054    
055            Map map = new HashMap();
056            Iterator iter = ALL.iterator();
057            while ( iter.hasNext() )
058            {
059                LogType type = (LogType) iter.next();
060                map.put( type.getId(), type );
061            }
062            MAP = Collections.unmodifiableMap( map );
063        }
064    
065        /**
066         * get all the log types defined (predefined and custom).
067         */
068        public static List getAllLogTypes()
069        {
070            return ALL;
071        }
072    
073        public static String listAllLogTypeIds()
074        {
075            return FormatUtil.join( ", ", MAP.keySet().iterator() );
076        }
077    
078        public static LogType getLogType( String id )
079        {
080            return (LogType) MAP.get( id );
081        }
082    
083        /**
084         * Loads logtypes defined by extension mechanism: if defined, <code>logtypes</code> property in
085         * <code>logdistiller.properties</code> is the full class name of a concrete implementation of <code>LogTypes</code>
086         * class.
087         *
088         * @return List the list of every <code>LogType</code> defined by loaded <code>LogTypes</code>
089         */
090        private static List loadExtensionLogTypes()
091        {
092            Iterator iter = ExtensionHelper.findExtensions( "logtypes" ).iterator();
093            List logtypes = new ArrayList();
094            while ( iter.hasNext() )
095            {
096                String logtypesClass = (String) iter.next();
097                if ( logtypesClass != null )
098                {
099                    logtypes.addAll( loadLogTypes( logtypesClass ) );
100                }
101            }
102            return logtypes;
103        }
104    
105        private static List loadLogTypes( String logtypesClass )
106        {
107            try
108            {
109                LogTypes logtypes = (LogTypes) Class.forName( logtypesClass ).newInstance();
110                return logtypes.defineLogTypes();
111            }
112            catch ( ClassNotFoundException cnfe )
113            {
114                throw new RuntimeException( "unable to load LogTypes subclass " + logtypesClass, cnfe );
115            }
116            catch ( IllegalAccessException iae )
117            {
118                throw new RuntimeException( "unable to access LogTypes subclass constructor for " + logtypesClass, iae );
119            }
120            catch ( InstantiationException ie )
121            {
122                throw new RuntimeException( "unable to instanciate LogTypes subclass " + logtypesClass, ie );
123            }
124        }
125    }