001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.util;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    
020    import java.lang.reflect.Constructor;
021    
022    import java.util.HashMap;
023    import java.util.LinkedHashMap;
024    import java.util.Map;
025    
026    /**
027     * @author Brian Wing Shun Chan
028     * @author Raymond Aug??
029     */
030    public class MapUtil {
031    
032            public static <K, V> void copy(
033                    Map<? extends K, ? extends V> master, Map<? super K, ? super V> copy) {
034    
035                    copy.clear();
036    
037                    merge(master, copy);
038            }
039    
040            public static <K> PredicateFilter<Map.Entry<K, ?>> entryKeyPredicateFilter(
041                    final PredicateFilter<K> predicateFilter) {
042    
043                    return new PredicateFilter<Map.Entry<K, ?>>() {
044    
045                            @Override
046                            public boolean filter(Map.Entry<K, ?> entry) {
047                                    return predicateFilter.filter(entry.getKey());
048                            }
049    
050                    };
051            }
052    
053            public static <V> PredicateFilter<Map.Entry<?, V>>
054                    entryValuePredicateFilter(final PredicateFilter<V> predicateFilter) {
055    
056                    return new PredicateFilter<Map.Entry<?, V>>() {
057    
058                            @Override
059                            public boolean filter(Map.Entry<?, V> entry) {
060                                    return predicateFilter.filter(entry.getValue());
061                            }
062    
063                    };
064            }
065    
066            public static <K1, V1, K2 extends K1, V2 extends V1> void filter(
067                    Map<? extends K2, ? extends V2> inputMap,
068                    Map<? super K2, ? super V2> outputMap,
069                    PredicateFilter<? super Map.Entry<K1, V1>> predicateFilter) {
070    
071                    for (Map.Entry<? extends K2, ? extends V2> entry :
072                                    inputMap.entrySet()) {
073    
074                            if (predicateFilter.filter((Map.Entry<K1, V1>)entry)) {
075                                    outputMap.put(entry.getKey(), entry.getValue());
076                            }
077                    }
078            }
079    
080            public static <K1, V1, K2 extends K1, V2 extends V1> Map<K2, V2> filter(
081                    Map<K2, V2> inputMap,
082                    PredicateFilter<? super Map.Entry<K1, V1>> predicateFilter) {
083    
084                    Map<K2, V2> outputMap = new HashMap<>();
085    
086                    filter(inputMap, outputMap, predicateFilter);
087    
088                    return outputMap;
089            }
090    
091            public static <K, V> void filterByKeys(
092                    Map<? extends K, ? extends V> inputMap,
093                    Map<? super K, ? super V> outputMap,
094                    PredicateFilter<? super K> keyPredicateFilter) {
095    
096                    filter(
097                            inputMap, outputMap, entryKeyPredicateFilter(keyPredicateFilter));
098            }
099    
100            public static <K, V> Map<K, V> filterByKeys(
101                    Map<K, V> inputMap, PredicateFilter<? super K> keyPredicateFilter) {
102    
103                    return filter(inputMap, entryKeyPredicateFilter(keyPredicateFilter));
104            }
105    
106            public static <K, V> void filterByValues(
107                    Map<? extends K, ? extends V> inputMap,
108                    Map<? super K, ? super V> outputMap,
109                    PredicateFilter<? super V> valuePredicateFilter) {
110    
111                    filter(
112                            inputMap, outputMap,
113                            entryValuePredicateFilter(valuePredicateFilter));
114            }
115    
116            public static <K, V> Map<K, V> filterByValues(
117                    Map<K, V> inputMap, PredicateFilter<? super V> keyPredicateFilter) {
118    
119                    return filter(inputMap, entryValuePredicateFilter(keyPredicateFilter));
120            }
121    
122            public static <T> Map<T, T> fromArray(T... array) {
123                    if ((array.length % 2) != 0) {
124                            throw new IllegalArgumentException(
125                                    "Array length is not an even number");
126                    }
127    
128                    Map<T, T> map = new HashMap<>();
129    
130                    for (int i = 0; i < array.length; i += 2) {
131                            T key = array[i];
132                            T value = array[i + 1];
133    
134                            map.put(key, value);
135                    }
136    
137                    return map;
138            }
139    
140            public static boolean getBoolean(Map<String, ?> map, String key) {
141                    return getBoolean(map, key, GetterUtil.DEFAULT_BOOLEAN);
142            }
143    
144            public static boolean getBoolean(
145                    Map<String, ?> map, String key, boolean defaultValue) {
146    
147                    Object value = map.get(key);
148    
149                    if (value == null) {
150                            return defaultValue;
151                    }
152    
153                    if (value instanceof Boolean) {
154                            return (Boolean)value;
155                    }
156    
157                    if (value instanceof String[]) {
158                            String[] array = (String[])value;
159    
160                            if (array.length == 0) {
161                                    return defaultValue;
162                            }
163    
164                            return GetterUtil.getBoolean(array[0], defaultValue);
165                    }
166    
167                    return GetterUtil.getBoolean(String.valueOf(value), defaultValue);
168            }
169    
170            public static double getDouble(Map<String, ?> map, String key) {
171                    return getDouble(map, key, GetterUtil.DEFAULT_DOUBLE);
172            }
173    
174            public static double getDouble(
175                    Map<String, ?> map, String key, double defaultValue) {
176    
177                    Object value = map.get(key);
178    
179                    if (value == null) {
180                            return defaultValue;
181                    }
182    
183                    if (value instanceof Double) {
184                            return (Double)value;
185                    }
186    
187                    if (value instanceof String[]) {
188                            String[] array = (String[])value;
189    
190                            if (array.length == 0) {
191                                    return defaultValue;
192                            }
193    
194                            return GetterUtil.getDouble(array[0], defaultValue);
195                    }
196    
197                    return GetterUtil.getDouble(String.valueOf(value), defaultValue);
198            }
199    
200            public static int getInteger(Map<String, ?> map, String key) {
201                    return getInteger(map, key, GetterUtil.DEFAULT_INTEGER);
202            }
203    
204            public static int getInteger(
205                    Map<String, ?> map, String key, int defaultValue) {
206    
207                    Object value = map.get(key);
208    
209                    if (value == null) {
210                            return defaultValue;
211                    }
212    
213                    if (value instanceof Integer) {
214                            return (Integer)value;
215                    }
216    
217                    if (value instanceof String[]) {
218                            String[] array = (String[])value;
219    
220                            if (array.length == 0) {
221                                    return defaultValue;
222                            }
223    
224                            return GetterUtil.getInteger(array[0], defaultValue);
225                    }
226    
227                    return GetterUtil.getInteger(String.valueOf(value), defaultValue);
228            }
229    
230            public static long getLong(Map<Long, Long> map, long key) {
231                    return getLong(map, key, GetterUtil.DEFAULT_LONG);
232            }
233    
234            public static long getLong(
235                    Map<Long, Long> map, long key, long defaultValue) {
236    
237                    Long value = map.get(key);
238    
239                    if (value == null) {
240                            return defaultValue;
241                    }
242                    else {
243                            return value;
244                    }
245            }
246    
247            public static long getLong(Map<String, ?> map, String key) {
248                    return getLong(map, key, GetterUtil.DEFAULT_LONG);
249            }
250    
251            public static long getLong(
252                    Map<String, ?> map, String key, long defaultValue) {
253    
254                    Object value = map.get(key);
255    
256                    if (value == null) {
257                            return defaultValue;
258                    }
259    
260                    if (value instanceof Long) {
261                            return (Long)value;
262                    }
263    
264                    if (value instanceof String[]) {
265                            String[] array = (String[])value;
266    
267                            if (array.length == 0) {
268                                    return defaultValue;
269                            }
270    
271                            return GetterUtil.getLong(array[0], defaultValue);
272                    }
273    
274                    return GetterUtil.getLong(String.valueOf(value), defaultValue);
275            }
276    
277            public static short getShort(Map<String, ?> map, String key) {
278                    return getShort(map, key, GetterUtil.DEFAULT_SHORT);
279            }
280    
281            public static short getShort(
282                    Map<String, ?> map, String key, short defaultValue) {
283    
284                    Object value = map.get(key);
285    
286                    if (value == null) {
287                            return defaultValue;
288                    }
289    
290                    if (value instanceof Short) {
291                            return (Short)value;
292                    }
293    
294                    if (value instanceof String[]) {
295                            String[] array = (String[])value;
296    
297                            if (array.length == 0) {
298                                    return defaultValue;
299                            }
300    
301                            return GetterUtil.getShort(array[0], defaultValue);
302                    }
303    
304                    return GetterUtil.getShort(String.valueOf(value), defaultValue);
305            }
306    
307            public static String getString(Map<String, ?> map, String key) {
308                    return getString(map, key, GetterUtil.DEFAULT_STRING);
309            }
310    
311            public static String getString(
312                    Map<String, ?> map, String key, String defaultValue) {
313    
314                    Object value = map.get(key);
315    
316                    if (value == null) {
317                            return defaultValue;
318                    }
319    
320                    if (value instanceof String) {
321                            return GetterUtil.getString((String)value, defaultValue);
322                    }
323    
324                    if (value instanceof String[]) {
325                            String[] array = (String[])value;
326    
327                            if (array.length == 0 ) {
328                                    return defaultValue;
329                            }
330    
331                            return GetterUtil.getString(array[0], defaultValue);
332                    }
333    
334                    return GetterUtil.getString(String.valueOf(value), defaultValue);
335            }
336    
337            public static boolean isEmpty(Map<?, ?> map) {
338                    if ((map == null) || map.isEmpty()) {
339                            return true;
340                    }
341    
342                    return false;
343            }
344    
345            public static boolean isNotEmpty(Map<?, ?> map) {
346                    return !isEmpty(map);
347            }
348    
349            public static <K, V> void merge(
350                    Map<? extends K, ? extends V> master, Map<? super K, ? super V> copy) {
351    
352                    copy.putAll(master);
353            }
354    
355            public static <T> LinkedHashMap<String, T> toLinkedHashMap(
356                    String[] params) {
357    
358                    return toLinkedHashMap(params, StringPool.COLON);
359            }
360    
361            public static <T> LinkedHashMap<String, T> toLinkedHashMap(
362                    String[] params, String delimiter) {
363    
364                    LinkedHashMap<String, Object> map = new LinkedHashMap<>();
365    
366                    if (params == null) {
367                            return (LinkedHashMap<String, T>)map;
368                    }
369    
370                    for (String param : params) {
371                            String[] kvp = StringUtil.split(param, delimiter);
372    
373                            if (kvp.length == 2) {
374                                    map.put(kvp[0], kvp[1]);
375                            }
376                            else if (kvp.length == 3) {
377                                    String type = kvp[2];
378    
379                                    if (StringUtil.equalsIgnoreCase(type, "boolean") ||
380                                            type.equals(Boolean.class.getName())) {
381    
382                                            map.put(kvp[0], Boolean.valueOf(kvp[1]));
383                                    }
384                                    else if (StringUtil.equalsIgnoreCase(type, "double") ||
385                                                     type.equals(Double.class.getName())) {
386    
387                                            map.put(kvp[0], Double.valueOf(kvp[1]));
388                                    }
389                                    else if (StringUtil.equalsIgnoreCase(type, "int") ||
390                                                     type.equals(Integer.class.getName())) {
391    
392                                            map.put(kvp[0], Integer.valueOf(kvp[1]));
393                                    }
394                                    else if (StringUtil.equalsIgnoreCase(type, "long") ||
395                                                     type.equals(Long.class.getName())) {
396    
397                                            map.put(kvp[0], Long.valueOf(kvp[1]));
398                                    }
399                                    else if (StringUtil.equalsIgnoreCase(type, "short") ||
400                                                     type.equals(Short.class.getName())) {
401    
402                                            map.put(kvp[0], Short.valueOf(kvp[1]));
403                                    }
404                                    else if (type.equals(String.class.getName())) {
405                                            map.put(kvp[0], kvp[1]);
406                                    }
407                                    else {
408                                            try {
409                                                    Class<?> clazz = Class.forName(type);
410    
411                                                    Constructor<?> constructor = clazz.getConstructor(
412                                                            String.class);
413    
414                                                    map.put(kvp[0], constructor.newInstance(kvp[1]));
415                                            }
416                                            catch (Exception e) {
417                                                    _log.error(e.getMessage(), e);
418                                            }
419                                    }
420                            }
421                    }
422    
423                    return (LinkedHashMap<String, T>)map;
424            }
425    
426            public static String toString(Map<?, ?> map) {
427                    return toString(map, null, null);
428            }
429    
430            public static String toString(
431                    Map<?, ?> map, String hideIncludesRegex, String hideExcludesRegex) {
432    
433                    if (isEmpty(map)) {
434                            return StringPool.OPEN_CURLY_BRACE + StringPool.CLOSE_CURLY_BRACE;
435                    }
436    
437                    StringBundler sb = new StringBundler(map.size() * 4 + 1);
438    
439                    sb.append(StringPool.OPEN_CURLY_BRACE);
440    
441                    for (Map.Entry<?, ?> entry : map.entrySet()) {
442                            Object key = entry.getKey();
443                            Object value = entry.getValue();
444    
445                            String keyString = String.valueOf(key);
446    
447                            if (hideIncludesRegex != null) {
448                                    if (!keyString.matches(hideIncludesRegex)) {
449                                            value = "********";
450                                    }
451                            }
452    
453                            if (hideExcludesRegex != null) {
454                                    if (keyString.matches(hideExcludesRegex)) {
455                                            value = "********";
456                                    }
457                            }
458    
459                            sb.append(keyString);
460                            sb.append(StringPool.EQUAL);
461    
462                            if (value instanceof Map<?, ?>) {
463                                    sb.append(MapUtil.toString((Map<?, ?>)value));
464                            }
465                            else if (value instanceof String[]) {
466                                    String valueString = StringUtil.merge(
467                                            (String[])value, StringPool.COMMA_AND_SPACE);
468    
469                                    sb.append(
470                                            StringPool.OPEN_BRACKET.concat(valueString).concat(
471                                                    StringPool.CLOSE_BRACKET));
472                            }
473                            else {
474                                    sb.append(value);
475                            }
476    
477                            sb.append(StringPool.COMMA_AND_SPACE);
478                    }
479    
480                    sb.setStringAt(StringPool.CLOSE_CURLY_BRACE, sb.index() - 1);
481    
482                    return sb.toString();
483            }
484    
485            private static final Log _log = LogFactoryUtil.getLog(MapUtil.class);
486    
487    }