KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > meta > info > builder > XMLTypeCreator


1 /*
2
3  ============================================================================
4                    The Apache Software License, Version 1.1
5  ============================================================================
6
7  Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
8
9  Redistribution and use in source and binary forms, with or without modifica-
10  tion, are permitted provided that the following conditions are met:
11
12  1. Redistributions of source code must retain the above copyright notice,
13     this list of conditions and the following disclaimer.
14
15  2. Redistributions in binary form must reproduce the above copyright notice,
16     this list of conditions and the following disclaimer in the documentation
17     and/or other materials provided with the distribution.
18
19  3. The end-user documentation included with the redistribution, if any, must
20     include the following acknowledgment: "This product includes software
21     developed by the Apache Software Foundation (http://www.apache.org/)."
22     Alternately, this acknowledgment may appear in the software itself, if
23     and wherever such third-party acknowledgments normally appear.
24
25  4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
26     "Apache Software Foundation" must not be used to endorse or promote
27     products derived from this software without prior written
28     permission. For written permission, please contact apache@apache.org.
29
30  5. Products derived from this software may not be called "Apache", nor may
31     "Apache" appear in their name, without prior written permission of the
32     Apache Software Foundation.
33
34  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
35  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
36  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
37  APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
38  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
39  DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
40  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
41  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
43  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44
45  This software consists of voluntary contributions made by many individuals
46  on behalf of the Apache Software Foundation. For more information on the
47  Apache Software Foundation, please see <http://www.apache.org/>.
48
49 */

50
51 package org.apache.avalon.meta.info.builder;
52
53 import java.io.InputStream JavaDoc;
54 import java.util.ArrayList JavaDoc;
55 import java.util.Properties JavaDoc;
56 import org.apache.avalon.excalibur.i18n.ResourceManager;
57 import org.apache.avalon.excalibur.i18n.Resources;
58 import org.apache.avalon.framework.Version;
59 import org.apache.avalon.framework.configuration.Configuration;
60 import org.apache.avalon.framework.configuration.ConfigurationException;
61 import org.apache.avalon.framework.context.Context;
62 import org.apache.avalon.meta.ConfigurationBuilder;
63 import org.apache.avalon.meta.info.InfoDescriptor;
64 import org.apache.avalon.meta.info.ContextDescriptor;
65 import org.apache.avalon.meta.info.DependencyDescriptor;
66 import org.apache.avalon.meta.info.EntryDescriptor;
67 import org.apache.avalon.meta.info.ExtensionDescriptor;
68 import org.apache.avalon.meta.info.CategoryDescriptor;
69 import org.apache.avalon.meta.info.ReferenceDescriptor;
70 import org.apache.avalon.meta.info.ServiceDescriptor;
71 import org.apache.avalon.meta.info.StageDescriptor;
72 import org.apache.avalon.meta.info.Type;
73 import org.apache.excalibur.configuration.ConfigurationUtil;
74 import org.xml.sax.InputSource JavaDoc;
75
76 /**
77  * Handles internalization of an XML based description of a {@link Type}
78  * from a Configuration object. The format for Configuration object
79  * is specified in the <a HREF="package-summary.html#external">package summary</a>.
80  *
81  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
82  * @version $Revision: 1.14 $ $Date: 2003/09/09 22:00:43 $
83  */

