001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.kernel.util;
016    
017    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
018    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
019    import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
020    import com.liferay.portal.kernel.nio.charset.CharsetDecoderUtil;
021    import com.liferay.portal.kernel.nio.charset.CharsetEncoderUtil;
022    
023    import java.io.IOException;
024    import java.io.InputStream;
025    import java.io.InputStreamReader;
026    import java.io.PrintStream;
027    import java.io.PrintWriter;
028    import java.io.Reader;
029    
030    import java.lang.reflect.Method;
031    
032    import java.nio.ByteBuffer;
033    import java.nio.CharBuffer;
034    import java.nio.charset.CharsetDecoder;
035    import java.nio.charset.CharsetEncoder;
036    
037    import java.util.Collections;
038    import java.util.Enumeration;
039    import java.util.List;
040    import java.util.Map;
041    import java.util.Properties;
042    
043    /**
044     * @author Brian Wing Shun Chan
045     * @author Shuyang Zhou
046     */
047    public class PropertiesUtil {
048    
049            public static void copyProperties(
050                    Properties sourceProperties, Properties targetProperties) {
051    
052                    for (Map.Entry<Object, Object> entry : sourceProperties.entrySet()) {
053                            String key = (String)entry.getKey();
054                            String value = (String)entry.getValue();
055    
056                            targetProperties.setProperty(key, value);
057                    }
058            }
059    
060            public static Properties fromMap(Map<String, String> map) {
061                    Properties properties = new Properties();
062    
063                    for (Map.Entry<String, String> entry : map.entrySet()) {
064                            String key = entry.getKey();
065                            String value = entry.getValue();
066    
067                            if (value != null) {
068                                    properties.setProperty(key, value);
069                            }
070                    }
071    
072                    return properties;
073            }
074    
075            public static Properties fromMap(Properties properties) {
076                    return properties;
077            }
078    
079            public static void fromProperties(
080                    Properties properties, Map<String, String> map) {
081    
082                    map.clear();
083    
084                    for (Map.Entry<Object, Object> entry : properties.entrySet()) {
085                            map.put((String)entry.getKey(), (String)entry.getValue());
086                    }
087            }
088    
089            public static Properties getProperties(
090                    Properties properties, String prefix, boolean removePrefix) {
091    
092                    Properties newProperties = new Properties();
093    
094                    Enumeration<String> enu =
095                            (Enumeration<String>)properties.propertyNames();
096    
097                    while (enu.hasMoreElements()) {
098                            String key = enu.nextElement();
099    
100                            if (key.startsWith(prefix)) {
101                                    String value = properties.getProperty(key);
102    
103                                    if (removePrefix) {
104                                            key = key.substring(prefix.length());
105                                    }
106    
107                                    newProperties.setProperty(key, value);
108                            }
109                    }
110    
111                    return newProperties;
112            }
113    
114            public static String list(Map<String, String> map) {
115                    Properties properties = fromMap(map);
116    
117                    return list(properties);
118            }
119    
120            public static void list(Map<String, String> map, PrintStream printWriter) {
121                    Properties properties = fromMap(map);
122    
123                    properties.list(printWriter);
124            }
125    
126            public static void list(Map<String, String> map, PrintWriter printWriter) {
127                    Properties properties = fromMap(map);
128    
129                    properties.list(printWriter);
130            }
131    
132            public static String list(Properties properties) {
133                    UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
134                            new UnsyncByteArrayOutputStream();
135    
136                    PrintStream printStream = new PrintStream(unsyncByteArrayOutputStream);
137    
138                    properties.list(printStream);
139    
140                    return unsyncByteArrayOutputStream.toString();
141            }
142    
143            public static Properties load(InputStream is, String charsetName)
144                    throws IOException {
145    
146                    return load(new InputStreamReader(is, charsetName));
147            }
148    
149            public static void load(Properties properties, String s)
150                    throws IOException {
151    
152                    if (Validator.isNull(s)) {
153                            return;
154                    }
155    
156                    s = UnicodeFormatter.toString(s);
157    
158                    s = StringUtil.replace(s, "\\u003d", "=");
159                    s = StringUtil.replace(s, "\\u000a", "\n");
160                    s = StringUtil.replace(s, "\\u0021", "!");
161                    s = StringUtil.replace(s, "\\u0023", "#");
162                    s = StringUtil.replace(s, "\\u0020", " ");
163                    s = StringUtil.replace(s, "\\u005c", "\\");
164    
165                    properties.load(new UnsyncByteArrayInputStream(s.getBytes()));
166    
167                    List<String> propertyNames = Collections.list(
168                            (Enumeration<String>)properties.propertyNames());
169    
170                    for (int i = 0; i < propertyNames.size(); i++) {
171                            String key = propertyNames.get(i);
172    
173                            String value = properties.getProperty(key);
174    
175                            // Trim values because it may leave a trailing \r in certain Windows
176                            // environments. This is a known case for loading SQL scripts in SQL
177                            // Server.
178    
179                            if (value != null) {
180                                    value = value.trim();
181    
182                                    properties.setProperty(key, value);
183                            }
184                    }
185            }
186    
187            public static Properties load(Reader reader) throws IOException {
188                    Properties properties = new Properties();
189    
190                    properties.load(reader);
191    
192                    return properties;
193            }
194    
195            public static Properties load(String s) throws IOException {
196                    return load(new UnsyncStringReader(s));
197            }
198    
199            /**
200             * @deprecated As of 6.2.0, replaced by {@link #load(String)}
201             */
202            @Deprecated
203            public static Properties load(String s, String charsetName)
204                    throws IOException {
205    
206                    if (JavaDetector.isJDK6() || JavaDetector.isJDK7()) {
207                            return loadJDK6(new UnsyncStringReader(s));
208                    }
209    
210                    ByteBuffer byteBuffer = CharsetEncoderUtil.encode(charsetName, s);
211    
212                    InputStream is = new UnsyncByteArrayInputStream(
213                            byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.limit());
214    
215                    return loadJDK5(is, charsetName);
216            }
217    
218            /**
219             * @deprecated As of 6.2.0, replaced by {@link #load(Reader)}
220             */
221            @Deprecated
222            public static Properties loadJDK5(InputStream is, String charsetName)
223                    throws IOException {
224    
225                    Properties iso8859_1Properties = new Properties();
226    
227                    iso8859_1Properties.load(is);
228    
229                    Properties properties = new Properties();
230    
231                    CharsetEncoder charsetEncoder = CharsetEncoderUtil.getCharsetEncoder(
232                            StringPool.ISO_8859_1);
233    
234                    CharsetDecoder charsetDecoder = CharsetDecoderUtil.getCharsetDecoder(
235                            charsetName);
236    
237                    for (Map.Entry<Object, Object> entry : iso8859_1Properties.entrySet()) {
238                            String key = (String)entry.getKey();
239                            String value = (String)entry.getValue();
240    
241                            CharBuffer keyCharBuffer = charsetDecoder.decode(
242                                    charsetEncoder.encode(CharBuffer.wrap(key)));
243                            CharBuffer valueCharBuffer = charsetDecoder.decode(
244                                    charsetEncoder.encode(CharBuffer.wrap(value)));
245    
246                            properties.put(
247                                    keyCharBuffer.toString(), valueCharBuffer.toString());
248                    }
249    
250                    return properties;
251            }
252    
253            /**
254             * @deprecated As of 6.2.0, replaced by {@link #load(Reader)}
255             */
256            @Deprecated
257            public static Properties loadJDK6(Reader reader) throws IOException {
258                    try {
259                            Properties properties = new Properties();
260    
261                            if (_jdk6LoadMethod == null) {
262                                    _jdk6LoadMethod = ReflectionUtil.getDeclaredMethod(
263                                            Properties.class, "load", Reader.class);
264                            }
265    
266                            _jdk6LoadMethod.invoke(properties, reader);
267    
268                            return properties;
269                    }
270                    catch (Exception e) {
271                            Throwable cause = e.getCause();
272    
273                            if (cause instanceof IOException) {
274                                    throw (IOException)cause;
275                            }
276    
277                            throw new IllegalStateException(
278                                    "Failed to invoke java.util.Properties.load(Reader reader)", e);
279                    }
280            }
281    
282            public static void merge(Properties properties1, Properties properties2) {
283                    Enumeration<String> enu =
284                            (Enumeration<String>)properties2.propertyNames();
285    
286                    while (enu.hasMoreElements()) {
287                            String key = enu.nextElement();
288                            String value = properties2.getProperty(key);
289    
290                            properties1.setProperty(key, value);
291                    }
292            }
293    
294            public static String toString(Properties properties) {
295                    SafeProperties safeProperties = null;
296    
297                    if (properties instanceof SafeProperties) {
298                            safeProperties = (SafeProperties)properties;
299                    }
300    
301                    StringBundler sb = null;
302    
303                    if (properties.isEmpty()) {
304                            sb = new StringBundler();
305                    }
306                    else {
307                            sb = new StringBundler(properties.size() * 4);
308                    }
309    
310                    Enumeration<String> enu =
311                            (Enumeration<String>)properties.propertyNames();
312    
313                    while (enu.hasMoreElements()) {
314                            String key = enu.nextElement();
315    
316                            sb.append(key);
317                            sb.append(StringPool.EQUAL);
318    
319                            if (safeProperties != null) {
320                                    sb.append(safeProperties.getEncodedProperty(key));
321                            }
322                            else {
323                                    sb.append(properties.getProperty(key));
324                            }
325    
326                            sb.append(StringPool.NEW_LINE);
327                    }
328    
329                    return sb.toString();
330            }
331    
332            public static void trimKeys(Properties properties) {
333                    Enumeration<String> enu =
334                            (Enumeration<String>)properties.propertyNames();
335    
336                    while (enu.hasMoreElements()) {
337                            String key = enu.nextElement();
338                            String value = properties.getProperty(key);
339    
340                            String trimmedKey = key.trim();
341    
342                            if (!key.equals(trimmedKey)) {
343                                    properties.remove(key);
344                                    properties.setProperty(trimmedKey, value);
345                            }
346                    }
347            }
348    
349            private static Method _jdk6LoadMethod;
350    
351    }