KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > repository > impl > DefaultRepository


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.impl;
19  
20
21 import java.io.File JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.List JavaDoc;
24
25 import java.net.URL JavaDoc;
26 import java.net.URLClassLoader JavaDoc;
27
28 import javax.naming.directory.Attributes JavaDoc;
29
30 import org.apache.avalon.repository.Artifact;
31 import org.apache.avalon.repository.Repository;
32 import org.apache.avalon.repository.RepositoryException;
33 import org.apache.avalon.repository.RepositoryRuntimeException;
34 import org.apache.avalon.repository.meta.FactoryDescriptor;
35 import org.apache.avalon.repository.meta.MetaException;
36 import org.apache.avalon.repository.util.LoaderUtils;
37 import org.apache.avalon.repository.util.RepositoryUtils;
38
39 /**
40  * A component that provides access to versioned resources based on
41  * an underlying file system.
42  *
43  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
44  * @version $Revision: 1.10 $ $Date: 2004/03/17 10:50:03 $
45  */

46 public class DefaultRepository implements Repository
47 {
48     //------------------------------------------------------------------
49
// immutable state
50
//------------------------------------------------------------------
51

52    /**
53     * The cache directory.
54     */

55     private final File JavaDoc m_cache;
56
57     private final LoaderUtils m_loader;
58
59    /**
60     * A list of registered factory descriptors.
61     */

62     private final List JavaDoc m_descriptors = new ArrayList JavaDoc();
63
64     //------------------------------------------------------------------
65
// mutable state
66
//------------------------------------------------------------------
67

68    /**
69     * Sequence of remote hosts.
70     */

71     private URL JavaDoc[] m_hosts;
72
73    /**
74     * Sequence of remote hosts.
75     */

76     private String JavaDoc[] m_roots;
77
78    /**
79     * Sequence of remote hosts.
80     */

81     private boolean m_online;
82     
83     //------------------------------------------------------------------
84
// constructor
85
//------------------------------------------------------------------
86

87    /**
88     * Creation of a new instance of the default repository.
89     * @param cache the cache manager assigned to the repository
90     * @param hosts the set of remote hosts
91     * @exception NullPointerException if the cache or hosts argument
92     * is null
93     */

94     DefaultRepository(
95       File JavaDoc cache, String JavaDoc[] hosts, boolean online, Artifact[] candidates )
96       throws RepositoryException
97     {
98         if( cache == null ) throw new NullPointerException JavaDoc( "cache" );
99         if( hosts == null ) throw new NullPointerException JavaDoc( "hosts" );
100         if( candidates == null ) throw new NullPointerException JavaDoc( "candidates" );
101
102         m_cache = cache;
103         m_roots = RepositoryUtils.getCleanPaths( hosts );
104         m_hosts = getHosts( m_roots );
105         m_online = online;
106         m_loader = new LoaderUtils( online );
107
108         setupRegistry( candidates );
109
110     }
111
112     //------------------------------------------------------------------
113
// Repository
114
//------------------------------------------------------------------
115

116     /**
117      * Return the metadata attribututes associated with an artifact.
118      * @param artifact the relative artifact from which a .meta resource will
119      * be resolved to establish the artifact attributes
120      * @return the attributes associated with the artifact
121      * @exception RepositoryException if an error occurs while retrieving
122      * or building the attributes
123      * @exception NullPointerException if the supplied artifact is null
124      */

125     public Attributes JavaDoc getAttributes( Artifact artifact )
126         throws RepositoryException
127     {
128         if( null == artifact )
129           throw new NullPointerException JavaDoc( "artifact" );
130
131         try
132         {
133             return RepositoryUtils.getAsAttributes(
134               RepositoryUtils.getProperties(
135                 getResource( artifact, "meta" ) ) );
136         }
137         catch( Throwable JavaDoc e )
138         {
139             final String JavaDoc error =
140               "Unable to retrieve the metadata for the artifact :"
141               + artifact;
142             throw new RepositoryException( error, e );
143         }
144     }
145
146    /**
147     * Return the set of available artifacts capable of providing the
148     * supplied service class.
149     *
150     * @return the set of candidate factory artifacts
151     */

152     public Artifact[] getCandidates( Class JavaDoc service )
153     {
154         ArrayList JavaDoc list = new ArrayList JavaDoc();
155         String JavaDoc classname = service.getName();
156         FactoryDescriptor[] descriptors = getFactoryDescriptors();
157         for( int i=0; i<descriptors.length; i++ )
158         {
159             FactoryDescriptor descriptor = descriptors[i];
160             final String JavaDoc key = descriptor.getInterface();
161             if( classname.equals( key ) )
162             {
163                 list.add( descriptor.getArtifact() );
164             }
165         }
166         return (Artifact[]) list.toArray( new Artifact[0] );
167     }
168
169     /**
170      * Get a resource url relative to the supplied artifact.
171      *
172      * @param artifact the artifact describing the resource
173      * @return the resource url
174      */

175     public URL JavaDoc getResource( Artifact artifact )
176         throws RepositoryException
177     {
178         return m_loader.getResource(
179           artifact, m_roots, m_cache, true );
180     }
181
182     /**
183      * Get a resource url relative to the supplied artifact.
184      *
185      * @param artifact the artifact describing the resource
186      * @param mime a mime type relative to the artifact address
187      * @return the mime instance url
188      */

189     private URL JavaDoc getResource( Artifact artifact, String JavaDoc mime )
190         throws RepositoryException
191     {
192         return m_loader.getResource(
193           artifact, mime, m_roots, m_cache, true );
194     }
195         
196     /**
197      * Returns a classloader based on the metadata associated with
198      * a supplied artifact. The classloader is created relative to
199      * the system classloader.
200      *
201      * @param artifact the artifact fro which dependency metadata
202      * will be resolved
203      * @return the classloader
204      */

205     public ClassLoader JavaDoc getClassLoader( Artifact artifact )
206         throws RepositoryException
207     {
208         return getClassLoader(
209           ClassLoader.getSystemClassLoader(), artifact );
210     }
211
212     /**
213      * Returns a classloader based on the metadata associated with
214      * a supplied artifact. The classloader is created relative to
215      * the supplied parent classloader.
216      *
217      * @param parent the parent classloader
218      * @param artifact the implementation artifact
219      * @return the classloader
220      */

221     public ClassLoader JavaDoc getClassLoader( ClassLoader JavaDoc parent, Artifact artifact )
222         throws RepositoryException
223     {
224         if( null == parent )
225           throw new NullPointerException JavaDoc( "parent" );
226         if( null == artifact )
227           throw new NullPointerException JavaDoc( "artifact" );
228
229         Attributes JavaDoc attributes = getAttributes( artifact );
230         FactoryDescriptor relational = null;
231         try
232         {
233             relational = new FactoryDescriptor( attributes );
234         }
235         catch( MetaException me )
236         {
237             final String JavaDoc error =
238               "Could not create a relational descriptor from the artifact: "
239               + artifact;
240             throw new RepositoryException( error, me );
241         }
242        
243         URL JavaDoc[] apis =
244           getURLs(
245             relational.getDependencies(
246               FactoryDescriptor.API_KEY ) );
247         ClassLoader JavaDoc api = buildClassLoader( apis, parent );
248
249         URL JavaDoc[] spis =
250           getURLs(
251             relational.getDependencies(
252               FactoryDescriptor.SPI_KEY ) );
253         ClassLoader JavaDoc spi = buildClassLoader( spis, api );
254
255         URL JavaDoc[] imps =
256           getURLs( artifact,
257             relational.getDependencies(
258               FactoryDescriptor.IMP_KEY ) );
259         return buildClassLoader( imps, spi );
260     }
261
262    /**
263     * Return a string representation of this repository.
264     * @return the string representation
265     */

266     public String JavaDoc toString()
267     {
268         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc( m_cache.toString() );
269         for( int i=0; i<m_hosts.length; i++ )
270         {
271             buffer.append( ", " );
272             buffer.append( m_hosts[i] );
273         }
274         return buffer.toString();
275     }
276
277     //------------------------------------------------------------------
278
// implementation
279
//------------------------------------------------------------------
280

281     private URL JavaDoc[] getHosts( String JavaDoc[] paths )
282     {
283         URL JavaDoc[] hosts = new URL JavaDoc[ paths.length ];
284         for( int i=0; i<paths.length; i++ )
285         {
286             String JavaDoc path = paths[i];
287             try
288             {
289                 hosts[i] = new URL JavaDoc( path );
290             }
291             catch( Throwable JavaDoc e )
292             {
293                 final String JavaDoc error =
294                   "Internal error while attempting to construct url for host: "
295                   + path;
296                 throw new RepositoryRuntimeException( error, e );
297             }
298         }
299         return hosts;
300     }
301
302     private ClassLoader JavaDoc buildClassLoader(
303       URL JavaDoc[] urls, ClassLoader JavaDoc parent )
304     {
305         if( 0 == urls.length ) return parent;
306         return new URLClassLoader JavaDoc( urls, parent );
307     }
308
309     private URL JavaDoc[] getURLs( Artifact[] artifacts )
310       throws RepositoryException
311     {
312         URL JavaDoc[] urls = new URL JavaDoc[ artifacts.length ];
313         for( int i=0; i<urls.length; i++ )
314         {
315             urls[i] = getResource( artifacts[i] );
316         }
317         return urls;
318     }
319
320     private URL JavaDoc[] getURLs( Artifact primary, Artifact[] artifacts )
321       throws RepositoryException
322     {
323         URL JavaDoc[] urls = new URL JavaDoc[ artifacts.length +1 ];
324         for( int i=0; i<artifacts.length; i++ )
325         {
326             urls[i] = getResource( artifacts[i] );
327         }
328         urls[ artifacts.length ] = getResource( primary );
329         return urls;
330     }
331
332     private void setupRegistry( Artifact[] artifacts ) throws RepositoryException
333     {
334         for( int i=0; i<artifacts.length; i++ )
335         {
336             Artifact artifact = artifacts[i];
337             registerArtifact( artifact );
338         }
339     }
340
341     private void registerArtifact( Artifact artifact ) throws RepositoryException
342     {
343         Attributes JavaDoc attributes = getAttributes( artifact );
344         FactoryDescriptor descriptor = new FactoryDescriptor( attributes );
345         final String JavaDoc key = descriptor.getInterface();
346         if( null == key )
347         {
348             final String JavaDoc error =
349               "Artifact [" + artifact + "] does not declare a exported interface.";
350             throw new RepositoryException( error );
351         }
352         else if( !m_descriptors.contains( descriptor ) )
353         {
354             m_descriptors.add( descriptor );
355         }
356     }
357
358     private FactoryDescriptor[] getFactoryDescriptors()
359     {
360         return (FactoryDescriptor[])
361           m_descriptors.toArray( new FactoryDescriptor[0] );
362     }
363
364 }
365
Popular Tags