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.krms.api.repository.type; 017 018import org.apache.commons.lang.StringUtils; 019import org.kuali.rice.core.api.CoreConstants; 020import org.kuali.rice.core.api.mo.AbstractDataTransferObject; 021import org.kuali.rice.core.api.mo.ModelBuilder; 022import org.kuali.rice.core.api.mo.ModelObjectUtils; 023import org.kuali.rice.krms.api.KrmsConstants; 024 025import javax.xml.bind.annotation.XmlAccessType; 026import javax.xml.bind.annotation.XmlAccessorType; 027import javax.xml.bind.annotation.XmlAnyElement; 028import javax.xml.bind.annotation.XmlElement; 029import javax.xml.bind.annotation.XmlRootElement; 030import javax.xml.bind.annotation.XmlType; 031import java.io.Serializable; 032import java.util.ArrayList; 033import java.util.Collection; 034import java.util.List; 035 036/** 037 * An immutable, concrete model object implementation of a {@link KrmsTypeDefinitionContract}. 038 * <p>To construct an instance of a KrmsTypeDefinition, use the {@link KrmsTypeDefinition.Builder} class. 039 * Instances of KrmsType can be (un)marshalled to and from XML.<p/> 040 * 041 * @see KrmsTypeDefinitionContract 042 */ 043@XmlRootElement(name = KrmsTypeDefinition.Constants.ROOT_ELEMENT_NAME) 044@XmlAccessorType(XmlAccessType.NONE) 045@XmlType(name = KrmsTypeDefinition.Constants.TYPE_NAME, propOrder = { 046 KrmsTypeDefinition.Elements.ID, 047 KrmsTypeDefinition.Elements.NAME, 048 KrmsTypeDefinition.Elements.NAMESPACE, 049 KrmsTypeDefinition.Elements.SERVICENAME, 050 KrmsTypeDefinition.Elements.ACTIVE, 051 KrmsTypeDefinition.Elements.ATTRIBUTES, 052 CoreConstants.CommonElements.VERSION_NUMBER, 053 CoreConstants.CommonElements.FUTURE_ELEMENTS 054}) 055public final class KrmsTypeDefinition extends AbstractDataTransferObject implements KrmsTypeDefinitionContract{ 056 private static final long serialVersionUID = -8314397393380856301L; 057 058 @XmlElement(name = Elements.ID, required = false) 059 private String id; 060 @XmlElement(name = Elements.NAME, required = true) 061 private String name; 062 @XmlElement(name = Elements.NAMESPACE, required = true) 063 private String namespace; 064 @XmlElement(name = Elements.SERVICENAME, required = false) 065 private String serviceName; 066 @XmlElement(name = Elements.ACTIVE, required = false) 067 private boolean active; 068 @XmlElement(name = Elements.ATTRIBUTE, required = false) 069 private List<KrmsTypeAttribute> attributes; 070 @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false) 071 private final Long versionNumber; 072 073 @SuppressWarnings("unused") 074 @XmlAnyElement 075 private final Collection<org.w3c.dom.Element> _futureElements = null; 076 077 /** 078 * This constructor should never be called. It is only present for use during JAXB unmarshalling. 079 */ 080 private KrmsTypeDefinition() { 081 this.id = null; 082 this.name = null; 083 this.namespace = null; 084 this.serviceName = null; 085 this.active = true; 086 this.attributes = null; 087 this.versionNumber = null; 088 } 089 090 /** 091 * Constructs a KRMS KrmsType from the given builder. This constructor is private and should only 092 * ever be invoked from the builder. 093 * 094 * @param builder the Builder from which to construct the KRMS type 095 */ 096 private KrmsTypeDefinition(Builder builder) { 097 this.id = builder.getId(); 098 this.name = builder.getName(); 099 this.namespace = builder.getNamespace(); 100 this.serviceName = builder.getServiceName(); 101 this.active = builder.isActive(); 102 this.attributes = ModelObjectUtils.buildImmutableCopy(builder.attributes); 103 this.versionNumber = builder.getVersionNumber(); 104 } 105 106 @Override 107 public String getId() { 108 return this.id; 109 } 110 111 @Override 112 public String getName() { 113 return this.name; 114 } 115 116 @Override 117 public String getNamespace() { 118 return this.namespace; 119 } 120 121 @Override 122 public String getServiceName() { 123 return this.serviceName; 124 } 125 126 @Override 127 public boolean isActive() { 128 return this.active; 129 } 130 131 @Override 132 public List<KrmsTypeAttribute> getAttributes() { 133 return this.attributes; 134 } 135 136 @Override 137 public Long getVersionNumber() { 138 return versionNumber; 139 } 140 141 /** 142 * This builder is used to construct instances of KrmsTypeDefinition. It enforces the constraints of the {@link KrmsTypeDefinitionContract}. 143 */ 144 public static class Builder implements KrmsTypeDefinitionContract, ModelBuilder, Serializable { 145 private static final long serialVersionUID = -3469525730879441547L; 146 147 private String id; 148 private String name; 149 private String namespace; 150 private String serviceName = ""; 151 private boolean active; 152 private List<KrmsTypeAttribute.Builder> attributes; 153 private Long versionNumber; 154 155 /** 156 * Private constructor for creating a builder with all of it's required attributes. 157 */ 158 private Builder(String name, String namespace) { 159 setName(name); 160 setNamespace(namespace); 161 setActive(true); 162 setAttributes(new ArrayList<KrmsTypeAttribute.Builder>()); 163 } 164 165 /** 166 * fluent interface that sets the serviceName field of the Builder. 167 * 168 * @param serviceName the service used to resolve attribute values 169 * @return a Builder object with the serviceName field set 170 */ 171 public Builder serviceName(String serviceName){ 172 this.serviceName = serviceName; 173 return this; 174 } 175 176 /** 177 * fluent interface that sets the attributes of KrmsTypeDefinition builder. 178 * 179 * @param attributes List of KrmsTypeAttribute builder objects. {@link KrmsTypeAttribute.Builder} 180 * @return a Builder object with the attributes collection set. 181 */ 182 public Builder attributes(List<KrmsTypeAttribute.Builder> attributes){ 183 setAttributes(attributes); 184 return this; 185 } 186 187 /** 188 * Creates a KrmsTypeDefinition builder from the given parameters. 189 * 190 * @param name of the KrmsTypeDefinition 191 * @param namespace to which the KrmsTypeDefinition belongs 192 * @return an instance of the builder with the fields already populated 193 * @throws IllegalArgumentException if the either the name or namespace is null or blank 194 */ 195 public static Builder create(String name, String namespace) { 196 return new Builder(name, namespace); 197 } 198 199 /** 200 * Creates a builder by populating it with data from the given {@link KrmsTypeDefinitionContract}. 201 * 202 * @param contract the contract from which to populate this builder 203 * @return an instance of the builder populated with data from the contract 204 * @throws IllegalArgumentException if the contract is null 205 */ 206 public static Builder create(KrmsTypeDefinitionContract contract) { 207 if (contract == null) { 208 throw new IllegalArgumentException("contract is null"); 209 } 210 Builder builder = new Builder(contract.getName(), contract.getNamespace()); 211 builder.setId(contract.getId()); 212 builder.setNamespace(contract.getNamespace()); 213 builder.setActive(contract.isActive()); 214 builder.setServiceName(contract.getServiceName()); 215 List <KrmsTypeAttribute.Builder> attrBuilderList = new ArrayList<KrmsTypeAttribute.Builder>(); 216 if (contract.getAttributes() != null) { 217 for(KrmsTypeAttributeContract attr : contract.getAttributes()){ 218 KrmsTypeAttribute.Builder myBuilder = 219 KrmsTypeAttribute.Builder.create(attr); 220 attrBuilderList.add(myBuilder); 221 } 222 } 223 builder.setAttributes(attrBuilderList); 224 builder.setVersionNumber(contract.getVersionNumber()); 225 return builder; 226 } 227 228 /** 229 * Sets the value of the id on this builder to the given value. 230 * 231 * @param id the id value to set; can be null; a null id is an indicator 232 * the this has not yet been persisted to the database. 233 * @throws IllegalArgumentException if the id is blank 234 */ 235 public void setId(String id) { 236 if (id != null && StringUtils.isBlank(id)) { 237 throw new IllegalArgumentException("ID must be non-blank"); 238 } 239 this.id = id; 240 } 241 242 /** 243 * Sets the name of the KrmsTypeDefinition 244 * @param name string value to assign to the name; cannot be null or blank 245 * @throws IllegalArgumentException if the name is null or blank 246 */ 247 public void setName(String name) { 248 if (StringUtils.isBlank(name)) { 249 throw new IllegalArgumentException("name is blank"); 250 } 251 this.name = name; 252 } 253 254 /** 255 * Sets the namespace of the KrmsTypeDefinition 256 * @param namespace string value to assign to the namespace; cannot be null or blank 257 * @throws IllegalArgumentException if the name is null or blank 258 */ 259 public void setNamespace(String namespace) { 260 if (StringUtils.isBlank(namespace)) { 261 throw new IllegalArgumentException("namespace is blank"); 262 } 263 this.namespace = namespace; 264 } 265 266 /** 267 * Sets the name of the KRMS type service 268 * @param serviceName can be null. 269 */ 270 public void setServiceName(String serviceName) { 271 this.serviceName = serviceName; 272 } 273 274 /** 275 * sets the List of attributes related to this KrmsTypeDefinition. 276 * 277 * @param attributes list of {@link KrmsTypeAttribute.Builder} representing the 278 * attributes assigned to this KrmsTypeDefinition; List may be empty, but not null 279 */ 280 public void setAttributes(List<KrmsTypeAttribute.Builder> attributes){ 281 this.attributes = attributes; 282 } 283 284 /** 285 * sets the active indicator value 286 * @param active boolean value to set 287 */ 288 public void setActive(boolean active) { 289 this.active = active; 290 } 291 292 /** 293 * Sets the version number for this object. In general, this value should only 294 * be null if the object has not yet been stored to a persistent data store. 295 * This version number is generally used for the purposes of optimistic locking. 296 * @param versionNumber the version number, or null if one has not been assigned yet. 297 */ 298 public void setVersionNumber(Long versionNumber){ 299 this.versionNumber = versionNumber; 300 } 301 302 @Override 303 public String getId() { 304 return id; 305 } 306 307 @Override 308 public String getName() { 309 return name; 310 } 311 312 @Override 313 public String getNamespace() { 314 return namespace; 315 } 316 317 @Override 318 public String getServiceName() { 319 return serviceName; 320 } 321 322 @Override 323 public List<KrmsTypeAttribute.Builder> getAttributes(){ 324 return attributes; 325 } 326 327 @Override 328 public boolean isActive() { 329 return active; 330 } 331 332 @Override 333 public Long getVersionNumber() { 334 return versionNumber; 335 } 336 337 /** 338 * Builds an instance of a KrmsTypeDefinition based on the current state of the builder. 339 * 340 * @return the fully-constructed KrmsTypeDefinition 341 */ 342 @Override 343 public KrmsTypeDefinition build() { 344 return new KrmsTypeDefinition(this); 345 } 346 347 } 348 349 /** 350 * Defines some internal constants used on this class. 351 */ 352 static class Constants { 353 final static String ROOT_ELEMENT_NAME = "KRMSType"; 354 final static String TYPE_NAME = "KRMSTypeType"; 355 } 356 357 /** 358 * A private class which exposes constants which define the XML element names to use 359 * when this object is marshalled to XML. 360 */ 361 public static class Elements { 362 final static String ID = "id"; 363 final static String NAME = "name"; 364 final static String NAMESPACE = "namespace"; 365 final static String SERVICENAME = "serviceName"; 366 final static String ACTIVE = "active"; 367 final static String ATTRIBUTE = "attribute"; 368 final static String ATTRIBUTES = "attributes"; 369 } 370 371 public static class Cache { 372 public static final String NAME = KrmsConstants.Namespaces.KRMS_NAMESPACE_2_0 + "/" + KrmsTypeDefinition.Constants.TYPE_NAME; 373 } 374}