KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > excalibur > source > impl > SourceResolverImpl


1 /*
2  * Copyright 2002-2004 The 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 package org.apache.excalibur.source.impl;
18
19 import java.io.File JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.net.MalformedURLException JavaDoc;
22 import java.net.URL JavaDoc;
23 import java.util.Map JavaDoc;
24
25 import org.apache.avalon.framework.CascadingRuntimeException;
26 import org.apache.avalon.framework.activity.Disposable;
27 import org.apache.avalon.framework.context.Context;
28 import org.apache.avalon.framework.context.ContextException;
29 import org.apache.avalon.framework.context.Contextualizable;
30 import org.apache.avalon.framework.logger.AbstractLogEnabled;
31 import org.apache.avalon.framework.service.ServiceException;
32 import org.apache.avalon.framework.service.ServiceManager;
33 import org.apache.avalon.framework.service.ServiceSelector;
34 import org.apache.avalon.framework.service.Serviceable;
35 import org.apache.avalon.framework.thread.ThreadSafe;
36 import org.apache.excalibur.source.*;
37
38 /**
39  * This is the default implemenation of a {@link SourceResolver}.
40  *
41  * The source resolving is done relative to a base directory/URI (if
42  * the given location is relative). This implementation looks for the
43  * base URI in the {@link Context} object of the "container" for the
44  * "context-root" information. This information can either be a
45  * {@link File} object or a {@link URL} object.
46  * If the entry does not exist, the system property "user.dir" is used
47  * as the base URI instead.
48  *
49  * @see org.apache.excalibur.source.SourceResolver
50  *
51  * @avalon.component
52  * @avalon.service type=SourceResolver
53  * @x-avalon.info name=resolver
54  * @x-avalon.lifestyle type=singleton
55  *
56  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
57  * @version $Id: SourceResolverImpl.java,v 1.4 2004/02/28 11:47:24 cziegeler Exp $
58  */

