001/** 002 * Copyright 2005-2018 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.krad.datadictionary; 017 018import org.apache.commons.lang.StringUtils; 019import org.kuali.rice.krad.data.metadata.DataObjectCollection; 020import org.kuali.rice.krad.datadictionary.parse.BeanTag; 021import org.kuali.rice.krad.datadictionary.validation.capability.CollectionSizeConstrainable; 022import org.kuali.rice.krad.datadictionary.validator.ValidationTrace; 023 024/** 025 * CollectionDefinition defines a single Collection attribute definition in the DataDictionary 026 * 027 * <p>It contains information relating to the display, validation, 028 * and general maintenance of a specific Collection attribute of an entry. It helps to provide meaningful labels for 029 * collections on a business or data object. 030 * It can be used to define collections that are generated at runtime and marked using @{@code Transient} in the 031 * containing 032 * business or data object class.</p> 033 * 034 * @author Kuali Rice Team (rice.collab@kuali.org) 035 */ 036@BeanTag(name = "collectionDefinition") 037public class CollectionDefinition extends DataDictionaryDefinitionBase implements CollectionSizeConstrainable { 038 private static final long serialVersionUID = -2644072136271281041L; 039 040 protected DataObjectCollection dataObjectCollection; 041 042 protected String dataObjectClass; 043 protected String name; 044 protected String label; 045 protected String shortLabel; 046 protected String elementLabel; 047 protected String summary; 048 protected String description; 049 protected Integer minOccurs; 050 protected Integer maxOccurs; 051 052 /** 053 * default constructor 054 */ 055 public CollectionDefinition() { 056 //empty 057 } 058 059 /** 060 * gets the name of the collection (collection property on owning data object) 061 * 062 * @return the collection name 063 */ 064 @Override 065 public String getName() { 066 return name; 067 } 068 069 /** 070 * sets the name of the collection 071 * 072 * @param name - the collection name 073 * @throws IllegalArgumentException if the name is blank 074 */ 075 public void setName(String name) { 076 if (StringUtils.isBlank(name)) { 077 throw new IllegalArgumentException("invalid (blank) name"); 078 } 079 this.name = name; 080 } 081 082 /** 083 * gets the label 084 * 085 * @return the label 086 */ 087 public String getLabel() { 088 if ( label != null ) { 089 return label; 090 } 091 // Otherwise, pull what we can from the metadata model 092 if ( getDataObjectCollection() != null ) { 093 return getDataObjectCollection().getLabel(); 094 } 095 return ""; 096 } 097 098 /** 099 * 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}