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.plugins.BasePlugins;
020import net.sf.logdistiller.util.ExtensionHelper;
021import net.sf.logdistiller.util.FormatUtil;
022
023/**
024 * Definition of available plugins. By default, some plugins come {@link net.sf.logdistiller.plugins.BasePlugins
025 * predefined} with <b>LogDistiller</b>. You can add custom plugins:
026 * <ul>
027 * <li>1. create a new <code>LogDistillation.Plugin</code> class</li>
028 * <li>2. create a new <code>Plugins</code> class defining previous <code>Plugin</code> with a default constructor</li>
029 * <li>3. create a <code>logdistiller.properties</code> resource file which <code>plugins</code> property is the full
030 * <code>Plugins</code> class name</li>
031 * </ul>
032 */
033public abstract class Plugins
034{
035    /**
036     * get the <code>Plugin</code> instances defined by this extension.
037     *
038     * @return the list of plugins
039     * @see Plugin
040     */
041    public abstract List<Plugin> definePlugins();
042
043    public static final List<Plugin> ALL;
044
045    public static final Map<String, Plugin> MAP;
046    static
047    {
048        List<Plugin> all = new ArrayList<Plugin>( new BasePlugins().definePlugins() );
049        all.addAll( loadExtensionPlugins() );
050        ALL = Collections.unmodifiableList( all );
051
052        Map<String, Plugin> map = new HashMap<String, Plugin>();
053        for ( Plugin plugin : ALL )
054        {
055            map.put( plugin.getId(), plugin );
056        }
057        MAP = Collections.unmodifiableMap( map );
058    }
059
060    /**
061     * get all the plugins defined (predefined and custom).
062     */
063    public static List<Plugin> getAllPlugins()
064    {
065        return ALL;
066    }
067
068    public static String listAllPluginIds()
069    {
070        return FormatUtil.join( ", ", MAP.keySet().iterator() );
071    }
072
073    public static Plugin getPlugin( String id )
074    {
075        return MAP.get( id );
076    }
077
078    /**
079     * Instanciates a new distillation plugin from its distiller configuration.
080     *
081     * @param pluginConf the plugin distiller configuration
082     * @return the distillation plugin
083     * @throws PluginConfigException if the plugin type defined in the configuration does not exist
084     */
085    public static LogDistillation.Plugin newInstance( LogDistiller.Plugin pluginConf )
086    {
087        Plugin plugin = getPlugin( pluginConf.getType() );
088        if ( plugin == null )
089        {
090            throw new PluginConfigException( "plugin type '" + pluginConf.getType() + "' unknown, valid value: "
091                + listAllPluginIds() );
092        }
093        return plugin.newInstance( pluginConf );
094    }
095
096    /**
097     * Loads plugins defined by extension mechanism: if defined, <code>plugins</code> property in
098     * <code>logdistiller.properties</code> is the full class name of a concrete implementation of <code>Plugins</code>
099     * class.
100     *
101     * @return List the list of every <code>Plugin</code> defined by loaded <code>Plugins</code>
102     */
103    private static List<Plugin> loadExtensionPlugins()
104    {
105        List<Plugin> plugins = new ArrayList<Plugin>();
106        for ( String pluginsClass : ExtensionHelper.findExtensions( "plugins" ) )
107        {
108            if ( pluginsClass != null )
109            {
110                plugins.addAll( loadPlugins( pluginsClass ) );
111            }
112        }
113        return plugins;
114    }
115
116    private static List<Plugin> loadPlugins( String pluginsClass )
117    {
118        try
119        {
120            Plugins plugins = (Plugins) Class.forName( pluginsClass ).newInstance();
121            return plugins.definePlugins();
122        }
123        catch ( ClassNotFoundException cnfe )
124        {
125            throw new RuntimeException( "unable to load plugins class " + pluginsClass, cnfe );
126        }
127        catch ( IllegalAccessException iae )
128        {
129            throw new RuntimeException( "unable to access plugins constructor for class " + pluginsClass, iae );
130        }
131        catch ( InstantiationException ie )
132        {
133            throw new RuntimeException( "unable to instanciate plugins class " + pluginsClass, ie );
134        }
135    }
136}