001/**
002 * Copyright 2005-2016 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 */
016package org.kuali.rice.kns.datadictionary;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.krad.bo.BusinessObject;
020import org.kuali.rice.krad.datadictionary.DataDictionary;
021import org.kuali.rice.krad.datadictionary.exception.AttributeValidationException;
022import org.kuali.rice.krad.datadictionary.exception.DuplicateEntryException;
023
024import java.util.ArrayList;
025import java.util.HashMap;
026import java.util.List;
027import 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
055public 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    /**
216summaryTitle 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}