1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.datadictionary;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.krad.datadictionary.exception.DuplicateEntryException;
20 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
21 import org.kuali.rice.krad.datadictionary.state.StateMapping;
22 import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
23 import org.kuali.rice.krad.exception.ValidationException;
24 import org.springframework.beans.BeanUtils;
25 import org.springframework.beans.factory.InitializingBean;
26
27 import java.io.Serializable;
28 import java.util.ArrayList;
29 import java.util.LinkedHashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Set;
33
34
35
36
37
38
39 abstract public class DataDictionaryEntryBase extends DictionaryBeanBase implements DataDictionaryEntry, Serializable, InitializingBean {
40 protected List<AttributeDefinition> attributes;
41 protected List<ComplexAttributeDefinition> complexAttributes;
42 protected List<CollectionDefinition> collections;
43 protected List<RelationshipDefinition> relationships;
44 protected Map<String, AttributeDefinition> attributeMap;
45 protected Map<String, ComplexAttributeDefinition> complexAttributeMap;
46 protected Map<String, CollectionDefinition> collectionMap;
47 protected Map<String, RelationshipDefinition> relationshipMap;
48
49 protected StateMapping stateMapping;
50
51 public DataDictionaryEntryBase() {
52 this.attributes = new ArrayList<AttributeDefinition>();
53 this.complexAttributes = new ArrayList<ComplexAttributeDefinition>();
54 this.collections = new ArrayList<CollectionDefinition>();
55 this.relationships = new ArrayList<RelationshipDefinition>();
56 this.attributeMap = new LinkedHashMap<String, AttributeDefinition>();
57 this.complexAttributeMap = new LinkedHashMap<String, ComplexAttributeDefinition>();
58 this.collectionMap = new LinkedHashMap<String, CollectionDefinition>();
59 this.relationshipMap = new LinkedHashMap<String, RelationshipDefinition>();
60 }
61
62
63 public abstract Class<?> getEntryClass();
64
65
66
67
68
69 public AttributeDefinition getAttributeDefinition(String attributeName) {
70 if (StringUtils.isBlank(attributeName)) {
71 throw new IllegalArgumentException("invalid (blank) attributeName");
72 }
73 return attributeMap.get(attributeName);
74 }
75
76
77
78
79
80 @BeanTagAttribute(name = "attributes", type = BeanTagAttribute.AttributeType.LISTBEAN)
81 public List<AttributeDefinition> getAttributes() {
82 return this.attributes;
83 }
84
85
86
87
88 public List<ComplexAttributeDefinition> getComplexAttributes() {
89 return this.complexAttributes;
90 }
91
92
93
94
95 public void setComplexAttributes(List<ComplexAttributeDefinition> complexAttributes) {
96 complexAttributeMap.clear();
97 for (ComplexAttributeDefinition complexAttribute : complexAttributes) {
98 if (complexAttribute == null) {
99 throw new IllegalArgumentException("invalid (null) complexAttributeDefinition");
100 }
101 String complexAttributeName = complexAttribute.getName();
102 if (StringUtils.isBlank(complexAttributeName)) {
103 throw new ValidationException("invalid (blank) collectionName");
104 }
105
106 if (complexAttributeMap.containsKey(complexAttribute)) {
107 throw new DuplicateEntryException("complex attribute '"
108 + complexAttribute
109 + "' already defined as an complex attribute for class '"
110 + getEntryClass().getName()
111 + "'");
112 } else if (collectionMap.containsKey(complexAttributeName)) {
113 throw new DuplicateEntryException("complex attribute '"
114 + complexAttributeName
115 + "' already defined as a Collection for class '"
116 + getEntryClass().getName()
117 + "'");
118 } else if (attributeMap.containsKey(complexAttributeName)) {
119 throw new DuplicateEntryException("complex attribute '"
120 + complexAttributeName
121 + "' already defined as an Attribute for class '"
122 + getEntryClass().getName()
123 + "'");
124 }
125
126 complexAttributeMap.put(complexAttributeName, complexAttribute);
127
128 }
129
130 this.complexAttributes = complexAttributes;
131 }
132
133
134
135
136
137 public CollectionDefinition getCollectionDefinition(String collectionName) {
138 if (StringUtils.isBlank(collectionName)) {
139 throw new IllegalArgumentException("invalid (blank) collectionName");
140 }
141 return collectionMap.get(collectionName);
142 }
143
144
145
146
147
148 @BeanTagAttribute(name = "collections", type = BeanTagAttribute.AttributeType.LISTBEAN)
149 public List<CollectionDefinition> getCollections() {
150 return this.collections;
151 }
152
153
154
155
156
157 public RelationshipDefinition getRelationshipDefinition(String relationshipName) {
158 if (StringUtils.isBlank(relationshipName)) {
159 throw new IllegalArgumentException("invalid (blank) relationshipName");
160 }
161 return relationshipMap.get(relationshipName);
162 }
163
164
165
166
167
168 @BeanTagAttribute(name = "relationships", type = BeanTagAttribute.AttributeType.LISTBEAN)
169 public List<RelationshipDefinition> getRelationships() {
170 return this.relationships;
171 }
172
173
174
175
176 public void completeValidation() {
177
178 for (AttributeDefinition attributeDefinition : attributes) {
179 attributeDefinition.completeValidation(getEntryClass(), null);
180 }
181
182 for (CollectionDefinition collectionDefinition : collections) {
183 collectionDefinition.completeValidation(getEntryClass(), null);
184 }
185
186 for (RelationshipDefinition relationshipDefinition : relationships) {
187 relationshipDefinition.completeValidation(getEntryClass(), null);
188 }
189 }
190
191
192
193
194
195
196
197 public void completeValidation(ValidationTrace tracer) {
198 for (AttributeDefinition definition : getAttributes()) {
199 definition.completeValidation(getEntryClass(), null, tracer.getCopy());
200 }
201 for (CollectionDefinition definition : getCollections()) {
202 definition.completeValidation(getEntryClass(), null, tracer.getCopy());
203 }
204 for (RelationshipDefinition definition : getRelationships()) {
205 definition.completeValidation(getEntryClass(), null, tracer.getCopy());
206 }
207 }
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257 public void setAttributes(List<AttributeDefinition> attributes) {
258 attributeMap.clear();
259 for (AttributeDefinition attribute : attributes) {
260 if (attribute == null) {
261 throw new IllegalArgumentException("invalid (null) attributeDefinition");
262 }
263 String attributeName = attribute.getName();
264 if (StringUtils.isBlank(attributeName)) {
265 throw new ValidationException("invalid (blank) attributeName");
266 }
267
268 if (attributeMap.containsKey(attributeName)) {
269 throw new DuplicateEntryException("attribute '"
270 + attributeName
271 + "' already defined as an Attribute for class '"
272 + getEntryClass().getName()
273 + "'");
274 } else if (collectionMap.containsKey(attributeName)) {
275 throw new DuplicateEntryException("attribute '"
276 + attributeName
277 + "' already defined as a Collection for class '"
278 + getEntryClass().getName()
279 + "'");
280 } else if (complexAttributeMap.containsKey(attributeName)) {
281 throw new DuplicateEntryException("attribute '"
282 + attributeName
283 + "' already defined as an Complex Attribute for class '"
284 + getEntryClass().getName()
285 + "'");
286 }
287 attributeMap.put(attributeName, attribute);
288 }
289 this.attributes = attributes;
290 }
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320 public void setCollections(List<CollectionDefinition> collections) {
321 collectionMap.clear();
322 for (CollectionDefinition collection : collections) {
323 if (collection == null) {
324 throw new IllegalArgumentException("invalid (null) collectionDefinition");
325 }
326 String collectionName = collection.getName();
327 if (StringUtils.isBlank(collectionName)) {
328 throw new ValidationException("invalid (blank) collectionName");
329 }
330
331 if (collectionMap.containsKey(collectionName)) {
332 throw new DuplicateEntryException("collection '"
333 + collectionName
334 + "' already defined for class '"
335 + getEntryClass().getName()
336 + "'");
337 } else if (attributeMap.containsKey(collectionName)) {
338 throw new DuplicateEntryException("collection '"
339 + collectionName
340 + "' already defined as an Attribute for class '"
341 + getEntryClass().getName()
342 + "'");
343 } else if (complexAttributeMap.containsKey(collectionName)) {
344 throw new DuplicateEntryException("collection '"
345 + collectionName
346 + "' already defined as Complex Attribute for class '"
347 + getEntryClass().getName()
348 + "'");
349 }
350
351 collectionMap.put(collectionName, collection);
352
353 }
354 this.collections = collections;
355 }
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387 public void setRelationships(List<RelationshipDefinition> relationships) {
388 this.relationships = relationships;
389 }
390
391 public Set<String> getCollectionNames() {
392 return collectionMap.keySet();
393 }
394
395 public Set<String> getAttributeNames() {
396 return attributeMap.keySet();
397 }
398
399 public Set<String> getRelationshipNames() {
400 return relationshipMap.keySet();
401 }
402
403
404
405
406 public void afterPropertiesSet() throws Exception {
407 if (relationships != null) {
408 relationshipMap.clear();
409 for (RelationshipDefinition relationship : relationships) {
410 if (relationship == null) {
411 throw new IllegalArgumentException("invalid (null) relationshipDefinition");
412 }
413 String relationshipName = relationship.getObjectAttributeName();
414 if (StringUtils.isBlank(relationshipName)) {
415 throw new ValidationException("invalid (blank) relationshipName");
416 }
417 relationship.setSourceClass(getEntryClass());
418 relationshipMap.put(relationshipName, relationship);
419 }
420 }
421
422
423 if (complexAttributes != null) {
424 for (ComplexAttributeDefinition complexAttribute : complexAttributes) {
425 addNestedAttributes(complexAttribute, complexAttribute.getName());
426 }
427 }
428 }
429
430
431
432
433
434
435
436 private void addNestedAttributes(ComplexAttributeDefinition complexAttribute, String attrPath) {
437 DataDictionaryEntryBase dataDictionaryEntry = (DataDictionaryEntryBase) complexAttribute.getDataObjectEntry();
438
439
440 for (AttributeDefinition attribute : dataDictionaryEntry.getAttributes()) {
441 String nestedAttributeName = attrPath + "." + attribute.getName();
442 AttributeDefinition nestedAttribute = copyAttributeDefinition(attribute);
443 nestedAttribute.setName(nestedAttributeName);
444
445 if (!attributeMap.containsKey(nestedAttributeName)) {
446 this.attributes.add(nestedAttribute);
447 this.attributeMap.put(nestedAttributeName, nestedAttribute);
448 }
449 }
450
451
452 List<ComplexAttributeDefinition> nestedComplexAttributes = dataDictionaryEntry.getComplexAttributes();
453 if (nestedComplexAttributes != null) {
454 for (ComplexAttributeDefinition nestedComplexAttribute : nestedComplexAttributes) {
455 addNestedAttributes(nestedComplexAttribute, attrPath + "." + nestedComplexAttribute.getName());
456 }
457 }
458 }
459
460
461
462
463
464
465
466 private AttributeDefinition copyAttributeDefinition(AttributeDefinition attrDefToCopy) {
467 AttributeDefinition attrDefCopy = new AttributeDefinition();
468
469 try {
470 BeanUtils.copyProperties(attrDefToCopy, attrDefCopy, new String[]{"formatterClass"});
471
472
473 attrDefCopy.setRequired(attrDefToCopy.isRequired());
474
475 } catch (Exception e) {
476 e.printStackTrace();
477 }
478
479 return attrDefCopy;
480 }
481
482
483
484
485 @BeanTagAttribute(name = "stateMapping", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
486 public StateMapping getStateMapping() {
487 return stateMapping;
488 }
489
490
491
492
493 public void setStateMapping(StateMapping stateMapping) {
494 this.stateMapping = stateMapping;
495 }
496 }