View Javadoc
1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krms.api.repository.proposition;
17  
18  import java.io.Serializable;
19  import java.util.Collection;
20  
21  import javax.xml.bind.annotation.XmlAccessType;
22  import javax.xml.bind.annotation.XmlAccessorType;
23  import javax.xml.bind.annotation.XmlAnyElement;
24  import javax.xml.bind.annotation.XmlElement;
25  import javax.xml.bind.annotation.XmlRootElement;
26  import javax.xml.bind.annotation.XmlType;
27  
28  import org.apache.commons.lang.StringUtils;
29  import org.kuali.rice.core.api.CoreConstants;
30  import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
31  import org.kuali.rice.core.api.mo.ModelBuilder;
32  import org.kuali.rice.krms.api.repository.term.TermDefinition;
33  
34  /**
35   * Concrete model object implementation of KRMS Proposition Parameter 
36   * immutable. 
37   * Instances of PropositionParameter can be (un)marshalled to and from XML.
38   *
39   * @see PropositionParameterContract
40   */
41  @XmlRootElement(name = PropositionParameter.Constants.ROOT_ELEMENT_NAME)
42  @XmlAccessorType(XmlAccessType.NONE)
43  @XmlType(name = PropositionParameter.Constants.TYPE_NAME, propOrder = {
44  		PropositionParameter.Elements.ID,
45  		PropositionParameter.Elements.PROP_ID,
46  		PropositionParameter.Elements.VALUE,
47  		PropositionParameter.Elements.PARM_TYPE,
48  		PropositionParameter.Elements.SEQUENCE,
49          CoreConstants.CommonElements.VERSION_NUMBER,
50          PropositionParameter.Elements.TERM_VALUE,
51  		CoreConstants.CommonElements.FUTURE_ELEMENTS
52  })
53  public final class PropositionParameter extends AbstractDataTransferObject implements PropositionParameterContract {
54  	private static final long serialVersionUID = 2783959459503209577L;
55  
56  	@XmlElement(name = Elements.ID, required=true)
57  	private String id;
58  	@XmlElement(name = Elements.PROP_ID, required=true)
59  	private String propId;
60  	@XmlElement(name = Elements.VALUE, required=true)
61  	private String value;
62  	@XmlElement(name = Elements.PARM_TYPE, required=true)
63  	private String parameterType;
64  	@XmlElement(name = Elements.SEQUENCE, required=true)
65  	private Integer sequenceNumber;
66      @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
67      private final Long versionNumber;
68      @XmlElement(name = Elements.TERM_VALUE, required=false)
69      private TermDefinition termValue;
70  
71  	@SuppressWarnings("unused")
72      @XmlAnyElement
73      private final Collection<org.w3c.dom.Element> _futureElements = null;
74  	
75  	 /** 
76       * This constructor should never be called.  
77       * It is only present for use during JAXB unmarshalling. 
78       */
79      private PropositionParameter() {
80      	this.id = null;
81      	this.propId = null;
82      	this.value = null;
83      	this.termValue = null;
84      	this.parameterType = null;
85      	this.sequenceNumber = null;
86          this.versionNumber = null;
87      }
88      
89      /**
90  	 * Constructs a PropositionParameter from the given builder.  
91  	 * This constructor is private and should only ever be invoked from the builder.
92  	 * 
93  	 * @param builder the Builder from which to construct the PropositionParameter
94  	 */
95      private PropositionParameter(Builder builder) {
96          this.id = builder.getId();
97          this.propId = builder.getPropId();
98          this.value = builder.getValue();
99          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 }