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