KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcorporate > expresso > kernel > management > ComponentFactory


1 /* ====================================================================
2  * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3  *
4  * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution,
19  * if any, must include the following acknowledgment:
20  * "This product includes software developed by Jcorporate Ltd.
21  * (http://www.jcorporate.com/)."
22  * Alternately, this acknowledgment may appear in the software itself,
23  * if and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. "Jcorporate" and product names such as "Expresso" must
26  * not be used to endorse or promote products derived from this
27  * software without prior written permission. For written permission,
28  * please contact info@jcorporate.com.
29  *
30  * 5. Products derived from this software may not be called "Expresso",
31  * or other Jcorporate product names; nor may "Expresso" or other
32  * Jcorporate product names appear in their name, without prior
33  * written permission of Jcorporate Ltd.
34  *
35  * 6. No product derived from this software may compete in the same
36  * market space, i.e. framework, without prior written permission
37  * of Jcorporate Ltd. For written permission, please contact
38  * partners@jcorporate.com.
39  *
40  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43  * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This software consists of voluntary contributions made by many
55  * individuals on behalf of the Jcorporate Ltd. Contributions back
56  * to the project(s) are encouraged when you make modifications.
57  * Please send them to support@jcorporate.com. For more information
58  * on Jcorporate Ltd. and its products, please see
59  * <http://www.jcorporate.com/>.
60  *
61  * Portions of this software are based upon other open source
62  * products and are subject to their respective licenses.
63  */

64
65 package com.jcorporate.expresso.kernel.management;
66
67 import com.jcorporate.expresso.kernel.ComponentContainer;
68 import com.jcorporate.expresso.kernel.ComponentLifecycle;
69 import com.jcorporate.expresso.kernel.Containable;
70 import com.jcorporate.expresso.kernel.DefaultContainerImpl;
71 import com.jcorporate.expresso.kernel.Describable;
72 import com.jcorporate.expresso.kernel.ExpressoComponent;
73 import com.jcorporate.expresso.kernel.RootContainer;
74 import com.jcorporate.expresso.kernel.RootContainerInterface;
75 import com.jcorporate.expresso.kernel.Startable;
76 import com.jcorporate.expresso.kernel.digester.ComponentConfig;
77 import com.jcorporate.expresso.kernel.digester.ComponentMetadataConfig;
78 import com.jcorporate.expresso.kernel.exception.ConfigurationException;
79 import com.jcorporate.expresso.kernel.internal.DefaultConfigBean;
80 import com.jcorporate.expresso.kernel.metadata.ComponentMetadata;
81 import com.jcorporate.expresso.kernel.metadata.IndexedProperty;
82 import com.jcorporate.expresso.kernel.metadata.MappedProperty;
83 import com.jcorporate.expresso.kernel.metadata.Property;
84 import com.jcorporate.expresso.kernel.metadata.SimpleProperty;
85 import com.jcorporate.expresso.kernel.util.ClassLocator;
86 import org.apache.log4j.Logger;
87
88 import java.net.URL JavaDoc;
89 import java.util.Iterator JavaDoc;
90 import java.util.Map JavaDoc;
91
92 /**
93  * This class provides several helper functions to help instantiate a particular
94  * component or runtime.
95  *
96  * @author Michael Rimov
97  * @version $Revision: 1.7 $ on $Date: 2004/11/17 20:48:17 $
98  */

