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