001: /*
002: * Copyright 2005-2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.opensource.org/licenses/ecl1.php
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.kuali.core.datadictionary;
017:
018: import java.util.Collections;
019: import java.util.Iterator;
020: import java.util.LinkedHashMap;
021: import java.util.Map;
022:
023: import org.apache.commons.lang.StringUtils;
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026: import org.kuali.core.datadictionary.exception.CompletionException;
027: import org.kuali.core.datadictionary.exception.DuplicateEntryException;
028: import org.kuali.core.datadictionary.exception.OverrideEntryException;
029: import org.kuali.core.exceptions.ValidationException;
030:
031: /**
032: * Contains common properties and methods for data dictionary entries.
033: *
034: *
035: */
036: abstract public class DataDictionaryEntryBase implements
037: DataDictionaryEntry {
038: // logger
039: private static Log LOG = LogFactory
040: .getLog(DataDictionaryEntryBase.class);
041:
042: private Map<String, AttributeDefinition> attributes;
043: private Map<String, CollectionDefinition> collections;
044: private Map<String, RelationshipDefinition> relationships;
045:
046: public DataDictionaryEntryBase() {
047: this .attributes = new LinkedHashMap();
048: this .collections = new LinkedHashMap();
049: this .relationships = new LinkedHashMap();
050: }
051:
052: /* Returns the given entry class (bo class or document class) */
053: public abstract Class getEntryClass();
054:
055: /**
056: * Adds the given AttributeDefinition to the collection of AttributeDefinitions associated with this BusinessObjectEntry.
057: *
058: * @param attributeDefinition
059: */
060: public void addAttributeDefinition(
061: AttributeDefinition attributeDefinition) {
062: if (attributeDefinition == null) {
063: throw new IllegalArgumentException(
064: "invalid (null) attributeDefinition");
065: }
066: LOG.debug("calling addAttributeDefinition '"
067: + attributeDefinition.getName() + "'");
068:
069: String attributeName = attributeDefinition.getName();
070: if (StringUtils.isBlank(attributeName)) {
071: throw new ValidationException(
072: "invalid (blank) attributeName");
073: }
074:
075: if (collections.containsKey(attributeName)) {
076: throw new DuplicateEntryException("attribute '"
077: + attributeName
078: + "' already defined as a Collection for class '"
079: + getEntryClass().getName() + "'");
080: } else {
081: if (Boolean.TRUE.equals(attributeDefinition.getOverride())) {
082: if (!attributes.containsKey(attributeName)) {
083: throw new OverrideEntryException(
084: "overriding attribute '"
085: + attributeName
086: + "' doesn't have an attribute to override for class '"
087: + getEntryClass().getName() + "'");
088: }
089: } else {
090: if (attributes.containsKey(attributeName)) {
091: throw new DuplicateEntryException("attribute '"
092: + attributeName
093: + "' already defined for class '"
094: + getEntryClass().getName() + "'");
095: }
096: }
097: }
098:
099: this .attributes.put(attributeName, attributeDefinition);
100: }
101:
102: /**
103: * @param attributeName
104: * @return AttributeDefinition with the given name, or null if none with that name exists
105: */
106: final public AttributeDefinition getAttributeDefinition(
107: String attributeName) {
108: if (StringUtils.isBlank(attributeName)) {
109: throw new IllegalArgumentException(
110: "invalid (blank) attributeName");
111: }
112: LOG.debug("calling getAttributeDefinition '" + attributeName
113: + "'");
114:
115: return (AttributeDefinition) attributes.get(attributeName);
116: }
117:
118: /**
119: * @return a Map containing all AttributeDefinitions associated with this BusinessObjectEntry, indexed by attributeName
120: */
121: public Map getAttributes() {
122: LOG.debug("calling getAttributeDefinitions");
123:
124: return Collections.unmodifiableMap(this .attributes);
125: }
126:
127: /**
128: * Adds the given CollectionDefinition to the collection of CollectionDefinitions associated with this BusinessObjectEntry.
129: *
130: * @param collectionEntry
131: */
132: public void addCollectionDefinition(
133: CollectionDefinition collectionDefinition) {
134: if (collectionDefinition == null) {
135: throw new IllegalArgumentException(
136: "invalid (null) collectionDefinition");
137: }
138: LOG.debug("calling addCollectionDefinition '"
139: + collectionDefinition.getName() + "'");
140:
141: String collectionName = collectionDefinition.getName();
142: if (StringUtils.isBlank(collectionName)) {
143: throw new ValidationException(
144: "invalid (blank) collectionName");
145: }
146:
147: if (collections.containsKey(collectionName)) {
148: throw new DuplicateEntryException("collection '"
149: + collectionName + "' already defined for class '"
150: + getEntryClass().getName() + "'");
151: } else if (attributes.containsKey(collectionName)) {
152: throw new DuplicateEntryException("collection '"
153: + collectionName
154: + "' already defined as an Attribute for class '"
155: + getEntryClass().getName() + "'");
156: }
157:
158: this .collections.put(collectionName, collectionDefinition);
159: }
160:
161: /**
162: * @param collectionName
163: * @return CollectionDefinition with the given name, or null if none with that name exists
164: */
165: public CollectionDefinition getCollectionDefinition(
166: String collectionName) {
167: if (StringUtils.isBlank(collectionName)) {
168: throw new IllegalArgumentException(
169: "invalid (blank) collectionName");
170: }
171: LOG.debug("calling getCollectionDefinition '" + collectionName
172: + "'");
173:
174: return (CollectionDefinition) collections.get(collectionName);
175: }
176:
177: /**
178: * @return a Map containing all CollectionDefinitions associated with this BusinessObjectEntry, indexed by collectionName
179: */
180: public Map getCollections() {
181: return Collections.unmodifiableMap(this .collections);
182: }
183:
184: /**
185: * Locates the delegates putatively associated with all component AttributeReferences, if any, or dies trying.
186: *
187: * @param dataDictionary
188: * @throws CompletionException if an AttributeReference can't be expanded
189: */
190: public void expandAttributeReferences(
191: DataDictionary dataDictionary,
192: ValidationCompletionUtils validationCompletionUtils) {
193: for (Iterator i = attributes.entrySet().iterator(); i.hasNext();) {
194: Map.Entry e = (Map.Entry) i.next();
195:
196: AttributeDefinition attributeDefinition = (AttributeDefinition) e
197: .getValue();
198: if (attributeDefinition instanceof AttributeReferenceDefinition) {
199: AttributeReferenceDefinition attributeReferenceDefinition = (AttributeReferenceDefinition) attributeDefinition;
200:
201: attributeReferenceDefinition.assignDelegate(this ,
202: dataDictionary);
203: attributeReferenceDefinition
204: .completeDeferredValidation(getEntryClass(),
205: validationCompletionUtils);
206: }
207: }
208: }
209:
210: /**
211: * Adds the given RelationshipDefinition to the collection of RelationshipDefinitions associated with this BusinessObjectEntry.
212: *
213: * @param relationshipDefinition
214: */
215: public void addRelationshipDefinition(
216: RelationshipDefinition relationshipDefinition) {
217: if (relationshipDefinition == null) {
218: throw new IllegalArgumentException(
219: "invalid (null) relationshipDefinition");
220: }
221: LOG
222: .debug("calling addRelationshipDefinition '"
223: + relationshipDefinition
224: .getObjectAttributeName() + "'");
225:
226: String relationshipName = relationshipDefinition
227: .getObjectAttributeName();
228: if (StringUtils.isBlank(relationshipName)) {
229: throw new ValidationException(
230: "invalid (blank) relationshipName");
231: }
232:
233: this .relationships
234: .put(relationshipName, relationshipDefinition);
235: }
236:
237: /**
238: * @param relationshipName
239: * @return RelationshipDefinition with the given name, or null if none with that name exists
240: */
241: public RelationshipDefinition getRelationshipDefinition(
242: String relationshipName) {
243: if (StringUtils.isBlank(relationshipName)) {
244: throw new IllegalArgumentException(
245: "invalid (blank) relationshipName");
246: }
247: LOG.debug("calling getRelationshipDefinition '"
248: + relationshipName + "'");
249:
250: return (RelationshipDefinition) relationships
251: .get(relationshipName);
252: }
253:
254: /**
255: * @return a Map containing all RelationshipDefinitions associated with this BusinessObjectEntry, indexed by relationshipName
256: */
257: public Map<String, RelationshipDefinition> getRelationships() {
258: return Collections.unmodifiableMap(this .relationships);
259: }
260:
261: /**
262: * Directly validate simple fields, call completeValidation on Definition fields.
263: */
264: public void completeValidation(
265: ValidationCompletionUtils validationCompletionUtils) {
266:
267: for (Iterator i = attributes.entrySet().iterator(); i.hasNext();) {
268: Map.Entry e = (Map.Entry) i.next();
269:
270: AttributeDefinition attributeDefinition = (AttributeDefinition) e
271: .getValue();
272: attributeDefinition.completeValidation(getEntryClass(),
273: null, validationCompletionUtils);
274: }
275:
276: for (Iterator i = collections.entrySet().iterator(); i
277: .hasNext();) {
278: Map.Entry e = (Map.Entry) i.next();
279:
280: CollectionDefinition collectionDefinition = (CollectionDefinition) e
281: .getValue();
282: collectionDefinition.completeValidation(getEntryClass(),
283: null, validationCompletionUtils);
284: }
285:
286: for (Iterator i = relationships.entrySet().iterator(); i
287: .hasNext();) {
288: Map.Entry e = (Map.Entry) i.next();
289:
290: RelationshipDefinition relationshipDefinition = (RelationshipDefinition) e
291: .getValue();
292: relationshipDefinition.completeValidation(getEntryClass(),
293: null, validationCompletionUtils);
294: }
295: }
296: }
|