View Javadoc
1   /**
2    * Copyright 2005-2015 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      @SuppressWarnings("unchecked")
74      public static <T> T buildImmutable(ModelBuilder builder) {
75          if (builder == null) {
76              return null;
77          }
78          return (T)builder.build();
79      }
80  
81      /**
82       * Takes the given list and returns an unmodifiable copy of that list containing the same elements as the original
83       * list.  This method handles a null list being passed to it by returning an unmodifiable empty list.
84       *
85       * @param listToCopy the list to copy
86       * @param <T> the type of the elements in the given list
87       *
88       * @return an unmodifiable copy containing the same elements as the given list
89       */
90      public static <T> List<T> createImmutableCopy(List<T> listToCopy) {
91          if (CollectionUtils.isEmpty(listToCopy)) {
92              return Collections.emptyList();
93          }
94          return Collections.unmodifiableList(new ArrayList<T>(listToCopy));
95      }
96  
97      /**
98       * Takes the given set and returns an unmodifiable copy of that set containing the same elements as the original
99       * set.  This method handles a null set being passed to it by returning an unmodifiable empty set.
100      *
101      * @param setToCopy the set to copy
102      * @param <T> the type of the elements in the given set
103      *
104      * @return an unmodifiable copy containing the same elements as the given set
105      */
106     public static <T> Set<T> createImmutableCopy(Set<T> setToCopy) {
107         if (CollectionUtils.isEmpty(setToCopy)) {
108             return Collections.emptySet();
109         }
110         return Collections.unmodifiableSet(new HashSet<T>(setToCopy));
111     }
112 
113     /**
114      * Takes the given map and returns an unmodifiable copy of that map containing the same entries as the original
115      * map.  This method handles a null map being passed to it by returning an unmodifiable empty map.
116      *
117      * @param mapToCopy the map to copy
118      * @param <K, V> the type of the key and value elements in the given map
119      *
120      * @return an unmodifiable copy containing the same elements as the given set
121      */
122     public static <K, V> Map<K, V> createImmutableCopy(Map<K, V> mapToCopy) {
123         if (mapToCopy == null || mapToCopy.isEmpty()) {
124             return Collections.emptyMap();
125         }
126         return Collections.unmodifiableMap(new HashMap<K, V>(mapToCopy));
127     }
128 
129 	/**
130 	 * This method is useful for converting a List&lt;? extends BlahContract&gt; to a
131 	 * List&lt;Blah.Builder&gt;.  You'll just need to implement Transformer to use it.
132 	 *
133 	 * @param <A>
134 	 * @param <B>
135 	 * @param toConvert
136 	 * @param xform
137 	 * @return
138 	 */
139 	public static <A,B> List<B> transform(Collection<? extends A> toConvert, Transformer<A,B> xform) {
140 		if (CollectionUtils.isEmpty(toConvert)) {
141 			return new ArrayList<B>();
142 		} else {
143 			List<B> results = new ArrayList<B>(toConvert.size());
144 			for (A elem : toConvert) {
145 				results.add(xform.transform(elem));
146 			}
147 			return results;
148 		}
149 	}
150 
151     /**
152      * This method is useful for converting a Set&lt;? extends BlahContract&gt; to a
153      * Set&lt;Blah.Builder&gt;.  You'll just need to implement Transformer to use it.
154      *
155      * @param <A>
156      * @param <B>
157      * @param toConvert
158      * @param xform
159      * @return
160      */
161 	public static <A,B> Set<B> transformSet(Collection<? extends A> toConvert, Transformer<A,B> xform) {
162 		if (CollectionUtils.isEmpty(toConvert)) {
163 			return new HashSet<B>();
164 		} else {
165 			Set<B> results = new HashSet<B>(toConvert.size());
166 			for (A elem : toConvert) {
167 				results.add(xform.transform(elem));
168 			}
169 			return results;
170 		}
171 	}
172 
173 	public interface Transformer<A,B> {
174 		public B transform(A input);
175 	}
176 
177     private ModelObjectUtils() {
178         throw new UnsupportedOperationException("Do not call.");
179     }
180 
181 }