001// Copyright 2004, 2005 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007//     http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.tapestry.util.text;
016
017import java.io.IOException;
018import java.io.InputStream;
019import java.io.Reader;
020import java.io.UnsupportedEncodingException;
021import java.util.HashMap;
022import java.util.Map;
023
024/**
025 * A version of java.util.Properties that can read the properties from files
026 * using an encoding other than ISO-8859-1. All non-latin characters are read 
027 * correctly using the given encoding and no longer need to be quoted using native2ascii.
028 * 
029 * In addition, the properties may be stored in an arbitrary map, rather than
030 * only in Properties. For example, using LinkedHashMap will preserve the order
031 * of the properties as defined in the file. 
032 * 
033 * @author mb
034 * @since 4.0
035 */
036public class LocalizedProperties
037{
038    private Map _propertyMap;
039    
040    /**
041     * Create a new object with an empty property storage 
042     */
043    public LocalizedProperties()
044    {
045        this(new HashMap());
046    }
047
048    /**
049     * Use the provided argument as the storage location for the properties managed
050     * by this object. This allows different types of Map implementations to be used,
051     * such as a LinkedHashMap to preserve the order of the keys, for example.
052     * The provided map may contain the default property values as well.
053     * 
054     * @param propertyMap the map where properties are to be stored
055     */
056    public LocalizedProperties(Map propertyMap)
057    {
058        _propertyMap = propertyMap;
059    }
060    
061    /**
062     * Returns the property value corresponding the provided key. If there is no such property,
063     * or the value in the provided map is not of type String, null is returned.
064     * 
065     * @param key the property key
066     * @return the value of the property, or null if there is no such property
067     */
068    public String getProperty(String key)
069    {
070       Object value = _propertyMap.get(key);
071       if (value instanceof String)
072           return (String) value;
073       return null;
074    }
075    
076    /**
077     * Returns the property value corresponding to the provided key, 
078     * or the provided default value if no such property exists.
079     * 
080     * @param key the property key
081     * @param defaultValue the default value of the property
082     * @return the value of the property, or the default value if there is no such property
083     */
084    public String getProperty(String key, String defaultValue)
085    {
086        String value = getProperty(key);
087        if (value != null)
088            return value;
089        return defaultValue;
090    }
091    
092    /**
093     * Stores a property value
094     * 
095     * @param key the property key
096     * @param value the property value
097     */
098    public void setProperty(String key, String value)
099    {
100        _propertyMap.put(key, value);
101    }
102    
103    /**
104     * Returns the map containing all properties. The map can be used to enumerate the 
105     * properties or their keys. 
106     * 
107     * @return a map containing the properties
108     */
109    public Map getPropertyMap()
110    {
111        return _propertyMap;
112    }
113    
114    /**
115     * Loads the properties from the given stream using the default character encoding.
116     * This method operates in the same way as the equivalent method in {@link java.util.Properties},
117     * but it also handles non-ascii symbols. 
118     * 
119     * @param ins the stream to load the properties from
120     * @throws IOException
121     */
122    public void load(InputStream ins) throws IOException
123    {
124        LocalizedPropertiesLoader loader = new LocalizedPropertiesLoader(ins);
125        loader.load(_propertyMap);
126    }
127    
128    /**
129     * Loads the properties from the given stream using the provided character encoding.
130     * This method operates in the same way as the equivalent method in {@link java.util.Properties},
131     * but it also handles non-ascii symbols. 
132     * 
133     * @param ins the stream to load the properties from
134     * @param encoding the encoding the use when parsing the stream
135     * @throws IOException
136     */
137    public void load(InputStream ins, String encoding) throws UnsupportedEncodingException, IOException
138    {
139        LocalizedPropertiesLoader loader = new LocalizedPropertiesLoader(ins, encoding);
140        loader.load(_propertyMap);
141    }
142    
143    /**
144     * Loads the properties from the given reader.
145     * This method operates in the same way as the equivalent method in {@link java.util.Properties},
146     * but it also handles non-ascii symbols. 
147     * 
148     * @param reader the reader to load the properties from
149     * @throws IOException
150     */
151    public void load(Reader reader) throws IOException
152    {
153        LocalizedPropertiesLoader loader = new LocalizedPropertiesLoader(reader);
154        loader.load(_propertyMap);
155    }
156}