Clover coverage report - Code Coverage for hivemind release 1.1-alpha-2
Coverage timestamp: Wed Feb 23 2005 09:59:04 EST
file stats: LOC: 218   Methods: 11
NCLOC: 133   Classes: 2
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
MessageFinderImpl.java 83.3% 94.1% 100% 93.2%
coverage coverage
 1   
 // Copyright 2005 The Apache Software Foundation
 2   
 //
 3   
 // Licensed under the Apache License, Version 2.0 (the "License");
 4   
 // you may not use this file except in compliance with the License.
 5   
 // You may obtain a copy of the License at
 6   
 //
 7   
 //     http://www.apache.org/licenses/LICENSE-2.0
 8   
 //
 9   
 // Unless required by applicable law or agreed to in writing, software
 10   
 // distributed under the License is distributed on an "AS IS" BASIS,
 11   
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12   
 // See the License for the specific language governing permissions and
 13   
 // limitations under the License.
 14   
 
 15   
 package org.apache.hivemind.impl;
 16   
 
 17   
 import java.io.BufferedInputStream;
 18   
 import java.io.IOException;
 19   
 import java.io.InputStream;
 20   
 import java.net.URL;
 21   
 import java.util.ArrayList;
 22   
 import java.util.Collections;
 23   
 import java.util.HashMap;
 24   
 import java.util.Iterator;
 25   
 import java.util.List;
 26   
 import java.util.Locale;
 27   
 import java.util.Map;
 28   
 import java.util.Properties;
 29   
 
 30   
 import org.apache.hivemind.ApplicationRuntimeException;
 31   
 import org.apache.hivemind.Resource;
 32   
 import org.apache.hivemind.internal.MessageFinder;
 33   
 import org.apache.hivemind.util.Defense;
 34   
 import org.apache.hivemind.util.LocalizedNameGenerator;
 35   
 
 36   
 /**
 37   
  * @author Howard M. Lewis Ship
 38   
  * @since 1.1
 39   
  */
 40   
 public class MessageFinderImpl implements MessageFinder
 41   
 {
 42   
     private static final String EXTENSION = ".properties";
 43   
 
 44   
     private static class Localization
 45   
     {
 46   
         private Locale _locale;
 47   
 
 48   
         private Resource _resource;
 49   
 
 50  16
         Localization(Locale locale, Resource resource)
 51   
         {
 52  16
             _locale = locale;
 53  16
             _resource = resource;
 54   
         }
 55   
 
 56  16
         public Locale getLocale()
 57   
         {
 58  16
             return _locale;
 59   
         }
 60   
 
 61  16
         public Resource getResource()
 62   
         {
 63  16
             return _resource;
 64   
         }
 65   
 
 66   
     }
 67   
 
 68   
     private Resource _baseResource;
 69   
 
 70   
     private String _baseName;
 71   
 
 72   
     private Map _propertiesMap = new HashMap();
 73   
 
 74   
     private Properties _emptyProperties = new Properties();
 75   
 
 76  10
     public MessageFinderImpl(Resource baseResource)
 77   
     {
 78  10
         Defense.notNull(baseResource, "baseResource");
 79   
 
 80  10
         _baseResource = baseResource;
 81   
 
 82   
         // Strip off the extension to form the base name
 83   
         // when building new (localized) resources.
 84   
 
 85  10
         String name = _baseResource.getName();
 86  10
         int dotx = name.lastIndexOf('.');
 87   
 
 88  10
         _baseName = name.substring(0, dotx);
 89   
     }
 90   
 
 91  6
     public String getMessage(String key, Locale locale)
 92   
     {
 93  6
         return findProperties(locale).getProperty(key);
 94   
     }
 95   
 
 96  6
     private synchronized Properties findProperties(Locale locale)
 97   
     {
 98  6
         Properties result = (Properties) _propertiesMap.get(locale);
 99   
 
 100   
         // If doesn't exist, build it (which will update the
 101   
         // propertiesMap as a side effect.
 102   
 
 103  6
         if (result == null)
 104  6
             result = buildProperties(locale);
 105   
 
 106  6
         return result;
 107   
     }
 108   
 
 109  6
     private Properties buildProperties(Locale locale)
 110   
     {
 111  6
         Properties result = _emptyProperties;
 112   
 
 113  6
         List localizations = findLocalizations(locale);
 114   
 
 115  6
         Iterator i = localizations.iterator();
 116  6
         while (i.hasNext())
 117   
         {
 118  16
             Localization l = (Localization) i.next();
 119   
 
 120  16
             result = readProperties(l.getLocale(), l.getResource(), result);
 121   
         }
 122   
 
 123  6
         return result;
 124   
     }
 125   
 
 126   
     /**
 127   
      * Returns the properties, reading them if necessary. Properties may have been previously read
 128   
      * for this locale, in which case the cached value is returned. Also, if the resource doesn't
 129   
      * exist, then the parent is returned as is. Updates the propertiesMap cache.
 130   
      */
 131   
 
 132  16
     private Properties readProperties(Locale locale, Resource propertiesResource, Properties parent)
 133   
     {
 134  16
         Properties result = (Properties) _propertiesMap.get(locale);
 135   
 
 136  16
         if (result != null)
 137  2
             return result;
 138   
 
 139  14
         URL url = propertiesResource.getResourceURL();
 140   
 
 141  14
         if (url == null)
 142  7
             result = parent;
 143   
         else
 144  7
             result = readPropertiesFile(url, parent);
 145   
 
 146  14
         _propertiesMap.put(locale, result);
 147   
 
 148  14
         return result;
 149   
     }
 150   
 
 151  7
     private Properties readPropertiesFile(URL url, Properties parent)
 152   
     {
 153  7
         InputStream stream = null;
 154   
 
 155  7
         Properties result = new Properties(parent);
 156   
 
 157  7
         try
 158   
         {
 159  7
             stream = new BufferedInputStream(url.openStream());
 160   
 
 161  7
             result.load(stream);
 162   
 
 163  7
             stream.close();
 164   
 
 165  7
             stream = null;
 166   
         }
 167   
         catch (IOException ex)
 168   
         {
 169  0
             throw new ApplicationRuntimeException(ImplMessages.unableToReadMessages(url), ex);
 170   
 
 171   
         }
 172   
         finally
 173   
         {
 174  7
             close(stream);
 175   
         }
 176   
 
 177  7
         return result;
 178   
     }
 179   
 
 180  7
     private void close(InputStream stream)
 181   
     {
 182  7
         if (stream != null)
 183  0
             try
 184   
             {
 185  0
                 stream.close();
 186   
             }
 187   
             catch (IOException ex)
 188   
             {
 189   
                 // Ignore.
 190   
             }
 191   
     }
 192   
 
 193   
     /**
 194   
      * Returns a List of Localizations, in order from most generic (i.e., hivemodule.properties) to
 195   
      * most specific (i.e., hivemodule_en_US_yokel.properties).
 196   
      */
 197   
 
 198  6
     private List findLocalizations(Locale locale)
 199   
     {
 200  6
         List result = new ArrayList();
 201   
 
 202  6
         LocalizedNameGenerator g = new LocalizedNameGenerator(_baseName, locale, EXTENSION);
 203   
 
 204  6
         while (g.more())
 205   
         {
 206  16
             String name = g.next();
 207   
 
 208  16
             Localization l = new Localization(g.getCurrentLocale(), _baseResource
 209   
                     .getRelativeResource(name));
 210   
 
 211  16
             result.add(l);
 212   
         }
 213   
 
 214  6
         Collections.reverse(result);
 215   
 
 216  6
         return result;
 217   
     }
 218   
 }