KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > barracuda > core > util > dom > DefaultDOMLoader


1 /*
2  * Copyright (C) 2001 Christian Cryder [christianc@granitepeaks.com]
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * $Id: DefaultDOMLoader.java,v 1.19 2004/01/29 18:02:35 christianc Exp $
19  */

20 package org.enhydra.barracuda.core.util.dom;
21
22 import java.io.IOException JavaDoc;
23 import java.util.*;
24 import org.apache.log4j.Logger;
25 import org.w3c.dom.Document JavaDoc;
26
27
28 /**
29  * Default implementation of a DOMLoader
30  *
31  * @see DOMLoader
32  */

33 public class DefaultDOMLoader implements DOMLoader {
34
35     protected static final Logger logger = Logger.getLogger(DefaultDOMLoader.class.getName());
36
37     /**
38      * @see #getGlobalInstance()
39      */

40     protected static DefaultDOMLoader globalLoader = null;
41
42     /**
43      * arbitrary object used to synchronize upon
44      */

45     protected static final Object JavaDoc sync = new Object JavaDoc();
46
47     /**
48      * used for flagging whether the globalLoader has been initialized and
49      * avoiding unnecessary instantiation and synchronization.
50      */

51     protected static boolean initialized = false;
52
53     /**
54      * @see #setDefaultDOMFactory(DOMFactory)
55      */

56     protected DOMFactory defaultDOMFactory = null;
57     
58     /**
59      * @see #registerDOMFactory(DOMFactory, String)
60      * @see #deregisterDOMFactory(String)
61      */

62     protected Map factories = null;
63     
64     /**
65      * @see #lookupClass(String)
66      */

67     protected Map classmap = null;
68
69     /**
70      * Make sure no one can directly instantiate this class using the
71      * default constructor. To get an instance of this class, one must use
72      * {@link #getGlobalInstance()}
73      */

74     private DefaultDOMLoader() {
75         defaultDOMFactory = new XMLCDeferredParsingDOMFactory();
76         factories = new HashMap();
77         classmap = new HashMap();
78     }
79
80     /**
81      * @see DOMLoader#getDOM(Class)
82      */

83     public Document JavaDoc getDOM(Class JavaDoc clazz) throws IOException JavaDoc {
84         return _getDOM(clazz, null);
85     }
86
87     /**
88      * @see DOMLoader#getDOM(Class, Locale)
89      */

90     public Document JavaDoc getDOM(Class JavaDoc clazz, Locale locale) throws IOException JavaDoc {
91         return _getDOM(clazz, locale);
92     }
93
94     /**
95      * Note: the default locale is currently ignored in this implementation
96      *
97      * @see DOMLoader#getDOM(String)
98      */

99     public Document JavaDoc getDOM(String JavaDoc docPath) throws IOException JavaDoc {
100         return _getDOMFromFile(docPath, null);
101     }
102
103     /**
104      * Note: the specified locale is currently ignored in this implementation
105      *
106      * @see DOMLoader#getDOM(String, Locale)
107      */

108     public Document JavaDoc getDOM(String JavaDoc docPath, Locale locale) throws IOException JavaDoc {
109         return _getDOMFromFile(docPath, locale);
110     }
111
112     /**
113      * All getDOM(Class) methods call this private method which takes care of
114      * parameter validation and then calls _getDOM(String, Locale) which does
115      * all the work
116      */

117     private Document JavaDoc _getDOM(Class JavaDoc clazz, Locale locale) throws IOException JavaDoc {
118         //eliminate the obvious
119
if (clazz==null) throw new IOException JavaDoc("Invalid class: class is null");
120         return _getDOM(clazz.getName(), doGetLocaleCheck(locale));
121     }
122
123     /**
124      * This private method does the work of loading a class based on
125      * a particular locale in a way similar to how resource bundles work and
126      * then invokes a dom factory to load the document associated with the class
127      */

128     private Document JavaDoc _getDOM(String JavaDoc className, Locale locale) throws IOException JavaDoc {
129         //first we need to figure out the real class name (taking into account
130
//the locale). To do this, we must understand the naming convention. As
131
//with resource bundles, we'll look for class name + locale. For example,
132
//if we request HelloWorldHTML.class, but the locale is Spanish (es),
133
//then we should get back an instance of the DOM for HelloWorldHTML_es.class,
134
//unless of course that class does not exist, in which case it should return
135
//the DOM for HelloWorld.class. In this way, the DOM classes themselves act
136
//like resource bundles.
137

138         String JavaDoc baseName = className;
139         Class JavaDoc targetClass = null;
140         String JavaDoc targetName = null;
141         String JavaDoc language = locale.getLanguage();
142         String JavaDoc country = locale.getCountry();
143         String JavaDoc variant = locale.getVariant();
144         targetName = baseName+"_"+language+"_"+country+"_"+variant;
145         targetClass = lookupClass(targetName);
146         if (targetClass==null) {
147             targetName = baseName+"_"+language+"_"+country;
148             targetClass = lookupClass(targetName);
149         }
150         if (targetClass==null) {
151             targetName = baseName+"_"+language;
152             targetClass = lookupClass(targetName);
153         }
154         if (targetClass==null) {
155             targetName = baseName;
156             targetClass = lookupClass(targetName);
157         }
158         if (logger.isDebugEnabled()) logger.debug("Target class: "+targetClass);
159         if (targetClass==null) throw new IOException JavaDoc("Unexpected Invalid class: class is null"); //essentially impossible for this to happen
160

161         //at this point we should have a valid class; now we
162
//need to create a DOM for it
163
synchronized (factories) {
164             if (logger.isDebugEnabled()) logger.debug("Loading DOM");
165             DOMFactory df = (DOMFactory) factories.get(targetName);
166             if (df!=null) {
167                 return df.getInstance(targetClass);
168             }
169             return defaultDOMFactory.getInstance(targetClass);
170         }
171     }
172
173     /**
174      * All getDOM(String) methods call this private method which takes care of
175      * parameter validation and then invokes a dom factory to load the document
176      * located at the specified document path
177      */

178     private Document JavaDoc _getDOMFromFile(String JavaDoc docPath, Locale locale) throws IOException JavaDoc {
179         //eliminate the obvious
180
if (docPath==null) throw new IOException JavaDoc("Invalid document path:"+docPath);
181         
182         //need to create a DOM for it
183
synchronized (factories) {
184             if (logger.isDebugEnabled()) logger.debug("Loading DOM");
185             DOMFactory df = (DOMFactory) factories.get(docPath);
186             if (df!=null) {
187                 return df.getInstance(docPath);
188             }
189             return defaultDOMFactory.getInstance(docPath);
190         }
191     }
192
193     /**
194      * Checks the provided locale and returns a default locale if the one
195      * provided is null
196      */

197     private static Locale doGetLocaleCheck(Locale locale) throws IOException JavaDoc {
198         //if the locale is still null, just use the default
199
if (locale==null) {
200             locale = Locale.getDefault();
201             if (logger.isDebugEnabled()) logger.debug("Using default locale: "+locale);
202         }
203         return locale;
204     }
205
206     /**
207      * Find a stored reference to a class. If not found, instantiate it
208      * and store it for later reference and faster retrieval.
209      *
210      * @param className the fully qualified name of a class
211      * @return the instantiated class
212      */

213     protected Class JavaDoc lookupClass(String JavaDoc className) {
214         synchronized (classmap) {
215             //first see if we have a reference to that class in our classmap
216
Class JavaDoc clazz = (Class JavaDoc) classmap.get(className);
217
218             //if not, try to instantiate it
219
if (clazz==null) {
220                 try {
221                     clazz = Class.forName(className, true, Thread.currentThread().getContextClassLoader());
222                     classmap.put(className, clazz);
223                 } catch (Exception JavaDoc e) {}
224             }
225             return clazz;
226         }
227     }
228
229     /**
230      * Specify the default DOM factory
231      *
232      * @param df the DOMFactory to be used by default
233      */

234     public void setDefaultDOMFactory(DOMFactory df) {
235         if (logger.isDebugEnabled()) logger.debug("Setting default DOM factory:"+df);
236         synchronized (factories) {
237             defaultDOMFactory = df;
238         }
239     }
240
241     /**
242      * Register a DOMFactory keyed against a fully qualified class name or a
243      * document path
244      *
245      * @param df the DOMFactory
246      * @param key the string which key's a particular DOMFactory to be used
247      */

248     public void registerDOMFactory(DOMFactory df, String JavaDoc key) {
249         if (logger.isDebugEnabled()) logger.debug("Registering DOM factory:"+df+" for key:"+key);
250         synchronized (factories) {
251             factories.put(key, df);
252         }
253     }
254
255     /**
256      * Deregister a DOMFactory keyed against a fully qualified class name or a
257      * document path
258      *
259      * @param key the string which key's a particular DOMFactory to be removed
260      */

261     public void deregisterDOMFactory(String JavaDoc key) {
262         if (logger.isDebugEnabled()) logger.debug("Deregistering DOM factory for key:"+key);
263         synchronized (factories) {
264             factories.remove(key);
265         }
266     }
267
268     /**
269      * Get the global instance of the DefaultDOMLoader
270      *
271      * @return the global instance of the DefaultDOMLoader
272      */

273     public static DefaultDOMLoader getGlobalInstance() {
274         if (initialized == false) {
275             synchronized (sync) {
276                 logger.info("initializing global instance of DefaultDOMLoader");
277                 globalLoader = new DefaultDOMLoader();
278                 initialized = true;
279             }
280         }
281         return globalLoader;
282     }
283
284 }
285
Popular Tags