001 /** 002 * Copyright 2005-2014 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 */ 016 package org.kuali.rice.krms.api.repository.proposition; 017 018 import java.io.Serializable; 019 import java.util.Collection; 020 021 import javax.xml.bind.annotation.XmlAccessType; 022 import javax.xml.bind.annotation.XmlAccessorType; 023 import javax.xml.bind.annotation.XmlAnyElement; 024 import javax.xml.bind.annotation.XmlElement; 025 import javax.xml.bind.annotation.XmlRootElement; 026 import javax.xml.bind.annotation.XmlType; 027 028 import org.apache.commons.lang.StringUtils; 029 import org.kuali.rice.core.api.CoreConstants; 030 import org.kuali.rice.core.api.mo.AbstractDataTransferObject; 031 import org.kuali.rice.core.api.mo.ModelBuilder; 032 import org.kuali.rice.krms.api.repository.term.TermDefinition; 033 034 /** 035 * Concrete model object implementation of KRMS Proposition Parameter 036 * immutable. 037 * Instances of PropositionParameter can be (un)marshalled to and from XML. 038 * 039 * @see PropositionParameterContract 040 */ 041 @XmlRootElement(name = PropositionParameter.Constants.ROOT_ELEMENT_NAME) 042 @XmlAccessorType(XmlAccessType.NONE) 043 @XmlType(name = PropositionParameter.Constants.TYPE_NAME, propOrder = { 044 PropositionParameter.Elements.ID, 045 PropositionParameter.Elements.PROP_ID, 046 PropositionParameter.Elements.VALUE, 047 PropositionParameter.Elements.PARM_TYPE, 048 PropositionParameter.Elements.SEQUENCE, 049 CoreConstants.CommonElements.VERSION_NUMBER, 050 PropositionParameter.Elements.TERM_VALUE, 051 CoreConstants.CommonElements.FUTURE_ELEMENTS 052 }) 053 public final class PropositionParameter extends AbstractDataTransferObject implements PropositionParameterContract { 054 private static final long serialVersionUID = 2783959459503209577L; 055 056 @XmlElement(name = Elements.ID, required=true) 057 private String id; 058 @XmlElement(name = Elements.PROP_ID, required=true) 059 private String propId; 060 @XmlElement(name = Elements.VALUE, required=true) 061 private String value; 062 @XmlElement(name = Elements.PARM_TYPE, required=true) 063 private String parameterType; 064 @XmlElement(name = Elements.SEQUENCE, required=true) 065 private Integer sequenceNumber; 066 @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false) 067 private final Long versionNumber; 068 @XmlElement(name = Elements.TERM_VALUE, required=false) 069 private TermDefinition termValue; 070 071 @SuppressWarnings("unused") 072 @XmlAnyElement 073 private final Collection<org.w3c.dom.Element> _futureElements = null; 074 075 /** 076 * This constructor should never be called. 077 * It is only present for use during JAXB unmarshalling. 078 */ 079 private PropositionParameter() { 080 this.id = null; 081 this.propId = null; 082 this.value = null; 083 this.termValue = null; 084 this.parameterType = null; 085 this.sequenceNumber = null; 086 this.versionNumber = null; 087 } 088 089 /** 090 * Constructs a PropositionParameter from the given builder. 091 * This constructor is private and should only ever be invoked from the builder. 092 * 093 * @param builder the Builder from which to construct the PropositionParameter 094 */ 095 private PropositionParameter(Builder builder) { 096 this.id = builder.getId(); 097 this.propId = builder.getPropId(); 098 this.value = builder.getValue(); 099 this.termValue = builder.getTermValue(); 100 this.parameterType = builder.getParameterType(); 101 this.sequenceNumber = builder.getSequenceNumber(); 102 this.versionNumber = builder.getVersionNumber(); 103 } 104 105 @Override 106 public String getId() { 107 return this.id; 108 } 109 110 @Override 111 public String getPropId() { 112 return this.propId; 113 } 114 115 @Override 116 public String getValue() { 117 return this.value; 118 } 119 120 @Override 121 public String getParameterType() { 122 return this.parameterType; 123 } 124 @Override 125 public Integer getSequenceNumber() { 126 return this.sequenceNumber; 127 } 128 129 @Override 130 public Long getVersionNumber() { 131 return versionNumber; 132 } 133 134 @Override 135 public TermDefinition getTermValue() { 136 return this.termValue; 137 } 138 139 /** 140 * This builder is used to construct instances of PropositionParameter. 141 * It enforces the constraints of the {@link PropositionParameterContract}. 142 */ 143 public static class Builder implements PropositionParameterContract, ModelBuilder, Serializable { 144 private static final long serialVersionUID = -6889320709850568900L; 145 146 private String id; 147 private String propId; 148 private String value; 149 private TermDefinition termValue; 150 private String parameterType; 151 private Integer sequenceNumber; 152 private Long versionNumber; 153 private PropositionDefinition.Builder proposition; 154 155 /** 156 * Private constructor for creating a builder with all of it's required attributes. 157 * @param id the id value to set, must not be null or blank 158 * @param propId the propId value to set, must not be null or blank 159 * @param value the value value to set, must not be null or blank 160 * @param parameterType the value parameterType to set, must not be null or blank 161 * @param sequenceNumber the value sequenceNumber to set, must not be null or blank 162 */ 163 private Builder(String id, String propId, String value, String parameterType, Integer sequenceNumber) { 164 setId(id); 165 setPropId(propId); 166 setValue(value); 167 setParameterType(parameterType); 168 setSequenceNumber(sequenceNumber); 169 } 170 171 /** 172 * Create a builder using the given values 173 * @param id the id value to set, must not be null or blank 174 * @param propId the propId value to set, must not be null or blank 175 * @param value the value value to set, must not be null or blank 176 * @param parameterType the value parameterType to set, must not be null or blank 177 * @param sequenceNumber the value sequenceNumber to set, must not be null or blank 178 * @return Builder with the given values set 179 */ 180 public static Builder create(String id, String propId, String value, String parameterType, Integer sequenceNumber) { 181 return new Builder(id, propId, value, parameterType, sequenceNumber); 182 } 183 184 /** 185 * Creates a builder by populating it with data from the given {@link PropositionParameterContract}. 186 * 187 * @param contract the contract from which to populate this builder 188 * @return an instance of the builder populated with data from the contract 189 */ 190 public static Builder create(PropositionParameterContract contract) { 191 if (contract == null) { 192 throw new IllegalArgumentException("contract is null"); 193 } 194 195 Builder builder = new Builder(contract.getId(), contract.getPropId(), contract.getValue(), contract.getParameterType(), contract.getSequenceNumber()); 196 builder.setVersionNumber(contract.getVersionNumber()); 197 builder.setTermValue(contract.getTermValue()); 198 199 return builder; 200 } 201 202 /** 203 * Creates a builder by populating it with data from the given {@link PropositionParameterContract}. 204 * 205 * @param propositionParameter the contract from which to populate this builder 206 * @return an instance of the builder populated with data from the contract 207 */ 208 public static PropositionParameter.Builder create(PropositionParameter propositionParameter) { 209 if (propositionParameter == null) { 210 throw new IllegalArgumentException("parameter is null"); 211 } 212 213 Builder builder = new Builder(propositionParameter.getId(), propositionParameter.getPropId(), propositionParameter.getValue(), propositionParameter.getParameterType(), propositionParameter.getSequenceNumber()); 214 builder.setVersionNumber(propositionParameter.getVersionNumber()); 215 builder.setTermValue(propositionParameter.getTermValue()); 216 217 return builder; 218 } 219 220 221 /** 222 * Creates a builder by populating it with data from the given {@link PropositionParameterContract}. 223 * 224 * @param inputBuilder the contract from which to populate this builder 225 * @return an instance of the builder populated with data from the contract 226 */ 227 public static PropositionParameter.Builder create(Builder inputBuilder) { 228 if (inputBuilder == null) { 229 throw new IllegalArgumentException("inputBuilder is null"); 230 } 231 Builder builder = new Builder(inputBuilder.getId(), inputBuilder.getPropId(), inputBuilder.getValue(), inputBuilder.getParameterType(), inputBuilder.getSequenceNumber()); 232 builder.setVersionNumber(inputBuilder.getVersionNumber()); 233 builder.setTermValue(inputBuilder.getTermValue()); 234 return builder; 235 } 236 237 /** 238 * Sets the value of the id on this builder to the given value. 239 * 240 * @param id the id value to set, must not be null or blank 241 * @throws IllegalArgumentException if the id is null or blank 242 */ 243 public void setId(String id) { 244 if (id != null && StringUtils.isBlank(id)) { 245 throw new IllegalArgumentException("id must not be null or blank"); 246 } 247 this.id = id; 248 } 249 250 /** 251 * Sets the value of the propId on this builder to the given value. 252 * 253 * @param propId the propId value to set, must not be null or blank 254 * @throws IllegalArgumentException if the propId is null or blank 255 */ 256 public void setPropId(String propId) { 257 // have to be able to create it with a null propId for chicken/egg reasons. 258 if (null != propId && StringUtils.isBlank(propId)) { 259 throw new IllegalArgumentException("propId must be not be null or blank"); 260 } 261 this.propId = propId; 262 } 263 264 /** 265 * Sets the value of the value on this builder to the given value. 266 * 267 * @param value the value value to set, may be null, otherwise must contain non-whitespace 268 * @throws IllegalArgumentException if the value is all whitespace characters 269 */ 270 public void setValue(String value) { 271 if (value != null && "".equals(value.trim())) { 272 throw new IllegalArgumentException("value must contain non-whitespace characters"); 273 } 274 this.value = value; 275 } 276 277 /** 278 * Sets the value of the termValue on this builder to the given value. 279 * 280 * @param termValue the termValue value to set, may be null 281 */ 282 public void setTermValue(TermDefinition termValue) { 283 this.termValue = termValue; 284 } 285 286 /** 287 * Sets the value of the parameterType on this builder to the given value. 288 * 289 * @param parameterType the value parameterType to set, must not be null or blank 290 * @throws IllegalArgumentException if the parameterType is null, blank, or invalid 291 */ 292 public void setParameterType(String parameterType) { 293 if (StringUtils.isBlank(parameterType)){ 294 throw new IllegalArgumentException("parameter type is null or blank"); 295 } 296 if (!PropositionParameterType.VALID_TYPE_CODES.contains(parameterType)){ 297 throw new IllegalArgumentException("parameter type is invalid"); 298 } 299 // TODO: check against valid values 300 this.parameterType = parameterType; 301 } 302 303 /** 304 * Sets the value of the sequenceNumber on this builder to the given value. 305 * 306 * @param sequenceNumber the value sequenceNumber to set, must not be null or blank 307 * @throws IllegalArgumentException if the sequenceNumber is null, blank, or invalid 308 */ 309 public void setSequenceNumber(Integer sequenceNumber) { 310 if (sequenceNumber == null) { 311 throw new IllegalArgumentException("sequenceNumber type is blank"); 312 } 313 this.sequenceNumber = sequenceNumber; 314 } 315 316 /** 317 * Sets the value of the proposition on this builder to the given value. 318 * 319 * @param proposition the value proposition to set 320 */ 321 public void setProposition(PropositionDefinition.Builder proposition) { 322 if (proposition != null && !StringUtils.isBlank(proposition.getId())) { 323 setPropId(proposition.getId()); 324 } 325 this.proposition = proposition; 326 } 327 328 /** 329 * Sets the value of the versionNumber on this builder to the given value. 330 * 331 * @param versionNumber the value versionNumber to set 332 */ 333 public void setVersionNumber(Long versionNumber){ 334 this.versionNumber = versionNumber; 335 } 336 337 @Override 338 public String getId() { 339 return id; 340 } 341 342 @Override 343 public String getPropId() { 344 return propId; 345 } 346 347 @Override 348 public String getValue() { 349 return value; 350 } 351 352 @Override 353 public TermDefinition getTermValue() { 354 return termValue; 355 } 356 357 @Override 358 public String getParameterType() { 359 return parameterType; 360 } 361 362 @Override 363 public Integer getSequenceNumber() { 364 return sequenceNumber; 365 } 366 367 @Override 368 public Long getVersionNumber() { 369 return versionNumber; 370 } 371 372 /** 373 * Builds an instance of a PropositionParameter based on the current state of the builder. 374 * 375 * @return the fully-constructed PropositionParameter 376 */ 377 @Override 378 public PropositionParameter build() { 379 if (proposition == null && StringUtils.isBlank(propId)) { 380 throw new IllegalStateException("either proposition must be non-null or propId must be non-blank"); 381 } 382 return new PropositionParameter(this); 383 } 384 385 } 386 387 /** 388 * Defines some internal constants used on this class. 389 */ 390 static class Constants { 391 final static String ROOT_ELEMENT_NAME = "PropositionParameter"; 392 final static String TYPE_NAME = "PropositionParameterType"; 393 } 394 395 /** 396 * A private class which exposes constants which define the XML element names to use 397 * when this object is marshalled to XML. 398 */ 399 public static class Elements { 400 final static String ID = "id"; 401 final static String PROP_ID = "propId"; 402 final static String VALUE = "value"; 403 final static String TERM_VALUE = "termValue"; 404 final static String PARM_TYPE = "parameterType"; 405 final static String SEQUENCE = "sequenceNumber"; 406 } 407 408 }