Coverage details for org.chwf.resources.ResourceLocator

LineHitsSource
1 /*
2 Chrysalis Web Framework [http://chrysalis.sourceforge.net]
3 Copyright (c) 2002, 2003, 2004, Paul Strack
4  
5 All rights reserved.
6  
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9  
10 1. Redistributions of source code must retain the above copyright notice, this
11 list of conditions and the following disclaimer.
12  
13 2. Redistributions in binary form must reproduce the above copyright notice,
14 this list of conditions and the following disclaimer in the documentation
15 and/or other materials provided with the distribution.
16  
17 3. Neither the name of the copyright holder nor the names of its contributors
18 may be used to endorse or promote products derived from this software without
19 specific prior written permission.
20  
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
25 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32  
33 package org.chwf.resources;
34  
35 import java.util.HashMap;
36 import java.util.Iterator;
37 import java.util.Map;
38  
39 import org.chwf.i18n.Message;
40  
41 /**
42  * A locator for resources. It delegates is calls to the appropriate
43  * [@link ResourceFactory}.
44  *
45  * @author Paul Strack
46  */
472public class ResourceLocator {
48  
49   /** Empty array. */
502  private static final Object[] EMPTY_ARRAY = new Object[0];
51  
52   /** The resource factories, indexed by ResourceID. */
531  private static final Map RESOURCE_FACTORIES = initResourceFactories();
54  
55   /** A thread local variable for caching managed resources. */
561  private static final ThreadLocal MANAGED_RESOURCES = new ThreadLocal();
57  
58   /**
59    * True if the resource has a (default) factory.
60    *
61    * @param resource The resource class.
62    * @return True if the resource has a factory.
63    */
64   public static boolean hasFactory(Class resource) {
652    return hasFactory(resource, ResourceManagerConfig.DEFAULT_FACTORY);
66   }
67  
68   /**
69    * True if the resource has a factory with the given name.
70    *
71    * @param resource The resource class.
72    * @param factoryName The factory name.
73    * @return True if the resource has a factory with the given name.
74    */
75   public static boolean hasFactory(Class resource, String factoryName) {
765    if (factoryName == null) {
771      factoryName = ResourceManagerConfig.DEFAULT_FACTORY;
78     }
795    ResourceID pair = new ResourceID(resource, factoryName);
805    return (RESOURCE_FACTORIES.get(pair) != null);
81   }
82  
83   /**
84    * True if this resource is managed for the default factory.
85    *
86    * @param resource The resource class.
87    * @return True if this resource is managed by the default factory.
88    */
89   public static boolean isManaged(Class resource) {
901    return isManaged(resource, ResourceManagerConfig.DEFAULT_FACTORY);
91   }
92  
93   /**
94    * True if this resource is managed for the given named factory.
95    *
96    * @param resource The resource class.
97    * @param factoryName The factory name.
98    * @return True if this resource is managed for the given named factory.
99    */
100   public static boolean isManaged(Class resource, String factoryName) {
1013    if (factoryName == null) {
1021      factoryName = ResourceManagerConfig.DEFAULT_FACTORY;
103     }
1043    ResourceID pair = new ResourceID(resource, factoryName);
1053    Object factory = RESOURCE_FACTORIES.get(pair);
1063    return ((factory != null) && (factory instanceof ManagedResourceFactory));
107   }
108  
109   /**
110    * Get a resource from its default factory.
111    *
112    * @param type The resource type.
113    * @return The resource.
114    * @throws ResourceException If there is no factory for this resource.
115    * @throws ResourceInitException If the factory cannot be found.
116    */
117   public static Object getResource(Class type)
118     throws ResourceException, ResourceInitException {
1192    return getResource(type, ResourceManagerConfig.DEFAULT_FACTORY);
120   }
121  
122   /**
123    * Get a resource from a named factory.
124    *
125    * @param type The resource type.
126    * @param factoryName The factory name.
127    * @return The resource.
128    * @throws ResourceException If there is no factory with this name.
129    * @throws ResourceInitException If the factory cannot be found.
130    */
131   public static Object getResource(Class type, String factoryName)
132     throws ResourceException, ResourceInitException {
133  
13411    if (factoryName == null) {
1351      factoryName = ResourceManagerConfig.DEFAULT_FACTORY;
136     }
13711    ResourceFactory factory = ResourceLocator.getFactory(type, factoryName);
13810    if (factory instanceof ManagedResourceFactory) {
1398      ManagedResourceFactory managedFactory = (ManagedResourceFactory) factory;
1408      return getManagedResource(type, factoryName, managedFactory);
141     } else {
1422      return factory.getResource();
143     }
144   }
145  
146   /**
147    * True if management is initialized.
148    *
149    * @return True if management is initialized.
150    */
151   public static boolean isManagementActive() {
152973    return (MANAGED_RESOURCES.get() != null);
153   }
154  
155   /**
156    * Initialize resource management for this thread. Developers should not call
157    * this method except for testing. This method can only be called once until
158    * the release() method is called.
159    *
160    * @throws ResourceInitException If called while initialized.
161    */
162   static void init() throws ResourceInitException {
163472    if (!isManagementActive()) {
164471      MANAGED_RESOURCES.set(new HashMap());
165     } else {
1661      throw new ResourceInitException(
167         ResourceInitException.MESSAGE_ALREADY_INITIALIZED);
168     }
169471  }
170  
171   /**
172    * Release all managed resources, and terminate resource management for this
173    * thread. Developers should not call this method except for testing. All
174    * resources are released, even if there are failures during the release
175    * process. The resources are not released in any particular order, however.
176    *
177    * @param error Error status for the thread of execution (null if there were
178    * no errors).
179    * @throws ResourceException If there were failures during the release.
180    * This is a chained exception; the full set of release errors can
181    * be retrieved via {@link ResourceException#getNextException()}
182    * @throws ResourceInitException If called when not initialized.
183    */
184   static void release(Throwable error)
185     throws ResourceException, ResourceInitException {
186  
187472    if (isManagementActive()) {
188471      ResourceException errors = null;
189471      Iterator resources = getManagedResources().values().iterator();
190948      while (resources.hasNext()) {
191         try {
1926          ManagedResource resource = (ManagedResource) resources.next();
1936          resource.release(error);
1944        } catch (ResourceException ex) {
1951          ex.setNextException(errors);
1961          errors = ex;
1971        } catch (Throwable ex) {
1981          ResourceException rex = new ResourceException(ex);
1991          rex.setNextException(errors);
2001          errors = rex;
201         }
202       }
203471      MANAGED_RESOURCES.set(null);
204471      if (errors != null) {
2052        Message msg =
206           Message.getMessage(
207             ResourceException.MESSAGE_RESOURCE_RELEASE_FAILURE,
208             EMPTY_ARRAY,
209             ResourceException.class);
2102        ResourceException ex = new ResourceException(msg.toString());
2112        ex.setNextException(errors);
2122        throw ex;
213       }
214     } else {
2151      throw new ResourceInitException(
216         ResourceInitException.MESSAGE_NOT_INITIALIZED);
217     }
218469  }
219  
220   /**
221    * Initialize all resource factories.
222    *
223    * @return The map containing the resource factories.
224    * @throws ResourceInitException If a factory class cannot be initialized.
225    */
226   private static Map initResourceFactories() throws ResourceInitException {
2271    Map map = new HashMap();
2281    ResourceManagerConfig config = ResourceManagerConfig.getConfig();
2291    String[] resourceClasses = config.getResourceClasses();
2303    for (int i = 0; i < resourceClasses.length; i++) {
2312      String resource = resourceClasses[i];
2322      Class resourceClass = deriveResourceClass(resource);
2332      Map factoryClasses = config.getFactoryClasses(resource);
2342      Iterator iterator = factoryClasses.keySet().iterator();
23510      while (iterator.hasNext()) {
2366        String factoryName = iterator.next().toString();
2376        String factoryClassName = factoryClasses.get(factoryName).toString();
2386        ResourceFactory factory = createFactory(factoryClassName, resource);
2396        if (!resourceClass.equals(factory.getType())) {
2400          Object[] args = { factoryName, resource };
2410          throw new ResourceInitException(
242             ResourceInitException.MESSAGE_WRONG_FACTORY_TYPE,
243             args);
244         }
2456        Map factoryProperties =
246           config.getFactoryProperties(resource, factoryName);
2476        ResourceFactoryConfigImpl factoryConfig =
248           new ResourceFactoryConfigImpl(factoryName, factoryProperties);
249         try {
2506          factory.init(factoryConfig);
2516        } catch (Exception ex) {
2520          Object[] args = { factoryName, resource, ex };
2530          throw new ResourceInitException(
254             ResourceInitException.MESSAGE_FACTORY_INIT_FAILED,
255             args);
256         }
2576        ResourceID id = new ResourceID(resourceClass, factoryName);
2586        map.put(id, factory);
259       }
260     }
2611    return map;
262   }
263  
264   /**
265    * Derive resource class for the given class name.
266    *
267    * @param className The class name.
268    * @return The class.
269    * @throws ResourceInitException If the factory class is not found.
270    */
271   private static Class deriveResourceClass(String className)
272     throws ResourceInitException {
273     try {
2742      return Class.forName(className);
275     } catch (ClassNotFoundException ex) {
2760      Object[] args = { className };
2770      throw new ResourceInitException(
278         ResourceInitException.MESSAGE_RESOURCE_CLASS_NOT_FOUND,
279         args);
280     }
281   }
282  
283   /**
284    * Derive resource factory class for the given class name.
285    *
286    * @param className The factory class name.
287    * @param resource The resource name.
288    * @return The class.
289    * @throws ResourceInitException If the factory class is not found.
290    */
291   private static Class deriveFactoryClass(String className, String resource)
292     throws ResourceInitException {
293     try {
2946      return Class.forName(className);
295     } catch (ClassNotFoundException ex) {
2960      Object[] args = { className, resource };
2970      throw new ResourceInitException(
298         ResourceInitException.MESSAGE_FACTORY_CLASS_NOT_FOUND,
299         args);
300     }
301   }
302  
303   /**
304    * Create resource factory for the given class name.
305    *
306    * @param className The factory class name.
307    * @param resource The resource name.
308    * @return The factory.
309    * @throws ResourceInitException If the factory cannot be created.
310    */
311   private static ResourceFactory createFactory(
312     String className,
313     String resource)
314     throws ResourceInitException {
3156    Class factoryClass = deriveFactoryClass(className, resource);
316     try {
3176      return (ResourceFactory) factoryClass.newInstance();
318     } catch (ClassCastException ex) {
3190      Object[] args = { factoryClass.getName(), resource };
3200      throw new ResourceInitException(
321         ResourceInitException.MESSAGE_NOT_A_RESOURCE_FACTORY,
322         args);
323     } catch (Exception ex) {
3240      Object[] args = { factoryClass.getName(), resource, ex };
3250      throw new ResourceInitException(
326         ResourceInitException.MESSAGE_FACTORY_NOT_CREATED,
327         args);
328     }
329   }
330  
331   /**
332    * Retrieve the factory for the given resource type.
333    *
334    * @param type The resource type.
335    * @param name The factory name.
336    * @return The factory.
337    * @throws ResourceInitException If the factory is not found.
338    */
339   private static ResourceFactory getFactory(Class type, String name)
340     throws ResourceInitException {
341  
34211    ResourceID pair = new ResourceID(type, name);
34311    ResourceFactory factory = (ResourceFactory) RESOURCE_FACTORIES.get(pair);
34411    if (factory == null) {
3451      Object[] args = { name, type };
3461      throw new ResourceInitException(
347         ResourceInitException.MESSAGE_FACTORY_NOT_FOUND,
348         args);
349     }
35010    return factory;
351   }
352  
353   /**
354    * Retrieve a managed resource.
355    *
356    * @param type The resource type.
357    * @param name The factory name.
358    * @param factory The factory.
359    * @return The managed resource.
360    * @throws ResourceException If the resource cannot be retrieved.
361    * @throws ResourceInitException If the factory is not initialized.
362    */
363   private static Object getManagedResource(
364     Class type,
365     String name,
366     ManagedResourceFactory factory)
367     throws ResourceException, ResourceInitException {
368  
3698    if (!isManagementActive()) {
3701      Object[] args = { type.getName(), name };
3711      throw new ResourceInitException(
372         ResourceInitException.MESSAGE_MANAGEMENT_NOT_INITIALIZED,
373         args);
374     }
3757    ResourceID id = new ResourceID(type, name);
3767    Map managedResources = getManagedResources();
3777    ManagedResource managed = (ManagedResource) managedResources.get(id);
3787    if (managed == null) {
3797      managed = new ManagedResource(factory, factory.getResource());
3806      managedResources.put(id, managed);
381     }
3826    return managed.getResource();
383   }
384  
385   /**
386    * The list of managed resources.
387    *
388    * @return The list of managed resources.
389    */
390   private static Map getManagedResources() {
391478    return (Map) MANAGED_RESOURCES.get();
392   }
393  
394   /**
395    * A class for map values for managed resources.
396    *
397    * @author Paul Strack
398    */
399   private static class ManagedResource {
400  
401     /** The factory. */
402     private final ManagedResourceFactory factory;
403  
404     /** The resource. */
405     private final Object resource;
406  
407     /**
408      * Constructor.
409      *
410      * @param factory The factory.
411      * @param resource The resource.
412      */
413     ManagedResource(ManagedResourceFactory factory, Object resource) {
414       this.factory = factory;
415       this.resource = resource;
416     }
417  
418     /**
419      * The resource.
420      *
421      * @return The resource.
422      */
423     Object getResource() {
424       return resource;
425     }
426  
427     /**
428      * Release the resource.
429      *
430      * @param error An error message (or null if there were no errors).
431      * @throws ResourceException If the release fails.
432      */
433     void release(Throwable error) throws ResourceException {
434       factory.release(resource, error);
435     }
436   }
437 }

this report was generated by version 1.0.5 of jcoverage.
visit www.jcoverage.com for updates.

copyright © 2003, jcoverage ltd. all rights reserved.
Java is a trademark of Sun Microsystems, Inc. in the United States and other countries.