KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > excalibur > i18n > XmlBundle


1 /*
2  * Copyright (C) The Apache Software Foundation. All rights reserved.
3  *
4  * This software is published under the terms of the Apache Software License
5  * version 1.1, a copy of which has been included with this distribution in
6  * the LICENSE.txt file.
7  */

8 package org.apache.avalon.excalibur.i18n;
9
10 /** JDK classes **/
11 import org.apache.avalon.framework.activity.Disposable;
12 import org.apache.avalon.framework.activity.Initializable;
13 import org.apache.avalon.framework.component.Composable;
14 import org.apache.avalon.framework.component.Component;
15 import org.apache.avalon.framework.component.ComponentManager;
16 import org.apache.avalon.framework.configuration.Configurable;
17 import org.apache.avalon.framework.configuration.Configuration;
18 import org.apache.avalon.framework.configuration.ConfigurationException;
19 import org.apache.avalon.excalibur.xml.xpath.XPathProcessor;
20 import org.apache.avalon.excalibur.xml.Parser;
21 import org.apache.avalon.excalibur.source.Source;
22 import org.apache.avalon.excalibur.source.SourceResolver;
23 import org.apache.avalon.excalibur.source.SourceUtil;
24 import org.w3c.dom.Document JavaDoc;
25 import org.w3c.dom.Node JavaDoc;
26 import org.w3c.dom.NodeList JavaDoc;
27 import org.w3c.dom.NamedNodeMap JavaDoc;
28 import org.xml.sax.InputSource JavaDoc;
29
30 import java.util.HashMap JavaDoc;
31 import java.util.Locale JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.MissingResourceException JavaDoc;
34
35 /**
36  * @author <a HREF="mailto:mengelhart@earthtrip.com">Mike Engelhart</a>
37  * @author <a HREF="mailto:neeme@apache.org">Neeme Praks</a>
38  * @author <a HREF="mailto:oleg@one.lv">Oleg Podolsky</a>
39  * @version $Id: XmlBundle.java,v 1.8 2002/01/04 13:21:31 cziegeler Exp $
40  */