99
100 public class ComponentFactory {
101
102     /**
103      * The actual singleton instance
104      */

105     static final protected ComponentFactory instance = new ComponentFactory();
106
107     /**
108      * The logger for this class.
109      */

110     static Logger log = Logger.getLogger(ComponentFactory.class);
111
112     /**
113      * Default constructor
114      */

115     protected ComponentFactory() {
116     }
117
118     /**
119      * Retrieve an instance of the component factory. This provides the ability
120      * to eventually substitute other component factories.
121      *
122      * @return an instantiated Component factory
123      */

124     public static final ComponentFactory getInstance() {
125         return instance;
126     }
127
128     /**
129      * Starts a component if it implements the <code>Startable</code> interface.
130      *
131      * @param ec the component to 'start'.
132      */

133     public void startComponent(ExpressoComponent ec) {
134         if (ec instanceof Startable) {
135             if (log.isDebugEnabled()) {
136                 log.debug("Starting component: " + ec.getClass().getName());
137             }
138
139             ((Startable) ec).start();
140
141             if (log.isInfoEnabled()) {
142                 log.info("Started component: " + ec.getClass().getName());
143             }
144         } else {
145             if (log.isDebugEnabled()) {
146                 log.debug("Object " + ec.getClass().getName() +
147                         " does not implement Startable. Skipping 'start' method");
148             }
149         }
150
151     }
152
153     /**
154      * This class provides the ability to instantiated a blank component initialized
155      * only with the default values provided by the component's metadata. The
156      * component itself must be fully initialized first. (but not necessarily
157      * configured).
158      *
159      * @param component the component to retrieve a blank configuration for.
160      * @return a filled out ComponentConfig instance for this component
161      * @throws ConfigurationException upon error.
162      */

163     public ComponentConfig constructDefaultConfig(ExpressoComponent component)
164             throws ConfigurationException {
165         ComponentConfig returnValue = new ComponentConfig();
166
167         ComponentMetadata metadata = component.getMetaData();
168         Map JavaDoc properties = metadata.getProperties();
169
170
171         returnValue.setName(metadata.getName());
172
173         for (Iterator JavaDoc j = properties.values().iterator(); j.hasNext();) {
174             Property p = (Property) j.next();
175             if (p instanceof SimpleProperty) {
176                 SimpleProperty prop = (SimpleProperty) p;
177                 returnValue.addProperty(p.getName(), prop.getValue());
178             } else if (p instanceof MappedProperty) {
179                 MappedProperty prop = (MappedProperty) p;
180                 for (Iterator JavaDoc i = prop.getValues().keySet().iterator();
181                      i.hasNext();) {
182                     String JavaDoc key = (String JavaDoc) i.next();
183                     String JavaDoc oneValue = (String JavaDoc) prop.getMappedValue(key);
184                     returnValue.addMappedProperty(p.getName(), key, oneValue);
185                 }
186             } else if (p instanceof IndexedProperty) {
187                 IndexedProperty prop = (IndexedProperty) p;
188                 for (Iterator JavaDoc i = prop.getValues().keySet().iterator();
189                      i.hasNext();) {
190                     Integer JavaDoc key = (Integer JavaDoc) i.next();
191                     String JavaDoc oneValue = (String JavaDoc) prop.getIndexedValue(key.intValue());
192                     returnValue.addIndexedProperty(prop.getName(), key.intValue(), oneValue);
193                 }
194
195             } else {
196                 throw new ConfigurationException("Unknown class instance for property: "
197                         + p.getClass().getName());
198             }
199         }
200
201         return returnValue;
202     }
203
204     /**
205      * Constructs a blank component container and provides an eventual single
206      * point to change to allow people to swap different implementations of
207      * their component containers.
208      *
209      * @return an instantiated ComponentContainer.
210      */

211     public ComponentContainer constructComponentContainer() {
212         return new DefaultContainerImpl();
213     }
214
215     /**
216      * Constructs a blank root container that has not been initialized yet, but
217      * has metadata fully loaded
218      *
219      * @return an instantiated RootContainerInterface
220      * @throws ConfigurationException upon error
221      */

222     public RootContainerInterface constructRootContainer() throws ConfigurationException {
223         RootContainerInterface rci = new RootContainer();
224         ComponentContainer componentContainer = constructComponentContainer();
225         componentContainer.setContainerComponent(rci);
226         rci.setContainerImplementation(componentContainer);
227
228         //
229
//Load component metadata for global container
230
//
231
ComponentMetadataConfig metaConfig = new ComponentMetadataConfig();
232
233         if (rci instanceof Describable) {
234             try {
235                 Describable desc = (Describable) rci;
236                 metaConfig.loadComponentMetadata(desc.getMetadataLocation());
237                 desc.setMetaData(metaConfig.getMetadata());
238             } catch (IllegalArgumentException JavaDoc ex) {
239                 log.error("Error loading Root container metadata", ex);
240             }
241         }
242
243         if (rci instanceof ComponentLifecycle) {
244             ((ComponentLifecycle) rci).initialize();
245         }
246
247         return rci;
248     }
249
250     /**
251      * Constructs a Component. This method constructs the object, checks for
252      * proper type, calls initialization if provided and loads/sets metadata
253      * if provided. This function does not configure a component. [Other than setName()
254      * which is part fot he metadata process]
255      *
256      * @param parent the ComponentContainer that is the parent of this component
257      * @param config The component configuration for the object
258      * @return a fully initialized (but not configured) ExpressoComponent
259      * @throws ConfigurationException upon error
260      */

261     public ExpressoComponent constructComponent(ComponentContainer parent,
262                                                 ComponentConfig config) throws ConfigurationException {
263         try {
264             Class JavaDoc clazz = ClassLocator.loadClass(config.getClassName());
265             Object JavaDoc oneObj = clazz.newInstance();
266
267
268             if (!(oneObj instanceof ExpressoComponent)) {
269                 throw new ConfigurationException(config.getClassName()
270                         + " does not implement the ExpressoComponent interface");
271             }
272
273             ExpressoComponent ec = (ExpressoComponent) oneObj;
274             this.initComponent((ExpressoComponent) oneObj);
275
276             ec.setParent(parent.getContainerComponent());
277
278             //
279
//Load and set the metadata for the object
280
//
281
if (ec instanceof Describable) {
282                 try {
283                     Describable desc = (Describable) ec;
284                     URL JavaDoc metadataLocation = desc.getMetadataLocation();
285                     if (metadataLocation == null) {
286                         throw new ConfigurationException(desc.getClass().getName() +
287                                 ".getMetadataLocation() returned null");
288                     }
289
290                     ComponentMetadataConfig digester = new ComponentMetadataConfig();
291                     digester.loadComponentMetadata(metadataLocation);
292                     ComponentMetadata metadata = digester.getMetadata();
293                     if (metadata == null) {
294                         throw new ConfigurationException("Parsed Metadata for component " +
295                                 desc.getClass().getName() + " was null");
296                     }
297                     desc.setMetaData(metadata);
298                 } catch (Exception JavaDoc e) {
299                     log.error("Error loading component " + ec.toString(), e);
300                     throw new ConfigurationException("Error loading Expresso Container", e);
301                 }
302             }
303
304             String JavaDoc name = config.getName();
305             ec.getMetaData().setName(name);
306             parent.addComponent(ec);
307
308             if (oneObj instanceof Containable) {
309                 ComponentContainer newContainer = this.constructComponentContainer();
310                 newContainer.setContainerComponent((Containable) oneObj);
311                 ((Containable) oneObj).setContainerImplementation(newContainer);
312             }
313
314
315             return ec;
316         } catch (IllegalAccessException JavaDoc ex) {
317             throw new ConfigurationException("Error creating component: " + config.getClassName(), ex);
318         } catch (ClassNotFoundException JavaDoc ex) {
319             throw new ConfigurationException("Error creating component: " + config.getClassName(), ex);
320         } catch (InstantiationException JavaDoc ex) {
321             throw new ConfigurationException("Error creating component: " + config.getClassName(), ex);
322         }
323     }
324
325     /**
326      * Initialize the component provided if the component implements the <code>
327      * ComponentLifecycle</code> interface
328      *
329      * @param ec The ExpressoComponent
330      */

331     public void initComponent(ExpressoComponent ec) {
332         if (ec instanceof ComponentLifecycle) {
333             ((ComponentLifecycle) ec).initialize();
334         }
335     }
336
337     /**
338      * Configures a single component. (Does NOT configure sub-components)
339      *
340      * @param config the ComponentConfig for this component
341      * @param ec the Component to configure
342      * @throws ConfigurationException upon error.
343      */

344     public void configureComponent(ComponentConfig config, ExpressoComponent ec)
345             throws ConfigurationException {
346         if (ec instanceof ComponentLifecycle) {
347             ComponentMetadata metadata = ec.getMetaData();
348             Map JavaDoc properties = metadata.getProperties();
349             DefaultConfigBean targetConfig = new DefaultConfigBean();
350
351             for (Iterator JavaDoc j = properties.values().iterator(); j.hasNext();) {
352                 Property p = (Property) j.next();
353                 p.createConfigBean(targetConfig, config, metadata);
354             }
355
356
357             ((ComponentLifecycle) ec).configure(targetConfig);
358         }
359
360     }
361
362
363 }
Popular Tags