1 /**
2 * Copyright 2005-2015 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 }