001package 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
017import java.util.*;
018
019import net.sf.logdistiller.logtypes.BaseLogTypes;
020import net.sf.logdistiller.util.ExtensionHelper;
021import 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 */
036public 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<LogType> defineLogTypes();
045
046    public static final List<LogType> ALL;
047
048    public static final Map<String, LogType> MAP;
049    static
050    {
051        List<LogType> all = new ArrayList<LogType>( new BaseLogTypes().defineLogTypes() );
052        all.addAll( loadExtensionLogTypes() );
053        ALL = Collections.unmodifiableList( all );
054
055        Map<String, LogType> map = new HashMap<String, LogType>();
056        for ( LogType type : ALL )
057        {
058            map.put( type.getId(), type );
059        }
060        MAP = Collections.unmodifiableMap( map );
061    }
062
063    /**
064     * get all the log types defined (predefined and custom).
065     */
066    public static List<LogType> getAllLogTypes()
067    {
068        return ALL;
069    }
070
071    public static String listAllLogTypeIds()
072    {
073        return FormatUtil.join( ", ", MAP.keySet().iterator() );
074    }
075
076    public static LogType getLogType( String id )
077    {
078        return (LogType) MAP.get( id );
079    }
080
081    /**
082     * Loads logtypes defined by extension mechanism: if defined, <code>logtypes</code> property in
083     * <code>logdistiller.properties</code> is the full class name of a concrete implementation of <code>LogTypes</code>
084     * class.
085     *
086     * @return List the list of every <code>LogType</code> defined by loaded <code>LogTypes</code>
087     */
088    private static List<LogType> loadExtensionLogTypes()
089    {
090        List<LogType> logtypes = new ArrayList<LogType>();
091        for ( String logtypesClass : ExtensionHelper.findExtensions( "logtypes" ) )
092        {
093            if ( logtypesClass != null )
094            {
095                logtypes.addAll( loadLogTypes( logtypesClass ) );
096            }
097        }
098        return logtypes;
099    }
100
101    private static List<LogType> loadLogTypes( String logtypesClass )
102    {
103        try
104        {
105            LogTypes logtypes = (LogTypes) Class.forName( logtypesClass ).newInstance();
106            return logtypes.defineLogTypes();
107        }
108        catch ( ClassNotFoundException cnfe )
109        {
110            throw new RuntimeException( "unable to load LogTypes subclass " + logtypesClass, cnfe );
111        }
112        catch ( IllegalAccessException iae )
113        {
114            throw new RuntimeException( "unable to access LogTypes subclass constructor for " + logtypesClass, iae );
115        }
116        catch ( InstantiationException ie )
117        {
118            throw new RuntimeException( "unable to instanciate LogTypes subclass " + logtypesClass, ie );
119        }
120    }
121}