Coverage Report - org.kuali.rice.kns.uif.container.ViewIndex
 
Classes in this File Line Coverage Branch Coverage Complexity
ViewIndex
0%
0/42
0%
0/20
2.2
 
 1  
 /*
 2  
  * Copyright 2007 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 1.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/ecl1.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.kns.uif.container;
 17  
 
 18  
 import java.io.Serializable;
 19  
 import java.util.HashMap;
 20  
 import java.util.HashSet;
 21  
 import java.util.List;
 22  
 import java.util.Map;
 23  
 import java.util.Set;
 24  
 
 25  
 import org.apache.commons.lang.StringUtils;
 26  
 import org.kuali.rice.kns.uif.core.BindingInfo;
 27  
 import org.kuali.rice.kns.uif.core.Component;
 28  
 import org.kuali.rice.kns.uif.field.AttributeField;
 29  
 import org.kuali.rice.kns.uif.field.Field;
 30  
 import org.kuali.rice.kns.uif.field.GroupField;
 31  
 import org.kuali.rice.kns.uif.util.ComponentUtils;
 32  
 
 33  
 /**
 34  
  * Holds field indexes of a <code>View</code> instance for retrieval
 35  
  * 
 36  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 37  
  */
 38  
 public class ViewIndex implements Serializable {
 39  
         private static final long serialVersionUID = 4700818801272201371L;
 40  
 
 41  
     private Map<String, Component> index;
 42  
         private Map<String, AttributeField> attributeFieldIndex;
 43  
         private Map<String, CollectionGroup> collectionsIndex;
 44  
 
 45  
     /**
 46  
      * Constructs new instance and performs indexing on View instance
 47  
      *
 48  
      * @param view - view instance to index
 49  
      */
 50  0
     public ViewIndex(View view) {
 51  0
         index(view);
 52  0
         }
 53  
 
 54  
         /**
 55  
          * Walks through the View tree and indexes all components found. All components
 56  
      * are indexed by their IDs with the special indexing done for certain components
 57  
          * 
 58  
          * <p>
 59  
          * <code>AttributeField</code> instances are indexed by the attribute path.
 60  
          * This is useful for retrieving the AttributeField based on the incoming
 61  
          * request parameter
 62  
          * </p>
 63  
          * 
 64  
          * <p>
 65  
          * <code>CollectionGroup</code> instances are indexed by the collection
 66  
          * path. This is useful for retrieving the CollectionGroup based on the
 67  
          * incoming request parameter
 68  
          * </p>
 69  
          */
 70  
         protected void index(View view) {
 71  0
         index = new HashMap<String, Component>();
 72  0
                 attributeFieldIndex = new HashMap<String, AttributeField>();
 73  0
         collectionsIndex = new HashMap<String, CollectionGroup>();
 74  
 
 75  0
         indexComponent(view);
 76  0
         }
 77  
 
 78  
     /**
 79  
      * Adds an entry to the main index for the given component. If the component
 80  
      * is of type <code>AttributeField</code> or <code>CollectionGroup</code> an
 81  
      * entry is created in the corresponding indexes for those types as well. Then
 82  
      * the #indexComponent method is called for each of the component's children
 83  
      *
 84  
      * <p>
 85  
      *   If the component is already contained in the indexes, it will be replaced
 86  
      * </p>
 87  
      *
 88  
      * @param component - component instance to index
 89  
      */
 90  
     public void indexComponent(Component component) {
 91  0
         if (component == null) {
 92  0
             return;
 93  
         }
 94  
 
 95  0
         index.put(component.getId(), component);
 96  
 
 97  0
         if (component instanceof AttributeField) {
 98  0
             AttributeField field = (AttributeField) component;
 99  0
             attributeFieldIndex.put(field.getBindingInfo().getBindingPath(), field);
 100  0
         } else if (component instanceof CollectionGroup) {
 101  0
             CollectionGroup collectionGroup = (CollectionGroup) component;
 102  0
             collectionsIndex.put(collectionGroup.getBindingInfo().getBindingPath(), collectionGroup);
 103  
         }
 104  
 
 105  0
         for (Component nestedComponent : component.getNestedComponents()) {
 106  0
             indexComponent(nestedComponent);
 107  
         }
 108  0
     }
 109  
 
 110  
     /**
 111  
      * Retrieves a <code>Component</code> from the view index by Id
 112  
      *
 113  
      * @param id - id for the component to retrieve
 114  
      * @return Component instance found in index, or null if no such component exists
 115  
      */
 116  
     public Component getComponentById(String id) {
 117  0
         return index.get(id);
 118  
     }
 119  
 
 120  
         /**
 121  
          * Retrieves a <code>AttributeField</code> instance from the index
 122  
          * 
 123  
          * @param attributePath
 124  
          *            - full path of the attribute (from the form)
 125  
          * @return AttributeField instance for the path or Null if not found
 126  
          */
 127  
         public AttributeField getAttributeFieldByPath(String attributePath) {
 128  0
                 return attributeFieldIndex.get(attributePath);
 129  
         }
 130  
 
 131  
         /**
 132  
          * Gets the Map that contains attribute field indexing information. The Map
 133  
          * key points to an attribute binding path, and the Map value is the
 134  
          * <code>AttributeField</code> instance
 135  
          * 
 136  
          * @return Map<String, AttributeField> attribute fields index map
 137  
          */
 138  
         public Map<String, AttributeField> getAttributeFieldIndex() {
 139  0
                 return this.attributeFieldIndex;
 140  
         }
 141  
 
 142  
         /**
 143  
          * Gets the Map that contains collection indexing information. The Map key
 144  
          * gives the binding path to the collection, and the Map value givens the
 145  
          * <code>CollectionGroup</code> instance
 146  
          * 
 147  
          * @return Map<String, CollectionGroup> collection index map
 148  
          */
 149  
         public Map<String, CollectionGroup> getCollectionsIndex() {
 150  0
                 return this.collectionsIndex;
 151  
         }
 152  
 
 153  
         /**
 154  
          * Retrieves a <code>CollectionGroup</code> instance from the index
 155  
          * 
 156  
          * @param collectionPath
 157  
          *            - full path of the collection (from the form)
 158  
          * @return CollectionGroup instance for the collection path or Null if not
 159  
          *         found
 160  
          */
 161  
         public CollectionGroup getCollectionGroupByPath(String collectionPath) {
 162  0
                 return collectionsIndex.get(collectionPath);
 163  
         }
 164  
 
 165  
     /**
 166  
      * Finds the attribute field based on the binding path. First, it tries
 167  
      * to find in the attribute collection. If not present there, search in the collection
 168  
      *
 169  
      * @param bindingInfo based on this this, attribute field will be return
 170  
      * @return AttributeField
 171  
      */
 172  
     public AttributeField getAttributeField(BindingInfo bindingInfo) {
 173  
         // Find in the attribute index first.
 174  0
         AttributeField attributeField = getAttributeFieldByPath(bindingInfo.getBindingPath());
 175  
 
 176  0
         if (attributeField == null) {
 177  
             // Lets search the collections (by collection's binding path)
 178  0
             String path = bindingInfo.getBindingObjectPath() + "." + bindingInfo.getBindByNamePrefix();
 179  
 
 180  0
             CollectionGroup collectionGroup = getCollectionGroupByPath(stripIndexesFromPropertyPath(path));
 181  0
             if (collectionGroup != null) {
 182  0
                 for (Component item : ((CollectionGroup) collectionGroup).getItems()) {
 183  0
                     if (item instanceof AttributeField) {
 184  0
                         if (StringUtils
 185  
                                 .equals(((AttributeField) item).getPropertyName(), bindingInfo.getBindingName())) {
 186  0
                             attributeField = (AttributeField) item;
 187  0
                             break;
 188  
                         }
 189  
                     }
 190  
                 }
 191  
             }
 192  
         }
 193  
 
 194  0
         return attributeField;
 195  
     }
 196  
         
 197  
         /**
 198  
      * Strips indexes from the property path. 
 199  
      * bo.fiscalOfficer.accounts[0].name returns bo.fiscalOfficer.accounts.name which can be used 
 200  
      * to find the components from the CollectionGroup index
 201  
      */
 202  
     private String stripIndexesFromPropertyPath(String propertyPath){
 203  0
             String returnValue = propertyPath;
 204  0
             String index = StringUtils.substringBetween(propertyPath, "[", "]");
 205  0
             if (StringUtils.isNotBlank(index)){
 206  0
                     returnValue = StringUtils.remove(propertyPath, "[" + index + "]");
 207  0
                     return stripIndexesFromPropertyPath(returnValue);
 208  
             }else{
 209  0
                     return returnValue;
 210  
             }
 211  
     }
 212  
 }