1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
package org.kuali.rice.kns.uif.util; |
12 | |
|
13 | |
import java.beans.PropertyDescriptor; |
14 | |
import java.io.Serializable; |
15 | |
import java.util.ArrayList; |
16 | |
import java.util.Collections; |
17 | |
import java.util.HashSet; |
18 | |
import java.util.List; |
19 | |
import java.util.Set; |
20 | |
|
21 | |
import org.apache.commons.lang.StringUtils; |
22 | |
import org.kuali.rice.core.util.type.TypeUtils; |
23 | |
import org.kuali.rice.kns.uif.UifConstants; |
24 | |
import org.kuali.rice.kns.uif.container.Container; |
25 | |
import org.kuali.rice.kns.uif.core.Component; |
26 | |
import org.kuali.rice.kns.uif.core.DataBinding; |
27 | |
import org.kuali.rice.kns.uif.core.Ordered; |
28 | |
import org.kuali.rice.kns.uif.field.Field; |
29 | |
import org.kuali.rice.kns.uif.field.GroupField; |
30 | |
import org.kuali.rice.kns.uif.layout.LayoutManager; |
31 | |
import org.kuali.rice.kns.util.ObjectUtils; |
32 | |
import org.springframework.beans.BeanUtils; |
33 | |
import org.springframework.core.OrderComparator; |
34 | |
|
35 | |
|
36 | |
|
37 | |
|
38 | |
|
39 | |
|
40 | |
|
41 | 0 | public class ComponentUtils { |
42 | |
|
43 | |
public static <T extends Component> T copy(T component) { |
44 | 0 | return copyObject(component); |
45 | |
} |
46 | |
|
47 | |
protected static <T extends Object> T copyObject(T object) { |
48 | 0 | if (object == null) { |
49 | 0 | return null; |
50 | |
} |
51 | |
|
52 | 0 | T copy = null; |
53 | |
try { |
54 | 0 | copy = CloneUtils.deepClone(object); |
55 | |
} |
56 | 0 | catch (Exception e) { |
57 | 0 | throw new RuntimeException(e); |
58 | 0 | } |
59 | |
|
60 | 0 | if (copy instanceof Component) { |
61 | 0 | setNewIds((Component) copy); |
62 | |
} |
63 | |
|
64 | 0 | return copy; |
65 | |
} |
66 | |
|
67 | |
protected static Object getCopyPropertyValue(Set<String> propertiesForReferenceCopy, String propertyName, |
68 | |
Object propertyValue) { |
69 | 0 | if (propertyValue == null) { |
70 | 0 | return null; |
71 | |
} |
72 | |
|
73 | 0 | Object copyValue = propertyValue; |
74 | |
|
75 | 0 | Class<?> valuePropertyType = propertyValue.getClass(); |
76 | 0 | if (propertiesForReferenceCopy.contains(propertyName) || TypeUtils.isSimpleType(valuePropertyType) |
77 | |
|| TypeUtils.isClassClass(valuePropertyType)) { |
78 | 0 | return copyValue; |
79 | |
} |
80 | |
|
81 | 0 | if (Component.class.isAssignableFrom(valuePropertyType) |
82 | |
|| LayoutManager.class.isAssignableFrom(valuePropertyType)) { |
83 | 0 | copyValue = copyObject(propertyValue); |
84 | |
} |
85 | |
else { |
86 | 0 | copyValue = ObjectUtils.deepCopy((Serializable) propertyValue); |
87 | |
} |
88 | |
|
89 | 0 | return copyValue; |
90 | |
} |
91 | |
|
92 | |
@SuppressWarnings("unchecked") |
93 | |
protected static <T extends Object> T getNewInstance(T object) { |
94 | 0 | T copy = null; |
95 | |
try { |
96 | 0 | copy = (T) object.getClass().newInstance(); |
97 | |
} |
98 | 0 | catch (Exception e) { |
99 | 0 | throw new RuntimeException("Unable to create new instance of class: " + object.getClass()); |
100 | 0 | } |
101 | |
|
102 | 0 | return copy; |
103 | |
} |
104 | |
|
105 | |
public static <T extends Component> T copyField(T component, String addBindingPrefix) { |
106 | 0 | T copy = copy(component); |
107 | |
|
108 | 0 | if (copy instanceof DataBinding) { |
109 | 0 | prefixBindingPath((DataBinding) copy, addBindingPrefix); |
110 | |
} |
111 | |
|
112 | 0 | return copy; |
113 | |
} |
114 | |
|
115 | |
public static <T extends Field> List<T> copyFieldList(List<T> fields, String addBindingPrefix) { |
116 | 0 | List<T> copiedFieldList = copyFieldList(fields); |
117 | |
|
118 | 0 | prefixBindingPath(copiedFieldList, addBindingPrefix); |
119 | |
|
120 | 0 | return copiedFieldList; |
121 | |
} |
122 | |
|
123 | |
public static <T extends Field> List<T> copyFieldList(List<T> fields) { |
124 | 0 | List<T> copiedFieldList = new ArrayList<T>(); |
125 | |
|
126 | 0 | for (T field : fields) { |
127 | 0 | T copiedField = copy(field); |
128 | 0 | copiedFieldList.add(copiedField); |
129 | 0 | } |
130 | |
|
131 | 0 | return copiedFieldList; |
132 | |
} |
133 | |
|
134 | |
public static <T extends Component> List<T> copyComponentList(List<T> components) { |
135 | 0 | List<T> copiedComponentList = new ArrayList<T>(); |
136 | |
|
137 | 0 | for (T field : components) { |
138 | 0 | T copiedComponent = copy(field); |
139 | 0 | copiedComponentList.add(copiedComponent); |
140 | 0 | } |
141 | |
|
142 | 0 | return copiedComponentList; |
143 | |
} |
144 | |
|
145 | |
@SuppressWarnings("unchecked") |
146 | |
public static <T extends Component> List<T> getComponentsOfType(List<? extends Component> items, |
147 | |
Class<T> componentType) { |
148 | 0 | List<T> typeComponents = new ArrayList<T>(); |
149 | |
|
150 | 0 | for (Component component : items) { |
151 | 0 | if (componentType.isAssignableFrom(component.getClass())) { |
152 | 0 | typeComponents.add((T) component); |
153 | |
} |
154 | |
} |
155 | |
|
156 | 0 | return typeComponents; |
157 | |
} |
158 | |
|
159 | |
public static void prefixBindingPath(List<? extends Field> fields, String addBindingPrefix) { |
160 | 0 | for (Field field : fields) { |
161 | 0 | if (field instanceof DataBinding) { |
162 | 0 | prefixBindingPath((DataBinding) field, addBindingPrefix); |
163 | |
} |
164 | 0 | else if (field instanceof GroupField) { |
165 | 0 | List<Field> groupFields = getComponentsOfType(((GroupField) field).getItems(), Field.class); |
166 | 0 | prefixBindingPath(groupFields, addBindingPrefix); |
167 | 0 | } |
168 | |
} |
169 | 0 | } |
170 | |
|
171 | |
public static void prefixBindingPath(DataBinding field, String addBindingPrefix) { |
172 | 0 | String bindingPrefix = addBindingPrefix; |
173 | 0 | if (StringUtils.isNotBlank(field.getBindingInfo().getBindByNamePrefix())) { |
174 | 0 | bindingPrefix += "." + field.getBindingInfo().getBindByNamePrefix(); |
175 | |
} |
176 | 0 | field.getBindingInfo().setBindByNamePrefix(bindingPrefix); |
177 | 0 | } |
178 | |
|
179 | |
public static void updateIdsWithSuffix(List<? extends Component> components, String idSuffix) { |
180 | 0 | for (Component component : components) { |
181 | 0 | updateIdsWithSuffix(component, idSuffix); |
182 | |
} |
183 | 0 | } |
184 | |
|
185 | |
public static void updateIdsWithSuffix(Component component, String idSuffix) { |
186 | 0 | component.setId(component.getId() + idSuffix); |
187 | |
|
188 | 0 | if (Container.class.isAssignableFrom(component.getClass())) { |
189 | 0 | LayoutManager layoutManager = ((Container) component).getLayoutManager(); |
190 | 0 | layoutManager.setId(layoutManager.getId() + idSuffix); |
191 | |
} |
192 | |
|
193 | 0 | for (Component nested : component.getNestedComponents()) { |
194 | 0 | if (nested != null) { |
195 | 0 | updateIdsWithSuffix(nested, idSuffix); |
196 | |
} |
197 | |
} |
198 | 0 | } |
199 | |
|
200 | |
public static void setNewIds(Component component) { |
201 | 0 | component.setId(ComponentFactory.getNextId()); |
202 | |
|
203 | 0 | if (Container.class.isAssignableFrom(component.getClass())) { |
204 | 0 | LayoutManager layoutManager = ((Container) component).getLayoutManager(); |
205 | 0 | layoutManager.setId(ComponentFactory.getNextId()); |
206 | |
} |
207 | |
|
208 | 0 | for (Component nested : component.getNestedComponents()) { |
209 | 0 | if (nested != null) { |
210 | 0 | setNewIds(nested); |
211 | |
} |
212 | |
} |
213 | 0 | } |
214 | |
|
215 | |
public static void setComponentsPropertyDeep(List<? extends Component> components, String propertyPath, |
216 | |
Object propertyValue) { |
217 | 0 | for (Component component : components) { |
218 | 0 | setComponentPropertyDeep(component, propertyPath, propertyValue); |
219 | |
} |
220 | 0 | } |
221 | |
|
222 | |
public static void setComponentPropertyDeep(Component component, String propertyPath, Object propertyValue) { |
223 | 0 | ObjectPropertyUtils.setPropertyValue(component, propertyPath, propertyValue, true); |
224 | |
|
225 | 0 | for (Component nested : component.getNestedComponents()) { |
226 | 0 | if (nested != null) { |
227 | 0 | setComponentPropertyDeep(nested, propertyPath, propertyValue); |
228 | |
} |
229 | |
} |
230 | 0 | } |
231 | |
|
232 | |
public static List<String> getComponentPropertyNames(Class<? extends Component> componentClass) { |
233 | 0 | List<String> componentProperties = new ArrayList<String>(); |
234 | |
|
235 | 0 | PropertyDescriptor[] properties = BeanUtils.getPropertyDescriptors(componentClass); |
236 | 0 | for (int i = 0; i < properties.length; i++) { |
237 | 0 | PropertyDescriptor descriptor = properties[i]; |
238 | 0 | if (descriptor.getReadMethod() != null) { |
239 | 0 | componentProperties.add(descriptor.getName()); |
240 | |
} |
241 | |
} |
242 | |
|
243 | 0 | return componentProperties; |
244 | |
} |
245 | |
|
246 | |
public static void pushObjectToContext(List<? extends Component> components, String contextName, Object contextValue) { |
247 | 0 | for (Component component : components) { |
248 | 0 | pushObjectToContext(component, contextName, contextValue); |
249 | |
} |
250 | 0 | } |
251 | |
|
252 | |
public static void pushObjectToContext(Component component, String contextName, Object contextValue) { |
253 | 0 | if (component == null) { |
254 | 0 | return; |
255 | |
} |
256 | |
|
257 | 0 | component.pushObjectToContext(contextName, contextValue); |
258 | |
|
259 | |
|
260 | 0 | if (Container.class.isAssignableFrom(component.getClass())) { |
261 | 0 | LayoutManager layoutManager = ((Container) component).getLayoutManager(); |
262 | 0 | if (layoutManager != null) { |
263 | 0 | layoutManager.pushObjectToContext(contextName, contextValue); |
264 | |
|
265 | 0 | for (Component nestedComponent : layoutManager.getNestedComponents()) { |
266 | 0 | pushObjectToContext(nestedComponent, contextName, contextValue); |
267 | |
} |
268 | |
} |
269 | |
} |
270 | |
|
271 | 0 | for (Component nestedComponent : component.getNestedComponents()) { |
272 | 0 | pushObjectToContext(nestedComponent, contextName, contextValue); |
273 | |
} |
274 | 0 | } |
275 | |
|
276 | |
public static void updateContextsForLine(List<? extends Component> components, Object collectionLine, |
277 | |
int lineIndex) { |
278 | 0 | for (Component component : components) { |
279 | 0 | updateContextForLine(component, collectionLine, lineIndex); |
280 | |
} |
281 | 0 | } |
282 | |
|
283 | |
public static void updateContextForLine(Component component, Object collectionLine, int lineIndex) { |
284 | 0 | pushObjectToContext(component, UifConstants.ContextVariableNames.LINE, collectionLine); |
285 | 0 | pushObjectToContext(component, UifConstants.ContextVariableNames.INDEX, new Integer(lineIndex)); |
286 | 0 | } |
287 | |
|
288 | |
|
289 | |
|
290 | |
|
291 | |
|
292 | |
|
293 | |
|
294 | |
|
295 | |
|
296 | |
|
297 | |
|
298 | |
|
299 | |
|
300 | |
|
301 | |
|
302 | |
|
303 | |
|
304 | |
|
305 | |
|
306 | |
public static List<? extends Ordered> sort(List<? extends Ordered> items, int defaultOrderSequence) { |
307 | 0 | List<Ordered> orderedItems = new ArrayList<Ordered>(); |
308 | |
|
309 | |
|
310 | 0 | Set<Integer> foundOrders = new HashSet<Integer>(); |
311 | |
|
312 | |
|
313 | 0 | Collections.reverse(items); |
314 | 0 | for (Ordered component : items) { |
315 | 0 | int order = component.getOrder(); |
316 | |
|
317 | |
|
318 | 0 | if (order == 0) { |
319 | 0 | orderedItems.add(component); |
320 | |
} |
321 | |
|
322 | 0 | else if (!foundOrders.contains(new Integer(order))) { |
323 | 0 | orderedItems.add(component); |
324 | 0 | foundOrders.add(new Integer(order)); |
325 | |
} |
326 | 0 | } |
327 | |
|
328 | |
|
329 | |
|
330 | 0 | Collections.reverse(items); |
331 | 0 | for (Ordered component : items) { |
332 | 0 | int order = component.getOrder(); |
333 | |
|
334 | |
|
335 | 0 | if (order == 0) { |
336 | 0 | defaultOrderSequence++; |
337 | 0 | while (foundOrders.contains(new Integer(defaultOrderSequence))) { |
338 | 0 | defaultOrderSequence++; |
339 | |
} |
340 | 0 | component.setOrder(defaultOrderSequence); |
341 | |
} |
342 | 0 | } |
343 | |
|
344 | |
|
345 | 0 | Collections.sort(orderedItems, new OrderComparator()); |
346 | |
|
347 | 0 | return orderedItems; |
348 | |
} |
349 | |
|
350 | |
} |