KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > soto > SotoContainer


1 package org.sapia.soto;
2
3 import org.sapia.soto.config.Include;
4 import org.sapia.soto.config.ServiceTag;
5 import org.sapia.soto.util.ClasspathResourceHandler;
6 import org.sapia.soto.util.FileResourceHandler;
7 import org.sapia.soto.util.Resource;
8 import org.sapia.soto.util.ResourceHandler;
9 import org.sapia.soto.util.ResourceHandlerChain;
10 import org.sapia.soto.util.UrlResourceHandler;
11 import org.sapia.soto.util.Utils;
12
13 import org.sapia.util.text.MapContext;
14 import org.sapia.util.text.SystemContext;
15 import org.sapia.util.text.TemplateContextIF;
16 import org.sapia.util.xml.confix.Dom4jProcessor;
17
18 import java.io.File JavaDoc;
19 import java.io.IOException JavaDoc;
20 import java.io.InputStream JavaDoc;
21
22 import java.net.URL JavaDoc;
23
24 import java.util.ArrayList JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Map JavaDoc;
28
29
30 /**
31  * An intance of this class contains service instances and manages their life-cycle.
32  *
33  * @author Yanick Duchesne
34  * <dl>
35  * <dt><b>Copyright:</b><dd>Copyright &#169; 2002-2003 <a HREF="http://www.sapia-oss.org">Sapia Open Source Software</a>. All Rights Reserved.</dd></dt>
36  * <dt><b>License:</b><dd>Read the license.txt file of the jar or visit the
37  * <a HREF="http://www.sapia-oss.org/license.html">license page</a> at the Sapia OSS web site</dd></dt>
38  * </dl>
39  */