59 public class SourceResolverImpl
60     extends AbstractLogEnabled
61     implements Serviceable,
62     Contextualizable,
63     Disposable,
64     SourceResolver,
65     ThreadSafe
66 {
67     /** The component m_manager */
68     protected ServiceManager m_manager;
69
70     /** The special Source factories */
71     protected ServiceSelector m_factorySelector;
72
73     /**
74      * The base URL
75      */

76     protected URL JavaDoc m_baseURL;
77
78     /**
79      * Get the context
80      */

81     public void contextualize( Context context )
82         throws ContextException
83     {
84         try
85         {
86             if( context.get( "context-root" ) instanceof URL JavaDoc )
87             {
88                 m_baseURL = (URL JavaDoc)context.get( "context-root" );
89             }
90             else
91             {
92                 m_baseURL = ( (File JavaDoc)context.get( "context-root" ) ).toURL();
93             }
94         }
95         catch( ContextException ce )
96         {
97             // set the base URL to the current directory
98
try
99             {
100                 m_baseURL = new File JavaDoc( System.getProperty( "user.dir" ) ).toURL();
101                 if( getLogger().isDebugEnabled() )
102                 {
103                     getLogger().debug( "SourceResolver: Using base URL: " + m_baseURL );
104                 }
105             }
106             catch( MalformedURLException JavaDoc mue )
107             {
108                 getLogger().warn( "Malformed URL for user.dir, and no container.rootDir exists", mue );
109                 throw new ContextException( "Malformed URL for user.dir, and no container.rootDir exists", mue );
110             }
111         }
112         catch( MalformedURLException JavaDoc mue )
113         {
114             getLogger().warn( "Malformed URL for container.rootDir", mue );
115             throw new ContextException( "Malformed URL for container.rootDir", mue );
116         }
117     }
118
119     /**
120      * Set the current <code>ComponentLocator</code> instance used by this
121      * <code>Composable</code>.
122      *
123      * @avalon.dependency type="org.apache.excalibur.source.SourceFactory"
124      */

125     public void service( final ServiceManager manager )
126         throws ServiceException
127     {
128         m_manager = manager;
129
130         if ( m_manager.hasService( SourceFactory.ROLE + "Selector" ) )
131         {
132             m_factorySelector = (ServiceSelector) m_manager.lookup( SourceFactory.ROLE + "Selector" );
133         }
134     }
135
136     public void dispose()
137     {
138         if( null != m_manager )
139         {
140             m_manager.release( m_factorySelector );
141             m_factorySelector = null;
142         }
143     }
144
145     /**
146      * Get a <code>Source</code> object.
147      * @throws org.apache.excalibur.source.SourceNotFoundException if the source cannot be found
148      */

149     public Source resolveURI( String JavaDoc location )
150         throws MalformedURLException JavaDoc, IOException JavaDoc, SourceException
151     {
152         return this.resolveURI( location, null, null );
153     }
154
155     /**
156      * Get a <code>Source</code> object.
157      * @throws org.apache.excalibur.source.SourceNotFoundException if the source cannot be found
158      */

159     public Source resolveURI( String JavaDoc location,
160                               String JavaDoc baseURI,
161                               Map JavaDoc parameters )
162         throws MalformedURLException JavaDoc, IOException JavaDoc, SourceException
163     {
164         if( getLogger().isDebugEnabled() )
165         {
166             getLogger().debug( "Resolving '" + location + "' with base '" + baseURI + "' in context '" + m_baseURL + "'" );
167         }
168         if( location == null ) throw new MalformedURLException JavaDoc( "Invalid System ID" );
169         if( null != baseURI && SourceUtil.indexOfSchemeColon(baseURI) == -1 )
170         {
171             throw new MalformedURLException JavaDoc( "BaseURI is not valid, it must contain a protocol: " + baseURI );
172         }
173
174         if( baseURI == null ) baseURI = m_baseURL.toExternalForm();
175
176         String JavaDoc systemID = location;
177         // special handling for windows file paths
178
if( location.length() > 1 && location.charAt( 1 ) == ':' )
179             systemID = "file:/" + location;
180         else if( location.length() > 2 && location.charAt(0) == '/' && location.charAt(2) == ':' )
181             systemID = "file:" + location;
182
183         // determine protocol (scheme): first try to get the one of the systemID, if that fails, take the one of the baseURI
184
String JavaDoc protocol;
185         int protocolPos = SourceUtil.indexOfSchemeColon(systemID);
186         if( protocolPos != -1 )
187         {
188             protocol = systemID.substring( 0, protocolPos );
189         }
190         else
191         {
192             protocolPos = SourceUtil.indexOfSchemeColon(baseURI);
193             if( protocolPos != -1 )
194                 protocol = baseURI.substring( 0, protocolPos );
195             else
196                 protocol = "*";
197         }
198
199         Source source = null;
200         // search for a SourceFactory implementing the protocol
201
SourceFactory factory = null;
202         try
203         {
204             factory = (SourceFactory)m_factorySelector.select( protocol );
205             systemID = absolutize( factory, baseURI, systemID );
206             if( getLogger().isDebugEnabled() )
207                 getLogger().debug( "Resolved to systemID : " + systemID );
208             source = factory.getSource( systemID, parameters );
209         }
210         catch( final ServiceException ce )
211         {
212             // no selector available, use fallback
213
}
214         finally
215         {
216             m_factorySelector.release( factory );
217         }
218
219         if( null == source )
220         {
221             try
222             {
223                 factory = (SourceFactory) m_factorySelector.select("*");
224                 systemID = absolutize( factory, baseURI, systemID );
225                 if( getLogger().isDebugEnabled() )
226                     getLogger().debug( "Resolved to systemID : " + systemID );
227                 source = factory.getSource( systemID, parameters );
228             }
229             catch (ServiceException se )
230             {
231                 throw new SourceException( "Unable to select source factory for " + systemID, se );
232             }
233             finally
234             {
235                 m_factorySelector.release(factory);
236             }
237         }
238
239         return source;
240     }
241
242     /**
243      * Makes an absolute URI based on a baseURI and a relative URI.
244      */

245     private String JavaDoc absolutize( SourceFactory factory, String JavaDoc baseURI, String JavaDoc systemID )
246     {
247         if( factory instanceof URIAbsolutizer )
248             systemID = ((URIAbsolutizer)factory).absolutize(baseURI, systemID);
249         else
250             systemID = SourceUtil.absolutize(baseURI, systemID);
251         return systemID;
252     }
253
254     /**
255      * Releases a resolved resource
256      * @param source the source to release
257      */

258     public void release( final Source source )
259     {
260         if( source == null ) return;
261
262         // search for a SourceFactory implementing the protocol
263
final String JavaDoc scheme = source.getScheme();
264         SourceFactory factory = null;
265
266         try
267         {
268             factory = (SourceFactory) m_factorySelector.select(scheme);
269             factory.release(source);
270         }
271         catch (ServiceException se )
272         {
273             try
274             {
275                 factory = (SourceFactory) m_factorySelector.select("*");
276                 factory.release(source);
277             }
278             catch (ServiceException sse )
279             {
280                 throw new CascadingRuntimeException( "Unable to select source factory for " + source.getURI(), se );
281             }
282         }
283         finally
284         {
285             m_factorySelector.release( factory );
286         }
287     }
288 }
289
Popular Tags