1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.kuali.rice.krad.datadictionary.validation;
17  
18  import java.beans.PropertyDescriptor;
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.kuali.rice.krad.datadictionary.AttributeDefinition;
23  import org.kuali.rice.krad.datadictionary.ComplexAttributeDefinition;
24  import org.kuali.rice.krad.datadictionary.DataDictionaryEntry;
25  import org.kuali.rice.krad.datadictionary.DataDictionaryEntryBase;
26  import org.kuali.rice.krad.datadictionary.exception.AttributeValidationException;
27  import org.kuali.rice.krad.datadictionary.validation.capability.Constrainable;
28  import org.springframework.beans.BeanWrapper;
29  import org.springframework.beans.BeanWrapperImpl;
30  import org.springframework.beans.NullValueInNestedPathException;
31  
32  
33  
34  
35  
36  
37  
38  public class DictionaryObjectAttributeValueReader extends BaseAttributeValueReader {
39  
40  	protected Object object;
41  	protected DataDictionaryEntry entry;
42  
43  	protected BeanWrapper beanWrapper;
44  	
45  	private String attributePath;
46  	
47  	public DictionaryObjectAttributeValueReader(Object object, String entryName, DataDictionaryEntry entry) {
48  		this.object = object;
49  		this.entry = entry;
50  		this.entryName = entryName;
51  
52  		if (object != null){
53  			beanWrapper = new BeanWrapperImpl(object);
54  		}		
55  	}
56  	
57  	public DictionaryObjectAttributeValueReader(Object object, String entryName, DataDictionaryEntry entry, String attributePath) {
58  		this(object, entryName, entry);
59  		this.attributePath = attributePath;
60  	}
61  	
62  	@Override
63  	public Constrainable getDefinition(String attrName) {
64  		return entry != null ? entry.getAttributeDefinition(attrName) : null;
65  	}
66  	
67  	@Override
68  	public List<Constrainable> getDefinitions() {
69  		if (entry instanceof DataDictionaryEntryBase) {
70  			DataDictionaryEntryBase entryBase = (DataDictionaryEntryBase)entry;
71  			List<Constrainable> definitions = new ArrayList<Constrainable>();
72  			List<AttributeDefinition> attributeDefinitions = entryBase.getAttributes();
73  			definitions.addAll(attributeDefinitions);
74  			return definitions;
75  		}
76  		
77  		return null;
78  	}
79  	
80  	@Override
81  	public Constrainable getEntry() {
82  		if (entry instanceof Constrainable)
83  			return (Constrainable) entry;
84  			
85  		return null;
86  	}
87  	
88  	@Override
89  	public String getLabel(String attrName) {
90  		AttributeDefinition attributeDefinition = entry != null ? entry.getAttributeDefinition(attrName) : null;
91  		return attributeDefinition != null ? attributeDefinition.getLabel()  : attrName;
92  	}
93  
94  	@Override
95  	public Object getObject() {
96  		return this.object;
97  	}
98  	
99  	@Override
100 	public String getPath() {
101 		String path = ValidationUtils.buildPath(attributePath, attributeName);
102 		return path != null ? path : "";
103 	}
104 
105 	@Override
106 	public Class<?> getType(String attrName) {
107 		PropertyDescriptor propertyDescriptor = beanWrapper.getPropertyDescriptor(attrName);
108 		
109 		return propertyDescriptor.getPropertyType();
110 	}
111 	
112 	@SuppressWarnings("unchecked")
113 	@Override
114 	public <X> X getValue() throws AttributeValidationException {
115 		Object value = getValue(attributeName);
116 		return (X) value;
117 	}
118 	
119 	@SuppressWarnings("unchecked")
120 	@Override
121 	public <X> X getValue(String attrName) throws AttributeValidationException {
122 		X attributeValue = null;
123 		
124 		Exception e = null;
125 		try {
126 			attributeValue = (X) beanWrapper.getPropertyValue(attrName);
127 
128 		} catch (IllegalArgumentException iae) {
129 			e = iae;
130 		} catch (NullValueInNestedPathException nvinp){
131 			
132 		}
133 		
134 		if (e != null)
135 			throw new AttributeValidationException("Unable to lookup attribute value by name (" + attrName + ") using introspection", e);
136 		
137 		
138 		
139 		
140 		
141 		
142 		
143 		
144 		
145 		
146 		return attributeValue;
147 	}
148 	
149 	
150 
151 
152 	public boolean isParentAttributeNull(){
153 	    boolean isParentNull = true;
154 	    
155 	    if (isNestedAttribute()){
156 	        String[] pathTokens = attributeName.split("\\.");
157 
158 	        isParentNull = false;
159             String parentPath = "";
160 	        for (int i=0; (i < pathTokens.length - 1) && !isParentNull;i++){
161                 parentPath += pathTokens[i];
162 	            isParentNull = beanWrapper.getPropertyValue(parentPath) == null;
163 	            parentPath += ".";
164 	        }
165 	    }
166 	    
167 	    return isParentNull;
168 	}
169 	
170 	public boolean isNestedAttribute(){
171 	    return (attributePath != null || attributeName.contains("."));
172 	}
173 	
174 	public DictionaryObjectAttributeValueReader clone(){
175 	    DictionaryObjectAttributeValueReader readerClone = 
176 	        new DictionaryObjectAttributeValueReader(this.object, this.entryName, this.entry, this.attributePath);
177 	    readerClone.setAttributeName(this.attributeName);
178 	    
179 	    
180 	    return readerClone;	    
181 	}
182 	
183 }