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 }