View Javadoc

    1   package org.apache.stratum.component;
    2
    3   /*
    4    * Copyright 2001-2005 The Apache Software Foundation or its licensors,
    5    * as applicable.
    6    *
    7    * Licensed under the Apache License, Version 2.0 (the "License");
    8    * you may not use this file except in compliance with the License.
    9    * You may obtain a copy of the License at
    10   *
    11   *     http://www.apache.org/licenses/LICENSE-2.0
    12   *
    13   * Unless required by applicable law or agreed to in writing, software
    14   * distributed under the License is distributed on an "AS IS" BASIS,
    15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16   * See the License for the specific language governing permissions and
    17   * limitations under the License.
    18   */
    19
    20  import java.io.IOException;
    21  import java.util.List;
    22
    23  import org.apache.commons.configuration.CompositeConfiguration;
    24  import org.apache.commons.configuration.Configuration;
    25  import org.apache.commons.configuration.PropertiesConfiguration;
    26  import org.apache.log4j.Category;
    27  import org.apache.stratum.lifecycle.Configurable;
    28  import org.apache.stratum.lifecycle.Initializable;
    29
    30  /***
    31   * Loader for Components implementing the lifecyle Interfaces. NOTE: This class is in its infancy and will more than likely change.
    32   *
    33   * @author <a href="mailto:eric NOSPAM dobbse.net">Eric Dobbs </a>
    34   * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl </a>
    35   * @version $Id: ComponentLoader.java 264191 2005-08-29 18:07:52Z henning $
    36   */
    37  public class ComponentLoader
    38  {
    39      /*** Log4j category used for logging. NOTE: we should change this to use the commons-logging API. */
    40      private static Category log = Category.getInstance(ComponentLoader.class);
    41
    42      /*** Component tag used in Configurations */
    43      private static String COMPONENT = "component";
    44
    45      /*** Class name tag used in Configurations */
    46      private static String CLASSNAME = "classname";
    47
    48      /*** Extension used for Configuration files. */
    49      private static String CONFIG = "config";
    50
    51      /*** Extension used for Additional properties. */
    52      private static String PROPERTY = "property";
    53
    54      /*** Name tag used in Configurations */
    55      private static String NAME = "name";
    56
    57      /*** Configuration used by this ComponentLoader. */
    58      private Configuration configuration;
    59
    60      /***
    61       * Constructor
    62       *
    63       * @param configuration
    64       */
    65      public ComponentLoader(Configuration configuration)
    66      {
    67          this.configuration = configuration;
    68      }
    69
    70      /***
    71       * Set the configuration for this ComponentLoader
    72       *
    73       * @param configuration Configuration
    74       */
    75      public void setConfiguration(Configuration configuration)
    76      {
    77          this.configuration = configuration;
    78      }
    79
    80      /***
    81       * Support method for testing the constructor
    82       *
    83       * @return the configuration
    84       */
    85      public Configuration getConfiguration()
    86      {
    87          return configuration;
    88      }
    89
    90      /***
    91       * <p>
    92       * Load all the components listed in the ComponentLoader's configuration. Log any errors, but throw no exceptions if components
    93       * cannot be loaded.
    94       * </p>
    95       * Configuration notes:<br>
    96       * Components are identified in the properties file as follows: <br>
    97       * <code> component.name=NAME component.NAME.classname = com.mycompany.components.SomeComponent component.NAME.config    =
    98       * path/to/SomeComponent.properties </code>
    99       *
    100      * @return an array of loaded components
    101      */
    102     public Object [] load()
    103     {
    104         List components = configuration.getList(COMPONENT + '.' + NAME);
    105         Object [] loadedComponents = new Object[components.size()];
    106
    107         String componentName;
    108         String componentClassName;
    109         String componentConfig;
    110         Configuration componentAdditionalConfig;
    111
    112         for (int i = 0; i < components.size(); i++)
    113         {
    114             componentName = (String) components.get(i);
    115             componentClassName = getComponentClassname(componentName);
    116             componentConfig = getComponentConfigFile(componentName);
    117             componentAdditionalConfig = getComponentAdditionalConfig(componentName);
    118
    119             log.info("loading component: name=" + componentName + " class=" + componentClassName + " config=" + componentConfig);
    120
    121             loadedComponents[i] = loadComponent(componentClassName, componentConfig, componentAdditionalConfig);
    122         }
    123
    124         return loadedComponents;
    125     }
    126
    127     /***
    128      * load the given component, configure it with the given config file, and initialize it. <br>
    129      * The component must implement the <code>Initializable</code> and <code>Configurable</code> interfaces.
    130      *
    131      * @param className the String class name of the component to load
    132      * @param configFile the String path name of the component's config file
    133      * @param additionalConfig TODO: DOCUMENT ME!
    134      *
    135      * @return the loaded component or null if it failed to load
    136      *
    137      * @see Initializable
    138      * @see Configurable
    139      */
    140     public Object loadComponent(String className, String configFile, Configuration additionalConfig)
    141     {
    142         Object component = null;
    143
    144         if (log.isDebugEnabled())
    145         {
    146             log.debug("attempting to load '" + className + "' with the config file '" + configFile + "'.");
    147         }
    148
    149         try
    150         {
    151             component = Class.forName(className).newInstance();
    152
    153             // configure component using the given config file
    154             CompositeConfiguration config = new CompositeConfiguration();
    155             config.addConfiguration(new PropertiesConfiguration(configFile));
    156             config.addConfiguration(additionalConfig);
    157             ((Configurable) component).configure(config);
    158
    159             // initialize component
    160             ((Initializable) component).initialize();
    161
    162             if (log.isDebugEnabled())
    163             {
    164                 log.debug("good news! " + className + " successfully configured and initialized");
    165             }
    166         }
    167         catch (IOException ioe)
    168         {
    169             log.error(className + " could not be configured with file '" + configFile + "'.", ioe);
    170         }
    171         catch (Exception e)
    172         {
    173             log.error(className + " could not be initialized!", e);
    174         }
    175
    176         return component;
    177     }
    178
    179     /***
    180      * <p>
    181      * Get the component's classname as defined in the ComponentLoader configuration.
    182      * </p>
    183      *
    184      * <p>
    185      * Example property: <br/> component.NAME.classname=com.mycompany.components.MyComponent
    186      * </p>
    187      *
    188      * @param name the String NAME of the component in the classfile
    189      *
    190      * @return the configured classname
    191      */
    192     private String getComponentClassname(String name)
    193     {
    194         return configuration.getString(COMPONENT + '.' + name + '.' + CLASSNAME);
    195     }
    196
    197     /***
    198      * <p>
    199      * Get the component's config file as defined in the ComponentLoader configuration.
    200      * </p>
    201      *
    202      * <p>
    203      * Example property: <br/>component.NAME.config=path/to/your/config
    204      * </p>
    205      *
    206      * @param name the String NAME of the component in the classfile
    207      *
    208      * @return the configured config file
    209      */
    210     private String getComponentConfigFile(String name)
    211     {
    212         return configuration.getString(COMPONENT + '.' + name + '.' + CONFIG);
    213     }
    214
    215     /***
    216      * <p>
    217      * Get any additional configuration properties from the master configuration.
    218      * </p>
    219      *
    220      * <p>
    221      * Example property: <br/>
    222      * component.NAME.property.key1==value1 <br/>
    223      * component.NAME.property.key2==value2 <br/>
    224      * component.NAME.property.key3==value3 <br/>
    225      * </p>
    226      *
    227      * @param name the String NAME of the component in the classfile
    228      *
    229      * @return the extra properties as a Configuration object
    230      */
    231     private Configuration getComponentAdditionalConfig(String name)
    232     {
    233         return configuration.subset(COMPONENT + '.' + name + '.' + PROPERTY);
    234     }
    235 }