2009/04/15 - Apache HiveMind has been retired.

For more information, please explore the Attic.

Clover coverage report - Code Coverage for hivemind release 1.2.1
Coverage timestamp: Fri Feb 10 2006 16:33:43 PST
file stats: LOC: 206   Methods: 10
NCLOC: 123   Classes: 2
 
 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  19 Localization(Locale locale, Resource resource)
 52    {
 53  19 _locale = locale;
 54  19 _resource = resource;
 55    }
 56   
 57  19 public Locale getLocale()
 58    {
 59  19 return _locale;
 60    }
 61   
 62  19 public Resource getResource()
 63    {
 64  19 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  11 public MessageFinderImpl(Resource baseResource)
 78    {
 79  11 Defense.notNull(baseResource, "baseResource");
 80   
 81  11 _baseResource = baseResource;
 82   
 83    // Strip off the extension to form the base name
 84    // when building new (localized) resources.
 85   
 86  11 String name = _baseResource.getName();
 87  11 int dotx = name.lastIndexOf('.');
 88   
 89  11 _baseName = name.substring(0, dotx);
 90    }
 91   
 92  7 public String getMessage(String key, Locale locale)
 93    {
 94  7 return findProperties(locale).getProperty(key);
 95    }
 96   
 97  7 private synchronized Properties findProperties(Locale locale)
 98    {
 99  7 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  7 if (result == null)
 105  7 result = buildProperties(locale);
 106   
 107  7 return result;
 108    }
 109   
 110  7 private Properties buildProperties(Locale locale)
 111    {
 112  7 Properties result = _emptyProperties;
 113   
 114  7 List localizations = findLocalizations(locale);
 115   
 116  7 Iterator i = localizations.iterator();
 117  7 while (i.hasNext())
 118    {
 119  19 Localization l = (Localization) i.next();
 120   
 121  19 result = readProperties(l.getLocale(), l.getResource(), result);
 122    }
 123   
 124  7 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  19 private Properties readProperties(Locale locale, Resource propertiesResource, Properties parent)
 134    {
 135  19 Properties result = (Properties) _propertiesMap.get(locale);
 136   
 137  19 if (result != null)
 138  2 return result;
 139   
 140  17 URL url = propertiesResource.getResourceURL();
 141   
 142  17 if (url == null)
 143  9 result = parent;
 144    else
 145  8 result = readPropertiesFile(url, parent);
 146   
 147  17 _propertiesMap.put(locale, result);
 148   
 149  17 return result;
 150    }
 151   
 152  8 private Properties readPropertiesFile(URL url, Properties parent)
 153    {
 154  8 InputStream stream = null;
 155   
 156  8 Properties result = new Properties(parent);
 157   
 158  8 try
 159    {
 160  8 stream = new BufferedInputStream(url.openStream());
 161   
 162  8 result.load(stream);
 163   
 164  8 stream.close();
 165   
 166  8 stream = null;
 167    }
 168    catch (IOException ex)
 169    {
 170  0 throw new ApplicationRuntimeException(ImplMessages.unableToReadMessages(url), ex);
 171   
 172    }
 173    finally
 174    {
 175  8 IOUtils.close(stream);
 176    }
 177   
 178  8 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  7 private List findLocalizations(Locale locale)
 187    {
 188  7 List result = new ArrayList();
 189   
 190  7 LocalizedNameGenerator g = new LocalizedNameGenerator(_baseName, locale, EXTENSION);
 191   
 192  7 while (g.more())
 193    {
 194  19 String name = g.next();
 195   
 196  19 Localization l = new Localization(g.getCurrentLocale(), _baseResource
 197    .getRelativeResource(name));
 198   
 199  19 result.add(l);
 200    }
 201   
 202  7 Collections.reverse(result);
 203   
 204  7 return result;
 205    }
 206    }