KickJava   Java API By Example, From Geeks To Geeks.

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


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 org.apache.avalon.excalibur.i18n.ResourceManager;
55 import org.apache.avalon.excalibur.i18n.Resources;
56 import org.apache.avalon.meta.info.Type;
57 import org.apache.avalon.framework.configuration.Configuration;
58 import org.apache.avalon.framework.configuration.DefaultConfiguration;
59 import org.apache.avalon.framework.configuration.ConfigurationException;
60 import org.apache.avalon.meta.ConfigurationBuilder;
61 import org.xml.sax.InputSource JavaDoc;
62
63 /**
64  * A TypeBuilder is responsible for building {@link Type}
65  * objects from Configuration objects. The format for Configuration object
66  * is specified in the <a HREF="package-summary.html#external">package summary</a>.
67  *
68  * <p><b>UML</b></p>
69  * <p><image SRC="doc-files/TypeBuilder.gif" border="0"/></p>
70  *
71  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
72  * @version $Revision: 1.7 $ $Date: 2003/07/24 12:12:01 $
73  */

74 public final class TypeBuilder
75 {
76     private static final Resources REZ =
77         ResourceManager.getPackageResources( TypeBuilder.class );
78
79     private final TypeFactory m_xmlTypeFactory = createxmlTypeFactory();
80     private final TypeCreator m_serialTypeCreator = new SerializedTypeCreator();
81
82     /**
83      * Create a {@link Type} object for specified Class.
84      *
85      * @param clazz The class of Component
86      * @return the created Type
87      * @throws Exception if an error occurs
88      */

89     public Type buildType( final Class JavaDoc clazz )
90         throws Exception JavaDoc
91     {
92         //
93
// build the configuration defaults and the profiles and
94
// supply these as arguments to thye type build
95
//
96

97         final Type info = buildFromSerDescriptor( clazz );
98         if( null != info )
99         {
100             return info;
101         }
102         else
103         {
104             return buildFromXMLDescriptor( clazz );
105         }
106     }
107
108     /**
109      * Build Type from the XML descriptor format.
110      *
111      * @param clazz The class for Component
112      * @return the created Type
113      * @throws Exception if an error occurs
114      */

115     private Type buildFromSerDescriptor( final Class JavaDoc clazz )
116         throws Exception JavaDoc
117     {
118         Type type = buildFromSerDescriptor( clazz, ".ztype" );
119         if( type != null )
120         {
121             return type;
122         }
123         else
124         {
125             return buildFromSerDescriptor( clazz, ".zinfo" );
126         }
127     }
128
129     private Type buildFromSerDescriptor( final Class JavaDoc clazz, String JavaDoc form )
130         throws Exception JavaDoc
131     {
132         final String JavaDoc classname = clazz.getName();
133         final ClassLoader JavaDoc classLoader = clazz.getClassLoader();
134         final String JavaDoc address = classname.replace( '.', '/' ) + form;
135         final InputStream JavaDoc stream =
136             classLoader.getResourceAsStream( address );
137         if( null == stream )
138         {
139             return null;
140         }
141         return m_serialTypeCreator.createType( classname, stream );
142     }
143
144     /**
145      * Build Type from the XML descriptor format. The implementation
146      * will attempt to locate a &lt;classname&gt;.xtype resource. If
147      * not found, the implementation will attempt to locate
148      * a &lt;classname&gt;.info resource. Once a resource is established
149      * the type will be resolved relative to the root element. Normally
150      * the root element is a &lttype&gt;, however the implementation
151      * also recognises the legacy &lt;blockinfo&gt; schema.
152      *
153      * @param clazz The class for Component
154      * @return the created Type
155      * @throws Exception if an error occurs
156      */

157     private Type buildFromXMLDescriptor( Class JavaDoc clazz )
158         throws Exception JavaDoc
159     {
160         final String JavaDoc classname = clazz.getName();
161         final ClassLoader JavaDoc classLoader = clazz.getClassLoader();
162
163         final TypeFactory xmlTypeFactory = getXMLTypeFactory();
164
165         //
166
// get the input stream for the .xtype resource
167
//
168

169         String JavaDoc path =
170             classname.replace( '.', '/' ) + ".xtype";
171         InputStream JavaDoc inputStream =
172             classLoader.getResourceAsStream( path );
173
174         if( null == inputStream )
175         {
176             path =
177               classname.replace( '.', '/' ) + ".xinfo";
178             inputStream =
179               classLoader.getResourceAsStream( path );
180         }
181
182         if( null == inputStream )
183         {
184             final String JavaDoc message =
185                 REZ.getString( "builder.missing-info.error" );
186             throw new Exception JavaDoc( message );
187         }
188
189         final InputSource JavaDoc inputSource = new InputSource JavaDoc( inputStream );
190         final Configuration xinfo = ConfigurationBuilder.build( inputSource );
191
192         final String JavaDoc xdefaults =
193             classname.replace( '.', '/' ) + ".xconfig";
194         final InputStream JavaDoc defaultsStream =
195             classLoader.getResourceAsStream( xdefaults );
196
197         Configuration defaults;
198         if( defaultsStream != null )
199         {
200             final InputSource JavaDoc defaultsSource = new InputSource JavaDoc( defaultsStream );
201             defaults = resolveConfiguration(
202               classLoader, ConfigurationBuilder.build( defaultsSource ) );
203         }
204         else
205         {
206             defaults = new DefaultConfiguration( "configuration", (String JavaDoc) null );
207         }
208
209         //
210
// build the type
211
//
212

213         return xmlTypeFactory.createType( classname, xinfo, defaults );
214     }
215
216     private Configuration resolveConfiguration( ClassLoader JavaDoc classloader, Configuration config )
217       throws Exception JavaDoc
218     {
219         if( config == null )
220         {
221             throw new NullPointerException JavaDoc("config");
222         }
223         String JavaDoc src = config.getAttribute( "src", null );
224         if( src == null )
225         {
226             return config;
227         }
228         else
229         {
230             if( src.startsWith( "resource://" ) )
231             {
232                 final String JavaDoc url = src.substring( 11 );
233                 final InputStream JavaDoc stream =
234                     classloader.getResourceAsStream( url );
235                 if( null == stream )
236                 {
237                     final String JavaDoc error =
238                         "Requested configuration source does not exist: " + src;
239                     throw new ConfigurationException( error );
240                 }
241                 final InputSource JavaDoc source = new InputSource JavaDoc( stream );
242                 return resolveConfiguration(
243                   classloader, ConfigurationBuilder.build( source ) );
244             }
245             else
246             {
247                 try
248                 {
249                     return resolveConfiguration(
250                       classloader, ConfigurationBuilder.build( src ) );
251                 }
252                 catch( Throwable JavaDoc e )
253                 {
254                     final String JavaDoc error =
255                         "Unexpected exception while attempting to resolve configuration from src : "
256                         + src;
257                     throw new ConfigurationException( error, e );
258                 }
259             }
260         }
261     }
262
263     /**
264      * Utility to get xml info builder, else throw
265      * an exception if missing descriptor.
266      *
267      * @return the TypeCreator
268      */

269     private TypeFactory getXMLTypeFactory()
270         throws Exception JavaDoc
271     {
272         if( null != m_xmlTypeFactory )
273         {
274             return m_xmlTypeFactory;
275         }
276         else
277         {
278             final String JavaDoc message =
279                 REZ.getString( "builder.missing-xml-creator.error" );
280             throw new Exception JavaDoc( message );
281         }
282     }
283
284     /**
285      * Utility to get xmlTypeFactory if XML files are on
286      * ClassPath.
287      *
288      * @return the XML {@link TypeFactory}
289      */

290     private static TypeFactory createxmlTypeFactory()
291     {
292         TypeFactory xmlTypeFactory = null;
293         try
294         {
295             xmlTypeFactory = new XMLTypeCreator();
296         }
297         catch( final Exception JavaDoc e )
298         {
299             //Ignore it if ClassNot found due to no
300
//XML Classes on classpath
301
}
302         return xmlTypeFactory;
303     }
304 }
305
Popular Tags