Coverage Report - org.kuali.rice.kns.uif.util.ComponentUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
ComponentUtils
0%
0/142
0%
0/84
3.273
 
 1  
 /*
 2  
  * Copyright 2007 The Kuali Foundation Licensed under the Educational Community
 3  
  * License, Version 1.0 (the "License"); you may not use this file except in
 4  
  * compliance with the License. You may obtain a copy of the License at
 5  
  * http://www.opensource.org/licenses/ecl1.php Unless required by applicable law
 6  
  * or agreed to in writing, software distributed under the License is
 7  
  * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 8  
  * KIND, either express or implied. See the License for the specific language
 9  
  * governing permissions and limitations under the License.
 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  
  * Utility class providing methods to help create and modify
 37  
  * <code>Component</code> instances
 38  
  * 
 39  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 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  
         // special container check so we pick up the layout manager
 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  
      * Performs sorting logic of the given list of <code>Ordered</code>
 290  
      * instances by its order property
 291  
      * <p>
 292  
      * Items list is sorted based on its order property. Lower order values are
 293  
      * placed higher in the list. If a item does not have a value assigned for
 294  
      * the order (or is equal to the default order of 0), it will be assigned
 295  
      * the a value based on the given order sequence integer. If two or more
 296  
      * items share the same order value, all but the last item found in the list
 297  
      * will be removed.
 298  
      * </p>
 299  
      * 
 300  
      * @param items
 301  
      * @param defaultOrderSequence
 302  
      * @return List<Ordered> sorted items
 303  
      * @see org.kuali.rice.kns.uif.Component.getOrder()
 304  
      * @see @see org.springframework.core.Ordered
 305  
      */
 306  
     public static List<? extends Ordered> sort(List<? extends Ordered> items, int defaultOrderSequence) {
 307  0
         List<Ordered> orderedItems = new ArrayList<Ordered>();
 308  
 
 309  
         // do replacement for items with the same order property value
 310  0
         Set<Integer> foundOrders = new HashSet<Integer>();
 311  
 
 312  
         // reverse the list, so items later in the list win
 313  0
         Collections.reverse(items);
 314  0
         for (Ordered component : items) {
 315  0
             int order = component.getOrder();
 316  
 
 317  
             // if order not set just add to list
 318  0
             if (order == 0) {
 319  0
                 orderedItems.add(component);
 320  
             }
 321  
             // check if the order value has been used already
 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  
         // now reverse the list back so we can assign defaults for items without
 329  
         // an order value
 330  0
         Collections.reverse(items);
 331  0
         for (Ordered component : items) {
 332  0
             int order = component.getOrder();
 333  
 
 334  
             // if order property not set assign default
 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  
         // now sort the list by its order property
 345  0
         Collections.sort(orderedItems, new OrderComparator());
 346  
 
 347  0
         return orderedItems;
 348  
     }
 349  
 
 350  
 }