KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > repository > main > DefaultBuilder


1 /*
2  * Copyright 2004 Apache Software Foundation
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12  * implied.
13  *
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.avalon.repository.main;
19
20 import java.io.File JavaDoc;
21 import java.io.InputStream JavaDoc;
22 import java.io.FileInputStream JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.util.Properties JavaDoc;
25
26 import javax.naming.directory.Attributes JavaDoc;
27
28 import org.apache.avalon.repository.Artifact;
29 import org.apache.avalon.repository.Repository;
30 import org.apache.avalon.repository.RepositoryException;
31 import org.apache.avalon.repository.RepositoryRuntimeException;
32 import org.apache.avalon.repository.meta.FactoryDescriptor;
33 import org.apache.avalon.repository.provider.Builder;
34 import org.apache.avalon.repository.provider.InitialContext;
35 import org.apache.avalon.repository.provider.Factory;
36
37
38 /**
39  * Application and component bootstrapper used to instantiate, and or invoke
40  * Classes and their methods within newly constructed Repository ClassLoaders.
41  *
42  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
43  * @version $Revision: 1.16 $
44  */

45 public class DefaultBuilder extends AbstractBuilder implements Builder
46 {
47     //-----------------------------------------------------------
48
// public static
49
//-----------------------------------------------------------
50

51    /**
52     * Resolve the default implementation taking into account
53     * local and home properties, and application defaults.
54     * @param classloader the embedding classloader
55     * @param base the base directory
56     * @param resource a properties filename
57     * @param key a property key containing an artifact specification
58     * @return the artifact reference
59     */

60     public static Artifact createImplementationArtifact(
61       ClassLoader JavaDoc classloader, File JavaDoc base,
62       String JavaDoc resource, String JavaDoc key ) throws Exception JavaDoc
63     {
64         return createImplementationArtifact(
65           classloader, null, base, resource, key );
66     }
67
68    /**
69     * Resolve the default implementation taking into account
70     * local and home properties, and application defaults.
71     * @param classloader the embedding classloader
72     * @param system the application system home directory
73     * @param base the base directory
74     * @param resource a properties filename
75     * @param key a property key containing an artifact specification
76     * @return the artifact reference
77     */

78     public static Artifact createImplementationArtifact(
79       ClassLoader JavaDoc classloader, File JavaDoc system, File JavaDoc base,
80       String JavaDoc resource, String JavaDoc key ) throws Exception JavaDoc
81     {
82         //
83
// check for the implementation property in the
84
// working directory
85
//
86

87         String JavaDoc spec =
88           getLocalProperties( base, resource ).getProperty( key );
89        
90         //
91
// check for the implementation property in the
92
// user's home directory
93
//
94

95         if( null == spec )
96         {
97             spec =
98               getLocalProperties( USER, resource ).getProperty( key );
99         }
100
101         //
102
// check for the implementation property in the
103
// applications home directory
104
//
105

106         if( null == spec )
107         {
108             spec =
109               getLocalProperties( system, resource ).getProperty( key );
110         }
111
112         //
113
// check for the implementation property in the
114
// classloader
115
//
116

117         if( null == spec )
118         {
119             Properties JavaDoc properties = new Properties JavaDoc();
120             InputStream JavaDoc input = classloader.getResourceAsStream( resource );
121             if( input == null )
122             {
123                 final String JavaDoc error =
124                   "Missing resource: [" + resource + "]";
125                 throw new IllegalStateException JavaDoc( error );
126             }
127             properties.load( input );
128             spec = properties.getProperty( key );
129             if( spec == null )
130             {
131                 final String JavaDoc error =
132                   "Missing property: [" + key + "] in resource: [" + resource + "]";
133                 throw new IllegalStateException JavaDoc( error );
134             }
135         }
136
137         //
138
// return the artifact referencing the implementation to be loaded
139
//
140

141         return Artifact.createArtifact( spec );
142     }
143
144     //-----------------------------------------------------------
145
// private static
146
//-----------------------------------------------------------
147

148     private static Properties JavaDoc getLocalProperties(
149       File JavaDoc dir, String JavaDoc filename ) throws IOException JavaDoc
150     {
151         Properties JavaDoc properties = new Properties JavaDoc();
152         if( null == dir ) return properties;
153         File JavaDoc file = new File JavaDoc( dir, filename );
154         if( !file.exists() ) return properties;
155         properties.load( new FileInputStream JavaDoc( file ) );
156         return properties;
157     }
158
159     private static final File JavaDoc USER =
160       new File JavaDoc( System.getProperty( "user.home" ) );
161
162     //-----------------------------------------------------------
163
// immutable state
164
//-----------------------------------------------------------
165

166    /**
167     * The repository established by the loader that will be used
168     * to cache the resources needed to establish the application
169     * classloader.
170     */

171     private final Repository m_repository;
172     
173    /**
174     * The classloader established by the loader used to load the
175     * the application factory.
176     */

177     private final ClassLoader JavaDoc m_classloader;
178     
179    /**
180     * The initial repository factory that may be supplied to
181     * application factories as a constructor argument for applications
182     * that need to create their own repositories.
183     */

184     private final InitialContext m_context;
185     
186    /**
187     * The factory class established by the builder.
188     */

189     private final Class JavaDoc m_class;
190
191    /**
192     * The factory instance.
193     */

194     private final Factory m_delegate;
195
196     //-----------------------------------------------------------
197
// constructors
198
//-----------------------------------------------------------
199

200    /**
201     * Creates a DefaultBuilder for a specific target application.
202     *
203     * @param context the initial repository context
204     * @param artifact the reference to the application
205     * @exception RepositoryException if a app factory creation error occurs
206     */

207     public DefaultBuilder( InitialContext context, Artifact artifact )
208         throws Exception JavaDoc
209     {
210         this( context, null, artifact );
211     }
212     
213    /**
214     * Creates a DefaultBuilder for a specific target application.
215     *
216     * @param context the initial repository context
217     * @param classloader the parent classloader
218     * @param artifact the reference to the application
219     * @exception Exception if a app factory creation error occurs
220     */

221     public DefaultBuilder(
222       InitialContext context, ClassLoader JavaDoc classloader, Artifact artifact )
223       throws Exception JavaDoc
224     {
225         if( null == context ) throw new NullPointerException JavaDoc( "context" );
226         if( null == artifact ) throw new NullPointerException JavaDoc( "artifact" );
227
228         m_context = context;
229
230         ClassLoader JavaDoc parent = getClassLoader( classloader );
231
232         m_repository = m_context.getRepository();
233
234         Attributes JavaDoc attributes = m_repository.getAttributes( artifact );
235         FactoryDescriptor descriptor = new FactoryDescriptor( attributes );
236         String JavaDoc classname = descriptor.getFactory();
237         if( null == classname )
238         {
239             final String JavaDoc error =
240               "Required property 'avalon.artifact.factory' not present in artifact: ["
241               + artifact + "] under the active repository: [" + m_repository + "].";
242             throw new IllegalArgumentException JavaDoc( error );
243         }
244
245         m_classloader = m_repository.getClassLoader( parent, artifact );
246         m_class = loadFactoryClass( m_classloader, classname );
247
248         if( Factory.class.isAssignableFrom( m_class ) )
249         {
250             try
251             {
252                 m_delegate = createDelegate( m_classloader, m_class, m_context );
253             }
254             catch( Throwable JavaDoc e )
255             {
256                 final String JavaDoc error =
257                   "Unable to establish a factory for the supplied artifact:";
258                 StringBuffer JavaDoc buffer = new StringBuffer JavaDoc( error );
259                 buffer.append( "\n artifact: " + artifact );
260                 buffer.append( "\n build: " + descriptor.getBuild() );
261                 buffer.append( "\n factory: " + descriptor.getFactory() );
262                 buffer.append( "\n source: "
263                   + m_class.getProtectionDomain().getCodeSource().getLocation() );
264                 buffer.append( "\n repository: " + m_repository );
265                 throw new RepositoryException( buffer.toString(), e );
266             }
267         }
268         else
269         {
270             m_delegate = null;
271         }
272     }
273
274     //-----------------------------------------------------------
275
// Builder
276
//-----------------------------------------------------------
277

278    /**
279     * Return the primary class established by the builder.
280     * @return the main class
281     */

282     public Class JavaDoc getFactoryClass()
283     {
284         return m_class;
285     }
286
287    /**
288     * Return the factory established by the loader.
289     * @return the delegate factory
290     * @exception RepositoryRuntimeException if the declared class does
291     * not implement the factory interface
292     * @see #getFactoryClass
293     */

294     public Factory getFactory()
295     {
296         if( null != m_delegate )
297         {
298             return m_delegate;
299         }
300         else
301         {
302             final String JavaDoc error =
303               "Supplied class [" + m_class.getName()
304               + "] does not implement the Factory interface.";
305             throw new RepositoryRuntimeException( error );
306         }
307     }
308
309     /**
310      * Gets the ClassLoader used by this Bootstrapper.
311      *
312      * @return the ClassLoader built by the Repository
313      */

314     public ClassLoader JavaDoc getClassLoader()
315     {
316         return m_classloader;
317     }
318     
319     //-----------------------------------------------------------
320
// internal
321
//-----------------------------------------------------------
322

323     private ClassLoader JavaDoc getClassLoader( ClassLoader JavaDoc classloader )
324     {
325         if( null != classloader ) return classloader;
326         return DefaultBuilder.class.getClassLoader();
327     }
328 }
329
Popular Tags