KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > core > CollectionFactory


1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.core;
18
19 import java.util.ArrayList JavaDoc;
20 import java.util.Collection JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.HashSet JavaDoc;
23 import java.util.IdentityHashMap JavaDoc;
24 import java.util.LinkedHashMap JavaDoc;
25 import java.util.LinkedHashSet JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.Set JavaDoc;
29 import java.util.SortedMap JavaDoc;
30 import java.util.SortedSet JavaDoc;
31 import java.util.TreeMap JavaDoc;
32 import java.util.TreeSet JavaDoc;
33
34 import org.apache.commons.collections.map.CaseInsensitiveMap;
35 import org.apache.commons.collections.map.IdentityMap;
36 import org.apache.commons.collections.map.LinkedMap;
37 import org.apache.commons.collections.map.ListOrderedMap;
38 import org.apache.commons.collections.set.ListOrderedSet;
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41
42 import org.springframework.util.ClassUtils;
43
44 /**
45  * Factory for collections, being aware of JDK 1.4+ extended collections
46  * and Commons Collection 3.x's corresponding versions for older JDKs.
47  * Mainly for internal use within the framework.
48  *
49  * <p>The goal of this class is to avoid runtime dependencies on JDK 1.4+
50  * or Commons Collections 3.x, simply using the best collection implementation
51  * that is available. Prefers JDK 1.4+ collection implementations to Commons
52  * Collections 3.x versions, falling back to JDK 1.3 collections as worst case.
53  *
54  * @author Juergen Hoeller
55  * @since 1.1.1
56  * @see #createLinkedSetIfPossible
57  * @see #createLinkedMapIfPossible
58  * @see #createLinkedCaseInsensitiveMapIfPossible
59  * @see #createIdentityMapIfPossible
60  */

