KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > webman > util > registry > Registry


1 package de.webman.util.registry JavaDoc;
2
3 import java.util.HashMap JavaDoc;
4 import java.io.IOException JavaDoc;
5 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
6 import javax.xml.parsers.DocumentBuilder JavaDoc;
7 import javax.xml.parsers.ParserConfigurationException JavaDoc;
8 import org.w3c.dom.Node JavaDoc;
9 import org.w3c.dom.Document JavaDoc;
10 import org.w3c.dom.Element JavaDoc;
11 import org.xml.sax.SAXException JavaDoc;
12 import org.xml.sax.InputSource JavaDoc;
13 import java.io.File JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.io.InputStream JavaDoc;
16 import java.io.FileInputStream JavaDoc;
17 import java.io.BufferedInputStream JavaDoc;
18 import org.apache.log4j.Category;
19
20
21 /**
22  * The central registry class. Implemented as singleton.<p>
23  *
24  * The normal way to use managers in webman is to request an instance of
25  * the Registry, using the {@link #getInstance()} method, and looking up
26  * the Manager from the resulting instance using the manager's id. For
27  * example:<p>
28  *
29  * <code><pre>
30  * MyManager reg = (MyManager)Registry.getInstance().lookup("acl");
31  * Boolean authgrp = (Boolean)reg.get("AUTH_GROUP", Boolean.FALSE);
32  * </pre></code>
33  *
34  * Since webman is a (kind of) webapplication and webapplications live in
35  * hostile environment (at least from the point of configuration at start
36  * up time), the configuration of the Registry is a bit weird. It is done
37  * using a xml file read in the very first time, the Registry is
38  * configured. Any following tries to configure it are simply ignored (see
39  * {@link #setConfiguration()}). The structure of the xml config file is
40  * as follows:<p>
41  *
42  * <code><pre>
43  * &lt;!ELEMENT registry (factories?)&gt;
44  * &lt;!ELEMENT factories (registry*)&gt;
45  * &lt;!ELEMENT manager #EMPTY&gt;
46  * &lt;!ATTLIST manager load-scheme (start|lazy) "lazy"
47  * factory-class CDATA #REQUIRED&gt;
48  * </pre></code>
49  *
50  * Example:<p>
51  *
52  * <code><pre>
53  * <registry>
54  * <factories>
55  * <manager load-scheme="start" factory-class="de.webman.acl.AclMgrFactory"/>
56  * <manager load-scheme="lazy" factory-class="de.webman.sync.SyncMgrFactory"/>
57  * <factories>
58  * </registry>
59  * </pre></code>
60  *
61  * @author <a HREF="mailto:gregor@webman.de">Gregor Klinke</a>
62  * @version $Revision: 1.2 $
63  **/

