View Javadoc

1   /**
2    * Copyright 2005-2012 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  import org.kuali.rice.krms.impl.repository.PropositionParameterBo;
34  
35  /**
36   * Concrete model object implementation of KRMS Proposition Parameter 
37   * immutable. 
38   * Instances of PropositionParameter can be (un)marshalled to and from XML.
39   *
40   * @see PropositionParameterContract
41   */
42  @XmlRootElement(name = PropositionParameter.Constants.ROOT_ELEMENT_NAME)
43  @XmlAccessorType(XmlAccessType.NONE)
44  @XmlType(name = PropositionParameter.Constants.TYPE_NAME, propOrder = {
45  		PropositionParameter.Elements.ID,
46  		PropositionParameter.Elements.PROP_ID,
47  		PropositionParameter.Elements.VALUE,
48  		PropositionParameter.Elements.TERM_VALUE,
49  		PropositionParameter.Elements.PARM_TYPE,
50  		PropositionParameter.Elements.SEQUENCE,
51          CoreConstants.CommonElements.VERSION_NUMBER,
52  		CoreConstants.CommonElements.FUTURE_ELEMENTS
53  })
54  public final class PropositionParameter extends AbstractDataTransferObject implements PropositionParameterContract {
55  	private static final long serialVersionUID = 2783959459503209577L;
56  
57  	@XmlElement(name = PropositionParameter.Elements.ID, required=true)
58  	private String id;
59  	@XmlElement(name = PropositionParameter.Elements.PROP_ID, required=true)
60  	private String propId;
61  	@XmlElement(name = PropositionParameter.Elements.VALUE, required=true)
62  	private String value;
63  	@XmlElement(name = PropositionParameter.Elements.TERM_VALUE, required=true)
64  	private TermDefinition termValue;
65  	@XmlElement(name = PropositionParameter.Elements.PARM_TYPE, required=true)
66  	private String parameterType;
67  	@XmlElement(name = PropositionParameter.Elements.SEQUENCE, required=true)
68  	private Integer sequenceNumber;
69      @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
70      private final Long versionNumber;
71  	
72  	@SuppressWarnings("unused")
73      @XmlAnyElement
74      private final Collection<org.w3c.dom.Element> _futureElements = null;
75  	
76  	 /** 
77       * This constructor should never be called.  
78       * It is only present for use during JAXB unmarshalling. 
79       */
80      private PropositionParameter() {
81      	this.id = null;
82      	this.propId = null;
83      	this.value = null;
84      	this.termValue = null;
85      	this.parameterType = null;
86      	this.sequenceNumber = null;
87          this.versionNumber = null;
88      }
89      
90      /**
91  	 * Constructs a PropositionParameter from the given builder.  
92  	 * This constructor is private and should only ever be invoked from the builder.
93  	 * 
94  	 * @param builder the Builder from which to construct the PropositionParameter
95  	 */
96      private PropositionParameter(PropositionParameter.Builder builder) {
97          this.id = builder.getId();
98          this.propId = builder.getPropId();
99          this.value = builder.getValue();
100         this.termValue = builder.getTermValue();
101         this.parameterType = builder.getParameterType();
102         this.sequenceNumber = builder.getSequenceNumber();
103         this.versionNumber = builder.getVersionNumber();
104     }
105     
106 	@Override
107 	public String getId() {
108 		return this.id;
109 	}
110 	
111 	@Override
112 	public String getPropId() {
113 		return this.propId;
114 	}
115 
116 	@Override
117 	public String getValue() {
118 		return this.value;
119 	}
120         
121 	public TermDefinition getTermValue() {
122 		return this.termValue;
123 	}
124 
125 	@Override
126 	public String getParameterType() {
127 		return this.parameterType;
128 	}
129 	@Override
130 	public Integer getSequenceNumber() {
131 		return this.sequenceNumber; 
132 	}
133 
134     @Override
135     public Long getVersionNumber() {
136         return versionNumber;
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             this.value = value;
167             setTermValue(null);
168             setParameterType(parameterType);
169 			setSequenceNumber(sequenceNumber);
170         }
171 
172         /**
173          * Create a builder using the given values
174          * @param id the id value to set, must not be null or blank
175          * @param propId the propId value to set, must not be null or blank
176          * @param value the value value to set, must not be null or blank
177          * @param parameterType the value parameterType to set, must not be null or blank
178          * @param sequenceNumber the value sequenceNumber to set, must not be null or blank
179          * @return Builder with the given values set
180          */
181         public static PropositionParameter.Builder create(String id, String propId, String value, String parameterType, Integer sequenceNumber) {
182         	return new PropositionParameter.Builder(id, propId, value, parameterType, sequenceNumber);
183         }
184 
185         /**
186          * Creates a builder by populating it with data from the given {@link PropositionParameterContract}.
187          * 
188          * @param contract the contract from which to populate this builder
189          * @return an instance of the builder populated with data from the contract
190          */
191         public static PropositionParameter.Builder create(PropositionParameterContract contract) {
192         	if (contract == null) {
193                 throw new IllegalArgumentException("contract is null");
194             }
195             PropositionParameter.Builder builder =  new PropositionParameter.Builder(contract.getId(), contract.getPropId(), contract.getValue(), contract.getParameterType(), contract.getSequenceNumber());
196             builder.setVersionNumber(contract.getVersionNumber());
197 
198             //TODO: this if statement should be removed once propositionparameterbo also implements the new interface.
199             if (!(contract instanceof PropositionParameterBo)){
200                 builder.setTermValue(contract.getTermValue());
201             }
202             return builder;
203         }
204 
205         /**
206          * Creates a builder by populating it with data from the given {@link PropositionParameterContract}.
207          * 
208          * @param propositionParameter the contract from which to populate this builder
209          * @return an instance of the builder populated with data from the contract
210          */
211         public static PropositionParameter.Builder create(PropositionParameter propositionParameter) {
212         	if (propositionParameter == null) {
213                 throw new IllegalArgumentException("parameter is null");
214             }
215             PropositionParameter.Builder builder =  new PropositionParameter.Builder(propositionParameter.getId(), propositionParameter.getPropId(), propositionParameter.getValue(), propositionParameter.getParameterType(), propositionParameter.getSequenceNumber());
216             builder.setVersionNumber(propositionParameter.getVersionNumber());
217             builder.setTermValue(propositionParameter.getTermValue());
218             return builder;
219         }
220 
221 
222         /**
223          * Creates a builder by populating it with data from the given {@link PropositionParameterContract}.
224          * 
225          * @param inputBuilder 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 PropositionParameter.Builder create(PropositionParameter.Builder inputBuilder) {
229         	if (inputBuilder == null) {
230                 throw new IllegalArgumentException("inputBuilder is null");
231             }
232             PropositionParameter.Builder builder =  new PropositionParameter.Builder(inputBuilder.getId(), inputBuilder.getPropId(), inputBuilder.getValue(), inputBuilder.getParameterType(), inputBuilder.getSequenceNumber());
233             builder.setVersionNumber(inputBuilder.getVersionNumber());
234             builder.setTermValue(inputBuilder.getTermValue());
235             return builder;
236         }
237 
238 		/**
239 		 * Sets the value of the id on this builder to the given value.
240 		 * 
241 		 * @param id the id value to set, must not be null or blank
242 		 * @throws IllegalArgumentException if the id is null or blank
243 		 */
244         public void setId(String id) {
245             if (id != null && StringUtils.isBlank(id)) {
246                 throw new IllegalArgumentException("id must not be null or blank");
247             }
248             this.id = id;
249         }
250 
251         /**
252          * Sets the value of the propId on this builder to the given value.
253          *
254          * @param propId the propId value to set, must not be null or blank
255          * @throws IllegalArgumentException if the propId is null or blank
256          */
257 		public void setPropId(String propId) {
258 		    // have to be able to create it with a null propId for chicken/egg reasons.
259             if (null != propId && StringUtils.isBlank(propId)) {
260                 throw new IllegalArgumentException("propId must be not be null or blank");
261             }
262 			this.propId = propId;
263 		}
264 
265         /**
266          * Sets the value of the value on this builder to the given value.
267          *
268          * @param value the value value to set, may be null, otherwise must contain non-whitespace
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 }