View Javadoc

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