View Javadoc

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.krad.uif.util;
12  
13  import org.apache.commons.lang.StringUtils;
14  import org.kuali.rice.krad.uif.container.View;
15  import org.kuali.rice.krad.uif.core.BindingInfo;
16  import org.kuali.rice.krad.uif.field.AttributeField;
17  
18  import java.util.Collection;
19  import java.util.Map;
20  
21  /**
22   * Provides methods for getting property values, types, and paths within the
23   * context of a <code>View</code>
24   * 
25   * <p>
26   * The view provides a special map named 'abstractTypeClasses' that indicates
27   * concrete classes that should be used in place of abstract property types that
28   * are encountered on the object graph. This classes takes into account that map
29   * while dealing with properties. e.g. suppose we have propertyPath
30   * 'document.name' on the form, with the type of the document property set to
31   * the interface Document. Using class introspection we would get back the
32   * interface type for document and this would not be able to get the property
33   * type for name. Using the view map, we can replace document with a concrete
34   * class and then use it to get the name property
35   * </p>
36   * 
37   * @author Kuali Rice Team (rice.collab@kuali.org)
38   */
39  public class ViewModelUtils {
40  
41      public static Class<?> getPropertyType(View view, String propertyPath) {
42          Class<?> propertyType = null;
43  
44          if (StringUtils.isBlank(propertyPath)) {
45              return propertyType;
46          }
47  
48          // in case of partial match, holds the class that matched and the
49          // property so we can get by reflection
50          Class<?> modelClass = view.getFormClass();
51          String modelProperty = propertyPath;
52  
53          int bestMatchLength = 0;
54  
55          // removed collection indexes from path for matching
56          String flattenedPropertyPath = propertyPath.replaceAll("\\[.+\\]", "");
57  
58          // check if property path matches one of the modelClass entries
59          Map<String, Class<?>> modelClasses = view.getAbstractTypeClasses();
60          for (String path : modelClasses.keySet()) {
61              // full match
62              if (StringUtils.equals(path, flattenedPropertyPath)) {
63                  propertyType = modelClasses.get(path);
64                  break;
65              }
66  
67              // partial match
68              if (flattenedPropertyPath.startsWith(path) && (path.length() > bestMatchLength)) {
69                  bestMatchLength = path.length();
70  
71                  modelClass = modelClasses.get(path);
72                  modelProperty = StringUtils.removeStart(flattenedPropertyPath, path);
73                  modelProperty = StringUtils.removeStart(modelProperty, ".");
74              }
75          }
76  
77          // if full match not found, get type based on reflection
78          if (propertyType == null) {
79              propertyType = ObjectPropertyUtils.getPropertyType(modelClass, modelProperty);
80          }
81  
82          return propertyType;
83      }
84  
85      public static String getParentObjectPath(AttributeField field) {
86          String parentObjectPath = "";
87  
88          String objectPath = field.getBindingInfo().getBindingObjectPath();
89          String propertyPrefix = field.getBindingInfo().getBindByNamePrefix();
90  
91          if (!field.getBindingInfo().isBindToForm() && StringUtils.isNotBlank(objectPath)) {
92              parentObjectPath = objectPath;
93          }
94  
95          if (StringUtils.isNotBlank(propertyPrefix)) {
96              if (StringUtils.isNotBlank(parentObjectPath)) {
97                  parentObjectPath += ".";
98              }
99  
100             parentObjectPath += propertyPrefix;
101         }
102 
103         return parentObjectPath;
104     }
105 
106     public static Class<?> getParentObjectClassForMetadata(View view, AttributeField field) {
107         String parentObjectPath = getParentObjectPath(field);
108 
109         return getPropertyType(view, parentObjectPath);
110     }
111 
112     public static Object getParentObjectForMetadata(View view, Object model, AttributeField field) {
113         // default to model as parent
114         Object parentObject = model;
115 
116         String parentObjectPath = getParentObjectPath(field);
117         if (StringUtils.isNotBlank(parentObjectPath)) {
118             parentObject = ObjectPropertyUtils.getPropertyValue(model, parentObjectPath);
119 
120             // attempt to create new instance if parent is null or is a
121             // collection or map
122             if ((parentObject == null) || Collection.class.isAssignableFrom(parentObject.getClass())
123                     || Map.class.isAssignableFrom(parentObject.getClass())) {
124                 try {
125                     Class<?> parentObjectClass = getPropertyType(view, parentObjectPath);
126                     parentObject = parentObjectClass.newInstance();
127                 }
128                 catch (InstantiationException e) {
129                     // swallow exception and let null be returned
130                 }
131                 catch (IllegalAccessException e) {
132                     // swallow exception and let null be returned
133                 }
134             }
135         }
136 
137         return parentObject;
138     }
139     
140     public static Object getValue(View view, Object model, String propertyName, BindingInfo bindingInfo){
141         Object value = null;
142         if(bindingInfo == null && StringUtils.isNotBlank(propertyName)){
143             if(StringUtils.isNotBlank(view.getDefaultBindingObjectPath())){
144                 value = ObjectPropertyUtils.getPropertyValue(model, view.getDefaultBindingObjectPath() + "." + propertyName);
145             }
146             else{
147                 value = ObjectPropertyUtils.getPropertyValue(model, propertyName);
148             }
149             
150         }
151         else if(bindingInfo != null){
152             if(StringUtils.isNotBlank(bindingInfo.getBindingPath()) && !bindingInfo.getBindingPath().equals("null")){
153                 value = ObjectPropertyUtils.getPropertyValue(model, bindingInfo.getBindingPath());
154             }
155         }
156         return value;
157     }
158 
159 }