Coverage Report - org.apache.commons.resources.impl.WebappXMLResources
 
Classes in this File Line Coverage Branch Coverage Complexity
WebappXMLResources
0%
0/47
0%
0/20
5
 
 1  
 /*
 2  
  * $Id: WebappXMLResources.java 348371 2005-11-23 04:56:51Z niallp $
 3  
  * $Revision: 348371 $
 4  
  * $Date: 2005-11-23 04:56:51 +0000 (Wed, 23 Nov 2005) $
 5  
  *
 6  
  * ====================================================================
 7  
  *
 8  
  *  Copyright 2003-2005 The Apache Software Foundation
 9  
  *
 10  
  *  Licensed under the Apache License, Version 2.0 (the "License");
 11  
  *  you may not use this file except in compliance with the License.
 12  
  *  You may obtain a copy of the License at
 13  
  *
 14  
  *      http://www.apache.org/licenses/LICENSE-2.0
 15  
  *
 16  
  *  Unless required by applicable law or agreed to in writing, software
 17  
  *  distributed under the License is distributed on an "AS IS" BASIS,
 18  
  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 19  
  *  See the License for the specific language governing permissions and
 20  
  *  limitations under the License.
 21  
  *
 22  
  */
 23  
 
 24  
 package org.apache.commons.resources.impl;
 25  
 
 26  
 import java.io.FileNotFoundException;
 27  
 import java.io.IOException;
 28  
 import java.io.InputStream;
 29  
 import java.util.HashMap;
 30  
 import java.util.Locale;
 31  
 import java.util.Map;
 32  
 
 33  
 import javax.servlet.ServletContext;
 34  
 
 35  
 import org.apache.commons.digester.Digester;
 36  
 import org.apache.commons.logging.Log;
 37  
 import org.apache.commons.logging.LogFactory;
 38  
 import org.xml.sax.SAXException;
 39  
 
 40  
 /**
 41  
  * <p>Concrete implementation of 
 42  
  * {@link org.apache.commons.resources.Resources} that wraps a family
 43  
  * (one per <code>Locale</code> of XML documents that share a base
 44  
  * context-relative path for servlet context resources, and have
 45  
  * name suffixes reflecting the <code>Locale</code> for which
 46  
  * the document's messages apply.  Resources are looked up in a hierarchy
 47  
  * of properties files in a manner identical to that performed by
 48  
  * <code>java.util.ResourceBundle.getBundle().</code>.</p>
 49  
  *
 50  
  * <p>The base resource path passed to our constructor must contain the
 51  
  * context-relative base name of the properties file family.
 52  
  * For example, if the base path is passed as
 53  
  * <code>http://localhost/foo/Bar</code>, the resources for the
 54  
  * <code>en_US</code> Locale would be stored under URL
 55  
  * <code>http://localhost/foo/Bar_en_US.xml</code>, and the default
 56  
  * resources would be stored in
 57  
  * <code>http://localhost/foo/Bar.xml</code>.</p>
 58  
  */
 59  
 public class WebappXMLResources extends CollectionResourcesBase {
 60  
 
 61  
     /**
 62  
      * <p>The <code>Log</code> instance for this class.</p>
 63  
      */
 64  0
     private transient Log log = LogFactory.getLog(WebappXMLResources.class);
 65  
 
 66  
     /**
 67  
      * <p>Create a new {@link org.apache.commons.resources.Resources} instance with the specified
 68  
      * logical name and base resource URL.</p>
 69  
      *
 70  
      * @param name Logical name of the new instance
 71  
      * @param base Base URL of the family of properties files that contain
 72  
      *  the resource keys and values
 73  
      * @param servletContext the <code>ServletContext</code> instance
 74  
      *  to use for resolving resource references
 75  
      */
 76  
     public WebappXMLResources(String name, String base,
 77  
                                    ServletContext servletContext) {
 78  
 
 79  0
         super(name, base);
 80  0
         this.servletContext = servletContext;
 81  
 
 82  0
     }
 83  
 
 84  
 
 85  
     // ----------------------------------------------------- Instance Variables
 86  
 
 87  
     /**
 88  
      * <p>The <code>ServletContext</code> instance for resolving
 89  
      * our resources references.</p>
 90  
      */
 91  0
     private ServletContext servletContext = null;
 92  
 
 93  
 
 94  
     // ------------------------------------------------------ Protected Methods
 95  
 
 96  
 
 97  
     /**
 98  
      * <p>Return a <code>Map</code> containing the name-value mappings for
 99  
      * the specified base URL and requested <code>Locale</code>, if there
 100  
      * are any.  If there are no defined mappings for the specified
 101  
      * <code>Locale</code>, return an empty <code>Map</code> instead.</p>
 102  
      *
 103  
      * <p>Concrete subclasses must override this method to perform the
 104  
      * appropriate lookup.  A typical implementation will construct an
 105  
      * absolute URL based on the specified base URL and <code>Locale</code>,
 106  
      * retrieve the specified resource file (if any), and parse it into
 107  
      * a <code>Map</code> structure.</p>
 108  
      *
 109  
      * <p>Caching of previously retrieved <code>Map</code>s (if any) should
 110  
      * be performed by callers of this method.  Therefore, this method should
 111  
      * always attempt to retrieve the specified resource and load it
 112  
      * appropriately.</p>
 113  
      *
 114  
      * @param baseUrl Base URL of the resource files for this {@link org.apache.commons.resources.Resources}
 115  
      *  instance
 116  
      * @param locale <code>Locale</code> for which name-value mappings
 117  
      *  are requested
 118  
      * @return A name-value Map for the specified URL and locale.
 119  
      */
 120  
     protected Map getLocaleMap(String baseUrl, Locale locale) {
 121  
 
 122  0
         if (getLog().isDebugEnabled()) {
 123  0
             getLog().debug("Loading locale '" + locale + "' resources from base '" +
 124  
                     baseUrl + "'");
 125  
         }
 126  
 
 127  0
         Map map = new HashMap();
 128  0
         String name = baseUrl + getLocaleSuffix(locale) + ".xml";
 129  0
         InputStream stream = null;
 130  
 
 131  
         try {
 132  
 
 133  
             // Open an input stream to the URL for this locale (if any)
 134  0
             if (getLog().isTraceEnabled()) {
 135  0
                 getLog().trace("Complete path is '" + name + "'");
 136  
             }
 137  0
             stream = servletContext.getResourceAsStream(name);
 138  
 
 139  
             // Create and configure a new Digester instance
 140  0
             if (stream != null) {
 141  
 
 142  0
                 if (getLog().isTraceEnabled()) {
 143  0
                     getLog().trace("Creating Digester instance");
 144  
                 }
 145  0
                 Digester digester = new Digester();
 146  0
                 digester.setNamespaceAware(false);
 147  0
                 digester.setValidating(false);
 148  0
                 digester.push(map);
 149  0
                 digester.addCallMethod("resources/resource", "put", 2,
 150  
                                        new String[] { "java.lang.Object",
 151  
                                                       "java.lang.Object" });
 152  0
                 digester.addCallParam("resources/resource", 0, "id");
 153  0
                 digester.addCallParam("resources/resource", 1);
 154  
 
 155  
                 // Parse the input stream and populate the name-value mappings
 156  0
                 if (getLog().isTraceEnabled()) {
 157  0
                     getLog().trace("Parsing input resource");
 158  
                 }
 159  0
                 digester.parse(stream);
 160  
 
 161  
             }
 162  
 
 163  0
         } catch (FileNotFoundException e) {
 164  
 
 165  
             // Log and swallow this exception
 166  0
             if (getLog().isDebugEnabled()) {
 167  0
                 getLog().debug("No resources for locale '" + locale +
 168  
                           "' from base '" + baseUrl + "'");
 169  
             }
 170  0
             map.clear();
 171  
 
 172  0
         } catch (IOException e) {
 173  
 
 174  
             // Log and swallow this exception
 175  0
             getLog().warn("IOException loading locale '" + locale +
 176  
                      "' from base '" + baseUrl + "'", e);
 177  0
             map.clear();
 178  
 
 179  0
         } catch (SAXException e) {
 180  
 
 181  
             // Log and swallow this exception
 182  0
             getLog().warn("SAXException loading locale '" + locale +
 183  
                      "' from base '" + baseUrl + "'", e);
 184  0
             map.clear();
 185  
 
 186  0
         } finally {
 187  
 
 188  
             // Close the input stream that was opened earlier
 189  0
             if (stream != null) {
 190  
                 try {
 191  0
                     stream.close();
 192  0
                 } catch (Exception e) {
 193  
                     // standard io
 194  0
                 }
 195  0
                 stream = null;
 196  
             }
 197  
 
 198  0
         }
 199  
 
 200  
         // Return the populated (or empty) map
 201  0
         return (map);
 202  
 
 203  
 
 204  
     }
 205  
 
 206  
     /**
 207  
      * Accessor method for Log instance.
 208  
      *
 209  
      * The Log instance variable is transient and
 210  
      * accessing it through this method ensures it
 211  
      * is re-initialized when this instance is
 212  
      * de-serialized.
 213  
      *
 214  
      * @return The Log instance.
 215  
      */
 216  
     private Log getLog() {
 217  0
         if (log == null) {
 218  0
             log =  LogFactory.getLog(WebappXMLResources.class);
 219  
         }
 220  0
         return log;
 221  
     }
 222  
 
 223  
 }