View Javadoc

1   /**
2    * Copyright 2005-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
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  package org.kuali.rice.core.api.mo;
17  
18  import org.apache.commons.collections.CollectionUtils;
19  
20  import java.util.ArrayList;
21  import java.util.Collection;
22  import java.util.Collections;
23  import java.util.HashMap;
24  import java.util.HashSet;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Set;
28  
29  /**
30   * A set of simple utilities to assist with common idioms in immutable model objects and their builders.
31   *
32   * @author Kuali Rice Team (rice.collab@kuali.org)
33   */
34  public class ModelObjectUtils {
35  
36      /**
37       * Takes the given list of {@code ModelBuilder} objects and invokes the
38       * {@link org.kuali.rice.core.api.mo.ModelBuilder#build()} method on each of them, adding them to a new list and
39       * return an unmodifiable copy.  If the given list is empty or null, will return an empty and unmodifiable list.
40       *
41       * @param builderList the list of builders to build and add to resulting list, may be empty or null
42       * @param <T> the type of the object that is built by the builders in the list, it is up to the caller of this
43       *        method to ensure they define the proper parameterized list for the return type.
44       * @return an unmodifiable list containing objects built from the given list of model builders
45       */
46      public static <T> List<T> buildImmutableCopy(List<? extends ModelBuilder> builderList) {
47          if (CollectionUtils.isEmpty(builderList)) {
48              return Collections.emptyList();
49          }
50          List<T> copy = new ArrayList<T>();
51          for (ModelBuilder builder : builderList) {
52              // since ModelBuilder is not parameterized, this code must assume that the appropriate type of object is built
53              @SuppressWarnings("unchecked")
54              T built = (T)builder.build();
55              copy.add(built);
56          }
57          return Collections.unmodifiableList(copy);
58      }
59  
60      @SuppressWarnings("unchecked")
61      public static <B> Set<B> buildImmutableCopy(Set<? extends ModelBuilder> toConvert) {
62          if (CollectionUtils.isEmpty(toConvert)) {
63              return Collections.emptySet();
64          } else {
65              Set<B> results = new HashSet<B>(toConvert.size());
66              for (ModelBuilder elem : toConvert) {
67                  results.add((B)elem.build());
68              }
69              return Collections.unmodifiableSet(results);
70          }
71      }
72  
73      /**
74       * Takes the given list and returns an unmodifiable copy of that list containing the same elements as the original
75       * list.  This method handles a null list being passed to it by returning an unmodifiable empty list.
76       *
77       * @param listToCopy the list to copy
78       * @param <T> the type of the elements in the given list
79       *
80       * @return an unmodifiable copy containing the same elements as the given list
81       */
82      public static <T> List<T> createImmutableCopy(List<T> listToCopy) {
83          if (CollectionUtils.isEmpty(listToCopy)) {
84              return Collections.emptyList();
85          }
86          return Collections.unmodifiableList(new ArrayList<T>(listToCopy));
87      }
88  
89      /**
90       * Takes the given set and returns an unmodifiable copy of that set containing the same elements as the original
91       * set.  This method handles a null set being passed to it by returning an unmodifiable empty set.
92       *
93       * @param setToCopy the set to copy
94       * @param <T> the type of the elements in the given set
95       *
96       * @return an unmodifiable copy containing the same elements as the given set
97       */
98      public static <T> Set<T> createImmutableCopy(Set<T> setToCopy) {
99          if (CollectionUtils.isEmpty(setToCopy)) {
100             return Collections.emptySet();
101         }
102         return Collections.unmodifiableSet(new HashSet<T>(setToCopy));
103     }
104 
105     /**
106      * Takes the given map and returns an unmodifiable copy of that map containing the same entries as the original
107      * map.  This method handles a null map being passed to it by returning an unmodifiable empty map.
108      *
109      * @param mapToCopy the map to copy
110      * @param <K, V> the type of the key and value elements in the given map
111      *
112      * @return an unmodifiable copy containing the same elements as the given set
113      */
114     public static <K, V> Map<K, V> createImmutableCopy(Map<K, V> mapToCopy) {
115         if (mapToCopy == null || mapToCopy.isEmpty()) {
116             return Collections.emptyMap();
117         }
118         return Collections.unmodifiableMap(new HashMap<K, V>(mapToCopy));
119     }
120 
121 	/**
122 	 * This method is useful for converting a List&lt;? extends BlahContract&gt; to a
123 	 * List&lt;Blah.Builder&gt;.  You'll just need to implement Transformer to use it.
124 	 *
125 	 * @param <A>
126 	 * @param <B>
127 	 * @param toConvert
128 	 * @param xform
129 	 * @return
130 	 */
131 	public static <A,B> List<B> transform(Collection<? extends A> toConvert, Transformer<A,B> xform) {
132 		if (CollectionUtils.isEmpty(toConvert)) {
133 			return new ArrayList<B>();
134 		} else {
135 			List<B> results = new ArrayList<B>(toConvert.size());
136 			for (A elem : toConvert) {
137 				results.add(xform.transform(elem));
138 			}
139 			return results;
140 		}
141 	}
142 
143     /**
144      * This method is useful for converting a Set&lt;? extends BlahContract&gt; to a
145      * Set&lt;Blah.Builder&gt;.  You'll just need to implement Transformer to use it.
146      *
147      * @param <A>
148      * @param <B>
149      * @param toConvert
150      * @param xform
151      * @return
152      */
153 	public static <A,B> Set<B> transformSet(Collection<? extends A> toConvert, Transformer<A,B> xform) {
154 		if (CollectionUtils.isEmpty(toConvert)) {
155 			return new HashSet<B>();
156 		} else {
157 			Set<B> results = new HashSet<B>(toConvert.size());
158 			for (A elem : toConvert) {
159 				results.add(xform.transform(elem));
160 			}
161 			return results;
162 		}
163 	}
164 
165 	public interface Transformer<A,B> {
166 		public B transform(A input);
167 	}
168 
169     private ModelObjectUtils() {
170         throw new UnsupportedOperationException("Do not call.");
171     }
172 
173 }