64 public class Registry
65 {
66     /* $Id: Registry.java,v 1.2 2002/04/12 12:30:24 gregor Exp $ */
67     
68     /**
69      * the loggin facility
70      **/

71     private static Category cat = Category.getInstance(Registry.class);
72     
73     /**
74      * denotes a manager load on start
75      **/

76     public static final String JavaDoc START_LOAD_SCHEME = "start";
77
78     /**
79      * denotes a lazy manager load
80      **/

81     public static final String JavaDoc LAZY_LOAD_SCHEME = "lazy";
82     
83     
84
85     /**
86      * the singleton instance
87      **/

88     private static Registry singleton = null;
89     
90     /**
91      * the cache of yet loaded managers. (contains {@link
92      * de.webman.util.registry.Manager} instances)
93      **/

94     private HashMap JavaDoc instMgrs = new HashMap JavaDoc();
95
96     /**
97      * the list of known manager factories. This maps manager ids to
98      * {@link de.webman.util.registry.ManagerFactory} instances. This
99      * classes are used to created Manager instances, which are cached in
100      * {@link #instMgrs}.
101      **/

102     private HashMap JavaDoc managers = new HashMap JavaDoc();
103
104     /**
105      * the base directory of the application
106      **/

107     private String JavaDoc basedir = "/";
108
109     /**
110      * is the mgr been configured yet?
111      **/

112     private boolean configuredYet = false;
113
114
115
116     /* ----------------------------------------------------------------------
117        creating and returning the singleton instance
118        ---------------------------------------------------------------------- */

119     /**
120      * private constructor, only to be used by getInstance
121      **/

122     private Registry() {
123     }
124
125     /**
126      * returns the singleton instance
127      * @return never <code>null</code>
128      **/

129     public static Registry getInstance() {
130         if (singleton == null)
131             singleton = new Registry();
132         return singleton;
133     }
134     
135
136     /* ----------------------------------------------------------------------
137        configuration
138        ---------------------------------------------------------------------- */

139     /**
140      * sets the configuration file of the instance. This is can be done only once.
141      * @param _basedir the absolute directory path to the base directory of
142      * the application
143      * @param _cfg the path to the configuration file relative to _basedir
144      *
145      * @return return <code>true</code> if the manager has not been
146      * configured before, and <code>false</code>, if it has (the
147      * configuration attempt) has been ignored).
148      *
149      * @throws IOException if the XML config file could not be read
150      **/

151     public boolean setConfiguration(String JavaDoc _basedir, String JavaDoc _cfg)
152         throws IOException JavaDoc, RegistryException
153     {
154         if (!configuredYet) {
155             basedir = _basedir;
156             readXMLStream(new BufferedInputStream JavaDoc(new FileInputStream JavaDoc(new File JavaDoc(_basedir, _cfg))));
157             configuredYet = true;
158             return true;
159         }
160         return false;
161     }
162
163     /**
164      * reads a xml config file. for the xml structure see above
165      **/

166     private void readXMLStream(BufferedInputStream JavaDoc in)
167         throws IOException JavaDoc, RegistryException
168     {
169         DocumentBuilderFactory JavaDoc factory = DocumentBuilderFactory.newInstance();
170         factory.setNamespaceAware(false);
171         factory.setValidating(false);
172             
173         Document JavaDoc doc = null;
174         try {
175             DocumentBuilder JavaDoc builder = factory.newDocumentBuilder();
176             doc = builder.parse(new InputSource JavaDoc(in));
177         }
178         catch (ParserConfigurationException JavaDoc pce) {
179             throw new RegistryException(pce);
180         }
181         catch (SAXException JavaDoc se) {
182             throw new RegistryException(se);
183         }
184         
185         Node JavaDoc nd = doc.getDocumentElement();
186         if (!("registry".equals(nd.getNodeName())))
187             throw new RegistryException("bad root element '" + nd.getNodeName() + "'");
188         
189         for (Node JavaDoc c1 = nd.getFirstChild(); c1 != null; c1 = c1.getNextSibling()) {
190             if (c1.getNodeType() == Node.ELEMENT_NODE) {
191                 if ("factories".equals(c1.getNodeName())) {
192                     for (Node JavaDoc c2 = c1.getFirstChild(); c2 != null; c2 = c2.getNextSibling()) {
193                         if (c2.getNodeType() == Node.ELEMENT_NODE) {
194                             if ("manager".equals(c2.getNodeName())) {
195                                 String JavaDoc load_scheme = ((Element JavaDoc)c2).getAttribute("load-scheme");
196                                 String JavaDoc factory_class = ((Element JavaDoc)c2).getAttribute("factory-class");
197                                 
198                                 registerFactoryClass(load_scheme, factory_class);
199                             }
200                             else
201                                 throw new RegistryException("unknown element: '" + c2.getNodeName() + "'");
202                         }
203                     }
204                 }
205                 else
206                     throw new RegistryException("unknown element: '" + c1.getNodeName() + "'");
207             }
208         }
209     }
210
211     /**
212      * returns the first text element below a context node
213      **/

214     private String JavaDoc getTextData(Node JavaDoc cntx) {
215         cntx.normalize();
216
217         for (Node JavaDoc n = cntx.getFirstChild(); n != null; n = n.getNextSibling()) {
218             if (n.getNodeType() == Node.TEXT_NODE) {
219                 return n.getNodeValue();
220             }
221             else if (n.getNodeType() == Node.CDATA_SECTION_NODE) {
222                 return n.getNodeValue();
223             }
224         }
225         return null;
226     }
227
228
229     /**
230      * loads and registers a manager class. If the load scheme of the
231      * manager is set to <b>start</b>, a manager instance is requested
232      * from the factory, initialized and registered with the cache; all
233      * other managers are handled lazy (they are only initialized and
234      * loaded when requested).
235      *
236      * @param load_scheme the load scheme, <b>lazy</b> means, creates and
237      * register a manager only when needed; <b>start</b> means, create the
238      * manager when loaded.
239      * @param factory_class the fully qualified class name for the manager
240      * factory class
241      **/

242     private void registerFactoryClass(String JavaDoc load_scheme, String JavaDoc factory_class) {
243         try {
244             Class JavaDoc factclass = Class.forName(factory_class);
245
246             ManagerFactory fact = (ManagerFactory)factclass.newInstance();
247             String JavaDoc mgrid = fact.getID();
248
249             if (START_LOAD_SCHEME.equals(load_scheme)) {
250                 try {
251                     instAndRegisterManager(fact);
252                     managers.put(mgrid, fact);
253                     cat.debug("Loading manager factory '" + fact.getID() + "': success");
254                 }
255                 catch (RegistryException re) {
256                     cat.error ("Manager could not be instanciated: " + re);
257                     /* don't register the factory, since creating an
258                        instance failed! */

259                 }
260             }
261             else if (LAZY_LOAD_SCHEME.equals(load_scheme)) {
262                 cat.debug("Loading manager factory '" + fact.getID() + "': success");
263                 managers.put(mgrid, fact);
264             }
265             else {
266                 cat.debug("Loading manager factory '" + fact.getID() + "': success");
267                 managers.put(mgrid, fact);
268             }
269         }
270         catch (ClassNotFoundException JavaDoc cnfe) {
271             cat.error("Class not found: '" + cnfe + "'");
272         }
273         catch (IllegalAccessException JavaDoc iae) {
274             cat.error("Class could not be instantiated: " + iae);
275         }
276         catch (InstantiationException JavaDoc ie) {
277             cat.error("Class could not be instantiated: " + ie);
278         }
279         catch (ClassCastException JavaDoc cce) {
280             cat.error("Class does not implement ManagerFactory: " + cce);
281         }
282     }
283
284
285
286     /* ----------------------------------------------------------------------
287        looking up managers
288        ---------------------------------------------------------------------- */

289     /**
290      * lookup a manager using the registry id. The manager is allocated
291      * newly (if not done yet), otherwise the cached instance of the
292      * manager is returned.
293      *
294      * @param mgrid the manager id
295      * @return the found manager or <code>null</code> if no such manager
296      * is known
297      *
298      * @throws RegistryException if anything fails
299      **/

300     public Manager lookup(String JavaDoc mgrid)
301         throws RegistryException
302     {
303         Manager mgr = (Manager)instMgrs.get(mgrid);
304         
305         if (mgr == null) {
306             ManagerFactory fact = (ManagerFactory) managers.get(mgrid);
307             if (fact != null)
308                 mgr = instAndRegisterManager(fact);
309         }
310         
311         return mgr;
312     }
313
314     /**
315      * instanciates and registers a manager from a manager factory
316      **/

317     private Manager instAndRegisterManager(ManagerFactory mgrfact)
318         throws RegistryException
319     {
320         Manager mgr = mgrfact.newManager(basedir);
321         instMgrs.put(mgrfact.getID(), mgr);
322         return mgr;
323     }
324 }
325
326
Popular Tags