Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
DataDictionaryEntryBase |
|
| 3.0625;3.062 |
1 | /* | |
2 | * Copyright 2005-2007 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.kns.datadictionary; | |
17 | ||
18 | import java.util.ArrayList; | |
19 | import java.util.LinkedHashMap; | |
20 | import java.util.List; | |
21 | import java.util.Map; | |
22 | import java.util.Set; | |
23 | ||
24 | import org.apache.commons.lang.StringUtils; | |
25 | import org.kuali.rice.kns.datadictionary.exception.DuplicateEntryException; | |
26 | import org.kuali.rice.kns.exception.ValidationException; | |
27 | import org.springframework.beans.factory.InitializingBean; | |
28 | ||
29 | /** | |
30 | * Contains common properties and methods for data dictionary entries. | |
31 | * | |
32 | * | |
33 | */ | |
34 | abstract public class DataDictionaryEntryBase implements DataDictionaryEntry, InitializingBean { | |
35 | ||
36 | protected List<AttributeDefinition> attributes; | |
37 | protected List<CollectionDefinition> collections; | |
38 | protected List<RelationshipDefinition> relationships; | |
39 | protected Map<String, AttributeDefinition> attributeMap; | |
40 | protected Map<String, CollectionDefinition> collectionMap; | |
41 | protected Map<String, RelationshipDefinition> relationshipMap; | |
42 | ||
43 | 0 | public DataDictionaryEntryBase() { |
44 | 0 | this.attributes = new ArrayList<AttributeDefinition>(); |
45 | 0 | this.collections = new ArrayList<CollectionDefinition>(); |
46 | 0 | this.relationships = new ArrayList<RelationshipDefinition>(); |
47 | 0 | this.attributeMap = new LinkedHashMap<String, AttributeDefinition>(); |
48 | 0 | this.collectionMap = new LinkedHashMap<String, CollectionDefinition>(); |
49 | 0 | this.relationshipMap = new LinkedHashMap<String, RelationshipDefinition>(); |
50 | 0 | } |
51 | ||
52 | /* Returns the given entry class (bo class or document class) */ | |
53 | public abstract Class getEntryClass(); | |
54 | ||
55 | /** | |
56 | * @param attributeName | |
57 | * @return AttributeDefinition with the given name, or null if none with that name exists | |
58 | */ | |
59 | public AttributeDefinition getAttributeDefinition(String attributeName) { | |
60 | 0 | if (StringUtils.isBlank(attributeName)) { |
61 | 0 | throw new IllegalArgumentException("invalid (blank) attributeName"); |
62 | } | |
63 | 0 | return (AttributeDefinition) attributeMap.get(attributeName); |
64 | } | |
65 | ||
66 | /** | |
67 | * @return a Map containing all AttributeDefinitions associated with this BusinessObjectEntry, indexed by attributeName | |
68 | */ | |
69 | public List<AttributeDefinition> getAttributes() { | |
70 | 0 | return this.attributes; |
71 | } | |
72 | ||
73 | /** | |
74 | * @param collectionName | |
75 | * @return CollectionDefinition with the given name, or null if none with that name exists | |
76 | */ | |
77 | public CollectionDefinition getCollectionDefinition(String collectionName) { | |
78 | 0 | if (StringUtils.isBlank(collectionName)) { |
79 | 0 | throw new IllegalArgumentException("invalid (blank) collectionName"); |
80 | } | |
81 | 0 | return (CollectionDefinition) collectionMap.get(collectionName); |
82 | } | |
83 | ||
84 | /** | |
85 | * @return a Map containing all CollectionDefinitions associated with this BusinessObjectEntry, indexed by collectionName | |
86 | */ | |
87 | public List<CollectionDefinition> getCollections() { | |
88 | 0 | return this.collections; |
89 | } | |
90 | ||
91 | /** | |
92 | * @param relationshipName | |
93 | * @return RelationshipDefinition with the given name, or null if none with that name exists | |
94 | */ | |
95 | public RelationshipDefinition getRelationshipDefinition(String relationshipName) { | |
96 | 0 | if (StringUtils.isBlank(relationshipName)) { |
97 | 0 | throw new IllegalArgumentException("invalid (blank) relationshipName"); |
98 | } | |
99 | 0 | return (RelationshipDefinition) relationshipMap.get(relationshipName); |
100 | } | |
101 | ||
102 | /** | |
103 | * @return a Map containing all RelationshipDefinitions associated with this BusinessObjectEntry, indexed by relationshipName | |
104 | */ | |
105 | public List<RelationshipDefinition> getRelationships() { | |
106 | 0 | return this.relationships; |
107 | } | |
108 | ||
109 | ||
110 | /** | |
111 | * Directly validate simple fields, call completeValidation on Definition fields. | |
112 | */ | |
113 | public void completeValidation() { | |
114 | ||
115 | 0 | for ( AttributeDefinition attributeDefinition : attributes ) { |
116 | 0 | attributeDefinition.completeValidation(getEntryClass(), null); |
117 | } | |
118 | ||
119 | 0 | for ( CollectionDefinition collectionDefinition : collections ) { |
120 | 0 | collectionDefinition.completeValidation(getEntryClass(), null); |
121 | } | |
122 | ||
123 | 0 | for ( RelationshipDefinition relationshipDefinition : relationships ) { |
124 | 0 | relationshipDefinition.completeValidation(getEntryClass(), null); |
125 | } | |
126 | 0 | } |
127 | ||
128 | /** | |
129 | The attributes element contains attribute | |
130 | elements. These define the specifications for business object fields. | |
131 | ||
132 | JSTL: attributes is a Map which is accessed by a key of "attributes". | |
133 | This map contains entries with the following keys: | |
134 | * attributeName of first attribute | |
135 | * attributeName of second attribute | |
136 | etc. | |
137 | ||
138 | The corresponding value for each entry is an attribute ExportMap. | |
139 | By the time the JSTL export happens, all attributeReferences will be | |
140 | indistinguishable from attributes. | |
141 | ||
142 | See AttributesMapBuilder.java | |
143 | ||
144 | The attribute element specifies the way in which a business object | |
145 | field appears on a screen for data entry or display purposes. These | |
146 | specifications include the following: | |
147 | * The title and formatting of the field | |
148 | * Descriptive information about the field | |
149 | * The edits used at time of data-entry | |
150 | ||
151 | DD: See AttributeDefinition.java | |
152 | ||
153 | JSTL: attribute is a Map which is accessed using a key which is the attributeName | |
154 | of an attribute. Each entry contains the following keys: | |
155 | * name (String) | |
156 | * forceUppercase (boolean String) | |
157 | * label (String) | |
158 | * shortLabel (String, copied from label if not present) | |
159 | * maxLength (String) | |
160 | * exclusiveMin (bigdecimal String) | |
161 | * exclusiveMax (bigdecimal String) | |
162 | * validationPattern (Map, optional) | |
163 | * required (boolean String) | |
164 | * control (Map) | |
165 | * summary (String) | |
166 | * description (String) | |
167 | * formatterClass (String, optional) | |
168 | * fullClassName (String) | |
169 | * displayWorkgroup(String, optional) | |
170 | * displayMaskClass(String, optional) | |
171 | ||
172 | See AttributesMapBuilder.java | |
173 | Note: exclusiveMax is mapped from the inclusiveMax element! | |
174 | The validation logic seems to be assuming inclusiveMax. | |
175 | * | |
176 | */ | |
177 | public void setAttributes(List<AttributeDefinition> attributes) { | |
178 | 0 | attributeMap.clear(); |
179 | 0 | for ( AttributeDefinition attribute : attributes ) { |
180 | 0 | if (attribute == null) { |
181 | 0 | throw new IllegalArgumentException("invalid (null) attributeDefinition"); |
182 | } | |
183 | 0 | String attributeName = attribute.getName(); |
184 | 0 | if (StringUtils.isBlank(attributeName)) { |
185 | 0 | throw new ValidationException("invalid (blank) attributeName"); |
186 | } | |
187 | ||
188 | 0 | if (attributeMap.containsKey(attributeName)) { |
189 | 0 | throw new DuplicateEntryException("collection '" + attributeName + "' already defined as an Attribute for class '" + getEntryClass().getName() + "'"); |
190 | 0 | } else if (collectionMap.containsKey(attributeName)) { |
191 | 0 | throw new DuplicateEntryException("attribute '" + attributeName + "' already defined as a Collection for class '" + getEntryClass().getName() + "'"); |
192 | } | |
193 | ||
194 | 0 | attributeMap.put(attributeName, attribute); |
195 | 0 | } |
196 | 0 | this.attributes = attributes; |
197 | 0 | } |
198 | ||
199 | /** | |
200 | The collections element contains collection elements. These define | |
201 | the lists of other business objects which are related to and | |
202 | defined in the business objects. | |
203 | ||
204 | JSTL: collections is a Map which is accessed by a key of "collections". | |
205 | This map contains entries with the following keys: | |
206 | * name of first collection | |
207 | * name of second collection | |
208 | etc. | |
209 | The corresponding value for each entry is a collection ExportMap. | |
210 | ||
211 | The collection element defines the name and description a | |
212 | list of objects related to the business object. | |
213 | ||
214 | DD: See CollectionDefinition.java. | |
215 | ||
216 | JSTL: collection is a Map which is accessed using a key which is the | |
217 | name of the collection. Each entry contains the following keys: | |
218 | * name (String) | |
219 | * label (String) | |
220 | * shortLabel (String, copied from label if missing) | |
221 | * elementLabel (String, copied from contained class if missing) | |
222 | * summary (String) | |
223 | * description (String) | |
224 | ||
225 | See CollectionsMapBuilder.java. | |
226 | */ | |
227 | public void setCollections(List<CollectionDefinition> collections) { | |
228 | 0 | collectionMap.clear(); |
229 | 0 | for ( CollectionDefinition collection : collections ) { |
230 | 0 | if (collection == null) { |
231 | 0 | throw new IllegalArgumentException("invalid (null) collectionDefinition"); |
232 | } | |
233 | 0 | String collectionName = collection.getName(); |
234 | 0 | if (StringUtils.isBlank(collectionName)) { |
235 | 0 | throw new ValidationException("invalid (blank) collectionName"); |
236 | } | |
237 | ||
238 | 0 | if (collectionMap.containsKey(collectionName)) { |
239 | 0 | throw new DuplicateEntryException("collection '" + collectionName + "' already defined for class '" + getEntryClass().getName() + "'"); |
240 | 0 | } else if (attributeMap.containsKey(collectionName)) { |
241 | 0 | throw new DuplicateEntryException("collection '" + collectionName + "' already defined as an Attribute for class '" + getEntryClass().getName() + "'"); |
242 | } | |
243 | ||
244 | 0 | collectionMap.put(collectionName, collection); |
245 | ||
246 | 0 | } |
247 | 0 | this.collections = collections; |
248 | 0 | } |
249 | ||
250 | /** | |
251 | The relationships element contains relationship elements. | |
252 | These are used to map attribute names to fields in a reference object. | |
253 | ||
254 | JSTL: relationships is a Map which is accessed by a key of "relationships". | |
255 | This map contains entries with the following keys: | |
256 | * objectAttributeName of first relationship | |
257 | * objectAttributeName of second relationship | |
258 | etc. | |
259 | The corresponding value for each entry is a relationship ExportMap. | |
260 | ||
261 | The relationship element defines how primitive attributes of this | |
262 | class can be used to retrieve an instance of some related Object instance | |
263 | DD: See RelationshipDefinition.java. | |
264 | ||
265 | JSTL: relationship is a Map which is accessed using a key which is the | |
266 | objectAttributeName of a relationship. The map contains a single entry | |
267 | with a key of "primitiveAttributes" and value which is an attributesMap ExportMap. | |
268 | ||
269 | The attributesMap ExportMap contains the following keys: | |
270 | * 0 (for first primitiveAttribute) | |
271 | * 1 (for second primitiveAttribute) | |
272 | etc. | |
273 | The corresponding value for each entry is an primitiveAttribute ExportMap | |
274 | which contains the following keys: | |
275 | * "sourceName" | |
276 | * "targetName" | |
277 | ||
278 | See RelationshipsMapBuilder.java. | |
279 | | |
280 | */ | |
281 | public void setRelationships(List<RelationshipDefinition> relationships) { | |
282 | 0 | this.relationships = relationships; |
283 | 0 | } |
284 | ||
285 | public Set<String> getCollectionNames() { | |
286 | 0 | return collectionMap.keySet(); |
287 | } | |
288 | ||
289 | public Set<String> getAttributeNames() { | |
290 | 0 | return attributeMap.keySet(); |
291 | } | |
292 | ||
293 | public Set<String> getRelationshipNames() { | |
294 | 0 | return relationshipMap.keySet(); |
295 | } | |
296 | ||
297 | /** | |
298 | * This overridden method ... | |
299 | * | |
300 | * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() | |
301 | */ | |
302 | public void afterPropertiesSet() throws Exception { | |
303 | 0 | if ( relationships != null ) { |
304 | 0 | relationshipMap.clear(); |
305 | 0 | for ( RelationshipDefinition relationship : relationships ) { |
306 | 0 | if (relationship == null) { |
307 | 0 | throw new IllegalArgumentException("invalid (null) relationshipDefinition"); |
308 | } | |
309 | 0 | String relationshipName = relationship.getObjectAttributeName(); |
310 | 0 | if (StringUtils.isBlank(relationshipName)) { |
311 | 0 | throw new ValidationException("invalid (blank) relationshipName"); |
312 | } | |
313 | 0 | relationship.setSourceClass(getEntryClass()); |
314 | 0 | relationshipMap.put(relationshipName, relationship); |
315 | 0 | } |
316 | } | |
317 | 0 | } |
318 | } |