View Javadoc

1   /**
2    * Copyright 2005-2013 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.data.metadata.impl;
17  
18  import java.beans.PropertyEditor;
19  import java.util.Collections;
20  import java.util.Set;
21  
22  import org.apache.commons.lang.StringUtils;
23  import org.kuali.rice.core.api.data.DataType;
24  import org.kuali.rice.krad.data.metadata.DataObjectAttribute;
25  import org.kuali.rice.krad.data.provider.annotation.UifDisplayHint;
26  import org.kuali.rice.krad.keyvalues.KeyValuesFinder;
27  
28  /**
29   * Base implementation class for attribute metadata for data object classes.
30   * 
31   * This implementation supports "chaining" for most attributes. That is, if the value for a property is defined locally,
32   * it will me used. If unset (null) it will, if there is an {@link #embeddedAttribute}, request it from that
33   * DataObjectAttribute. (This could be a recursive operation if multiple metadata providers are chained.)
34   * 
35   * If the value is unset and there is no embedded attribute, most methods will return a non-null default value.
36   * 
37   * @author Kuali Rice Team (rice.collab@kuali.org)
38   */
39  public class DataObjectAttributeImpl extends MetadataCommonBase implements DataObjectAttributeInternal {
40  	private static final long serialVersionUID = -5241499559388935579L;
41  	private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DataObjectAttributeImpl.class);
42  
43  	protected DataObjectAttribute embeddedAttribute;
44  
45  	protected Class<?> owningType;
46  
47  	// These are temporary placeholders for the source property from which a property was inherited when
48  	// it "lives" on a related object. E.g., accountType.codeAndDescription
49  	// After all metadata has been imported, this information will be used to "embed" the parent
50  	// DataObjectAttribute so that properties (E.g., label) are inherited from there
51  	protected Class<?> inheritedFromType;
52  	protected String inheritedFromAttributeName;
53  	protected String inheritedFromParentAttributeName;
54  	protected String displayAttributeName;
55  	protected Boolean caseInsensitive;
56  	protected Boolean forceUppercase;
57  	protected Boolean required;
58  	protected Boolean persisted;
59  	protected Boolean sensitive;
60  	protected Long maxLength;
61  	protected Long minLength;
62  	protected String validCharactersConstraintBeanName;
63  
64  	protected PropertyEditor propertyEditor;
65  	protected KeyValuesFinder validValues;
66  	protected DataType dataType = DataType.STRING;
67  	protected Class<?> type = String.class;
68  	
69  	protected Set<UifDisplayHint> displayHints;
70  
71  	@Override
72  	public String getDisplayAttributeName() {
73  		if (displayAttributeName != null) {
74  			return displayAttributeName;
75  		}
76  		if (embeddedAttribute != null) {
77  			return embeddedAttribute.getDisplayAttributeName();
78  		}
79  		return getName();
80  	}
81  
82  	public void setDisplayAttributeName(String displayAttributeName) {
83  		if (StringUtils.isBlank(displayAttributeName)) {
84  			displayAttributeName = null;
85  		}
86  		this.displayAttributeName = displayAttributeName;
87  	}
88  
89  	@Override
90  	public boolean isCaseInsensitive() {
91  		if (caseInsensitive != null) {
92  			return caseInsensitive;
93  		}
94  		if (embeddedAttribute != null) {
95  			return embeddedAttribute.isCaseInsensitive();
96  		}
97  		return false;
98  	}
99  
100 	public void setCaseInsensitive(boolean caseInsensitive) {
101 		this.caseInsensitive = caseInsensitive;
102 	}
103 
104 	@Override
105 	public boolean isForceUppercase() {
106 		if (forceUppercase != null) {
107 			return forceUppercase;
108 		}
109 		if (embeddedAttribute != null) {
110 			return embeddedAttribute.isForceUppercase();
111 		}
112 		return false;
113 	}
114 
115 	public void setForceUppercase(boolean forceUppercase) {
116 		this.forceUppercase = forceUppercase;
117 	}
118 
119 	@Override
120 	public PropertyEditor getPropertyEditor() {
121 		if (propertyEditor != null) {
122 			return propertyEditor;
123 		}
124 		if (embeddedAttribute != null) {
125 			return embeddedAttribute.getPropertyEditor();
126 		}
127 		return null;
128 	}
129 
130 	public void setPropertyEditor(PropertyEditor propertyEditor) {
131 		this.propertyEditor = propertyEditor;
132 	}
133 	@Override
134 	public KeyValuesFinder getValidValues() {
135 		if (validValues != null) {
136 			return validValues;
137 		}
138 		if (embeddedAttribute != null) {
139 			return embeddedAttribute.getValidValues();
140 		}
141 		return null;
142 	}
143 
144 	public void setValidValues(KeyValuesFinder validValues) {
145 		this.validValues = validValues;
146 	}
147 	@Override
148 	public DataType getDataType() {
149 		if (dataType != null) {
150 			return dataType;
151 		}
152 		if (embeddedAttribute != null) {
153 			return embeddedAttribute.getDataType();
154 		}
155 		return DataType.STRING;
156 	}
157 	public void setDataType(DataType dataType) {
158 		this.dataType = dataType;
159 	}
160 
161 	@Override
162 	public String toString() {
163 		StringBuilder builder = new StringBuilder();
164 		builder.append("DataObjectAttribute [");
165 		builder.append("name=").append(name);
166 		if (label != null) {
167 			builder.append(", ").append("label=").append(label);
168 		}
169 		if (backingObjectName != null) {
170 			builder.append(", ").append("backingObjectName=").append(backingObjectName);
171 		}
172 		if (dataType != null) {
173 			builder.append(", ").append("dataType=").append(dataType);
174 		}
175 		if (type != null) {
176 			builder.append(", ").append("type=").append(type.getName());
177 		}
178 		if (caseInsensitive != null) {
179 			builder.append(", ").append("caseInsensitive=").append(caseInsensitive);
180 		}
181 		if (propertyEditor != null) {
182 			builder.append(", ").append("propertyEditor=").append(propertyEditor);
183 		}
184 		if (sensitive != null && sensitive) {
185 			builder.append(", ").append("sensitive=").append(sensitive);
186 		}
187 		if (validValues != null) {
188 			builder.append(", ").append("validValues=").append(validValues);
189 		}
190 		if (inheritedFromType != null) {
191 			builder.append(", ").append("inheritedFromType=").append(inheritedFromType);
192 		}
193 		if (inheritedFromAttributeName != null) {
194 			builder.append(", ").append("inheritedFromAttributeName=").append(inheritedFromAttributeName);
195 		}
196 		builder.append(", ").append("mergeAction=").append(mergeAction);
197 		builder.append("]");
198 		return builder.toString();
199 	}
200 
201 	@Override
202 	public Long getMaxLength() {
203 		if (maxLength != null) {
204 			return maxLength;
205 		}
206 		if (embeddedAttribute != null) {
207 			return embeddedAttribute.getMaxLength();
208 		}
209 		return null;
210 	}
211 
212 	public void setMaxLength(Long maxLength) {
213 		this.maxLength = maxLength;
214 	}
215 
216 	@Override
217 	public DataObjectAttribute getEmbeddedAttribute() {
218 		return embeddedAttribute;
219 	}
220 
221 	@Override
222 	public void setEmbeddedAttribute(DataObjectAttribute embeddedAttribute) {
223 		// protect against embedding itself
224 		if (embeddedAttribute == this) {
225 			LOG.warn(
226 					"ERROR!!!!  Attempt to embed a DataObjectAttribute into itself.  You must really want a stack overflow!  Trace: ",
227 					new Throwable("Throw-away Throwable for tracing purposes."));
228 			return;
229 		}
230 		this.embeddedAttribute = embeddedAttribute;
231 		setEmbeddedCommonMetadata(embeddedAttribute);
232 	}
233 
234 	@Override
235 	public boolean isRequired() {
236 		if (required != null) {
237 			return required;
238 		}
239 		if (embeddedAttribute != null) {
240 			return embeddedAttribute.isRequired();
241 		}
242 		return false;
243 	}
244 
245 	public void setRequired(boolean required) {
246 		this.required = required;
247 	}
248 
249 	@Override
250 	public String getValidCharactersConstraintBeanName() {
251 		if (validCharactersConstraintBeanName != null) {
252 			return validCharactersConstraintBeanName;
253 		}
254 		if (embeddedAttribute != null) {
255 			return embeddedAttribute.getValidCharactersConstraintBeanName();
256 		}
257 		return validCharactersConstraintBeanName;
258 	}
259 
260 	public void setValidCharactersConstraintBeanName(String validCharactersConstraintBeanName) {
261 		this.validCharactersConstraintBeanName = validCharactersConstraintBeanName;
262 	}
263 
264 	@Override
265 	public Class<?> getOwningType() {
266 		if (owningType != null) {
267 			return owningType;
268 		}
269 		if (embeddedAttribute != null) {
270 			return embeddedAttribute.getOwningType();
271 		}
272 		return null;
273 	}
274 
275 	public void setOwningType(Class<?> owningType) {
276 		this.owningType = owningType;
277 	}
278 
279 	@Override
280 	public boolean isPersisted() {
281 		if (persisted != null) {
282 			return persisted;
283 		}
284 		if (embeddedAttribute != null) {
285 			return embeddedAttribute.isPersisted();
286 		}
287 		return true;
288 	}
289 
290 	public void setPersisted(boolean persisted) {
291 		this.persisted = persisted;
292 	}
293 
294 	public Class<?> getType() {
295 		return type;
296 	}
297 
298 	public void setType(Class<?> javaType) {
299 		this.type = javaType;
300 	}
301 
302 	@Override
303 	public Class<?> getInheritedFromType() {
304 		if (inheritedFromType != null) {
305 			return inheritedFromType;
306 		}
307 		if (embeddedAttribute != null) {
308 			return embeddedAttribute.getInheritedFromType();
309 		}
310 		return null;
311 	}
312 
313 	public void setInheritedFromType(Class<?> inheritedFromType) {
314 		this.inheritedFromType = inheritedFromType;
315 	}
316 
317 	@Override
318 	public String getInheritedFromAttributeName() {
319 		if (inheritedFromAttributeName != null) {
320 			return inheritedFromAttributeName;
321 		}
322 		if (embeddedAttribute != null) {
323 			return embeddedAttribute.getInheritedFromAttributeName();
324 		}
325 		return null;
326 	}
327 
328 	public void setInheritedFromAttributeName(String inheritedFromAttributeName) {
329 		this.inheritedFromAttributeName = inheritedFromAttributeName;
330 	}
331 
332 	@Override
333 	public String getInheritedFromParentAttributeName() {
334 		if (inheritedFromParentAttributeName != null) {
335 			return inheritedFromParentAttributeName;
336 		}
337 		if (embeddedAttribute != null) {
338 			return embeddedAttribute.getInheritedFromParentAttributeName();
339 		}
340 		return null;
341 	}
342 
343 	public void setInheritedFromParentAttributeName(String inheritedFromParentAttributeName) {
344 		this.inheritedFromParentAttributeName = inheritedFromParentAttributeName;
345 	}
346 
347 	@Override
348 	public boolean isInherited() {
349 		return getInheritedFromAttributeName() != null;
350 	}
351 
352 	@Override
353 	public DataObjectAttribute getOriginalDataObjectAttribute() {
354 		if (embeddedAttribute == null) {
355 			return this;
356 		}
357 		return embeddedAttribute.getOriginalDataObjectAttribute();
358 	}
359 
360 	@Override
361 	public Long getMinLength() {
362 		if (minLength != null) {
363 			return minLength;
364 		}
365 		if (embeddedAttribute != null) {
366 			return embeddedAttribute.getMinLength();
367 		}
368 		return null;
369 	}
370 
371 	public void setMinLength(Long minLength) {
372 		this.minLength = minLength;
373 	}
374 
375 	@Override
376 	public boolean isSensitive() {
377 		if (sensitive != null) {
378 			return sensitive;
379 		}
380 		if (embeddedAttribute != null) {
381 			return embeddedAttribute.isSensitive();
382 		}
383 		return false;
384 	}
385 
386 	public void setSensitive(boolean sensitive) {
387 		this.sensitive = sensitive;
388 	}
389 
390 	@Override
391 	public Set<UifDisplayHint> getDisplayHints() {
392 		if (displayHints != null) {
393 			return displayHints;
394 		}
395 		if (embeddedAttribute != null) {
396 			return embeddedAttribute.getDisplayHints();
397 		}
398 		return Collections.emptySet();
399 	}
400 
401 	public void setDisplayHints(Set<UifDisplayHint> displayHints) {
402 		this.displayHints = displayHints;
403 	}
404 }