61 public abstract class CollectionFactory {
62
63     private static final Log logger = LogFactory.getLog(CollectionFactory.class);
64
65     /** Whether the Commons Collections 3.x library is present on the classpath */
66     private static final boolean commonsCollections3Available =
67             ClassUtils.isPresent(
68                     "org.apache.commons.collections.map.LinkedMap", CollectionFactory.class.getClassLoader());
69
70
71     /**
72      * Create a linked set if possible: that is, if running on JDK >= 1.4
73      * or if Commons Collections 3.x is available. Prefers a JDK 1.4+
74      * LinkedHashSet to a Commons Collections 3.x ListOrderedSet.
75      * @param initialCapacity the initial capacity of the set
76      * @return the new set instance
77      * @see java.util.LinkedHashSet
78      * @see org.apache.commons.collections.set.ListOrderedSet
79      */

80     public static Set JavaDoc createLinkedSetIfPossible(int initialCapacity) {
81         if (JdkVersion.isAtLeastJava14()) {
82             logger.trace("Creating [java.util.LinkedHashSet]");
83             return Jdk14CollectionFactory.createLinkedHashSet(initialCapacity);
84         }
85         else if (commonsCollections3Available) {
86             logger.trace("Creating [org.apache.commons.collections.set.ListOrderedSet]");
87             return CommonsCollectionFactory.createListOrderedSet(initialCapacity);
88         }
89         else {
90             logger.debug("Falling back to plain [java.util.HashSet] for linked set");
91             return new HashSet JavaDoc(initialCapacity);
92         }
93     }
94
95     /**
96      * Create a linked map if possible: that is, if running on JDK >= 1.4
97      * or if Commons Collections 3.x is available. Prefers a JDK 1.4+
98      * LinkedHashMap to a Commons Collections 3.x LinkedMap.
99      * @param initialCapacity the initial capacity of the map
100      * @return the new map instance
101      * @see java.util.LinkedHashMap
102      * @see org.apache.commons.collections.map.LinkedMap
103      */

104     public static Map JavaDoc createLinkedMapIfPossible(int initialCapacity) {
105         if (JdkVersion.isAtLeastJava14()) {
106             logger.trace("Creating [java.util.LinkedHashMap]");
107             return Jdk14CollectionFactory.createLinkedHashMap(initialCapacity);
108         }
109         else if (commonsCollections3Available) {
110             logger.trace("Creating [org.apache.commons.collections.map.LinkedMap]");
111             return CommonsCollectionFactory.createLinkedMap(initialCapacity);
112         }
113         else {
114             logger.debug("Falling back to plain[java.util.HashMap] for linked map");
115             return new HashMap JavaDoc(initialCapacity);
116         }
117     }
118
119     /**
120      * Create a linked case-insensitive map if possible: if Commons Collections
121      * 3.x is available, a CaseInsensitiveMap with ListOrderedMap decorator will
122      * be created. Else, a JDK 1.4+ LinkedHashMap or plain HashMap will be used.
123      * @param initialCapacity the initial capacity of the map
124      * @return the new map instance
125      * @see org.apache.commons.collections.map.CaseInsensitiveMap
126      * @see org.apache.commons.collections.map.ListOrderedMap
127      */

128     public static Map JavaDoc createLinkedCaseInsensitiveMapIfPossible(int initialCapacity) {
129         if (commonsCollections3Available) {
130             logger.trace("Creating [org.apache.commons.collections.map.ListOrderedMap/CaseInsensitiveMap]");
131             return CommonsCollectionFactory.createListOrderedCaseInsensitiveMap(initialCapacity);
132         }
133         else if (JdkVersion.isAtLeastJava14()) {
134             logger.debug("Falling back to [java.util.LinkedHashMap] for linked case-insensitive map");
135             return Jdk14CollectionFactory.createLinkedHashMap(initialCapacity);
136         }
137         else {
138             logger.debug("Falling back to plain [java.util.HashMap] for linked case-insensitive map");
139             return new HashMap JavaDoc(initialCapacity);
140         }
141     }
142
143     /**
144      * Create an identity map if possible: that is, if running on JDK >= 1.4
145      * or if Commons Collections 3.x is available. Prefers a JDK 1.4+
146      * IdentityHashMap to a Commons Collections 3.x IdentityMap.
147      * @param initialCapacity the initial capacity of the map
148      * @return the new map instance
149      * @see java.util.IdentityHashMap
150      * @see org.apache.commons.collections.map.IdentityMap
151      */

152     public static Map JavaDoc createIdentityMapIfPossible(int initialCapacity) {
153         if (JdkVersion.isAtLeastJava14()) {
154             logger.trace("Creating [java.util.IdentityHashMap]");
155             return Jdk14CollectionFactory.createIdentityHashMap(initialCapacity);
156         }
157         else if (commonsCollections3Available) {
158             logger.trace("Creating [org.apache.commons.collections.map.IdentityMap]");
159             return CommonsCollectionFactory.createIdentityMap(initialCapacity);
160         }
161         else {
162             logger.debug("Falling back to plain [java.util.HashMap] for identity map");
163             return new HashMap JavaDoc(initialCapacity);
164         }
165     }
166
167
168     /**
169      * Create the most approximate collection for the given collection.
170      * <p>Creates an ArrayList, TreeSet or linked Set for a List, SortedSet
171      * or Set, respectively.
172      * @param collection the original collection object
173      * @param initialCapacity the initial capacity
174      * @return the new collection instance
175      * @see java.util.ArrayList
176      * @see java.util.TreeSet
177      * @see #createLinkedSetIfPossible
178      */

179     public static Collection JavaDoc createApproximateCollection(Object JavaDoc collection, int initialCapacity) {
180         if (collection instanceof List JavaDoc) {
181             return new ArrayList JavaDoc(initialCapacity);
182         }
183         else if (collection instanceof SortedSet JavaDoc) {
184             return new TreeSet JavaDoc(((SortedSet JavaDoc) collection).comparator());
185         }
186         else {
187             return createLinkedSetIfPossible(initialCapacity);
188         }
189     }
190
191     /**
192      * Create the most approximate map for the given map.
193      * <p>Creates a TreeMap or linked Map for a SortedMap or Map, respectively.
194      * @param map the original map object
195      * @param initialCapacity the initial capacity
196      * @return the new collection instance
197      * @see java.util.TreeMap
198      * @see #createLinkedMapIfPossible
199      */

200     public static Map JavaDoc createApproximateMap(Object JavaDoc map, int initialCapacity) {
201         if (map instanceof SortedMap JavaDoc) {
202             return new TreeMap JavaDoc(((SortedMap JavaDoc) map).comparator());
203         }
204         else {
205             return createLinkedMapIfPossible(initialCapacity);
206         }
207     }
208
209
210     /**
211      * Actual creation of JDK 1.4+ Collections.
212      * In separate inner class to avoid runtime dependency on JDK 1.4+.
213      */

214     private static abstract class Jdk14CollectionFactory {
215
216         private static Set JavaDoc createLinkedHashSet(int initialCapacity) {
217             return new LinkedHashSet JavaDoc(initialCapacity);
218         }
219
220         private static Map JavaDoc createLinkedHashMap(int initialCapacity) {
221             return new LinkedHashMap JavaDoc(initialCapacity);
222         }
223
224         private static Map JavaDoc createIdentityHashMap(int initialCapacity) {
225             return new IdentityHashMap JavaDoc(initialCapacity);
226         }
227     }
228
229
230     /**
231      * Actual creation of Commons Collections.
232      * In separate inner class to avoid runtime dependency on Commons Collections 3.x.
233      */

234     private static abstract class CommonsCollectionFactory {
235
236         private static Set JavaDoc createListOrderedSet(int initialCapacity) {
237             return ListOrderedSet.decorate(new HashSet JavaDoc(initialCapacity));
238         }
239
240         private static Map JavaDoc createLinkedMap(int initialCapacity) {
241             // Commons Collections does not support initial capacity of 0.
242
return new LinkedMap(initialCapacity == 0 ? 1 : initialCapacity);
243         }
244
245         private static Map JavaDoc createListOrderedCaseInsensitiveMap(int initialCapacity) {
246             // Commons Collections does not support initial capacity of 0.
247
return ListOrderedMap.decorate(new CaseInsensitiveMap(initialCapacity == 0 ? 1 : initialCapacity));
248         }
249
250         private static Map JavaDoc createIdentityMap(int initialCapacity) {
251             // Commons Collections does not support initial capacity of 0.
252
return new IdentityMap(initialCapacity == 0 ? 1 : initialCapacity);
253         }
254     }
255
256 }
257
Popular Tags