Coverage Report - org.apache.commons.resources.impl.WebappPropertyResources
 
Classes in this File Line Coverage Branch Coverage Complexity
WebappPropertyResources
0%
0/45
0%
0/22
5.333
 
 1  
 /*
 2  
  * $Id: WebappPropertyResources.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.Locale;
 30  
 import java.util.Map;
 31  
 import java.util.Properties;
 32  
 
 33  
 import javax.servlet.ServletContext;
 34  
 
 35  
 import org.apache.commons.logging.Log;
 36  
 import org.apache.commons.logging.LogFactory;
 37  
 
 38  
 /**
 39  
  * <p>Concrete implementation of {@link org.apache.commons.resources.Resources} that wraps a family
 40  
  * (one per <code>Locale</code> of properties files that share a base
 41  
  * context-relative path for servlet context resources, and have
 42  
  * name suffixes reflecting the <code>Locale</code> for which
 43  
  * the document's messages apply.  Resources are looked up in a hierarchy
 44  
  * of properties files in a manner identical to that performed by
 45  
  * <code>java.util.ResourceBundle.getBundle().</code>.</p>
 46  
  *
 47  
  * <p>The base resource path passed to our constructor must contain the
 48  
  * context-relative base name of the properties file family.
 49  
  * For example, if the base path is passed as
 50  
  * <code>http://localhost/foo/Bar</code>, the resources for the
 51  
  * <code>en_US</code> Locale would be stored under URL
 52  
  * <code>http://localhost/foo/Bar_en_US.properties</code>, and the default
 53  
  * resources would be stored in
 54  
  * <code>http://localhost/foo/Bar.properties</code>.</p>
 55  
  */
 56  
 public class WebappPropertyResources extends CollectionResourcesBase {
 57  
 
 58  
     /**
 59  
      * <p>The <code>Log</code> instance for this class.</p>
 60  
      */
 61  0
     private transient Log log =
 62  0
         LogFactory.getLog(WebappPropertyResources.class);
 63  
 
 64  
     // ----------------------------------------------------------- Constructors
 65  
 
 66  
 
 67  
     /**
 68  
      * <p>Create a new {@link org.apache.commons.resources.Resources} instance with the specified
 69  
      * logical name and base resource URL.</p>
 70  
      *
 71  
      * @param name Logical name of the new instance
 72  
      * @param base Base URL of the family of properties files that contain
 73  
      *  the resource keys and values
 74  
      * @param servletContext the <code>ServletContext</code> instance
 75  
      *  to use for resolving resource references
 76  
      */
 77  
     public WebappPropertyResources(String name, String base,
 78  
                                    ServletContext servletContext) {
 79  
 
 80  0
         super(name, base);
 81  0
         this.servletContext = servletContext;
 82  
 
 83  0
     }
 84  
 
 85  
 
 86  
     // ----------------------------------------------------- Instance Variables
 87  
 
 88  
 
 89  
     /**
 90  
      * <p>The <code>ServletContext</code> instance for resolving
 91  
      * our resources references.</p>
 92  
      */
 93  0
     private ServletContext servletContext = null;
 94  
 
 95  
 
 96  
     // ------------------------------------------------------ Protected Methods
 97  
 
 98  
 
 99  
     /**
 100  
      * <p>Return a <code>Map</code> containing the name-value mappings for
 101  
      * the specified base URL and requested <code>Locale</code>, if there
 102  
      * are any.  If there are no defined mappings for the specified
 103  
      * <code>Locale</code>, return an empty <code>Map</code> instead.</p>
 104  
      *
 105  
      * <p>Concrete subclasses must override this method to perform the
 106  
      * appropriate lookup.  A typical implementation will construct an
 107  
      * absolute URL based on the specified base URL and <code>Locale</code>,
 108  
      * retrieve the specified resource file (if any), and parse it into
 109  
      * a <code>Map</code> structure.</p>
 110  
      *
 111  
      * <p>Caching of previously retrieved <code>Map</code>s (if any) should
 112  
      * be performed by callers of this method.  Therefore, this method should
 113  
      * always attempt to retrieve the specified resource and load it
 114  
      * appropriately.</p>
 115  
      *
 116  
      * @param baseUrl Base URL of the resource files for this {@link org.apache.commons.resources.Resources}
 117  
      *  instance
 118  
      * @param locale <code>Locale</code> for which name-value mappings
 119  
      *  are requested
 120  
      * @return A name-value Map for the specified URL and locale.
 121  
      */
 122  
     protected Map getLocaleMap(String baseUrl, Locale locale) {
 123  
 
 124  0
         if (getLog().isDebugEnabled()) {
 125  0
             getLog().debug("Loading locale '" + locale + "' resources from base '" +
 126  
                     baseUrl + "'");
 127  
         }
 128  
 
 129  0
         Properties props = new Properties();
 130  0
         String name = baseUrl.replace('.', '/');
 131  0
         name += getLocaleSuffix(locale) + ".properties";
 132  
         
 133  0
         InputStream stream = null;
 134  
 
 135  
         try {
 136  
 
 137  
             // Open an input stream to the URL for this locale (if any)
 138  0
             if (getLog().isTraceEnabled()) {
 139  0
                 getLog().trace("Complete path is '" + name + "'");
 140  
             }
 141  
             try{
 142  0
                 stream = servletContext.getResourceAsStream(name);
 143  
             }
 144  0
             catch(Exception e){
 145  
                 // not found
 146  
                 // try ContextClassLoader
 147  0
             }
 148  0
             if (stream == null){
 149  
                 
 150  0
                 ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
 151  0
                 if (classLoader == null) {
 152  0
                     classLoader = this.getClass().getClassLoader();
 153  
                 }
 154  0
                 stream = classLoader.getResourceAsStream(name);
 155  
             }
 156  
             
 157  
             // Parse the input stream and populate the name-value mappings map
 158  0
             if (stream != null) {
 159  0
                 if (getLog().isTraceEnabled()) {
 160  0
                     getLog().trace("Parsing input resource");
 161  
                 }
 162  0
                 props.load(stream);
 163  
             }
 164  
 
 165  0
         } catch (FileNotFoundException e) {
 166  
 
 167  
             // Log and swallow this exception
 168  0
             if (getLog().isDebugEnabled()) {
 169  0
                 getLog().debug("No resources for locale '" + locale +
 170  
                           "' from base '" + baseUrl + "'");
 171  
             }
 172  0
             props.clear();
 173  
 
 174  0
         } catch (IOException e) {
 175  
 
 176  0
             getLog().warn("IOException loading locale '" + locale +
 177  
                      "' from base '" + baseUrl + "'", e);
 178  0
             props.clear();
 179  
 
 180  0
         } finally {
 181  
 
 182  
             // Close the input stream that was opened earlier
 183  0
             if (stream != null) {
 184  
                 try {
 185  0
                     stream.close();
 186  0
                 } catch (IOException e) {
 187  0
                     getLog().error("Error closing stream.", e);
 188  0
                 }
 189  0
                 stream = null;
 190  
             }
 191  
 
 192  0
         }
 193  
 
 194  
         // Return the populated (or empty) properties
 195  0
         return (props);
 196  
 
 197  
     }
 198  
 
 199  
     /**
 200  
      * Accessor method for Log instance.
 201  
      *
 202  
      * The Log instance variable is transient and
 203  
      * accessing it through this method ensures it
 204  
      * is re-initialized when this instance is
 205  
      * de-serialized.
 206  
      *
 207  
      * @return The Log instance.
 208  
      */
 209  
     private Log getLog() {
 210  0
         if (log == null) {
 211  0
             log =  LogFactory.getLog(WebappPropertyResources.class);
 212  
         }
 213  0
         return log;
 214  
     }
 215  
 
 216  
 }