84 public class XMLTypeCreator
85     extends XMLServiceCreator implements TypeFactory
86 {
87     private static final Resources REZ =
88         ResourceManager.getPackageResources( XMLTypeCreator.class );
89
90     /**
91      * Create a {@link Type} object for specified
92      * classname, loaded from specified {@link InputStream}.
93      *
94      * @param classname The classname of Component
95      * @param inputStream the InputStream to load Type from
96      * @return the created Type
97      * @throws Exception if an error occurs
98      */

99     public Type createType( String JavaDoc classname,
100                             InputStream JavaDoc inputStream )
101         throws Exception JavaDoc
102     {
103         if( inputStream == null )
104         {
105             throw new NullPointerException JavaDoc( "input" );
106         }
107
108         final InputSource JavaDoc input = new InputSource JavaDoc( inputStream );
109         final Configuration xinfo = ConfigurationBuilder.build( input );
110         return createType( classname, xinfo, (Configuration) null );
111     }
112
113     /**
114      * Create an {@link Type} object for a specified classname from
115      * specified configuration data.
116      *
117      * @param classname The classname of Component
118      * @param info the Type configuration
119      * @param defaults the default configuration
120      * @return the created Type
121      * @throws Exception if an error occurs
122      */

123     public Type createType(
124         final String JavaDoc classname, final Configuration info, final Configuration defaults )
125         throws BuildException
126     {
127         final String JavaDoc topLevelName = info.getName();
128          
129         if( topLevelName.equals( "blockinfo" ) )
130         {
131             return new XMLLegacyCreator().createType( classname, info );
132         }
133
134         if( !topLevelName.equals( "type" ) )
135         {
136             final String JavaDoc message =
137                 REZ.getString( "builder.bad-toplevel-element.error",
138                                classname,
139                                topLevelName );
140             throw new BuildException( message );
141         }
142
143         Configuration configuration = null;
144
145         //
146
// changed the information block from "component" to "info" to
147
// avoid confusion with the "component" element definition in the
148
// meta-data level - change is backward compatible
149
//
150

151         configuration = info.getChild( "info", false );
152
153         final InfoDescriptor descriptor =
154             buildInfoDescriptor( classname, configuration );
155
156         configuration = info.getChild( "loggers" );
157         final CategoryDescriptor[] loggers = buildLoggers( configuration );
158
159         configuration = info.getChild( "context" );
160         final ContextDescriptor context = buildContext( configuration );
161
162         configuration = info.getChild( "services" );
163         final ServiceDescriptor[] services = buildServices( configuration );
164
165         configuration = info.getChild( "dependencies" );
166         final DependencyDescriptor[] dependencies =
167            buildDependencies( configuration );
168
169         configuration = info.getChild( "stages" );
170         final StageDescriptor[] phases = buildStages( configuration );
171
172         configuration = info.getChild( "extensions" );
173         final ExtensionDescriptor[] extensions = buildExtensions( configuration );
174
175         return new Type(
176           descriptor, loggers, context, services, dependencies, phases,
177           extensions, defaults );
178     }
179
180     /**
181      * Utility function to create a set of phase descriptor from a configuration.
182      * @param config a configuration containing 0..n phase elements
183      * @return an array of phase descriptors
184      * @exception Exception if a build error occurs
185      */

186     protected StageDescriptor[] buildStages( Configuration config )
187       throws BuildException
188     {
189         ArrayList JavaDoc list = new ArrayList JavaDoc();
190         Configuration[] stages = config.getChildren( "stage" );
191         for( int i = 0; i < stages.length; i++ )
192         {
193             StageDescriptor stage = buildPhase( stages[i] );
194             list.add( stage );
195         }
196         return (StageDescriptor[])list.toArray( new StageDescriptor[ 0 ] );
197     }
198
199     /**
200      * Utility function to create a set of phase descriptor from a configuration.
201      * @param config a configuration containing 0..n phase elements
202      * @return an array of phase descriptors
203      * @exception Exception if a build error occurs
204      */

205     protected StageDescriptor buildPhase( Configuration config )
206       throws BuildException
207     {
208
209         try
210         {
211             String JavaDoc id = null;
212             if( config.getAttribute( "type", null ) != null ) // legacy
213
{
214                 id = config.getAttribute( "type" );
215             }
216             else if( config.getAttribute( "key", null ) != null ) // legacy
217
{
218                id = config.getAttribute( "key" );
219             }
220
221             if( id == null ) id = config.getAttribute( "id" ); // standard
222

223             final Properties JavaDoc attributes =
224               buildAttributes( config.getChild( "attributes" ) );
225             return new StageDescriptor( id, attributes );
226         }
227         catch( Throwable JavaDoc e )
228         {
229             final String JavaDoc error =
230               "Unable to construct a stage descriptor from source fragment:"
231               + ConfigurationUtil.list( config );
232             throw new BuildException( error, e );
233         }
234     }
235
236     /**
237      * A utility method to build a {@link ReferenceDescriptor}
238      * object from specified configuration data.
239      *
240      * @param service the service Configuration
241      * @return the created ReferenceDescriptor
242      * @throws ConfigurationException if an error occurs
243      */

244     protected ReferenceDescriptor buildReferenceDescriptor( final Configuration service )
245         throws BuildException
246     {
247         return buildReferenceDescriptor( service, null );
248     }
249
250     /**
251      * A utility method to build a {@link ReferenceDescriptor}
252      * object from specified configuration data.
253      *
254      * @param service the service Configuration
255      * @param classname the default type classname
256      * @return the created ReferenceDescriptor
257      * @throws ConfigurationException if an error occurs
258      */

259     protected ReferenceDescriptor buildReferenceDescriptor( final Configuration service, String JavaDoc classname )
260         throws BuildException
261     {
262         final String JavaDoc type = service.getAttribute("type", classname );
263         if( type == null )
264         {
265             final String JavaDoc error =
266               "Missing 'type' attribute in configuration: "
267               + ConfigurationUtil.list( service );
268             throw new BuildException( error );
269         }
270         if( type.indexOf( ":" ) > -1 )
271         {
272             return createReference( type );
273         }
274         final String JavaDoc versionString = service.getAttribute( "version", "1.0" );
275         final Version version = buildVersion( versionString );
276         return new ReferenceDescriptor( type, version );
277     }
278
279     /**
280      * A utility method to build an array of {@link CategoryDescriptor} objects
281      * from specified configuraiton.
282      *
283      * @param configuration the loggers configuration
284      * @return the created CategoryDescriptor
285      * @throws ConfigurationException if an error occurs
286      */

287     protected CategoryDescriptor[] buildLoggers( final Configuration configuration )
288         throws BuildException
289     {
290         final Configuration[] elements = configuration.getChildren( "logger" );
291         final ArrayList JavaDoc loggers = new ArrayList JavaDoc();
292
293         for( int i = 0; i < elements.length; i++ )
294         {
295             final CategoryDescriptor logger = buildLogger( elements[ i ] );
296             loggers.add( logger );
297         }
298
299         return (CategoryDescriptor[])loggers.toArray( new CategoryDescriptor[ loggers.size() ] );
300     }
301
302     /**
303      * A utility method to build a {@link CategoryDescriptor}
304      * object from specified configuraiton.
305      *
306      * @param logger the Logger configuration
307      * @return the created CategoryDescriptor
308      * @throws ConfigurationException if an error occurs
309      */

310     private CategoryDescriptor buildLogger( Configuration logger )
311         throws BuildException
312     {
313         final Properties JavaDoc attributes = buildAttributes( logger.getChild( "attributes" ) );
314         final String JavaDoc name = logger.getAttribute( "name", "" );
315         return new CategoryDescriptor( name, attributes );
316     }
317
318     /**
319      * A utility method to build an array of {@link DependencyDescriptor}
320      * objects from specified configuration.
321      *
322      * @param configuration the dependencies configuration
323      * @return the created DependencyDescriptor
324      * @throws ConfigurationException if an error occurs
325      */

326     public DependencyDescriptor[] buildDependencies( final Configuration configuration )
327         throws BuildException
328     {
329         final Configuration[] elements = configuration.getChildren( "dependency" );
330         final ArrayList JavaDoc dependencies = new ArrayList JavaDoc();
331
332         for( int i = 0; i < elements.length; i++ )
333         {
334             final DependencyDescriptor dependency =
335                 buildDependency( elements[ i ] );
336             dependencies.add( dependency );
337         }
338
339         return (DependencyDescriptor[])dependencies.toArray( new DependencyDescriptor[ 0 ] );
340     }
341
342     /**
343      * A utility method to build a {@link DependencyDescriptor}
344      * object from specified configuraiton.
345      *
346      * @param dependency the dependency configuration
347      * @return the created DependencyDescriptor
348      * @throws BuildException if an error occurs
349      */

350     protected DependencyDescriptor buildDependency( final Configuration dependency )
351         throws BuildException
352     {
353         String JavaDoc role = dependency.getAttribute( "role", null ); // legacy
354
if( role == null )
355         {
356             role = dependency.getAttribute( "key", null );
357         }
358         ReferenceDescriptor reference =
359           buildReferenceDescriptor( dependency );
360         
361         final boolean optional =
362            dependency.getAttributeAsBoolean( "optional", false );
363         final Properties JavaDoc attributes =
364             buildAttributes( dependency.getChild( "attributes" ) );
365
366         //
367
// default to name of service if role unspecified
368
//
369

370         if( null == role )
371         {
372             role = reference.getClassname();
373         }
374
375         return new DependencyDescriptor( role, reference, optional, attributes );
376     }
377
378     /**
379      * A utility method to build a {@link ContextDescriptor}
380      * object from specified configuraiton.
381      *
382      * @param context the dependency configuration
383      * @return the created ContextDescriptor
384      * @throws ConfigurationException if an error occurs
385      */

386     protected ContextDescriptor buildContext( final Configuration context )
387         throws BuildException
388     {
389         final EntryDescriptor[] entrys =
390           buildEntries( context.getChildren( "entry" ) );
391
392         final Properties JavaDoc attributes =
393           buildAttributes( context.getChild( "attributes" ) );
394
395         String JavaDoc classname = context.getAttribute( "type", null );
396
397         return new ContextDescriptor( classname, entrys, attributes );
398     }
399
400
401     /**
402      * A utility method to build an array of {@link ServiceDescriptor}
403      * objects from specified configuraiton.
404      *
405      * @param servicesSet the services configuration
406      * @return the created ServiceDescriptor
407      * @throws ConfigurationException if an error occurs
408      */

409     public ServiceDescriptor[] buildServices( final Configuration servicesSet )
410         throws BuildException
411     {
412         final Configuration[] elements = servicesSet.getChildren( "service" );
413         final ArrayList JavaDoc services = new ArrayList JavaDoc();
414
415         for( int i = 0; i < elements.length; i++ )
416         {
417             final ServiceDescriptor service = buildService( elements[ i ] );
418             services.add( service );
419         }
420
421         return (ServiceDescriptor[])services.toArray( new ServiceDescriptor[ 0 ] );
422     }
423
424     /**
425      * A utility method to build a <code>ServiceDescriptor</code>
426      * object from specified configuraiton data.
427      *
428      * @param service the service Configuration
429      * @return the created ServiceDescriptor
430      * @throws ConfigurationException if an error occurs
431      */

432     public ServiceDescriptor buildService( final Configuration service )
433         throws BuildException
434     {
435         ReferenceDescriptor reference = buildReferenceDescriptor( service );
436         final Properties JavaDoc attributes =
437             buildAttributes( service.getChild( "attributes" ) );
438         return new ServiceDescriptor( reference, attributes );
439     }
440
441     /**
442      * A utility method to build a {@link InfoDescriptor}
443      * object from specified configuraiton data and classname.
444      *
445      * @param classname The classname of Component (used to create descriptor)
446      * @param info the component info configuration fragment
447      * @return the created InfoDescriptor
448      * @throws ConfigurationException if an error occurs
449      */

450     public InfoDescriptor buildInfoDescriptor(
451       final String JavaDoc classname, final Configuration info )
452       throws BuildException
453     {
454         final String JavaDoc name =
455           info.getChild( "name" ).getValue( null );
456         final Version version =
457           buildVersion( info.getChild( "version" ).getValue( "1.0" ) );
458         final String JavaDoc schema =
459           info.getChild( "schema" ).getValue( null );
460         final Properties JavaDoc attributes =
461             buildAttributes( info.getChild( "attributes" ) );
462         final String JavaDoc lifestyle =
463           buildLifestyle( info, attributes );
464         return new InfoDescriptor(
465           name, classname, version, lifestyle, schema, attributes );
466     }
467
468    /**
469     * Handle the resolution of the component lifestyle. Normally this is
470     * resolved by retrieving the &lt;lifestyle&gt; element value, however, for
471     * backward compatability - if the lifecycle element is not present, we will
472     * attempt to resolve the lifestyle using the attribute value relative to the
473     * key urn:avalon:lifestyle.
474     *
475     * @param info the info configuration fragment
476     * @param attributes the component attributes
477     * @return the lifestyle policy value
478     */

479     private String JavaDoc buildLifestyle( Configuration info, Properties JavaDoc attributes )
480     {
481         String JavaDoc lifestyle = info.getChild( "lifestyle" ).getValue( null );
482         if( lifestyle != null )
483         {
484             return lifestyle;
485         }
486         else
487         {
488             return attributes.getProperty( "urn:avalon:lifestyle" );
489         }
490     }
491
492     /**
493      * Utility function to create a set of phase descriptor from a configuration.
494      * @param config a configuration containing 0..n phase elements
495      * @return an array of phase descriptors
496      * @exception Exception if a build error occurs
497      */

498     protected ExtensionDescriptor[] buildExtensions( Configuration config )
499       throws BuildException
500     {
501         ArrayList JavaDoc list = new ArrayList JavaDoc();
502         Configuration[] extensions = config.getChildren( "extension" );
503         for( int i = 0; i < extensions.length; i++ )
504         {
505             list.add( buildExtension( extensions[i] ) );
506         }
507         return (ExtensionDescriptor[])list.toArray( new ExtensionDescriptor[ 0 ] );
508     }
509
510     /**
511      * Utility function to create an extension descriptor from a configuration.
512      * @param config a configuration containing the extension definition
513      * @return the extension descriptor
514      * @exception Exception if a build error occurs
515      */

516     protected ExtensionDescriptor buildExtension( Configuration config )
517       throws BuildException
518     {
519         if( config.getAttribute( "type", null ) != null ) // legacy
520
{
521             String JavaDoc urn = config.getAttribute( "type", null );
522             final Properties JavaDoc attributes =
523               buildAttributes( config.getChild( "attributes" ) );
524             return new ExtensionDescriptor( urn, attributes );
525         }
526         else
527         {
528             String JavaDoc id = config.getAttribute( "urn", null ); // legacy
529
if( id == null )
530             {
531                try
532                {
533                    id = config.getAttribute( "id" );
534                }
535                catch( ConfigurationException e )
536                {
537                    final String JavaDoc error =
538                      "Missing extensions identifier 'id' attribute."
539                      + ConfigurationUtil.list( config );
540                    throw new BuildException( error, e );
541                }
542             }
543             final Properties JavaDoc attributes =
544               buildAttributes( config.getChild( "attributes" ) );
545             return new ExtensionDescriptor( id, attributes );
546         }
547     }
548
549    /**
550     * Creation of a reference descriptor from the supplied path.
551     * @param path the classname
552     * @return the reference descriptor
553     */

554     public ReferenceDescriptor createReference( String JavaDoc path )
555       throws BuildException
556     {
557         final String JavaDoc type;
558         final Version version;
559         int index = path.indexOf(":");
560         if( index > -1 )
561         {
562             type = path.substring( 0, index );
563             version = buildVersion( path.substring( index + 1 ) );
564         }
565         else
566         {
567             type = path;
568             version = buildVersion( "1.0.0" );
569         }
570
571         return new ReferenceDescriptor( type, version );
572     }
573 }
574
Popular Tags