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    
015    package org.apache.tapestry.util.text;
016    
017    import java.io.IOException;
018    import java.io.InputStream;
019    import java.io.Reader;
020    import java.util.HashMap;
021    import java.util.Map;
022    
023    /**
024     * A version of java.util.Properties that can read the properties from files
025     * using an encoding other than ISO-8859-1. All non-latin characters are read
026     * correctly using the given encoding and no longer need to be quoted using
027     * native2ascii. In addition, the properties may be stored in an arbitrary map,
028     * rather than only in Properties. For example, using LinkedHashMap will
029     * preserve the order of the properties as defined in the file.
030     * 
031     * @author mb
032     * @since 4.0
033     */
034    public class LocalizedProperties
035    {
036    
037        private Map _propertyMap;
038    
039        /**
040         * Create a new object with an empty property storage.
041         */
042        public LocalizedProperties()
043        {
044            this(new HashMap());
045        }
046    
047        /**
048         * Use the provided argument as the storage location for the properties
049         * managed by this object. This allows different types of Map
050         * implementations to be used, such as a LinkedHashMap to preserve the order
051         * of the keys, for example. The provided map may contain the default
052         * property values as well.
053         * 
054         * @param propertyMap
055         *            the map where properties are to be stored
056         */
057        public LocalizedProperties(Map propertyMap)
058        {
059            _propertyMap = propertyMap;
060        }
061    
062        /**
063         * Returns the property value corresponding the provided key. If there is no
064         * such property, or the value in the provided map is not of type String,
065         * null is returned.
066         * 
067         * @param key
068         *            the property key
069         * @return the value of the property, or null if there is no such property
070         */
071        public String getProperty(String key)
072        {
073            Object value = _propertyMap.get(key);
074            if (value instanceof String) return (String) value;
075            return null;
076        }
077    
078        /**
079         * Returns the property value corresponding to the provided key, or the
080         * provided default value if no such property exists.
081         * 
082         * @param key
083         *            the property key
084         * @param defaultValue
085         *            the default value of the property
086         * @return the value of the property, or the default value if there is no
087         *         such property
088         */
089        public String getProperty(String key, String defaultValue)
090        {
091            String value = getProperty(key);
092            if (value != null) return value;
093            return defaultValue;
094        }
095    
096        /**
097         * Stores a property value.
098         * 
099         * @param key
100         *            the property key
101         * @param value
102         *            the property value
103         */
104        public void setProperty(String key, String value)
105        {
106            _propertyMap.put(key, value);
107        }
108    
109        /**
110         * Returns the map containing all properties. The map can be used to
111         * enumerate the properties or their keys.
112         * 
113         * @return a map containing the properties
114         */
115        public Map getPropertyMap()
116        {
117            return _propertyMap;
118        }
119    
120        /**
121         * Loads the properties from the given stream using the default character
122         * encoding. This method operates in the same way as the equivalent method
123         * in {@link java.util.Properties}, but it also handles non-ascii symbols.
124         * 
125         * @param ins
126         *            the stream to load the properties from
127         * @throws IOException
128         */
129        public void load(InputStream ins)
130            throws IOException
131        {
132            LocalizedPropertiesLoader loader = new LocalizedPropertiesLoader(ins);
133            loader.load(_propertyMap);
134        }
135    
136        /**
137         * Loads the properties from the given stream using the provided character
138         * encoding. This method operates in the same way as the equivalent method
139         * in {@link java.util.Properties}, but it also handles non-ascii symbols.
140         * 
141         * @param ins
142         *            the stream to load the properties from
143         * @param encoding
144         *            the encoding the use when parsing the stream
145         * @throws IOException
146         */
147        public void load(InputStream ins, String encoding)
148            throws IOException
149        {
150            LocalizedPropertiesLoader loader = new LocalizedPropertiesLoader(ins,
151                    encoding);
152            loader.load(_propertyMap);
153        }
154    
155        /**
156         * Loads the properties from the given reader. This method operates in the
157         * same way as the equivalent method in {@link java.util.Properties}, but
158         * it also handles non-ascii symbols.
159         * 
160         * @param reader
161         *            the reader to load the properties from
162         * @throws IOException
163         */
164        public void load(Reader reader)
165            throws IOException
166        {
167            LocalizedPropertiesLoader loader = new LocalizedPropertiesLoader(reader);
168            loader.load(_propertyMap);
169        }
170    }