40 public class SotoContainer implements Consts {
41     
42     /**
43      * This constant can be used as a key to bind a <code>SotoContainer</code>'s
44      * environment (<code>Env</code>) into various application-related contexts/maps.
45      * By convention, this constant should be used in such cases.
46      *
47      * @see #toEnv()
48      * @see Env
49      */

50     public static final String JavaDoc SOTO_ENV_KEY = "SOTO_ENV";
51     
52   private ResourceHandlerChain _resourceHandlers = new ResourceHandlerChain();
53   private Map JavaDoc _services = new HashMap JavaDoc();
54   private List JavaDoc _toStart = new ArrayList JavaDoc();
55   private SotoApplicationFactory _fac;
56   private boolean _started;
57   private boolean _resourceLoaded;
58   private Env _env;
59
60   /**
61    * Constructor for SotoContainer.
62    */

63   public SotoContainer() {
64     _fac = new SotoApplicationFactory(this);
65     _resourceHandlers.append(new FileResourceHandler());
66     _resourceHandlers.append(new ClasspathResourceHandler());
67     _resourceHandlers.append(new UrlResourceHandler());
68     _env = new EnvImpl(this);
69   }
70
71   /**
72    * Returns the list of services held within this instance.
73    *
74    * @return a <code>List</code> of <code>ServiceTag</code>.
75    */

76   List JavaDoc getServiceList() {
77     return _toStart;
78   }
79
80   /**
81    * Binds the given object to this instance, using the specified
82    * identifier.
83    *
84    * @param id the given object's identifier.
85    * @param svc a <code>ServiceMetaData</code>.
86    *
87    */

88   public void bind(ServiceMetaData meta) throws DuplicateException, Exception JavaDoc {
89     if (meta.getServiceID() == null) {
90       throw new IllegalArgumentException JavaDoc("No identifier provided for service: " +
91         meta.getService().getClass().getName());
92     }
93
94     if (_services.get(meta.getServiceID()) != null) {
95       throw new DuplicateException("A service already exists for ID: " +
96         meta.getServiceID());
97     }
98
99     _services.put(meta.getServiceID(), meta);
100   }
101
102   /**
103    * Looks up for the object identified by the given ID and returns
104    * it.
105    *
106    * @throws NotFoundException if no object could be found.
107    */

108   public Object JavaDoc lookup(String JavaDoc id) throws NotFoundException {
109     //checkStarted();
110
ServiceMetaData service = (ServiceMetaData) _services.get(id);
111
112     if (service == null) {
113       throw new NotFoundException(id);
114     }
115
116     return service.getService();
117   }
118
119   /**
120    * Loads the Soto XML descriptor whose stream is given.
121    *
122    * @param is an <code>InputStream</code>.
123    * @param a <code>Map</code> of name/value pairs that can be recuperated in the
124    * configuration using the ${varname} notation.
125    * @return this instance.
126    */

127   public SotoContainer load(InputStream JavaDoc is, Map JavaDoc vars) throws Exception JavaDoc {
128     if (vars == null) {
129       vars = new HashMap JavaDoc();
130     }
131
132     TemplateContextIF ctx = new MapContext(vars, new SystemContext(), true);
133
134     if (_fac == null) {
135       _fac = new SotoApplicationFactory(this);
136     }
137
138     _fac.setContext(ctx);
139
140     Dom4jProcessor proc = new Dom4jProcessor(_fac);
141
142     if (!_resourceLoaded) {
143       InputStream JavaDoc resources = getResourceAsStream("soto_defs.xml");
144
145       if (resources == null) {
146       } else {
147         proc.process(resources);
148       }
149
150       _resourceLoaded = true;
151     }
152
153     proc.process(Utils.replaceVars(ctx, is, "null"));
154
155     return this;
156   }
157
158   /**
159    * Loads the Soto XML descriptor whose stream is given.
160    *
161    * @param is an <code>InputStream</code>.
162    * @return this instance.
163    */

164   public SotoContainer load(InputStream JavaDoc is) throws Exception JavaDoc {
165     return load(is, null);
166   }
167
168   /**
169    * Loads the Soto XML descriptor whose resource is given.
170    *
171    * @param resourceName the name of the classpath resource that contains the configuration.
172    * @param a <code>Map</code> of name/value pairs that can be recuperated in the
173    * configuration using the ${varname} notation.
174    * @throws Exception
175    * @return this instance.
176    */

177   public SotoContainer load(String JavaDoc resourceName, Map JavaDoc vars)
178     throws Exception JavaDoc {
179     return include("resource:/" + resourceName, vars);
180   }
181
182   /**
183    * Loads the Soto XML descriptor whose resource is given.
184    *
185    * @param resourceName the name of the classpath resource that contains the configuration.
186    * @throws Exception
187    * @return this instance.
188    */

189   public SotoContainer load(String JavaDoc resourceName) throws Exception JavaDoc {
190     return load(resourceName, null);
191   }
192
193   /**
194    * Loads the Soto XML descriptor whose file is given.
195    *
196    * @param is an <code>File</code>.
197    * @param a <code>Map</code> of name/value pairs that can be recuperated in the
198    * configuration using the ${varname} notation.
199    * @return this instance
200    */

201   public SotoContainer load(File JavaDoc f, Map JavaDoc map) throws Exception JavaDoc {
202     String JavaDoc path = f.getAbsolutePath().trim();
203
204     if (path.charAt(0) == '/') {
205       return include("file:" + f.getAbsolutePath(), map);
206     } else {
207       return include("file:/" + f.getAbsolutePath(), map);
208     }
209   }
210
211   /**
212    * Loads the Soto XML descriptor whose URL is given.
213    *
214    * @param is an <code>URL</code>.
215    * @param a <code>Map</code> of name/value pairs that can be recuperated in the
216    * configuration using the ${varname} notation.
217    * @return this instance
218    */

219   public SotoContainer load(URL JavaDoc url, Map JavaDoc map) throws Exception JavaDoc {
220     return include(url.toExternalForm(), map);
221   }
222
223   /**
224    * Loads the Soto XML descriptor whose file is given.
225    *
226    * @param is an <code>File</code>.
227    * @return this instance.
228    */

229   public SotoContainer load(File JavaDoc f) throws Exception JavaDoc {
230     return load(f, null);
231   }
232
233   /**
234    * Internally starts the services bound to this container.
235    *
236    * @see Service#start()
237    */

238   public void start() throws Exception JavaDoc {
239     ServiceTag svc;
240     ServiceMetaData meta;
241     List JavaDoc services = new ArrayList JavaDoc(_toStart.size());
242
243     for (int i = 0; i < _toStart.size(); i++) {
244       svc = (ServiceTag) _toStart.get(i);
245       services.add(meta = svc.getServiceMetaData());
246       meta.start();
247     }
248
249     _started = true;
250     _toStart.clear();
251     _toStart = services;
252   }
253
254   /**
255    * Internally shuts down all services and layers.
256    *
257    * @see Service#dispose()
258    * @see Layer#dispose()
259    */

260   public void dispose() {
261     for (int i = _toStart.size() - 1; i >= 0; i--) {
262         try{
263           ((ServiceMetaData) _toStart.get(i)).dispose();
264         }catch(ClassCastException JavaDoc e){
265             // ServiceTag instance probably left (occurs if
266
// start() method has not completed successfully)
267
if(_toStart.get(i) instanceof ServiceTag){
268                 _toStart.remove(i--);
269             }
270         }
271     }
272   }
273   
274   /**
275    * Returns the resource handlers held by this instance. New handlers can be
276    * added by client applications.
277    *
278    * @return the <code>ResourceHandlerChain</code> that this instance
279    * holds.
280    */

281   public ResourceHandlerChain getResourceHandlers(){
282     return _resourceHandlers;
283   }
284   
285   /**
286    * Returns the resource handler that corresponds to the given scheme.
287    *
288    * @see #registerResourceHandler(String, ResourceHandler)
289    */

290   public ResourceHandler getResourceHandlerFor(String JavaDoc uri) {
291     ResourceHandler handler = _resourceHandlers.select(uri);
292
293     if (handler == null) {
294       throw new IllegalArgumentException JavaDoc("No resource handler defined for: " +
295         uri);
296     }
297
298     return handler;
299   }
300
301   /**
302    * @return the <code>SotoApplicationFactory</code> that is used to create objects from an
303    * XML configuration.
304    */

305   public SotoApplicationFactory getApplicationFactory() {
306     return _fac;
307   }
308
309   private void checkStarted() {
310     if (!_started) {
311       throw new IllegalStateException JavaDoc(
312         "Soto container must be started prior to operation being performed");
313     }
314   }
315
316   private SotoContainer include(String JavaDoc uri, Map JavaDoc vars) throws Exception JavaDoc {
317     TemplateContextIF ctx;
318
319     if (vars == null) {
320       vars = new HashMap JavaDoc();
321     }
322
323     ctx = new MapContext(vars, new SystemContext(), true);
324
325     if (_fac == null) {
326       _fac = new SotoApplicationFactory(this);
327     }
328
329     _fac.setContext(ctx);
330
331         Dom4jProcessor proc = new Dom4jProcessor(_fac);
332
333     if (!_resourceLoaded) {
334       InputStream JavaDoc resources = getResourceAsStream("soto_defs.xml");
335
336       if (resources == null) {
337       } else {
338         proc.process(resources);
339       }
340
341       _resourceLoaded = true;
342     }
343
344     Include include = new Include(this, _fac);
345     include.setUri(uri);
346     include.onCreate();
347
348     return this;
349   }
350
351   private InputStream JavaDoc getResourceAsStream(String JavaDoc resourceName) {
352     InputStream JavaDoc resource = getClass().getResourceAsStream(resourceName);
353
354     if (resource == null) {
355       resource = Thread.currentThread().getContextClassLoader()
356                        .getResourceAsStream(resourceName);
357     }
358
359     if (resource == null) {
360       resource = ClassLoader.getSystemResourceAsStream(resourceName);
361     }
362
363     return resource;
364   }
365
366   /**
367    * @return the <code>Env</code> instance that corresponds to this container.
368    */

369   public Env toEnv() {
370     return _env;
371   }
372
373   // INNER CLASSES ////////////////////////////////////////////////////
374
public static final class EnvImpl implements Env {
375     SotoContainer _cont;
376
377     EnvImpl(SotoContainer cont) {
378       _cont = cont;
379     }
380
381     /**
382      * @see org.sapia.soto.Env#getResourceHandlerFor(java.lang.String)
383      */

384     public ResourceHandler getResourceHandlerFor(String JavaDoc protocol) {
385       return _cont.getResourceHandlerFor(protocol);
386     }
387
388     /**
389      * @see org.sapia.soto.Env#lookup(java.lang.String)
390      */

391     public Object JavaDoc lookup(String JavaDoc serviceId) throws NotFoundException {
392       return _cont.lookup(serviceId);
393     }
394     
395     /**
396      * @see org.sapia.soto.Env#getResourceHandlers()
397      */

398     public ResourceHandlerChain getResourceHandlers() {
399       return _cont.getResourceHandlers();
400     }
401
402     /**
403      * @see org.sapia.soto.Env#resolveStream(java.lang.String)
404      */

405     public InputStream JavaDoc resolveStream(String JavaDoc path) throws IOException JavaDoc {
406         return _cont.getResourceHandlerFor(path).getResource(path);
407     }
408
409     /**
410      * @see org.sapia.soto.Env#resolveResource(java.lang.String)
411      */

412     public Resource resolveResource(String JavaDoc path) throws IOException JavaDoc {
413             return _cont.getResourceHandlerFor(path).getResourceObject(path);
414     }
415
416     public SotoContainer getContainer() {
417       return _cont;
418     }
419   }
420 }
421
Popular Tags