001    /**
002     * Copyright 2005-2012 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.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/ecl2.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.rice.kns.datadictionary;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.kuali.rice.krad.bo.BusinessObject;
020    import org.kuali.rice.krad.datadictionary.DataDictionary;
021    import org.kuali.rice.krad.datadictionary.exception.AttributeValidationException;
022    import org.kuali.rice.krad.datadictionary.exception.DuplicateEntryException;
023    
024    import java.util.ArrayList;
025    import java.util.HashMap;
026    import java.util.List;
027    import java.util.Map;
028    
029    /**
030        The maintainableCollection element defines a set of data fields, nested
031        collections, summaryFields and duplicateIdentificationsFields.
032    
033        JSTL: maintainableCollection is a Map which is accessed using a
034        key of the name of the maintainableCollection.  Each entry
035        contains the following keys and values:
036            **Key**                **Value**
037            collection             true
038            name                   name of collection
039            dataObjectClass    name of collection class
040            
041    * name is the name of the collection
042    * dataObjectClass is the class name of the objects in the collection
043    * sourceClassName is the class name of the BO used in a lookup
044    * sourceAttributeName is the name of the attribute which returns the collection
045    * includeAddLine is true if the user is given the ability to add multiple lines.
046    * includeMultipleLookupLine whether to render a quickfinder icon for multiple value lookups on the collection.  Defaults to true
047    * summaryTitle is the label of the summary
048    * attributeToHighlightOnDuplicateKey is the name of an attribute to highlight
049        if two records in the collection are the same based on the
050        duplicateIdentificationFields element.
051    
052     *
053     */
054    @Deprecated
055    public class MaintainableCollectionDefinition extends MaintainableItemDefinition implements CollectionDefinitionI {
056        private static final long serialVersionUID = -5617868782623587053L;
057    
058            // logger
059        //private static Log LOG = LogFactory.getLog(MaintainableCollectionDefinition.class);
060    
061            protected Class<? extends BusinessObject> businessObjectClass;
062    
063        protected Class<? extends BusinessObject> sourceClassName;
064        protected String summaryTitle;
065        protected String attributeToHighlightOnDuplicateKey;
066    
067        protected boolean includeAddLine = true;
068        protected boolean includeMultipleLookupLine = true;
069        private boolean alwaysAllowCollectionDeletion = false;
070    
071        protected Map<String,MaintainableFieldDefinition> maintainableFieldMap = new HashMap<String, MaintainableFieldDefinition>();
072        protected Map<String,MaintainableCollectionDefinition> maintainableCollectionMap = new HashMap<String, MaintainableCollectionDefinition>();
073        protected Map<String,MaintainableFieldDefinition> summaryFieldMap = new HashMap<String, MaintainableFieldDefinition>();
074        protected Map<String,MaintainableFieldDefinition> duplicateIdentificationFieldMap = new HashMap<String, MaintainableFieldDefinition>();
075        protected List<MaintainableFieldDefinition> maintainableFields = new ArrayList<MaintainableFieldDefinition>();
076        protected List<MaintainableCollectionDefinition> maintainableCollections = new ArrayList<MaintainableCollectionDefinition>();
077        protected List<MaintainableFieldDefinition> summaryFields = new ArrayList<MaintainableFieldDefinition>();
078        protected List<MaintainableFieldDefinition> duplicateIdentificationFields = new ArrayList<MaintainableFieldDefinition>();
079    
080        public MaintainableCollectionDefinition() {}
081    
082    
083    
084        /**
085         * @return businessObjectClass
086         */
087        public Class<? extends BusinessObject> getBusinessObjectClass() {
088            return businessObjectClass;
089        }
090    
091        /**
092         * The BusinessObject class used for each row of this collection.
093         */
094        public void setBusinessObjectClass(Class<? extends BusinessObject> businessObjectClass) {
095            if (businessObjectClass == null) {
096                throw new IllegalArgumentException("invalid (null) dataObjectClass");
097            }
098    
099            this.businessObjectClass = businessObjectClass;
100        }
101    
102        /**
103         * @return Collection of all lookupField MaintainableFieldDefinitions associated with this MaintainableCollectionDefinition, in
104         *         the order in which they were added
105         */
106        public List<MaintainableFieldDefinition> getMaintainableFields() {
107            return maintainableFields;
108        }
109    
110        public List<? extends FieldDefinitionI> getFields() {
111            return maintainableFields;
112        }
113    
114        /**
115         * Directly validate simple fields, call completeValidation on Definition fields.
116         * 
117         * @see org.kuali.rice.krad.datadictionary.DataDictionaryDefinition#completeValidation(java.lang.Class, java.lang.Object)
118         */
119        public void completeValidation(Class rootBusinessObjectClass, Class otherBusinessObjectClass) {
120            if (!DataDictionary.isCollectionPropertyOf(rootBusinessObjectClass, getName())) {
121                throw new AttributeValidationException("unable to find collection named '" + getName() + "' in rootBusinessObjectClass '" + rootBusinessObjectClass.getName() + "' (" + "" + ")");
122            }
123    
124            if (dissallowDuplicateKey()) {
125                if (!DataDictionary.isPropertyOf(businessObjectClass, attributeToHighlightOnDuplicateKey)) {
126                    throw new AttributeValidationException("unable to find attribute named '" + attributeToHighlightOnDuplicateKey + "'in dataObjectClass '" + businessObjectClass.getName() + "' of collection '" + getName() + "' in rootBusinessObjectClass '" + rootBusinessObjectClass.getName() + "' (" + "" + ")");
127                }
128            }
129            
130            for (MaintainableFieldDefinition maintainableField : maintainableFields ) {
131                maintainableField.completeValidation(businessObjectClass, null);
132            }
133    
134            for (MaintainableCollectionDefinition maintainableCollection : maintainableCollections ) {
135                maintainableCollection.completeValidation(businessObjectClass, null);
136            }
137    
138    //        for (MaintainableFieldDefinition summaryField : summaryFields ) {
139    //            summaryField.completeValidation(dataObjectClass, null, validationCompletionUtils);
140    //        }
141    //        
142    //        for (MaintainableFieldDefinition identifierField : duplicateIdentificationFields) {
143    //            identifierField.completeValidation(dataObjectClass, null, validationCompletionUtils);
144    //        }
145        }
146    
147    
148        /**
149         * @see java.lang.Object#toString()
150         */
151        public String toString() {
152            return "MaintainableCollectionDefinition for " + getName();
153        }
154    
155    
156        public Class<? extends BusinessObject> getSourceClassName() {
157            return sourceClassName;
158        }
159    
160    
161        /** BusinessObject class which should be used for multiple value lookups for this collection.
162         */
163        public void setSourceClassName(Class<? extends BusinessObject> sourceClass) {
164            this.sourceClassName = sourceClass;
165        }
166    
167        public boolean getIncludeAddLine() {
168            return includeAddLine;
169        }
170    
171    
172        /** Control whether an "add" line should be included at the top of this collection. */
173        public void setIncludeAddLine(boolean includeAddLine) {
174            this.includeAddLine = includeAddLine;
175        }
176    
177        /**
178         * @return Collection of all lookupField MaintainableCollectionDefinitions associated with this
179         *         MaintainableCollectionDefinition, in the order in which they were added
180         */
181        public List<MaintainableCollectionDefinition> getMaintainableCollections() {
182            return maintainableCollections;
183        }
184    
185        public List<? extends CollectionDefinitionI> getCollections() {
186            return maintainableCollections;
187        }
188    
189        
190        /**
191         * @return Collection of all SummaryFieldDefinitions associated with this SummaryFieldDefinition, in the order in which they
192         *         were added
193         */
194        public List<? extends FieldDefinitionI> getSummaryFields() {
195            return summaryFields;
196        }
197    
198        public boolean hasSummaryField(String key) {
199            return summaryFieldMap.containsKey(key);
200        }
201    
202        public boolean isIncludeMultipleLookupLine() {
203            return includeMultipleLookupLine;
204        }
205    
206        /** Set whether the multiple lookup line (and link) should appear above this collection. */
207        public void setIncludeMultipleLookupLine(boolean includeMultipleLookupLine) {
208            this.includeMultipleLookupLine = includeMultipleLookupLine;
209        }
210    
211        public String getSummaryTitle() {
212            return summaryTitle;
213        }
214    
215        /**
216    summaryTitle is the label of the summary
217         */
218        public void setSummaryTitle(String overrideSummaryName) {
219            this.summaryTitle = overrideSummaryName;
220        }
221    
222    
223        public String getAttributeToHighlightOnDuplicateKey() {
224            return attributeToHighlightOnDuplicateKey;
225        }
226    
227        /**
228     attributeToHighlightOnDuplicateKey is the name of an attribute to highlight
229                                if two records in the collection are the same based on the
230                                duplicateIdentificationFields element.
231        */
232        public void setAttributeToHighlightOnDuplicateKey(String attributeToHighlightOnDuplicate) {
233            this.attributeToHighlightOnDuplicateKey = attributeToHighlightOnDuplicate;
234        }
235    
236        public boolean dissallowDuplicateKey() {
237            return StringUtils.isNotBlank(getAttributeToHighlightOnDuplicateKey());
238        }
239    
240        public List<MaintainableFieldDefinition> getDuplicateIdentificationFields() {
241            return duplicateIdentificationFields;
242        }
243    
244        /** The list of fields to include in this collection. */
245        public void setMaintainableFields(List<MaintainableFieldDefinition> maintainableFields) {
246            maintainableFieldMap.clear();
247            for ( MaintainableFieldDefinition maintainableField : maintainableFields ) {
248                if (maintainableField == null) {
249                    throw new IllegalArgumentException("invalid (null) maintainableField");
250                }
251    
252                String fieldName = maintainableField.getName();
253                if (maintainableFieldMap.containsKey(fieldName)) {
254                    throw new DuplicateEntryException("duplicate fieldName entry for field '" + fieldName + "'");
255                }
256    
257                maintainableFieldMap.put(fieldName, maintainableField);
258            }
259            this.maintainableFields = maintainableFields;
260        }
261    
262        /** The list of sub-collections to include in this collection. */
263        public void setMaintainableCollections(List<MaintainableCollectionDefinition> maintainableCollections) {
264            maintainableCollectionMap.clear();
265            for (MaintainableCollectionDefinition maintainableCollection : maintainableCollections ) {
266                if (maintainableCollection == null) {
267                    throw new IllegalArgumentException("invalid (null) maintainableCollection");
268                }
269    
270                String fieldName = maintainableCollection.getName();
271                if (maintainableCollectionMap.containsKey(fieldName)) {
272                    throw new DuplicateEntryException("duplicate fieldName entry for field '" + fieldName + "'");
273                }
274    
275                maintainableCollectionMap.put(fieldName, maintainableCollection);
276            }
277            this.maintainableCollections = maintainableCollections;
278        }
279    
280        /**
281    
282                            The summaryFields element defines a set of summaryField
283                            elements.
284         */
285        public void setSummaryFields(List<MaintainableFieldDefinition> summaryFields) {
286            summaryFieldMap.clear();
287            for (MaintainableFieldDefinition summaryField : summaryFields ) {
288                if (summaryField == null) {
289                    throw new IllegalArgumentException("invalid (null) summaryField");
290                }
291    
292                String fieldName = summaryField.getName();
293                if (summaryFieldMap.containsKey(fieldName)) {
294                    throw new DuplicateEntryException("duplicate fieldName entry for field '" + fieldName + "'");
295                }
296    
297                summaryFieldMap.put(fieldName, summaryField);
298            }
299            this.summaryFields = summaryFields;
300        }
301    
302        /**
303        The duplicateIdentificationFields element is used to define a set of
304        fields that will be used to determine if two records in the collection
305        are duplicates.
306        */
307        public void setDuplicateIdentificationFields(List<MaintainableFieldDefinition> duplicateIdentificationFields) {
308            duplicateIdentificationFieldMap.clear();
309            for (MaintainableFieldDefinition identifierField : duplicateIdentificationFields) {
310                if (identifierField == null) {
311                    throw new IllegalArgumentException("invalid (null) identifierField");
312                }
313    
314                String fieldName = identifierField.getName();
315                if (duplicateIdentificationFieldMap.containsKey(fieldName)) {
316                    throw new DuplicateEntryException("duplicate fieldName entry for field '" + fieldName + "'");
317                }
318    
319                duplicateIdentificationFieldMap.put(fieldName, identifierField);            
320            }
321            this.duplicateIdentificationFields = duplicateIdentificationFields;
322        }
323    
324    
325    
326            public boolean isAlwaysAllowCollectionDeletion() {
327                    return this.alwaysAllowCollectionDeletion;
328            }
329    
330    
331    
332            public void setAlwaysAllowCollectionDeletion(
333                            boolean alwaysAllowCollectionDeletion) {
334                    this.alwaysAllowCollectionDeletion = alwaysAllowCollectionDeletion;
335            }
336        
337    }