Source Code Cross Referenced for MapUtils.java in  » Library » Apache-common-Collections » org » apache » commons » collections » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Library » Apache common Collections » org.apache.commons.collections 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *  Copyright 2001-2005 The Apache Software Foundation
0003:         *
0004:         *  Licensed under the Apache License, Version 2.0 (the "License");
0005:         *  you may not use this file except in compliance with the License.
0006:         *  You may obtain a copy of the License at
0007:         *
0008:         *      http://www.apache.org/licenses/LICENSE-2.0
0009:         *
0010:         *  Unless required by applicable law or agreed to in writing, software
0011:         *  distributed under the License is distributed on an "AS IS" BASIS,
0012:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         *  See the License for the specific language governing permissions and
0014:         *  limitations under the License.
0015:         */
0016:        package org.apache.commons.collections;
0017:
0018:        import java.io.PrintStream;
0019:        import java.text.NumberFormat;
0020:        import java.text.ParseException;
0021:        import java.util.Collections;
0022:        import java.util.Enumeration;
0023:        import java.util.HashMap;
0024:        import java.util.Iterator;
0025:        import java.util.Map;
0026:        import java.util.Properties;
0027:        import java.util.ResourceBundle;
0028:        import java.util.SortedMap;
0029:        import java.util.TreeMap;
0030:
0031:        import org.apache.commons.collections.map.FixedSizeMap;
0032:        import org.apache.commons.collections.map.FixedSizeSortedMap;
0033:        import org.apache.commons.collections.map.LazyMap;
0034:        import org.apache.commons.collections.map.LazySortedMap;
0035:        import org.apache.commons.collections.map.ListOrderedMap;
0036:        import org.apache.commons.collections.map.MultiValueMap;
0037:        import org.apache.commons.collections.map.PredicatedMap;
0038:        import org.apache.commons.collections.map.PredicatedSortedMap;
0039:        import org.apache.commons.collections.map.TransformedMap;
0040:        import org.apache.commons.collections.map.TransformedSortedMap;
0041:        import org.apache.commons.collections.map.TypedMap;
0042:        import org.apache.commons.collections.map.TypedSortedMap;
0043:        import org.apache.commons.collections.map.UnmodifiableMap;
0044:        import org.apache.commons.collections.map.UnmodifiableSortedMap;
0045:
0046:        /** 
0047:         * Provides utility methods and decorators for
0048:         * {@link Map} and {@link SortedMap} instances.
0049:         * <p>
0050:         * It contains various type safe methods
0051:         * as well as other useful features like deep copying.
0052:         * <p>
0053:         * It also provides the following decorators:
0054:         *
0055:         *  <ul>
0056:         *  <li>{@link #fixedSizeMap(Map)}
0057:         *  <li>{@link #fixedSizeSortedMap(SortedMap)}
0058:         *  <li>{@link #lazyMap(Map,Factory)}
0059:         *  <li>{@link #lazyMap(Map,Transformer)}
0060:         *  <li>{@link #lazySortedMap(SortedMap,Factory)}
0061:         *  <li>{@link #lazySortedMap(SortedMap,Transformer)}
0062:         *  <li>{@link #predicatedMap(Map,Predicate,Predicate)}
0063:         *  <li>{@link #predicatedSortedMap(SortedMap,Predicate,Predicate)}
0064:         *  <li>{@link #transformedMap(Map, Transformer, Transformer)}
0065:         *  <li>{@link #transformedSortedMap(SortedMap, Transformer, Transformer)}
0066:         *  <li>{@link #typedMap(Map, Class, Class)}
0067:         *  <li>{@link #typedSortedMap(SortedMap, Class, Class)}
0068:         *  <li>{@link #multiValueMap( Map )}
0069:         *  <li>{@link #multiValueMap( Map, Class )}
0070:         *  <li>{@link #multiValueMap( Map, Factory )}
0071:         *  </ul>
0072:         *
0073:         * @since Commons Collections 1.0
0074:         * @version $Revision: 357494 $ $Date: 2005-12-18 19:05:31 +0000 (Sun, 18 Dec 2005) $
0075:         * 
0076:         * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
0077:         * @author <a href="mailto:nissim@nksystems.com">Nissim Karpenstein</a>
0078:         * @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
0079:         * @author Paul Jack
0080:         * @author Stephen Colebourne
0081:         * @author Matthew Hawthorne
0082:         * @author Arun Mammen Thomas
0083:         * @author Janek Bogucki
0084:         * @author Max Rydahl Andersen
0085:         * @author <a href="mailto:equinus100@hotmail.com">Ashwin S</a>
0086:         * @author <a href="mailto:jcarman@apache.org">James Carman</a>
0087:         * @author Neil O'Toole
0088:         */
0089:        public class MapUtils {
0090:
0091:            /**
0092:             * An empty unmodifiable map.
0093:             * This was not provided in JDK1.2.
0094:             */
0095:            public static final Map EMPTY_MAP = UnmodifiableMap
0096:                    .decorate(new HashMap(1));
0097:            /**
0098:             * An empty unmodifiable sorted map.
0099:             * This is not provided in the JDK.
0100:             */
0101:            public static final SortedMap EMPTY_SORTED_MAP = UnmodifiableSortedMap
0102:                    .decorate(new TreeMap());
0103:            /**
0104:             * String used to indent the verbose and debug Map prints.
0105:             */
0106:            private static final String INDENT_STRING = "    ";
0107:
0108:            /**
0109:             * <code>MapUtils</code> should not normally be instantiated.
0110:             */
0111:            public MapUtils() {
0112:            }
0113:
0114:            // Type safe getters
0115:            //-------------------------------------------------------------------------
0116:            /**
0117:             * Gets from a Map in a null-safe manner.
0118:             *
0119:             * @param map  the map to use
0120:             * @param key  the key to look up
0121:             * @return the value in the Map, <code>null</code> if null map input
0122:             */
0123:            public static Object getObject(final Map map, final Object key) {
0124:                if (map != null) {
0125:                    return map.get(key);
0126:                }
0127:                return null;
0128:            }
0129:
0130:            /**
0131:             * Gets a String from a Map in a null-safe manner.
0132:             * <p>
0133:             * The String is obtained via <code>toString</code>.
0134:             *
0135:             * @param map  the map to use
0136:             * @param key  the key to look up
0137:             * @return the value in the Map as a String, <code>null</code> if null map input
0138:             */
0139:            public static String getString(final Map map, final Object key) {
0140:                if (map != null) {
0141:                    Object answer = map.get(key);
0142:                    if (answer != null) {
0143:                        return answer.toString();
0144:                    }
0145:                }
0146:                return null;
0147:            }
0148:
0149:            /**
0150:             * Gets a Boolean from a Map in a null-safe manner.
0151:             * <p>
0152:             * If the value is a <code>Boolean</code> it is returned directly.
0153:             * If the value is a <code>String</code> and it equals 'true' ignoring case
0154:             * then <code>true</code> is returned, otherwise <code>false</code>.
0155:             * If the value is a <code>Number</code> an integer zero value returns
0156:             * <code>false</code> and non-zero returns <code>true</code>.
0157:             * Otherwise, <code>null</code> is returned.
0158:             *
0159:             * @param map  the map to use
0160:             * @param key  the key to look up
0161:             * @return the value in the Map as a Boolean, <code>null</code> if null map input
0162:             */
0163:            public static Boolean getBoolean(final Map map, final Object key) {
0164:                if (map != null) {
0165:                    Object answer = map.get(key);
0166:                    if (answer != null) {
0167:                        if (answer instanceof  Boolean) {
0168:                            return (Boolean) answer;
0169:
0170:                        } else if (answer instanceof  String) {
0171:                            return new Boolean((String) answer);
0172:
0173:                        } else if (answer instanceof  Number) {
0174:                            Number n = (Number) answer;
0175:                            return (n.intValue() != 0) ? Boolean.TRUE
0176:                                    : Boolean.FALSE;
0177:                        }
0178:                    }
0179:                }
0180:                return null;
0181:            }
0182:
0183:            /**
0184:             * Gets a Number from a Map in a null-safe manner.
0185:             * <p>
0186:             * If the value is a <code>Number</code> it is returned directly.
0187:             * If the value is a <code>String</code> it is converted using
0188:             * {@link NumberFormat#parse(String)} on the system default formatter
0189:             * returning <code>null</code> if the conversion fails.
0190:             * Otherwise, <code>null</code> is returned.
0191:             *
0192:             * @param map  the map to use
0193:             * @param key  the key to look up
0194:             * @return the value in the Map as a Number, <code>null</code> if null map input
0195:             */
0196:            public static Number getNumber(final Map map, final Object key) {
0197:                if (map != null) {
0198:                    Object answer = map.get(key);
0199:                    if (answer != null) {
0200:                        if (answer instanceof  Number) {
0201:                            return (Number) answer;
0202:
0203:                        } else if (answer instanceof  String) {
0204:                            try {
0205:                                String text = (String) answer;
0206:                                return NumberFormat.getInstance().parse(text);
0207:
0208:                            } catch (ParseException e) {
0209:                                logInfo(e);
0210:                            }
0211:                        }
0212:                    }
0213:                }
0214:                return null;
0215:            }
0216:
0217:            /**
0218:             * Gets a Byte from a Map in a null-safe manner.
0219:             * <p>
0220:             * The Byte is obtained from the results of {@link #getNumber(Map,Object)}.
0221:             *
0222:             * @param map  the map to use
0223:             * @param key  the key to look up
0224:             * @return the value in the Map as a Byte, <code>null</code> if null map input
0225:             */
0226:            public static Byte getByte(final Map map, final Object key) {
0227:                Number answer = getNumber(map, key);
0228:                if (answer == null) {
0229:                    return null;
0230:                } else if (answer instanceof  Byte) {
0231:                    return (Byte) answer;
0232:                }
0233:                return new Byte(answer.byteValue());
0234:            }
0235:
0236:            /**
0237:             * Gets a Short from a Map in a null-safe manner.
0238:             * <p>
0239:             * The Short is obtained from the results of {@link #getNumber(Map,Object)}.
0240:             *
0241:             * @param map  the map to use
0242:             * @param key  the key to look up
0243:             * @return the value in the Map as a Short, <code>null</code> if null map input
0244:             */
0245:            public static Short getShort(final Map map, final Object key) {
0246:                Number answer = getNumber(map, key);
0247:                if (answer == null) {
0248:                    return null;
0249:                } else if (answer instanceof  Short) {
0250:                    return (Short) answer;
0251:                }
0252:                return new Short(answer.shortValue());
0253:            }
0254:
0255:            /**
0256:             * Gets a Integer from a Map in a null-safe manner.
0257:             * <p>
0258:             * The Integer is obtained from the results of {@link #getNumber(Map,Object)}.
0259:             *
0260:             * @param map  the map to use
0261:             * @param key  the key to look up
0262:             * @return the value in the Map as a Integer, <code>null</code> if null map input
0263:             */
0264:            public static Integer getInteger(final Map map, final Object key) {
0265:                Number answer = getNumber(map, key);
0266:                if (answer == null) {
0267:                    return null;
0268:                } else if (answer instanceof  Integer) {
0269:                    return (Integer) answer;
0270:                }
0271:                return new Integer(answer.intValue());
0272:            }
0273:
0274:            /**
0275:             * Gets a Long from a Map in a null-safe manner.
0276:             * <p>
0277:             * The Long is obtained from the results of {@link #getNumber(Map,Object)}.
0278:             *
0279:             * @param map  the map to use
0280:             * @param key  the key to look up
0281:             * @return the value in the Map as a Long, <code>null</code> if null map input
0282:             */
0283:            public static Long getLong(final Map map, final Object key) {
0284:                Number answer = getNumber(map, key);
0285:                if (answer == null) {
0286:                    return null;
0287:                } else if (answer instanceof  Long) {
0288:                    return (Long) answer;
0289:                }
0290:                return new Long(answer.longValue());
0291:            }
0292:
0293:            /**
0294:             * Gets a Float from a Map in a null-safe manner.
0295:             * <p>
0296:             * The Float is obtained from the results of {@link #getNumber(Map,Object)}.
0297:             *
0298:             * @param map  the map to use
0299:             * @param key  the key to look up
0300:             * @return the value in the Map as a Float, <code>null</code> if null map input
0301:             */
0302:            public static Float getFloat(final Map map, final Object key) {
0303:                Number answer = getNumber(map, key);
0304:                if (answer == null) {
0305:                    return null;
0306:                } else if (answer instanceof  Float) {
0307:                    return (Float) answer;
0308:                }
0309:                return new Float(answer.floatValue());
0310:            }
0311:
0312:            /**
0313:             * Gets a Double from a Map in a null-safe manner.
0314:             * <p>
0315:             * The Double is obtained from the results of {@link #getNumber(Map,Object)}.
0316:             *
0317:             * @param map  the map to use
0318:             * @param key  the key to look up
0319:             * @return the value in the Map as a Double, <code>null</code> if null map input
0320:             */
0321:            public static Double getDouble(final Map map, final Object key) {
0322:                Number answer = getNumber(map, key);
0323:                if (answer == null) {
0324:                    return null;
0325:                } else if (answer instanceof  Double) {
0326:                    return (Double) answer;
0327:                }
0328:                return new Double(answer.doubleValue());
0329:            }
0330:
0331:            /**
0332:             * Gets a Map from a Map in a null-safe manner.
0333:             * <p>
0334:             * If the value returned from the specified map is not a Map then
0335:             * <code>null</code> is returned.
0336:             *
0337:             * @param map  the map to use
0338:             * @param key  the key to look up
0339:             * @return the value in the Map as a Map, <code>null</code> if null map input
0340:             */
0341:            public static Map getMap(final Map map, final Object key) {
0342:                if (map != null) {
0343:                    Object answer = map.get(key);
0344:                    if (answer != null && answer instanceof  Map) {
0345:                        return (Map) answer;
0346:                    }
0347:                }
0348:                return null;
0349:            }
0350:
0351:            // Type safe getters with default values
0352:            //-------------------------------------------------------------------------
0353:            /**
0354:             *  Looks up the given key in the given map, converting null into the
0355:             *  given default value.
0356:             *
0357:             *  @param map  the map whose value to look up
0358:             *  @param key  the key of the value to look up in that map
0359:             *  @param defaultValue  what to return if the value is null
0360:             *  @return  the value in the map, or defaultValue if the original value
0361:             *    is null or the map is null
0362:             */
0363:            public static Object getObject(Map map, Object key,
0364:                    Object defaultValue) {
0365:                if (map != null) {
0366:                    Object answer = map.get(key);
0367:                    if (answer != null) {
0368:                        return answer;
0369:                    }
0370:                }
0371:                return defaultValue;
0372:            }
0373:
0374:            /**
0375:             *  Looks up the given key in the given map, converting the result into
0376:             *  a string, using the default value if the the conversion fails.
0377:             *
0378:             *  @param map  the map whose value to look up
0379:             *  @param key  the key of the value to look up in that map
0380:             *  @param defaultValue  what to return if the value is null or if the
0381:             *     conversion fails
0382:             *  @return  the value in the map as a string, or defaultValue if the 
0383:             *    original value is null, the map is null or the string conversion
0384:             *    fails
0385:             */
0386:            public static String getString(Map map, Object key,
0387:                    String defaultValue) {
0388:                String answer = getString(map, key);
0389:                if (answer == null) {
0390:                    answer = defaultValue;
0391:                }
0392:                return answer;
0393:            }
0394:
0395:            /**
0396:             *  Looks up the given key in the given map, converting the result into
0397:             *  a boolean, using the default value if the the conversion fails.
0398:             *
0399:             *  @param map  the map whose value to look up
0400:             *  @param key  the key of the value to look up in that map
0401:             *  @param defaultValue  what to return if the value is null or if the
0402:             *     conversion fails
0403:             *  @return  the value in the map as a boolean, or defaultValue if the 
0404:             *    original value is null, the map is null or the boolean conversion
0405:             *    fails
0406:             */
0407:            public static Boolean getBoolean(Map map, Object key,
0408:                    Boolean defaultValue) {
0409:                Boolean answer = getBoolean(map, key);
0410:                if (answer == null) {
0411:                    answer = defaultValue;
0412:                }
0413:                return answer;
0414:            }
0415:
0416:            /**
0417:             *  Looks up the given key in the given map, converting the result into
0418:             *  a number, using the default value if the the conversion fails.
0419:             *
0420:             *  @param map  the map whose value to look up
0421:             *  @param key  the key of the value to look up in that map
0422:             *  @param defaultValue  what to return if the value is null or if the
0423:             *     conversion fails
0424:             *  @return  the value in the map as a number, or defaultValue if the 
0425:             *    original value is null, the map is null or the number conversion
0426:             *    fails
0427:             */
0428:            public static Number getNumber(Map map, Object key,
0429:                    Number defaultValue) {
0430:                Number answer = getNumber(map, key);
0431:                if (answer == null) {
0432:                    answer = defaultValue;
0433:                }
0434:                return answer;
0435:            }
0436:
0437:            /**
0438:             *  Looks up the given key in the given map, converting the result into
0439:             *  a byte, using the default value if the the conversion fails.
0440:             *
0441:             *  @param map  the map whose value to look up
0442:             *  @param key  the key of the value to look up in that map
0443:             *  @param defaultValue  what to return if the value is null or if the
0444:             *     conversion fails
0445:             *  @return  the value in the map as a number, or defaultValue if the 
0446:             *    original value is null, the map is null or the number conversion
0447:             *    fails
0448:             */
0449:            public static Byte getByte(Map map, Object key, Byte defaultValue) {
0450:                Byte answer = getByte(map, key);
0451:                if (answer == null) {
0452:                    answer = defaultValue;
0453:                }
0454:                return answer;
0455:            }
0456:
0457:            /**
0458:             *  Looks up the given key in the given map, converting the result into
0459:             *  a short, using the default value if the the conversion fails.
0460:             *
0461:             *  @param map  the map whose value to look up
0462:             *  @param key  the key of the value to look up in that map
0463:             *  @param defaultValue  what to return if the value is null or if the
0464:             *     conversion fails
0465:             *  @return  the value in the map as a number, or defaultValue if the 
0466:             *    original value is null, the map is null or the number conversion
0467:             *    fails
0468:             */
0469:            public static Short getShort(Map map, Object key, Short defaultValue) {
0470:                Short answer = getShort(map, key);
0471:                if (answer == null) {
0472:                    answer = defaultValue;
0473:                }
0474:                return answer;
0475:            }
0476:
0477:            /**
0478:             *  Looks up the given key in the given map, converting the result into
0479:             *  an integer, using the default value if the the conversion fails.
0480:             *
0481:             *  @param map  the map whose value to look up
0482:             *  @param key  the key of the value to look up in that map
0483:             *  @param defaultValue  what to return if the value is null or if the
0484:             *     conversion fails
0485:             *  @return  the value in the map as a number, or defaultValue if the 
0486:             *    original value is null, the map is null or the number conversion
0487:             *    fails
0488:             */
0489:            public static Integer getInteger(Map map, Object key,
0490:                    Integer defaultValue) {
0491:                Integer answer = getInteger(map, key);
0492:                if (answer == null) {
0493:                    answer = defaultValue;
0494:                }
0495:                return answer;
0496:            }
0497:
0498:            /**
0499:             *  Looks up the given key in the given map, converting the result into
0500:             *  a long, using the default value if the the conversion fails.
0501:             *
0502:             *  @param map  the map whose value to look up
0503:             *  @param key  the key of the value to look up in that map
0504:             *  @param defaultValue  what to return if the value is null or if the
0505:             *     conversion fails
0506:             *  @return  the value in the map as a number, or defaultValue if the 
0507:             *    original value is null, the map is null or the number conversion
0508:             *    fails
0509:             */
0510:            public static Long getLong(Map map, Object key, Long defaultValue) {
0511:                Long answer = getLong(map, key);
0512:                if (answer == null) {
0513:                    answer = defaultValue;
0514:                }
0515:                return answer;
0516:            }
0517:
0518:            /**
0519:             *  Looks up the given key in the given map, converting the result into
0520:             *  a float, using the default value if the the conversion fails.
0521:             *
0522:             *  @param map  the map whose value to look up
0523:             *  @param key  the key of the value to look up in that map
0524:             *  @param defaultValue  what to return if the value is null or if the
0525:             *     conversion fails
0526:             *  @return  the value in the map as a number, or defaultValue if the 
0527:             *    original value is null, the map is null or the number conversion
0528:             *    fails
0529:             */
0530:            public static Float getFloat(Map map, Object key, Float defaultValue) {
0531:                Float answer = getFloat(map, key);
0532:                if (answer == null) {
0533:                    answer = defaultValue;
0534:                }
0535:                return answer;
0536:            }
0537:
0538:            /**
0539:             *  Looks up the given key in the given map, converting the result into
0540:             *  a double, using the default value if the the conversion fails.
0541:             *
0542:             *  @param map  the map whose value to look up
0543:             *  @param key  the key of the value to look up in that map
0544:             *  @param defaultValue  what to return if the value is null or if the
0545:             *     conversion fails
0546:             *  @return  the value in the map as a number, or defaultValue if the 
0547:             *    original value is null, the map is null or the number conversion
0548:             *    fails
0549:             */
0550:            public static Double getDouble(Map map, Object key,
0551:                    Double defaultValue) {
0552:                Double answer = getDouble(map, key);
0553:                if (answer == null) {
0554:                    answer = defaultValue;
0555:                }
0556:                return answer;
0557:            }
0558:
0559:            /**
0560:             *  Looks up the given key in the given map, converting the result into
0561:             *  a map, using the default value if the the conversion fails.
0562:             *
0563:             *  @param map  the map whose value to look up
0564:             *  @param key  the key of the value to look up in that map
0565:             *  @param defaultValue  what to return if the value is null or if the
0566:             *     conversion fails
0567:             *  @return  the value in the map as a number, or defaultValue if the 
0568:             *    original value is null, the map is null or the map conversion
0569:             *    fails
0570:             */
0571:            public static Map getMap(Map map, Object key, Map defaultValue) {
0572:                Map answer = getMap(map, key);
0573:                if (answer == null) {
0574:                    answer = defaultValue;
0575:                }
0576:                return answer;
0577:            }
0578:
0579:            // Type safe primitive getters
0580:            //-------------------------------------------------------------------------
0581:            /**
0582:             * Gets a boolean from a Map in a null-safe manner.
0583:             * <p>
0584:             * If the value is a <code>Boolean</code> its value is returned.
0585:             * If the value is a <code>String</code> and it equals 'true' ignoring case
0586:             * then <code>true</code> is returned, otherwise <code>false</code>.
0587:             * If the value is a <code>Number</code> an integer zero value returns
0588:             * <code>false</code> and non-zero returns <code>true</code>.
0589:             * Otherwise, <code>false</code> is returned.
0590:             *
0591:             * @param map  the map to use
0592:             * @param key  the key to look up
0593:             * @return the value in the Map as a Boolean, <code>false</code> if null map input
0594:             */
0595:            public static boolean getBooleanValue(final Map map,
0596:                    final Object key) {
0597:                Boolean booleanObject = getBoolean(map, key);
0598:                if (booleanObject == null) {
0599:                    return false;
0600:                }
0601:                return booleanObject.booleanValue();
0602:            }
0603:
0604:            /**
0605:             * Gets a byte from a Map in a null-safe manner.
0606:             * <p>
0607:             * The byte is obtained from the results of {@link #getNumber(Map,Object)}.
0608:             *
0609:             * @param map  the map to use
0610:             * @param key  the key to look up
0611:             * @return the value in the Map as a byte, <code>0</code> if null map input
0612:             */
0613:            public static byte getByteValue(final Map map, final Object key) {
0614:                Byte byteObject = getByte(map, key);
0615:                if (byteObject == null) {
0616:                    return 0;
0617:                }
0618:                return byteObject.byteValue();
0619:            }
0620:
0621:            /**
0622:             * Gets a short from a Map in a null-safe manner.
0623:             * <p>
0624:             * The short is obtained from the results of {@link #getNumber(Map,Object)}.
0625:             *
0626:             * @param map  the map to use
0627:             * @param key  the key to look up
0628:             * @return the value in the Map as a short, <code>0</code> if null map input
0629:             */
0630:            public static short getShortValue(final Map map, final Object key) {
0631:                Short shortObject = getShort(map, key);
0632:                if (shortObject == null) {
0633:                    return 0;
0634:                }
0635:                return shortObject.shortValue();
0636:            }
0637:
0638:            /**
0639:             * Gets an int from a Map in a null-safe manner.
0640:             * <p>
0641:             * The int is obtained from the results of {@link #getNumber(Map,Object)}.
0642:             *
0643:             * @param map  the map to use
0644:             * @param key  the key to look up
0645:             * @return the value in the Map as an int, <code>0</code> if null map input
0646:             */
0647:            public static int getIntValue(final Map map, final Object key) {
0648:                Integer integerObject = getInteger(map, key);
0649:                if (integerObject == null) {
0650:                    return 0;
0651:                }
0652:                return integerObject.intValue();
0653:            }
0654:
0655:            /**
0656:             * Gets a long from a Map in a null-safe manner.
0657:             * <p>
0658:             * The long is obtained from the results of {@link #getNumber(Map,Object)}.
0659:             *
0660:             * @param map  the map to use
0661:             * @param key  the key to look up
0662:             * @return the value in the Map as a long, <code>0L</code> if null map input
0663:             */
0664:            public static long getLongValue(final Map map, final Object key) {
0665:                Long longObject = getLong(map, key);
0666:                if (longObject == null) {
0667:                    return 0L;
0668:                }
0669:                return longObject.longValue();
0670:            }
0671:
0672:            /**
0673:             * Gets a float from a Map in a null-safe manner.
0674:             * <p>
0675:             * The float is obtained from the results of {@link #getNumber(Map,Object)}.
0676:             *
0677:             * @param map  the map to use
0678:             * @param key  the key to look up
0679:             * @return the value in the Map as a float, <code>0.0F</code> if null map input
0680:             */
0681:            public static float getFloatValue(final Map map, final Object key) {
0682:                Float floatObject = getFloat(map, key);
0683:                if (floatObject == null) {
0684:                    return 0f;
0685:                }
0686:                return floatObject.floatValue();
0687:            }
0688:
0689:            /**
0690:             * Gets a double from a Map in a null-safe manner.
0691:             * <p>
0692:             * The double is obtained from the results of {@link #getNumber(Map,Object)}.
0693:             *
0694:             * @param map  the map to use
0695:             * @param key  the key to look up
0696:             * @return the value in the Map as a double, <code>0.0</code> if null map input
0697:             */
0698:            public static double getDoubleValue(final Map map, final Object key) {
0699:                Double doubleObject = getDouble(map, key);
0700:                if (doubleObject == null) {
0701:                    return 0d;
0702:                }
0703:                return doubleObject.doubleValue();
0704:            }
0705:
0706:            // Type safe primitive getters with default values
0707:            //-------------------------------------------------------------------------
0708:            /**
0709:             * Gets a boolean from a Map in a null-safe manner,
0710:             * using the default value if the the conversion fails.
0711:             * <p>
0712:             * If the value is a <code>Boolean</code> its value is returned.
0713:             * If the value is a <code>String</code> and it equals 'true' ignoring case
0714:             * then <code>true</code> is returned, otherwise <code>false</code>.
0715:             * If the value is a <code>Number</code> an integer zero value returns
0716:             * <code>false</code> and non-zero returns <code>true</code>.
0717:             * Otherwise, <code>defaultValue</code> is returned.
0718:             *
0719:             * @param map  the map to use
0720:             * @param key  the key to look up
0721:             * @param defaultValue  return if the value is null or if the
0722:             *     conversion fails
0723:             * @return the value in the Map as a Boolean, <code>defaultValue</code> if null map input
0724:             */
0725:            public static boolean getBooleanValue(final Map map,
0726:                    final Object key, boolean defaultValue) {
0727:                Boolean booleanObject = getBoolean(map, key);
0728:                if (booleanObject == null) {
0729:                    return defaultValue;
0730:                }
0731:                return booleanObject.booleanValue();
0732:            }
0733:
0734:            /**
0735:             * Gets a byte from a Map in a null-safe manner,
0736:             * using the default value if the the conversion fails.     
0737:             * <p>
0738:             * The byte is obtained from the results of {@link #getNumber(Map,Object)}.
0739:             *
0740:             * @param map  the map to use
0741:             * @param key  the key to look up
0742:             * @param defaultValue  return if the value is null or if the
0743:             *     conversion fails
0744:             * @return the value in the Map as a byte, <code>defaultValue</code> if null map input
0745:             */
0746:            public static byte getByteValue(final Map map, final Object key,
0747:                    byte defaultValue) {
0748:                Byte byteObject = getByte(map, key);
0749:                if (byteObject == null) {
0750:                    return defaultValue;
0751:                }
0752:                return byteObject.byteValue();
0753:            }
0754:
0755:            /**
0756:             * Gets a short from a Map in a null-safe manner,
0757:             * using the default value if the the conversion fails.     
0758:             * <p>
0759:             * The short is obtained from the results of {@link #getNumber(Map,Object)}.
0760:             *
0761:             * @param map  the map to use
0762:             * @param key  the key to look up
0763:             * @param defaultValue  return if the value is null or if the
0764:             *     conversion fails
0765:             * @return the value in the Map as a short, <code>defaultValue</code> if null map input
0766:             */
0767:            public static short getShortValue(final Map map, final Object key,
0768:                    short defaultValue) {
0769:                Short shortObject = getShort(map, key);
0770:                if (shortObject == null) {
0771:                    return defaultValue;
0772:                }
0773:                return shortObject.shortValue();
0774:            }
0775:
0776:            /**
0777:             * Gets an int from a Map in a null-safe manner,
0778:             * using the default value if the the conversion fails.     
0779:             * <p>
0780:             * The int is obtained from the results of {@link #getNumber(Map,Object)}.
0781:             *
0782:             * @param map  the map to use
0783:             * @param key  the key to look up
0784:             * @param defaultValue  return if the value is null or if the
0785:             *     conversion fails
0786:             * @return the value in the Map as an int, <code>defaultValue</code> if null map input
0787:             */
0788:            public static int getIntValue(final Map map, final Object key,
0789:                    int defaultValue) {
0790:                Integer integerObject = getInteger(map, key);
0791:                if (integerObject == null) {
0792:                    return defaultValue;
0793:                }
0794:                return integerObject.intValue();
0795:            }
0796:
0797:            /**
0798:             * Gets a long from a Map in a null-safe manner,
0799:             * using the default value if the the conversion fails.     
0800:             * <p>
0801:             * The long is obtained from the results of {@link #getNumber(Map,Object)}.
0802:             *
0803:             * @param map  the map to use
0804:             * @param key  the key to look up
0805:             * @param defaultValue  return if the value is null or if the
0806:             *     conversion fails
0807:             * @return the value in the Map as a long, <code>defaultValue</code> if null map input
0808:             */
0809:            public static long getLongValue(final Map map, final Object key,
0810:                    long defaultValue) {
0811:                Long longObject = getLong(map, key);
0812:                if (longObject == null) {
0813:                    return defaultValue;
0814:                }
0815:                return longObject.longValue();
0816:            }
0817:
0818:            /**
0819:             * Gets a float from a Map in a null-safe manner,
0820:             * using the default value if the the conversion fails.     
0821:             * <p>
0822:             * The float is obtained from the results of {@link #getNumber(Map,Object)}.
0823:             *
0824:             * @param map  the map to use
0825:             * @param key  the key to look up
0826:             * @param defaultValue  return if the value is null or if the
0827:             *     conversion fails
0828:             * @return the value in the Map as a float, <code>defaultValue</code> if null map input
0829:             */
0830:            public static float getFloatValue(final Map map, final Object key,
0831:                    float defaultValue) {
0832:                Float floatObject = getFloat(map, key);
0833:                if (floatObject == null) {
0834:                    return defaultValue;
0835:                }
0836:                return floatObject.floatValue();
0837:            }
0838:
0839:            /**
0840:             * Gets a double from a Map in a null-safe manner,
0841:             * using the default value if the the conversion fails.     
0842:             * <p>
0843:             * The double is obtained from the results of {@link #getNumber(Map,Object)}.
0844:             *
0845:             * @param map  the map to use
0846:             * @param key  the key to look up
0847:             * @param defaultValue  return if the value is null or if the
0848:             *     conversion fails
0849:             * @return the value in the Map as a double, <code>defaultValue</code> if null map input
0850:             */
0851:            public static double getDoubleValue(final Map map,
0852:                    final Object key, double defaultValue) {
0853:                Double doubleObject = getDouble(map, key);
0854:                if (doubleObject == null) {
0855:                    return defaultValue;
0856:                }
0857:                return doubleObject.doubleValue();
0858:            }
0859:
0860:            // Conversion methods
0861:            //-------------------------------------------------------------------------
0862:            /**
0863:             * Gets a new Properties object initialised with the values from a Map.
0864:             * A null input will return an empty properties object.
0865:             * 
0866:             * @param map  the map to convert to a Properties object, may not be null
0867:             * @return the properties object
0868:             */
0869:            public static Properties toProperties(final Map map) {
0870:                Properties answer = new Properties();
0871:                if (map != null) {
0872:                    for (Iterator iter = map.entrySet().iterator(); iter
0873:                            .hasNext();) {
0874:                        Map.Entry entry = (Map.Entry) iter.next();
0875:                        Object key = entry.getKey();
0876:                        Object value = entry.getValue();
0877:                        answer.put(key, value);
0878:                    }
0879:                }
0880:                return answer;
0881:            }
0882:
0883:            /**
0884:             * Creates a new HashMap using data copied from a ResourceBundle.
0885:             * 
0886:             * @param resourceBundle  the resource bundle to convert, may not be null
0887:             * @return the hashmap containing the data
0888:             * @throws NullPointerException if the bundle is null
0889:             */
0890:            public static Map toMap(final ResourceBundle resourceBundle) {
0891:                Enumeration enumeration = resourceBundle.getKeys();
0892:                Map map = new HashMap();
0893:
0894:                while (enumeration.hasMoreElements()) {
0895:                    String key = (String) enumeration.nextElement();
0896:                    Object value = resourceBundle.getObject(key);
0897:                    map.put(key, value);
0898:                }
0899:
0900:                return map;
0901:            }
0902:
0903:            // Printing methods
0904:            //-------------------------------------------------------------------------
0905:            /**
0906:             * Prints the given map with nice line breaks.
0907:             * <p>
0908:             * This method prints a nicely formatted String describing the Map.
0909:             * Each map entry will be printed with key and value.
0910:             * When the value is a Map, recursive behaviour occurs.
0911:             * <p>
0912:             * This method is NOT thread-safe in any special way. You must manually
0913:             * synchronize on either this class or the stream as required.
0914:             *
0915:             * @param out  the stream to print to, must not be null
0916:             * @param label  The label to be used, may be <code>null</code>.
0917:             *  If <code>null</code>, the label is not output.
0918:             *  It typically represents the name of the property in a bean or similar.
0919:             * @param map  The map to print, may be <code>null</code>.
0920:             *  If <code>null</code>, the text 'null' is output.
0921:             * @throws NullPointerException if the stream is <code>null</code>
0922:             */
0923:            public static void verbosePrint(final PrintStream out,
0924:                    final Object label, final Map map) {
0925:
0926:                verbosePrintInternal(out, label, map, new ArrayStack(), false);
0927:            }
0928:
0929:            /**
0930:             * Prints the given map with nice line breaks.
0931:             * <p>
0932:             * This method prints a nicely formatted String describing the Map.
0933:             * Each map entry will be printed with key, value and value classname.
0934:             * When the value is a Map, recursive behaviour occurs.
0935:             * <p>
0936:             * This method is NOT thread-safe in any special way. You must manually
0937:             * synchronize on either this class or the stream as required.
0938:             *
0939:             * @param out  the stream to print to, must not be null
0940:             * @param label  The label to be used, may be <code>null</code>.
0941:             *  If <code>null</code>, the label is not output.
0942:             *  It typically represents the name of the property in a bean or similar.
0943:             * @param map  The map to print, may be <code>null</code>.
0944:             *  If <code>null</code>, the text 'null' is output.
0945:             * @throws NullPointerException if the stream is <code>null</code>
0946:             */
0947:            public static void debugPrint(final PrintStream out,
0948:                    final Object label, final Map map) {
0949:
0950:                verbosePrintInternal(out, label, map, new ArrayStack(), true);
0951:            }
0952:
0953:            // Implementation methods
0954:            //-------------------------------------------------------------------------
0955:            /**
0956:             * Logs the given exception to <code>System.out</code>.
0957:             * <p>
0958:             * This method exists as Jakarta Collections does not depend on logging.
0959:             *
0960:             * @param ex  the exception to log
0961:             */
0962:            protected static void logInfo(final Exception ex) {
0963:                System.out.println("INFO: Exception: " + ex);
0964:            }
0965:
0966:            /**
0967:             * Implementation providing functionality for {@link #debugPrint} and for 
0968:             * {@link #verbosePrint}.  This prints the given map with nice line breaks.
0969:             * If the debug flag is true, it additionally prints the type of the object 
0970:             * value.  If the contents of a map include the map itself, then the text 
0971:             * <em>(this Map)</em> is printed out.  If the contents include a 
0972:             * parent container of the map, the the text <em>(ancestor[i] Map)</em> is 
0973:             * printed, where i actually indicates the number of levels which must be 
0974:             * traversed in the sequential list of ancestors (e.g. father, grandfather, 
0975:             * great-grandfather, etc).  
0976:             *
0977:             * @param out  the stream to print to
0978:             * @param label  the label to be used, may be <code>null</code>.
0979:             *  If <code>null</code>, the label is not output.
0980:             *  It typically represents the name of the property in a bean or similar.
0981:             * @param map  the map to print, may be <code>null</code>.
0982:             *  If <code>null</code>, the text 'null' is output
0983:             * @param lineage  a stack consisting of any maps in which the previous 
0984:             *  argument is contained. This is checked to avoid infinite recursion when
0985:             *  printing the output
0986:             * @param debug  flag indicating whether type names should be output.
0987:             * @throws NullPointerException if the stream is <code>null</code>
0988:             */
0989:            private static void verbosePrintInternal(final PrintStream out,
0990:                    final Object label, final Map map,
0991:                    final ArrayStack lineage, final boolean debug) {
0992:
0993:                printIndent(out, lineage.size());
0994:
0995:                if (map == null) {
0996:                    if (label != null) {
0997:                        out.print(label);
0998:                        out.print(" = ");
0999:                    }
1000:                    out.println("null");
1001:                    return;
1002:                }
1003:                if (label != null) {
1004:                    out.print(label);
1005:                    out.println(" = ");
1006:                }
1007:
1008:                printIndent(out, lineage.size());
1009:                out.println("{");
1010:
1011:                lineage.push(map);
1012:
1013:                for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
1014:                    Map.Entry entry = (Map.Entry) it.next();
1015:                    Object childKey = entry.getKey();
1016:                    Object childValue = entry.getValue();
1017:                    if (childValue instanceof  Map
1018:                            && !lineage.contains(childValue)) {
1019:                        verbosePrintInternal(out, (childKey == null ? "null"
1020:                                : childKey), (Map) childValue, lineage, debug);
1021:                    } else {
1022:                        printIndent(out, lineage.size());
1023:                        out.print(childKey);
1024:                        out.print(" = ");
1025:
1026:                        final int lineageIndex = lineage.indexOf(childValue);
1027:                        if (lineageIndex == -1) {
1028:                            out.print(childValue);
1029:                        } else if (lineage.size() - 1 == lineageIndex) {
1030:                            out.print("(this Map)");
1031:                        } else {
1032:                            out.print("(ancestor["
1033:                                    + (lineage.size() - 1 - lineageIndex - 1)
1034:                                    + "] Map)");
1035:                        }
1036:
1037:                        if (debug && childValue != null) {
1038:                            out.print(' ');
1039:                            out.println(childValue.getClass().getName());
1040:                        } else {
1041:                            out.println();
1042:                        }
1043:                    }
1044:                }
1045:
1046:                lineage.pop();
1047:
1048:                printIndent(out, lineage.size());
1049:                out.println(debug ? "} " + map.getClass().getName() : "}");
1050:            }
1051:
1052:            /**
1053:             * Writes indentation to the given stream.
1054:             *
1055:             * @param out  the stream to indent
1056:             */
1057:            private static void printIndent(final PrintStream out,
1058:                    final int indent) {
1059:                for (int i = 0; i < indent; i++) {
1060:                    out.print(INDENT_STRING);
1061:                }
1062:            }
1063:
1064:            // Misc
1065:            //-----------------------------------------------------------------------
1066:            /**
1067:             * Inverts the supplied map returning a new HashMap such that the keys of
1068:             * the input are swapped with the values.
1069:             * <p>
1070:             * This operation assumes that the inverse mapping is well defined.
1071:             * If the input map had multiple entries with the same value mapped to
1072:             * different keys, the returned map will map one of those keys to the 
1073:             * value, but the exact key which will be mapped is undefined.
1074:             *
1075:             * @param map  the map to invert, may not be null
1076:             * @return a new HashMap containing the inverted data
1077:             * @throws NullPointerException if the map is null
1078:             */
1079:            public static Map invertMap(Map map) {
1080:                Map out = new HashMap(map.size());
1081:                for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
1082:                    Map.Entry entry = (Map.Entry) it.next();
1083:                    out.put(entry.getValue(), entry.getKey());
1084:                }
1085:                return out;
1086:            }
1087:
1088:            //-----------------------------------------------------------------------
1089:            /**
1090:             * Protects against adding null values to a map.
1091:             * <p>
1092:             * This method checks the value being added to the map, and if it is null
1093:             * it is replaced by an empty string.
1094:             * <p>
1095:             * This could be useful if the map does not accept null values, or for
1096:             * receiving data from a source that may provide null or empty string
1097:             * which should be held in the same way in the map.
1098:             * <p>
1099:             * Keys are not validated.
1100:             * 
1101:             * @param map  the map to add to, may not be null
1102:             * @param key  the key
1103:             * @param value  the value, null converted to ""
1104:             * @throws NullPointerException if the map is null
1105:             */
1106:            public static void safeAddToMap(Map map, Object key, Object value)
1107:                    throws NullPointerException {
1108:                if (value == null) {
1109:                    map.put(key, "");
1110:                } else {
1111:                    map.put(key, value);
1112:                }
1113:            }
1114:
1115:            //-----------------------------------------------------------------------
1116:            /**
1117:             * Puts all the keys and values from the specified array into the map.
1118:             * <p>
1119:             * This method is an alternative to the {@link java.util.Map#putAll(java.util.Map)}
1120:             * method and constructors. It allows you to build a map from an object array
1121:             * of various possible styles.
1122:             * <p>
1123:             * If the first entry in the object array implements {@link java.util.Map.Entry}
1124:             * or {@link KeyValue} then the key and value are added from that object.
1125:             * If the first entry in the object array is an object array itself, then
1126:             * it is assumed that index 0 in the sub-array is the key and index 1 is the value.
1127:             * Otherwise, the array is treated as keys and values in alternate indices.
1128:             * <p>
1129:             * For example, to create a color map:
1130:             * <pre>
1131:             * Map colorMap = MapUtils.putAll(new HashMap(), new String[][] {
1132:             *     {"RED", "#FF0000"},
1133:             *     {"GREEN", "#00FF00"},
1134:             *     {"BLUE", "#0000FF"}
1135:             * });
1136:             * </pre>
1137:             * or:
1138:             * <pre>
1139:             * Map colorMap = MapUtils.putAll(new HashMap(), new String[] {
1140:             *     "RED", "#FF0000",
1141:             *     "GREEN", "#00FF00",
1142:             *     "BLUE", "#0000FF"
1143:             * });
1144:             * </pre>
1145:             * or:
1146:             * <pre>
1147:             * Map colorMap = MapUtils.putAll(new HashMap(), new Map.Entry[] {
1148:             *     new DefaultMapEntry("RED", "#FF0000"),
1149:             *     new DefaultMapEntry("GREEN", "#00FF00"),
1150:             *     new DefaultMapEntry("BLUE", "#0000FF")
1151:             * });
1152:             * </pre>
1153:             *
1154:             * @param map  the map to populate, must not be null
1155:             * @param array  an array to populate from, null ignored
1156:             * @return the input map
1157:             * @throws NullPointerException  if map is null
1158:             * @throws IllegalArgumentException  if sub-array or entry matching used and an
1159:             *  entry is invalid
1160:             * @throws ClassCastException if the array contents is mixed
1161:             * @since Commons Collections 3.2
1162:             */
1163:            public static Map putAll(Map map, Object[] array) {
1164:                map.size(); // force NPE
1165:                if (array == null || array.length == 0) {
1166:                    return map;
1167:                }
1168:                Object obj = array[0];
1169:                if (obj instanceof  Map.Entry) {
1170:                    for (int i = 0; i < array.length; i++) {
1171:                        Map.Entry entry = (Map.Entry) array[i];
1172:                        map.put(entry.getKey(), entry.getValue());
1173:                    }
1174:                } else if (obj instanceof  KeyValue) {
1175:                    for (int i = 0; i < array.length; i++) {
1176:                        KeyValue keyval = (KeyValue) array[i];
1177:                        map.put(keyval.getKey(), keyval.getValue());
1178:                    }
1179:                } else if (obj instanceof  Object[]) {
1180:                    for (int i = 0; i < array.length; i++) {
1181:                        Object[] sub = (Object[]) array[i];
1182:                        if (sub == null || sub.length < 2) {
1183:                            throw new IllegalArgumentException(
1184:                                    "Invalid array element: " + i);
1185:                        }
1186:                        map.put(sub[0], sub[1]);
1187:                    }
1188:                } else {
1189:                    for (int i = 0; i < array.length - 1;) {
1190:                        map.put(array[i++], array[i++]);
1191:                    }
1192:                }
1193:                return map;
1194:            }
1195:
1196:            //-----------------------------------------------------------------------
1197:            /**
1198:             * Null-safe check if the specified map is empty.
1199:             * <p>
1200:             * Null returns true.
1201:             * 
1202:             * @param map  the map to check, may be null
1203:             * @return true if empty or null
1204:             * @since Commons Collections 3.2
1205:             */
1206:            public static boolean isEmpty(Map map) {
1207:                return (map == null || map.isEmpty());
1208:            }
1209:
1210:            /**
1211:             * Null-safe check if the specified map is not empty.
1212:             * <p>
1213:             * Null returns false.
1214:             * 
1215:             * @param map  the map to check, may be null
1216:             * @return true if non-null and non-empty
1217:             * @since Commons Collections 3.2
1218:             */
1219:            public static boolean isNotEmpty(Map map) {
1220:                return !MapUtils.isEmpty(map);
1221:            }
1222:
1223:            // Map decorators
1224:            //-----------------------------------------------------------------------
1225:            /**
1226:             * Returns a synchronized map backed by the given map.
1227:             * <p>
1228:             * You must manually synchronize on the returned buffer's iterator to 
1229:             * avoid non-deterministic behavior:
1230:             *  
1231:             * <pre>
1232:             * Map m = MapUtils.synchronizedMap(myMap);
1233:             * Set s = m.keySet();  // outside synchronized block
1234:             * synchronized (m) {  // synchronized on MAP!
1235:             *     Iterator i = s.iterator();
1236:             *     while (i.hasNext()) {
1237:             *         process (i.next());
1238:             *     }
1239:             * }
1240:             * </pre>
1241:             * 
1242:             * This method uses the implementation in {@link java.util.Collections Collections}.
1243:             * 
1244:             * @param map  the map to synchronize, must not be null
1245:             * @return a synchronized map backed by the given map
1246:             * @throws IllegalArgumentException  if the map is null
1247:             */
1248:            public static Map synchronizedMap(Map map) {
1249:                return Collections.synchronizedMap(map);
1250:            }
1251:
1252:            /**
1253:             * Returns an unmodifiable map backed by the given map.
1254:             * <p>
1255:             * This method uses the implementation in the decorators subpackage.
1256:             *
1257:             * @param map  the map to make unmodifiable, must not be null
1258:             * @return an unmodifiable map backed by the given map
1259:             * @throws IllegalArgumentException  if the map is null
1260:             */
1261:            public static Map unmodifiableMap(Map map) {
1262:                return UnmodifiableMap.decorate(map);
1263:            }
1264:
1265:            /**
1266:             * Returns a predicated (validating) map backed by the given map.
1267:             * <p>
1268:             * Only objects that pass the tests in the given predicates can be added to the map.
1269:             * Trying to add an invalid object results in an IllegalArgumentException.
1270:             * Keys must pass the key predicate, values must pass the value predicate.
1271:             * It is important not to use the original map after invoking this method,
1272:             * as it is a backdoor for adding invalid objects.
1273:             *
1274:             * @param map  the map to predicate, must not be null
1275:             * @param keyPred  the predicate for keys, null means no check
1276:             * @param valuePred  the predicate for values, null means no check
1277:             * @return a predicated map backed by the given map
1278:             * @throws IllegalArgumentException  if the Map is null
1279:             */
1280:            public static Map predicatedMap(Map map, Predicate keyPred,
1281:                    Predicate valuePred) {
1282:                return PredicatedMap.decorate(map, keyPred, valuePred);
1283:            }
1284:
1285:            /**
1286:             * Returns a typed map backed by the given map.
1287:             * <p>
1288:             * Only keys and values of the specified types can be added to the map.
1289:             * 
1290:             * @param map  the map to limit to a specific type, must not be null
1291:             * @param keyType  the type of keys which may be added to the map, must not be null
1292:             * @param valueType  the type of values which may be added to the map, must not be null
1293:             * @return a typed map backed by the specified map
1294:             * @throws IllegalArgumentException  if the Map or Class is null
1295:             */
1296:            public static Map typedMap(Map map, Class keyType, Class valueType) {
1297:                return TypedMap.decorate(map, keyType, valueType);
1298:            }
1299:
1300:            /**
1301:             * Returns a transformed map backed by the given map.
1302:             * <p>
1303:             * This method returns a new map (decorating the specified map) that
1304:             * will transform any new entries added to it.
1305:             * Existing entries in the specified map will not be transformed.
1306:             * If you want that behaviour, see {@link TransformedMap#decorateTransform}.
1307:             * <p>
1308:             * Each object is passed through the transformers as it is added to the
1309:             * Map. It is important not to use the original map after invoking this 
1310:             * method, as it is a backdoor for adding untransformed objects.
1311:             * <p>
1312:             * If there are any elements already in the map being decorated, they
1313:             * are NOT transformed.
1314:             *
1315:             * @param map  the map to transform, must not be null, typically empty
1316:             * @param keyTransformer  the transformer for the map keys, null means no transformation
1317:             * @param valueTransformer  the transformer for the map values, null means no transformation
1318:             * @return a transformed map backed by the given map
1319:             * @throws IllegalArgumentException  if the Map is null
1320:             */
1321:            public static Map transformedMap(Map map,
1322:                    Transformer keyTransformer, Transformer valueTransformer) {
1323:                return TransformedMap.decorate(map, keyTransformer,
1324:                        valueTransformer);
1325:            }
1326:
1327:            /**
1328:             * Returns a fixed-sized map backed by the given map.
1329:             * Elements may not be added or removed from the returned map, but 
1330:             * existing elements can be changed (for instance, via the 
1331:             * {@link Map#put(Object,Object)} method).
1332:             *
1333:             * @param map  the map whose size to fix, must not be null
1334:             * @return a fixed-size map backed by that map
1335:             * @throws IllegalArgumentException  if the Map is null
1336:             */
1337:            public static Map fixedSizeMap(Map map) {
1338:                return FixedSizeMap.decorate(map);
1339:            }
1340:
1341:            /**
1342:             * Returns a "lazy" map whose values will be created on demand.
1343:             * <p>
1344:             * When the key passed to the returned map's {@link Map#get(Object)}
1345:             * method is not present in the map, then the factory will be used
1346:             * to create a new object and that object will become the value
1347:             * associated with that key.
1348:             * <p>
1349:             * For instance:
1350:             * <pre>
1351:             * Factory factory = new Factory() {
1352:             *     public Object create() {
1353:             *         return new Date();
1354:             *     }
1355:             * }
1356:             * Map lazyMap = MapUtils.lazyMap(new HashMap(), factory);
1357:             * Object obj = lazyMap.get("test");
1358:             * </pre>
1359:             *
1360:             * After the above code is executed, <code>obj</code> will contain
1361:             * a new <code>Date</code> instance.  Furthermore, that <code>Date</code>
1362:             * instance is the value for the <code>"test"</code> key in the map.
1363:             *
1364:             * @param map  the map to make lazy, must not be null
1365:             * @param factory  the factory for creating new objects, must not be null
1366:             * @return a lazy map backed by the given map
1367:             * @throws IllegalArgumentException  if the Map or Factory is null
1368:             */
1369:            public static Map lazyMap(Map map, Factory factory) {
1370:                return LazyMap.decorate(map, factory);
1371:            }
1372:
1373:            /**
1374:             * Returns a "lazy" map whose values will be created on demand.
1375:             * <p>
1376:             * When the key passed to the returned map's {@link Map#get(Object)}
1377:             * method is not present in the map, then the factory will be used
1378:             * to create a new object and that object will become the value
1379:             * associated with that key. The factory is a {@link Transformer}
1380:             * that will be passed the key which it must transform into the value.
1381:             * <p>
1382:             * For instance:
1383:             * <pre>
1384:             * Transformer factory = new Transformer() {
1385:             *     public Object transform(Object mapKey) {
1386:             *         return new File(mapKey);
1387:             *     }
1388:             * }
1389:             * Map lazyMap = MapUtils.lazyMap(new HashMap(), factory);
1390:             * Object obj = lazyMap.get("C:/dev");
1391:             * </pre>
1392:             *
1393:             * After the above code is executed, <code>obj</code> will contain
1394:             * a new <code>File</code> instance for the C drive dev directory.
1395:             * Furthermore, that <code>File</code> instance is the value for the
1396:             * <code>"C:/dev"</code> key in the map.
1397:             * <p>
1398:             * If a lazy map is wrapped by a synchronized map, the result is a simple
1399:             * synchronized cache. When an object is not is the cache, the cache itself
1400:             * calls back to the factory Transformer to populate itself, all within the
1401:             * same synchronized block.
1402:             *
1403:             * @param map  the map to make lazy, must not be null
1404:             * @param transformerFactory  the factory for creating new objects, must not be null
1405:             * @return a lazy map backed by the given map
1406:             * @throws IllegalArgumentException  if the Map or Transformer is null
1407:             */
1408:            public static Map lazyMap(Map map, Transformer transformerFactory) {
1409:                return LazyMap.decorate(map, transformerFactory);
1410:            }
1411:
1412:            /**
1413:             * Returns a map that maintains the order of keys that are added
1414:             * backed by the given map.
1415:             * <p>
1416:             * If a key is added twice, the order is determined by the first add.
1417:             * The order is observed through the keySet, values and entrySet.
1418:             *
1419:             * @param map  the map to order, must not be null
1420:             * @return an ordered map backed by the given map
1421:             * @throws IllegalArgumentException  if the Map is null
1422:             */
1423:            public static Map orderedMap(Map map) {
1424:                return ListOrderedMap.decorate(map);
1425:            }
1426:
1427:            /**
1428:             * Creates a mult-value map backed by the given map which returns
1429:             * collections of type ArrayList.
1430:             *
1431:             * @param map  the map to decorate
1432:             * @return a multi-value map backed by the given map which returns ArrayLists of values.
1433:             * @see MultiValueMap
1434:             * @since Commons Collections 3.2
1435:             */
1436:            public static Map multiValueMap(Map map) {
1437:                return MultiValueMap.decorate(map);
1438:            }
1439:
1440:            /**
1441:             * Creates a multi-value map backed by the given map which returns
1442:             * collections of the specified type.
1443:             *
1444:             * @param map  the map to decorate
1445:             * @param collectionClass  the type of collections to return from the map (must contain public no-arg constructor
1446:             *  and extend Collection).
1447:             * @return a multi-value map backed by the given map which returns collections of the specified type
1448:             * @see MultiValueMap
1449:             * @since Commons Collections 3.2
1450:             */
1451:            public static Map multiValueMap(Map map, Class collectionClass) {
1452:                return MultiValueMap.decorate(map, collectionClass);
1453:            }
1454:
1455:            /**
1456:             * Creates a multi-value map backed by the given map which returns
1457:             * collections created by the specified collection factory.
1458:             *
1459:             * @param map  the map to decorate
1460:             * @param collectionFactory  a factor which creates collection objects
1461:             * @return a multi-value map backed by the given map which returns collections
1462:             * created by the specified collection factory
1463:             * @see MultiValueMap
1464:             * @since Commons Collections 3.2
1465:             */
1466:            public static Map multiValueMap(Map map, Factory collectionFactory) {
1467:                return MultiValueMap.decorate(map, collectionFactory);
1468:            }
1469:
1470:            // SortedMap decorators
1471:            //-----------------------------------------------------------------------
1472:            /**
1473:             * Returns a synchronized sorted map backed by the given sorted map.
1474:             * <p>
1475:             * You must manually synchronize on the returned buffer's iterator to 
1476:             * avoid non-deterministic behavior:
1477:             *  
1478:             * <pre>
1479:             * Map m = MapUtils.synchronizedSortedMap(myMap);
1480:             * Set s = m.keySet();  // outside synchronized block
1481:             * synchronized (m) {  // synchronized on MAP!
1482:             *     Iterator i = s.iterator();
1483:             *     while (i.hasNext()) {
1484:             *         process (i.next());
1485:             *     }
1486:             * }
1487:             * </pre>
1488:             * 
1489:             * This method uses the implementation in {@link java.util.Collections Collections}.
1490:             * 
1491:             * @param map  the map to synchronize, must not be null
1492:             * @return a synchronized map backed by the given map
1493:             * @throws IllegalArgumentException  if the map is null
1494:             */
1495:            public static Map synchronizedSortedMap(SortedMap map) {
1496:                return Collections.synchronizedSortedMap(map);
1497:            }
1498:
1499:            /**
1500:             * Returns an unmodifiable sorted map backed by the given sorted map.
1501:             * <p>
1502:             * This method uses the implementation in the decorators subpackage.
1503:             *
1504:             * @param map  the sorted map to make unmodifiable, must not be null
1505:             * @return an unmodifiable map backed by the given map
1506:             * @throws IllegalArgumentException  if the map is null
1507:             */
1508:            public static Map unmodifiableSortedMap(SortedMap map) {
1509:                return UnmodifiableSortedMap.decorate(map);
1510:            }
1511:
1512:            /**
1513:             * Returns a predicated (validating) sorted map backed by the given map.
1514:             * <p>
1515:             * Only objects that pass the tests in the given predicates can be added to the map.
1516:             * Trying to add an invalid object results in an IllegalArgumentException.
1517:             * Keys must pass the key predicate, values must pass the value predicate.
1518:             * It is important not to use the original map after invoking this method,
1519:             * as it is a backdoor for adding invalid objects.
1520:             *
1521:             * @param map  the map to predicate, must not be null
1522:             * @param keyPred  the predicate for keys, null means no check
1523:             * @param valuePred  the predicate for values, null means no check
1524:             * @return a predicated map backed by the given map
1525:             * @throws IllegalArgumentException  if the SortedMap is null
1526:             */
1527:            public static SortedMap predicatedSortedMap(SortedMap map,
1528:                    Predicate keyPred, Predicate valuePred) {
1529:                return PredicatedSortedMap.decorate(map, keyPred, valuePred);
1530:            }
1531:
1532:            /**
1533:             * Returns a typed sorted map backed by the given map.
1534:             * <p>
1535:             * Only keys and values of the specified types can be added to the map.
1536:             * 
1537:             * @param map  the map to limit to a specific type, must not be null
1538:             * @param keyType  the type of keys which may be added to the map, must not be null
1539:             * @param valueType  the type of values which may be added to the map, must not be null
1540:             * @return a typed map backed by the specified map
1541:             */
1542:            public static SortedMap typedSortedMap(SortedMap map,
1543:                    Class keyType, Class valueType) {
1544:                return TypedSortedMap.decorate(map, keyType, valueType);
1545:            }
1546:
1547:            /**
1548:             * Returns a transformed sorted map backed by the given map.
1549:             * <p>
1550:             * This method returns a new sorted map (decorating the specified map) that
1551:             * will transform any new entries added to it.
1552:             * Existing entries in the specified map will not be transformed.
1553:             * If you want that behaviour, see {@link TransformedSortedMap#decorateTransform}.
1554:             * <p>
1555:             * Each object is passed through the transformers as it is added to the
1556:             * Map. It is important not to use the original map after invoking this 
1557:             * method, as it is a backdoor for adding untransformed objects.
1558:             * <p>
1559:             * If there are any elements already in the map being decorated, they
1560:             * are NOT transformed.
1561:             *
1562:             * @param map  the map to transform, must not be null, typically empty
1563:             * @param keyTransformer  the transformer for the map keys, null means no transformation
1564:             * @param valueTransformer  the transformer for the map values, null means no transformation
1565:             * @return a transformed map backed by the given map
1566:             * @throws IllegalArgumentException  if the SortedMap is null
1567:             */
1568:            public static SortedMap transformedSortedMap(SortedMap map,
1569:                    Transformer keyTransformer, Transformer valueTransformer) {
1570:                return TransformedSortedMap.decorate(map, keyTransformer,
1571:                        valueTransformer);
1572:            }
1573:
1574:            /**
1575:             * Returns a fixed-sized sorted map backed by the given sorted map.
1576:             * Elements may not be added or removed from the returned map, but 
1577:             * existing elements can be changed (for instance, via the 
1578:             * {@link Map#put(Object,Object)} method).
1579:             *
1580:             * @param map  the map whose size to fix, must not be null
1581:             * @return a fixed-size map backed by that map
1582:             * @throws IllegalArgumentException  if the SortedMap is null
1583:             */
1584:            public static SortedMap fixedSizeSortedMap(SortedMap map) {
1585:                return FixedSizeSortedMap.decorate(map);
1586:            }
1587:
1588:            /**
1589:             * Returns a "lazy" sorted map whose values will be created on demand.
1590:             * <p>
1591:             * When the key passed to the returned map's {@link Map#get(Object)}
1592:             * method is not present in the map, then the factory will be used
1593:             * to create a new object and that object will become the value
1594:             * associated with that key.
1595:             * <p>
1596:             * For instance:
1597:             *
1598:             * <pre>
1599:             * Factory factory = new Factory() {
1600:             *     public Object create() {
1601:             *         return new Date();
1602:             *     }
1603:             * }
1604:             * SortedMap lazy = MapUtils.lazySortedMap(new TreeMap(), factory);
1605:             * Object obj = lazy.get("test");
1606:             * </pre>
1607:             *
1608:             * After the above code is executed, <code>obj</code> will contain
1609:             * a new <code>Date</code> instance.  Furthermore, that <code>Date</code>
1610:             * instance is the value for the <code>"test"</code> key.
1611:             *
1612:             * @param map  the map to make lazy, must not be null
1613:             * @param factory  the factory for creating new objects, must not be null
1614:             * @return a lazy map backed by the given map
1615:             * @throws IllegalArgumentException  if the SortedMap or Factory is null
1616:             */
1617:            public static SortedMap lazySortedMap(SortedMap map, Factory factory) {
1618:                return LazySortedMap.decorate(map, factory);
1619:            }
1620:
1621:            /**
1622:             * Returns a "lazy" sorted map whose values will be created on demand.
1623:             * <p>
1624:             * When the key passed to the returned map's {@link Map#get(Object)}
1625:             * method is not present in the map, then the factory will be used
1626:             * to create a new object and that object will become the value
1627:             * associated with that key. The factory is a {@link Transformer}
1628:             * that will be passed the key which it must transform into the value.
1629:             * <p>
1630:             * For instance:
1631:             * <pre>
1632:             * Transformer factory = new Transformer() {
1633:             *     public Object transform(Object mapKey) {
1634:             *         return new File(mapKey);
1635:             *     }
1636:             * }
1637:             * SortedMap lazy = MapUtils.lazySortedMap(new TreeMap(), factory);
1638:             * Object obj = lazy.get("C:/dev");
1639:             * </pre>
1640:             *
1641:             * After the above code is executed, <code>obj</code> will contain
1642:             * a new <code>File</code> instance for the C drive dev directory.
1643:             * Furthermore, that <code>File</code> instance is the value for the
1644:             * <code>"C:/dev"</code> key in the map.
1645:             * <p>
1646:             * If a lazy map is wrapped by a synchronized map, the result is a simple
1647:             * synchronized cache. When an object is not is the cache, the cache itself
1648:             * calls back to the factory Transformer to populate itself, all within the
1649:             * same synchronized block.
1650:             *
1651:             * @param map  the map to make lazy, must not be null
1652:             * @param transformerFactory  the factory for creating new objects, must not be null
1653:             * @return a lazy map backed by the given map
1654:             * @throws IllegalArgumentException  if the Map or Transformer is null
1655:             */
1656:            public static SortedMap lazySortedMap(SortedMap map,
1657:                    Transformer transformerFactory) {
1658:                return LazySortedMap.decorate(map, transformerFactory);
1659:            }
1660:
1661:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.