View Javadoc

1   /**
2    * Copyright 2005-2012 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.krad.util.documentserializer;
17  
18  import org.kuali.rice.krad.bo.BusinessObject;
19  import org.kuali.rice.krad.document.Document;
20  import org.kuali.rice.krad.util.documentserializer.PropertySerializabilityMetadata.PropertySerializability;
21  
22  import java.util.Collection;
23  
24  /**
25   * This abstract implementation provides a default implementation of {@link #determinePropertyType(Object)}, which should suffice for most
26   * use cases.
27   *
28   */
29  public abstract class PropertySerializabilityEvaluatorBase implements PropertySerializabilityEvaluator {
30  	
31      protected PropertySerializerTrie serializableProperties;
32      
33      @Override
34  	public void initializeEvaluatorForDocument(Document document){
35  		
36  	}
37  	
38      @Override
39  	public void initializeEvaluatorForDataObject(Object businessObject){
40  		
41  	}
42  	
43      /**
44       * @see org.kuali.rice.krad.util.documentserializer.PropertySerializabilityEvaluator#determinePropertyType(java.lang.Object)
45       */
46      @Override
47      public PropertyType determinePropertyType(Object propertyValue) {
48          if (propertyValue == null) {
49              return PropertyType.PRIMITIVE;
50          }
51          if (propertyValue instanceof BusinessObject) {
52              return PropertyType.BUSINESS_OBJECT;
53          }
54          if (propertyValue instanceof Collection) {
55              return PropertyType.COLLECTION;
56          }
57          return PropertyType.PRIMITIVE;
58      }
59      
60      /**
61       * Returns whether a child property of a given containing object should be serialized, based on the metadata provided in the data dictionary.
62       * 
63       * @see org.kuali.rice.krad.util.documentserializer.PropertySerializabilityEvaluator#isPropertySerializable(org.kuali.rice.krad.util.documentserializer.DocumentSerializationState, java.lang.Object, java.lang.String, java.lang.Object)
64       */
65      @Override
66      public boolean isPropertySerializable(SerializationState state, Object containingObject, String childPropertyName, Object childPropertyValue) {
67          boolean allPropertiesMatched = true;
68          
69          PropertySerializabilityMetadata metadata = serializableProperties.getRootPropertySerializibilityMetadata();
70          int i = 0;
71          for (; i < state.numPropertyElements(); i++) {
72              String nextPropertyName = state.getElementName(i);
73              PropertySerializabilityMetadata nextMetadata = metadata.getSerializableChildProperty(nextPropertyName);
74              
75              if (nextMetadata == null) {
76                  allPropertiesMatched = false;
77                  break;
78              }
79              else {
80                  // we've found the child... continue searching deeper
81                  metadata = nextMetadata;
82              }
83          }
84          
85          if (allPropertiesMatched) {
86              // complete match, so we determine if the child property is serializable
87              return evaluateCompleteMatch(state, containingObject, metadata, childPropertyName, childPropertyValue);
88          }
89          else {
90              // we have a partial match, so we have a different algorithm to determine serializibility
91              // partial matches can occur for primitives that contains nested primitives.  For example, if we have a member field named
92              // "amount" of type KualiDecimal, then the XML will have to look something like <amount><value>100.00</value></amount>.
93              // It is likely that "value" isn't specified in the serializability path, so we need to make inferences about whether "value" is 
94              // serializable
95              return evaluatePartialMatch(state, i, containingObject, metadata, childPropertyName, childPropertyValue);
96          }
97      }
98      
99      /**
100      * Evaluates whether a property is serializable when all properties in the serialization state have been matched up with the properties
101      * defined in the data dictionary.
102      * 
103      * @param state
104      * @param containingObject
105      * @param metadata
106      * @param childPropertyName
107      * @param childPropertyValue
108      * @return whether the child property is serializable
109      */
110     protected boolean evaluateCompleteMatch(SerializationState state, Object containingObject, PropertySerializabilityMetadata metadata, String childPropertyName, Object childPropertyValue) {
111         if (metadata.getPropertySerializability().equals(PropertySerializability.SERIALIZE_OBJECT_AND_ALL_PRIMITIVES)) {
112             if (isPrimitiveObject(childPropertyValue)) {
113                 return true;
114             }
115         }
116         return metadata.getSerializableChildProperty(childPropertyName) != null;
117     }
118     
119     /**
120      * Evaluates whether a property is serializable when only some of the properties in the serialization state have been matched up with the 
121      * serializable properties specified in the data dictionary.  This often occurs when we determine whether to serialize a primitive of a serialized primitive
122      * 
123      * @param state
124      * @param lastMatchedStateIndex the index of the state parameter that represents the last matched property
125      * @param containingObject the object containing the child property
126      * @param metadata metadata of the last matched property
127      * @param childPropertyName the name of the child property that we are going to determine whether it is serializable
128      * @param childPropertyValue the value of the child property that we are going to determine whether it is serializable
129      * @return whether the child property is serializable
130      */
131     protected boolean evaluatePartialMatch(SerializationState state, int lastMatchedStateIndex, Object containingObject, PropertySerializabilityMetadata metadata, String childPropertyName, Object childPropertyValue) {
132         
133         if (metadata.getPropertySerializability().equals(PropertySerializability.SERIALIZE_OBJECT_AND_ALL_PRIMITIVES)) {
134             return isPrimitiveObject(childPropertyValue);
135         }
136         return false;
137     }
138     
139     /**
140      * Whether the object represents a primitive
141      * 
142      * @param object
143      * @return
144      */
145     protected boolean isPrimitiveObject(Object object) {
146         return PropertyType.PRIMITIVE.equals(determinePropertyType(object));
147     }
148 
149 }