Clover coverage report - Code Coverage for hivemind release 1.1-alpha-3
Coverage timestamp: Tue Mar 22 2005 09:10:26 EST
file stats: LOC: 206   Methods: 10
NCLOC: 123   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 90% 97.9% 100% 97.1%
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.IOUtils;
 35   
 import org.apache.hivemind.util.LocalizedNameGenerator;
 36   
 
 37   
 /**
 38   
  * @author Howard M. Lewis Ship
 39   
  * @since 1.1
 40   
  */
 41   
 public class MessageFinderImpl implements MessageFinder
 42   
 {
 43   
     private static final String EXTENSION = ".properties";
 44   
 
 45   
     private static class Localization
 46   
     {
 47   
         private Locale _locale;
 48   
 
 49   
         private Resource _resource;
 50   
 
 51  16
         Localization(Locale locale, Resource resource)
 52   
         {
 53  16
             _locale = locale;
 54  16
             _resource = resource;
 55   
         }
 56   
 
 57  16
         public Locale getLocale()
 58   
         {
 59  16
             return _locale;
 60   
         }
 61   
 
 62  16
         public Resource getResource()
 63   
         {
 64  16
             return _resource;
 65   
         }
 66   
 
 67   
     }
 68   
 
 69   
     private Resource _baseResource;
 70   
 
 71   
     private String _baseName;
 72   
 
 73   
     private Map _propertiesMap = new HashMap();
 74   
 
 75   
     private Properties _emptyProperties = new Properties();
 76   
 
 77  10
     public MessageFinderImpl(Resource baseResource)
 78   
     {
 79  10
         Defense.notNull(baseResource, "baseResource");
 80   
 
 81  10
         _baseResource = baseResource;
 82   
 
 83   
         // Strip off the extension to form the base name
 84   
         // when building new (localized) resources.
 85   
 
 86  10
         String name = _baseResource.getName();
 87  10
         int dotx = name.lastIndexOf('.');
 88   
 
 89  10
         _baseName = name.substring(0, dotx);
 90   
     }
 91   
 
 92  6
     public String getMessage(String key, Locale locale)
 93   
     {
 94  6
         return findProperties(locale).getProperty(key);
 95   
     }
 96   
 
 97  6
     private synchronized Properties findProperties(Locale locale)
 98   
     {
 99  6
         Properties result = (Properties) _propertiesMap.get(locale);
 100   
 
 101   
         // If doesn't exist, build it (which will update the
 102   
         // propertiesMap as a side effect.
 103   
 
 104  6
         if (result == null)
 105  6
             result = buildProperties(locale);
 106   
 
 107  6
         return result;
 108   
     }
 109   
 
 110  6
     private Properties buildProperties(Locale locale)
 111   
     {
 112  6
         Properties result = _emptyProperties;
 113   
 
 114  6
         List localizations = findLocalizations(locale);
 115   
 
 116  6
         Iterator i = localizations.iterator();
 117  6
         while (i.hasNext())
 118   
         {
 119  16
             Localization l = (Localization) i.next();
 120   
 
 121  16
             result = readProperties(l.getLocale(), l.getResource(), result);
 122   
         }
 123   
 
 124  6
         return result;
 125   
     }
 126   
 
 127   
     /**
 128   
      * Returns the properties, reading them if necessary. Properties may have been previously read
 129   
      * for this locale, in which case the cached value is returned. Also, if the resource doesn't
 130   
      * exist, then the parent is returned as is. Updates the propertiesMap cache.
 131   
      */
 132   
 
 133  16
     private Properties readProperties(Locale locale, Resource propertiesResource, Properties parent)
 134   
     {
 135  16
         Properties result = (Properties) _propertiesMap.get(locale);
 136   
 
 137  16
         if (result != null)
 138  2
             return result;
 139   
 
 140  14
         URL url = propertiesResource.getResourceURL();
 141   
 
 142  14
         if (url == null)
 143  7
             result = parent;
 144   
         else
 145  7
             result = readPropertiesFile(url, parent);
 146   
 
 147  14
         _propertiesMap.put(locale, result);
 148   
 
 149  14
         return result;
 150   
     }
 151   
 
 152  7
     private Properties readPropertiesFile(URL url, Properties parent)
 153   
     {
 154  7
         InputStream stream = null;
 155   
 
 156  7
         Properties result = new Properties(parent);
 157   
 
 158  7
         try
 159   
         {
 160  7
             stream = new BufferedInputStream(url.openStream());
 161   
 
 162  7
             result.load(stream);
 163   
 
 164  7
             stream.close();
 165   
 
 166  7
             stream = null;
 167   
         }
 168   
         catch (IOException ex)
 169   
         {
 170  0
             throw new ApplicationRuntimeException(ImplMessages.unableToReadMessages(url), ex);
 171   
 
 172   
         }
 173   
         finally
 174   
         {
 175  7
             IOUtils.close(stream);
 176   
         }
 177   
 
 178  7
         return result;
 179   
     }
 180   
 
 181   
     /**
 182   
      * Returns a List of Localizations, in order from most generic (i.e., hivemodule.properties) to
 183   
      * most specific (i.e., hivemodule_en_US_yokel.properties).
 184   
      */
 185   
 
 186  6
     private List findLocalizations(Locale locale)
 187   
     {
 188  6
         List result = new ArrayList();
 189   
 
 190  6
         LocalizedNameGenerator g = new LocalizedNameGenerator(_baseName, locale, EXTENSION);
 191   
 
 192  6
         while (g.more())
 193   
         {
 194  16
             String name = g.next();
 195   
 
 196  16
             Localization l = new Localization(g.getCurrentLocale(), _baseResource
 197   
                     .getRelativeResource(name));
 198   
 
 199  16
             result.add(l);
 200   
         }
 201   
 
 202  6
         Collections.reverse(result);
 203   
 
 204  6
         return result;
 205   
     }
 206   
 }