| 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 | } |