41 public class XmlBundle extends AbstractBundle implements Configurable, Initializable, Disposable, Composable {
42
43     /** Constants for configuration keys */
44     public static class ConfigurationKeys {
45         public static final String JavaDoc LOAD_ON_INIT = "load-on-init";
46         public static final String JavaDoc USE_ROOT = "use-root-element";
47     }
48
49     /** Cache for storing string values for existing XPaths */
50     private Map JavaDoc cache = new HashMap JavaDoc();
51
52     /** Cache for storing non-existing XPaths */
53     private Map JavaDoc cacheNotFound = new HashMap JavaDoc();
54
55     /** DOM-tree containing the bundle content */
56     private Document JavaDoc doc;
57
58     /** Component Manager */
59     protected ComponentManager manager = null;
60
61     /** XPath Processor */
62     private XPathProcessor processor = null;
63
64     /** bundle info mapper */
65     private BundleInfoMapper mapper;
66
67     /** bundle name prefix */
68     private String JavaDoc prefix;
69
70     /** bundle name suffix */
71     private String JavaDoc suffix;
72
73     /** Load all the keys when initializing? */
74     private boolean loadOnInit = true;
75
76     /** Use the XML root element in key names when pre-loading? */
77     private boolean useRootElement = false;
78
79     public void compose(ComponentManager manager) {
80         this.manager = manager;
81         try {
82             this.processor = (XPathProcessor)this.manager.lookup(XPathProcessor.ROLE);
83             this.mapper = (BundleInfoMapper)this.manager.lookup(BundleInfoMapper.ROLE);
84         } catch (Exception JavaDoc e) {
85             getLogger().error("cannot obtain XPathProcessor", e);
86         }
87     }
88
89     public void configure(Configuration configuration) throws ConfigurationException {
90         this.loadOnInit = configuration.getAttributeAsBoolean(ConfigurationKeys.LOAD_ON_INIT, true);
91         this.useRootElement = configuration.getAttributeAsBoolean(ConfigurationKeys.USE_ROOT, false);
92     }
93
94     /**
95      * Initalize the bundle
96      *
97      * @param document XML source document (DOM)
98      */

99     public void initialize() throws Exception JavaDoc {
100         initialize(getMapper().map(getBundleInfo()));
101     }
102
103     /**
104      * Initalize the bundle
105      *
106      * @param uri URI of the XML source
107      * @exception IOException if an IO error occurs while reading the file
108      * @exception ParserConfigurationException if no parser is configured
109      * @exception SAXException if an error occurs while parsing the file
110      */

111     public void initialize(String JavaDoc uri) throws Exception JavaDoc {
112         SourceResolver resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
113         initialize(resolver.resolve(uri));
114         this.manager.release(resolver);
115     }
116
117     /**
118      * Initalize the bundle
119      *
120      * @param file XML source file
121      * @exception IOException if an IO error occurs while reading the file
122      * @exception ParserConfigurationException if no parser is configured
123      * @exception SAXException if an error occurs while parsing the file
124      */

125     public void initialize(Source source) throws Exception JavaDoc {
126         initialize( SourceUtil.getInputSource( source ) );
127     }
128
129     /**
130      * Initalize the bundle
131      *
132      * @param inStream XML source stream
133      * @exception IOException if an IO error occurs while reading the file
134      * @exception ParserConfigurationException if no parser is configured
135      * @exception SAXException if an error occurs while parsing the file
136      */

137     public void initialize(InputSource JavaDoc inSource) throws Exception JavaDoc {
138         Parser parser = (Parser) this.manager.lookup(Parser.ROLE);
139         this.doc = parser.parseDocument(inSource);
140         load();
141     }
142
143     /**
144      * Load (pre-cache) the contents
145      *
146      * @param document XML source document (DOM)
147      */

148     private void load() throws Exception JavaDoc {
149         if (this.loadOnInit) {
150             cacheAll(doc.getDocumentElement(), useRootElement ? '/' + doc.getDocumentElement().getTagName() : "");
151         }
152     }
153
154     /**
155      * Convert the &quot;user view&quot; of the lookup key to the
156      * &quot;system view&quot;.
157      * Current implementation coverts dots into slashes, so common Java property
158      * names become XPath paths.
159      * E.g: this.is.java.property.key --> /this/is/java/property/key
160      *
161      * @param key user key
162      * @return system key
163      */

164     public String JavaDoc convertKey(String JavaDoc userKey) {
165         return '/' + userKey.replace('.', '/');
166     }
167
168     /**
169      * Gets the source DOM tree of the bundle.
170      *
171      * @return the DOM tree
172      */

173     public Document JavaDoc getDocument() {
174         return this.doc;
175     }
176
177     /**
178      * Does the &quot;key-cache&quot; contain the value with such key?
179      *
180      * @param key the key to the value to be returned
181      * @return true if contains, false otherwise
182      */

183     protected boolean cacheContains(String JavaDoc key) {
184         boolean result = cache.containsKey(key);
185         if (getLogger().isDebugEnabled()) getLogger().debug(getBundleInfo() + ": cache contains key '" + key + "': " + result);
186         return result;
187     }
188
189     /**
190      * Does the &quot;key-not-found-cache&quot; contain such key?
191      *
192      * @param key the key to the value to be returned
193      * @return true if contains, false otherwise
194      */

195     protected boolean cacheNotFoundContains(String JavaDoc key) {
196         boolean result = cacheNotFound.containsKey(key);
197         if (getLogger().isDebugEnabled()) getLogger().debug(getBundleInfo() + ": cache_not_found contains key '" + key + "': " + result);
198         return result;
199     }
200
201     /**
202      * Cache the key and value in &quot;key-cache&quot;.
203      *
204      * @param key the key
205      * @param value the value
206      */

207     protected void cacheKey(String JavaDoc key, String JavaDoc value) {
208         if (getLogger().isDebugEnabled()) getLogger().debug(getBundleInfo() + ": caching: " + key + " = " + value);
209         cache.put(key, value);
210     }
211
212     /**
213      * Cache the key in &quot;key-not-found-cache&quot;.
214      *
215      * @param key the key
216      */

217     protected void cacheNotFoundKey(String JavaDoc key) {
218         if (getLogger().isDebugEnabled()) getLogger().debug(getBundleInfo() + ": caching not_found: " + key);
219         cacheNotFound.put(key, "");
220     }
221
222     /**
223      * Gets the value by the key from the &quot;key-cache&quot;.
224      *
225      * @param key the key
226      * @return the value
227      */

228     protected String JavaDoc getFromCache(String JavaDoc key) {
229         if (getLogger().isDebugEnabled()) getLogger().debug(getBundleInfo() + ": returning from cache: " + key);
230         return (String JavaDoc) cache.get(key);
231     }
232
233     /**
234      * Steps through the bundle tree and stores all text element values
235      * in bundle's cache. Also stores attributes for all element nodes.
236      *
237      * @param parent parent node, must be an element
238      * @param pathToParent XPath to the parent node
239      */

240     protected void cacheAll(Node JavaDoc parent, String JavaDoc pathToParent) {
241         NodeList JavaDoc children = parent.getChildNodes();
242         int childnum = children.getLength();
243
244         for(int i = 0; i < childnum; i++) {
245             Node JavaDoc child = children.item(i);
246
247             if(child.getNodeType() == Node.ELEMENT_NODE) {
248                 StringBuffer JavaDoc pathToChild = new StringBuffer JavaDoc(pathToParent).append('/').append(child.getNodeName());
249
250                 NamedNodeMap JavaDoc attrs = child.getAttributes();
251                 if(attrs != null) {
252                     Node JavaDoc temp = null;
253                     String JavaDoc pathToAttr = null;
254                     int attrnum = attrs.getLength();
255                     for(int j = 0; j < attrnum; j++) {
256                         temp = attrs.item(j);
257                         if (!temp.getNodeName().equalsIgnoreCase("xml:lang"))
258                             pathToChild.append("[@").append(temp.getNodeName())
259                                     .append("='").append(temp.getNodeValue())
260                                     .append("']");
261                     }
262                 }
263
264                 String JavaDoc childValue = getTextValue(child);
265                 if(childValue != null)
266                     cacheKey(pathToChild.toString(), childValue);
267                 else
268                     cacheAll(child, pathToChild.toString());
269             }
270         }
271     }
272
273     /**
274      * Get value by key.
275      *
276      * @param key key
277      * @return value
278      * @exception MissingResourceException if value was not found
279      */

280     public String JavaDoc getString(String JavaDoc key) throws MissingResourceException JavaDoc {
281         String JavaDoc value = _getString(convertKey(key));
282         if (value == null)
283             throw new MissingResourceException JavaDoc(
284                     "Unable to locate resource: " + key,
285                     XmlBundle.class.getName(),
286                     key);
287         else
288             return value;
289     }
290
291     /**
292      * Get value by key.
293      *
294      * @param key the key
295      * @return the value
296      */

297     protected String JavaDoc _getString(String JavaDoc key) {
298         if (key == null) return null;
299         String JavaDoc value = getFromCache(key);
300
301         if (value == null && !cacheNotFoundContains(key))
302         {
303         if (doc != null)
304                 value = _getString(this.doc.getDocumentElement(), key);
305
306             if (value == null)
307             {
308                 if (getParent() != null)
309                     value = getParent().getString(key);
310             }
311
312             if (value != null)
313                 cacheKey(key, value);
314             else
315                 cacheNotFoundKey(key);
316         }
317         return value;
318     }
319
320     /**
321      * Get value by key from a concrete node.
322      *
323      * @param node the node
324      * @param key the key
325      * @return the value
326      */

327     protected String JavaDoc _getString(Node JavaDoc node, String JavaDoc key) {
328         String JavaDoc value = null;
329         try {
330             value = getTextValue(_getNode(node, key));
331         }
332         catch (Exception JavaDoc e) {
333             getLogger().error(getBundleInfo() + ": error while locating resource: " + key, e);
334         }
335         return value;
336     }
337
338     /**
339      * Get the text value of the node.
340      *
341      * @param node the node
342      * @return the value
343      */

344     protected static String JavaDoc getTextValue(Node JavaDoc element) {
345         if (element == null) return null;
346         NodeList JavaDoc list = element.getChildNodes();
347         int listsize = list.getLength();
348
349         Node JavaDoc item = null;
350         String JavaDoc itemValue = null;
351
352         for(int i = 0; i < listsize; i++) {
353             item = list.item(i);
354         if(item.getNodeType() != Node.TEXT_NODE)
355             return null;
356
357             itemValue = item.getNodeValue();
358         if(itemValue == null)
359             return null;
360
361             itemValue = itemValue.trim();
362         if(itemValue.length() == 0)
363             return null;
364
365             return itemValue;
366         }
367         return null;
368     }
369
370     /**
371      * Get the node with the supplied XPath key.
372      *
373      * @param key the key
374      * @return the node
375      */

376     protected Node JavaDoc _getNode(String JavaDoc key) {
377         return _getNode(this.doc.getDocumentElement(), key);
378     }
379
380     /**
381      * Get the node with the supplied XPath key, starting from concrete
382      * root node.
383      *
384      * @param rootNode the root node
385      * @param key the key
386      * @return the node
387      */

388     protected Node JavaDoc _getNode(Node JavaDoc rootNode, String JavaDoc key) {
389         Node JavaDoc node = null;
390         try {
391             node = this.processor.selectSingleNode(rootNode, key);
392         }
393         catch (Exception JavaDoc e) {
394             getLogger().error("Error while locating resource with key: " + key, e);
395         }
396         return node;
397     }
398
399     public void dispose() {
400         this.manager.release((Component)this.processor);
401     }
402 }
403
Popular Tags