View Javadoc
1   /**
2    * Copyright 2005-2014 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.krad.datadictionary;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.krad.data.metadata.DataObjectCollection;
20  import org.kuali.rice.krad.datadictionary.parse.BeanTag;
21  import org.kuali.rice.krad.datadictionary.validation.capability.CollectionSizeConstrainable;
22  import org.kuali.rice.krad.datadictionary.validator.ValidationTrace;
23  
24  /**
25   * CollectionDefinition defines a single Collection attribute definition in the DataDictionary
26   *
27   * <p>It contains information relating to the display, validation,
28   * and general maintenance of a specific Collection attribute of an entry. It helps to provide meaningful labels for
29   * collections on a business or data object.
30   * It can be used to define collections that are generated at runtime and marked using @{@code Transient} in the
31   * containing
32   * business or data object class.</p>
33   *
34   * @author Kuali Rice Team (rice.collab@kuali.org)
35   */
36  @BeanTag(name = "collectionDefinition")
37  public class CollectionDefinition extends DataDictionaryDefinitionBase implements CollectionSizeConstrainable {
38      private static final long serialVersionUID = -2644072136271281041L;
39  
40      protected DataObjectCollection dataObjectCollection;
41  
42      protected String dataObjectClass;
43      protected String name;
44      protected String label;
45      protected String shortLabel;
46      protected String elementLabel;
47      protected String summary;
48      protected String description;
49      protected Integer minOccurs;
50      protected Integer maxOccurs;
51  
52      /**
53       * default constructor
54       */
55      public CollectionDefinition() {
56          //empty
57      }
58  
59      /**
60       * gets the name of the collection (collection property on owning data object)
61       *
62       * @return the collection name
63       */
64      @Override
65      public String getName() {
66          return name;
67      }
68  
69      /**
70       * sets the name of the collection
71       *
72       * @param name - the collection name
73       * @throws IllegalArgumentException if the name is blank
74       */
75      public void setName(String name) {
76          if (StringUtils.isBlank(name)) {
77              throw new IllegalArgumentException("invalid (blank) name");
78          }
79          this.name = name;
80      }
81  
82      /**
83       * gets the label
84       *
85       * @return the label
86       */
87      public String getLabel() {
88          if ( label != null ) {
89              return label;
90          }
91          // Otherwise, pull what we can from the metadata model
92          if ( getDataObjectCollection() != null ) {
93              return getDataObjectCollection().getLabel();
94          }
95          return "";
96      }
97  
98      /**
99       * sets the label
100      *
101      * @param label - a descriptive string to use for a label
102      */
103     public void setLabel(String label) {
104         if (StringUtils.isBlank(label)) {
105             throw new IllegalArgumentException("invalid (blank) label");
106         }
107         this.label = label;
108     }
109 
110     /**
111      * gets the short label
112      *
113      * @return the shortLabel, or the label if no shortLabel has been set
114      */
115     public String getShortLabel() {
116         if ( shortLabel != null ) {
117             return shortLabel;
118         }
119         if ( getDataObjectCollection() != null ) {
120             // if the short label was not explicitly set on the metadata but the label was on the DD, default to the DD label
121             if ( StringUtils.equals(getDataObjectCollection().getLabel(), getDataObjectCollection().getShortLabel())
122                     && label != null ) {
123                 return getLabel();
124             }
125             return getDataObjectCollection().getShortLabel();
126         }
127         return getLabel();
128     }
129 
130     /**
131      * sets the short label
132      *
133      * @param shortLabel - the short label
134      * @throws IllegalArgumentException when {@code shortLabel} is blank
135      */
136     public void setShortLabel(String shortLabel) {
137         if (StringUtils.isBlank(shortLabel)) {
138             throw new IllegalArgumentException("invalid (blank) shortLabel");
139         }
140         this.shortLabel = shortLabel;
141     }
142 
143     /**
144      * Gets the elementLabel attribute
145      *
146      * @return the element Label
147      */
148     public String getElementLabel() {
149         if ( elementLabel != null ) {
150             return elementLabel;
151         }
152         // Otherwise, pull what we can from the metadata model
153         if ( getDataObjectCollection() != null ) {
154             return getDataObjectCollection().getElementLabel();
155         }
156         return dataObjectClass;
157     }
158 
159     /**
160      * gets the element label
161      *
162      * <p>The elementLabel defines the name to be used for a single object within the collection.
163      * For example: "Address" may be the name
164      * of one object within the "Addresses" collection.</p>
165      */
166     public void setElementLabel(String elementLabel) {
167         this.elementLabel = elementLabel;
168     }
169 
170     /**
171      * gets the summary
172      *
173      * <p>summary element is used to provide a short description of the
174      * attribute or collection. This is designed to be used for help purposes.</p>
175      *
176      * @return the summary
177      */
178     public String getSummary() {
179         if ( summary != null ) {
180             return summary;
181         }
182         return "";
183     }
184 
185     /**
186      * gets the summary
187      */
188     public void setSummary(String summary) {
189         this.summary = summary;
190     }
191 
192     /**
193      * gets the description
194      *
195      * <p>The description element is used to provide a long description of the
196      * attribute or collection.  This is designed to be used for help purposes.</p>
197      *
198      * @return the description
199      */
200     public String getDescription() {
201         if ( description != null ) {
202             return description;
203         }
204         if ( getDataObjectCollection() != null ) {
205             return getDataObjectCollection().getDescription();
206         }
207         return "";
208     }
209 
210     /**
211      * sets the description
212      *
213      * @param description - the description to set
214      */
215     public void setDescription(String description) {
216         this.description = description;
217     }
218 
219     /**
220      * gets the data object class
221      *
222      * <p>This is the Java class type of the object contained in this collection</p>
223      *
224      * @return the dataObjectClass
225      */
226     public String getDataObjectClass() {
227         // we aren't going to allow this value to change over the life of the
228         // system, so we push it in directly if not set in the DD
229         // (E.g., the implementor may only be overriding the labels)
230         if ( dataObjectClass == null ) {
231             if ( getDataObjectCollection() != null ) {
232                 dataObjectClass = getDataObjectCollection().getRelatedType().getName();
233             }
234         }
235         return dataObjectClass;
236     }
237 
238     /**
239      * sets the data object class
240      *
241      * @param dataObjectClass the dataObjectClass to set
242      */
243     public void setDataObjectClass(String dataObjectClass) {
244         this.dataObjectClass = dataObjectClass;
245     }
246 
247     /**
248      * Directly validate simple fields, call completeValidation on Definition fields
249      *
250      * @see org.kuali.rice.krad.datadictionary.DataDictionaryEntry#completeValidation()
251      */
252     @Override
253     @Deprecated
254     public void completeValidation(Class rootBusinessObjectClass, Class otherBusinessObjectClass) {
255         completeValidation(rootBusinessObjectClass, otherBusinessObjectClass, new ValidationTrace());
256     }
257 
258     /**
259      * Directly validate simple fields, call completeValidation on Definition
260      * fields.
261      *
262      * @see org.kuali.rice.krad.datadictionary.DataDictionaryEntry#completeValidation(org.kuali.rice.krad.datadictionary.validator.ValidationTrace)
263      */
264     @Override
265     public void completeValidation(Class rootBusinessObjectClass, Class otherBusinessObjectClass,
266             ValidationTrace tracer) {
267         tracer.addBean(this.getClass().getSimpleName(), "Attribute: " + getName());
268         if (!DataDictionary.isCollectionPropertyOf(rootBusinessObjectClass, name)) {
269             String currentValues[] = {"property = " + getName(), "Class =" + rootBusinessObjectClass};
270             tracer.createError("Property is not collection property of the class", currentValues);
271         }
272     }
273 
274     /**
275      * @see org.kuali.rice.krad.datadictionary.validation.constraint.CollectionSizeConstraint#getMaximumNumberOfElements()
276      */
277     @Override
278     public Integer getMaximumNumberOfElements() {
279         return this.maxOccurs;
280     }
281 
282     /**
283      * @see org.kuali.rice.krad.datadictionary.validation.constraint.CollectionSizeConstraint#getMinimumNumberOfElements()
284      */
285     @Override
286     public Integer getMinimumNumberOfElements() {
287         if ( minOccurs != null ) {
288             return minOccurs;
289         }
290         if ( getDataObjectCollection() != null ) {
291             return getDataObjectCollection().getMinItems().intValue();
292         }
293         return null;
294     }
295 
296     /**
297      * gets the minimum amount of items in this collection
298      *
299      * @return the minOccurs
300      */
301     public Integer getMinOccurs() {
302         return this.minOccurs;
303     }
304 
305     /**
306      * gets the minimum amount of items in this collection
307      *
308      * @param minOccurs the minOccurs to set
309      */
310     public void setMinOccurs(Integer minOccurs) {
311         this.minOccurs = minOccurs;
312     }
313 
314     /**
315      * gets maximum amount of items in this collection
316      *
317      * @return the maxOccurs
318      */
319     public Integer getMaxOccurs() {
320         if ( maxOccurs != null ) {
321             return maxOccurs;
322         }
323         if ( getDataObjectCollection() != null ) {
324             return getDataObjectCollection().getMaxItems().intValue();
325         }
326         return null;
327     }
328 
329     /**
330      * sets maximum amount of items in this collection
331      *
332      * @param maxOccurs the maxOccurs to set
333      */
334     public void setMaxOccurs(Integer maxOccurs) {
335         this.maxOccurs = maxOccurs;
336     }
337 
338     public DataObjectCollection getDataObjectCollection() {
339         return this.dataObjectCollection;
340     }
341 
342     public void setDataObjectCollection(DataObjectCollection dataObjectCollection) {
343         this.dataObjectCollection = dataObjectCollection;
344     }
345 
346 }