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