View Javadoc

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      public DataDictionaryEntryBase() {
44          this.attributes = new ArrayList<AttributeDefinition>();
45          this.collections = new ArrayList<CollectionDefinition>();
46          this.relationships = new ArrayList<RelationshipDefinition>();
47          this.attributeMap = new LinkedHashMap<String, AttributeDefinition>();
48          this.collectionMap = new LinkedHashMap<String, CollectionDefinition>();
49          this.relationshipMap = new LinkedHashMap<String, RelationshipDefinition>();
50      }
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          if (StringUtils.isBlank(attributeName)) {
61              throw new IllegalArgumentException("invalid (blank) attributeName");
62          }
63          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          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          if (StringUtils.isBlank(collectionName)) {
79              throw new IllegalArgumentException("invalid (blank) collectionName");
80          }
81          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          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          if (StringUtils.isBlank(relationshipName)) {
97              throw new IllegalArgumentException("invalid (blank) relationshipName");
98          }
99          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         return this.relationships;
107     }
108 
109 
110     /**
111      * Directly validate simple fields, call completeValidation on Definition fields.
112      */
113     public void completeValidation() {
114         
115         for ( AttributeDefinition attributeDefinition : attributes ) {
116             attributeDefinition.completeValidation(getEntryClass(), null);
117         }
118 
119         for ( CollectionDefinition collectionDefinition : collections ) {
120             collectionDefinition.completeValidation(getEntryClass(), null);
121         }
122 
123         for ( RelationshipDefinition relationshipDefinition : relationships ) {
124             relationshipDefinition.completeValidation(getEntryClass(), null);
125         }
126     }
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         attributeMap.clear();
179         for ( AttributeDefinition attribute : attributes ) {
180             if (attribute == null) {
181                 throw new IllegalArgumentException("invalid (null) attributeDefinition");
182             }
183             String attributeName = attribute.getName();
184             if (StringUtils.isBlank(attributeName)) {
185                 throw new ValidationException("invalid (blank) attributeName");
186             }
187 
188             if (attributeMap.containsKey(attributeName)) {
189                 throw new DuplicateEntryException("collection '" + attributeName + "' already defined as an Attribute for class '" + getEntryClass().getName() + "'");
190             } else if (collectionMap.containsKey(attributeName)) {
191                 throw new DuplicateEntryException("attribute '" + attributeName + "' already defined as a Collection for class '" + getEntryClass().getName() + "'");
192             }
193 
194             attributeMap.put(attributeName, attribute);            
195         }
196         this.attributes = attributes;
197     }
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         collectionMap.clear();
229         for ( CollectionDefinition collection : collections ) {
230             if (collection == null) {
231                 throw new IllegalArgumentException("invalid (null) collectionDefinition");
232             }
233             String collectionName = collection.getName();
234             if (StringUtils.isBlank(collectionName)) {
235                 throw new ValidationException("invalid (blank) collectionName");
236             }
237 
238             if (collectionMap.containsKey(collectionName)) {
239                 throw new DuplicateEntryException("collection '" + collectionName + "' already defined for class '" + getEntryClass().getName() + "'");
240             } else if (attributeMap.containsKey(collectionName)) {
241                 throw new DuplicateEntryException("collection '" + collectionName + "' already defined as an Attribute for class '" + getEntryClass().getName() + "'");
242             }
243 
244             collectionMap.put(collectionName, collection);
245             
246         }
247         this.collections = collections;
248     }
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         this.relationships = relationships;
283     }
284 
285     public Set<String> getCollectionNames() {
286         return collectionMap.keySet();
287     }
288     
289     public Set<String> getAttributeNames() {
290         return attributeMap.keySet();
291     }
292 
293     public Set<String> getRelationshipNames() {
294         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     	if ( relationships != null ) {
304             relationshipMap.clear();
305             for ( RelationshipDefinition relationship : relationships ) {            
306                 if (relationship == null) {
307                     throw new IllegalArgumentException("invalid (null) relationshipDefinition");
308                 }
309                 String relationshipName = relationship.getObjectAttributeName();
310                 if (StringUtils.isBlank(relationshipName)) {
311                     throw new ValidationException("invalid (blank) relationshipName");
312                 }
313                 relationship.setSourceClass(getEntryClass());
314                 relationshipMap.put(relationshipName, relationship);
315             }
316     	}
317    	}
318 }