1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.chain;
17
18 import java.util.HashMap;
19 import java.util.Iterator;
20 import java.util.Map;
21 import org.apache.commons.chain.impl.CatalogFactoryBase;
22
23 /***
24 * <p>A {@link CatalogFactory} is a class used to store and retrieve
25 * {@link Catalog}s. The factory allows for a default {@link Catalog}
26 * as well as {@link Catalog}s stored with a name key. Follows the
27 * Factory pattern (see GoF).</p>
28 *
29 * @author Sean Schofield
30 * @version $Revision: 1.5 $ $Date: 2004/11/30 05:52:22 $
31 */
32
33 public abstract class CatalogFactory {
34
35
36
37
38
39 /***
40 * <p>Gets the default instance of Catalog associated with the factory
41 * (if any); otherwise, return <code>null</code>.</p>
42 *
43 * @return the default Catalog instance
44 */
45 public abstract Catalog getCatalog();
46
47
48 /***
49 * <p>Sets the default instance of Catalog associated with the factory.</p>
50 *
51 * @param catalog the default Catalog instance
52 */
53 public abstract void setCatalog(Catalog catalog);
54
55
56 /***
57 * <p>Retrieves a Catalog instance by name (if any); otherwise
58 * return <code>null</code>.</p>
59 *
60 * @param name the name of the Catalog to retrieve
61 * @return the specified Catalog
62 */
63 public abstract Catalog getCatalog(String name);
64
65
66 /***
67 * <p>Adds a named instance of Catalog to the factory (for subsequent
68 * retrieval later).</p>
69 *
70 * @param name the name of the Catalog to add
71 * @param catalog the Catalog to add
72 */
73 public abstract void addCatalog(String name, Catalog catalog);
74
75
76 /***
77 * <p>Return an <code>Iterator</code> over the set of named
78 * {@link Catalog}s known to this {@link CatalogFactory}.
79 * If there are no known catalogs, an empty Iterator is returned.</p>
80 */
81 public abstract Iterator getNames();
82
83
84
85
86
87 /***
88 * <p>The set of registered {@link CatalogFactory} instances,
89 * keyed by the relevant class loader.</p>
90 */
91 private static Map factories = new HashMap();
92
93
94
95
96
97 /***
98 * <p>Return the singleton {@link CatalogFactory} instance
99 * for the relevant <code>ClassLoader</code>. For applications
100 * that use a thread context class loader (such as web applications
101 * running inside a servet container), this will return a separate
102 * instance for each application, even if this class is loaded from
103 * a shared parent class loader.</p>
104 *
105 * @return the per-application singleton instance of {@link CatalogFactory}
106 */
107 public static CatalogFactory getInstance() {
108
109 CatalogFactory factory = null;
110 ClassLoader cl = getClassLoader();
111 synchronized (factories) {
112 factory = (CatalogFactory) factories.get(cl);
113 if (factory == null) {
114 factory = new CatalogFactoryBase();
115 factories.put(cl, factory);
116 }
117 }
118 return factory;
119
120 }
121
122
123 /***
124 * <p>Clear all references to registered catalogs, as well as to the
125 * relevant class loader. This method should be called, for example,
126 * when a web application utilizing this class is removed from
127 * service, to allow for garbage collection.</p>
128 */
129 public static void clear() {
130
131 synchronized (factories) {
132 factories.remove(getClassLoader());
133 }
134
135 }
136
137
138
139
140
141 /***
142 * <p>Return the relevant <code>ClassLoader</code> to use as a Map key
143 * for this request. If there is a thread context class loader, return
144 * that; otherwise, return the class loader that loaded this class.</p>
145 */
146 private static ClassLoader getClassLoader() {
147
148 ClassLoader cl = Thread.currentThread().getContextClassLoader();
149 if (cl == null) {
150 cl = CatalogFactory.class.getClassLoader();
151 }
152 return cl;
153
154 }
155
156
157 }