Clover Coverage Report - rice-krms-api 2.0.0-SNAPSHOT
Coverage timestamp: Wed Dec 31 1969 19:00:00 EST
../../../../../../img/srcFileCovDistChart0.png 0% of files have more coverage
95   420   51   2.71
28   291   0.54   7
35     1.46  
5    
 
  Proposition       Line # 59 31 0% 13 45 0% 0.0
  Proposition.Builder       Line # 169 61 0% 35 107 0% 0.0
  Proposition.Constants       Line # 369 0 - 0 0 - -1.0
  Proposition.Elements       Line # 379 0 - 0 0 - -1.0
  Proposition.PropositionTypes       Line # 397 3 0% 3 6 0% 0.0
 
No Tests
 
1    package org.kuali.rice.krms.api.repository;
2   
3    import java.io.Serializable;
4    import java.util.ArrayList;
5    import java.util.Arrays;
6    import java.util.Collection;
7    import java.util.Collections;
8    import java.util.List;
9   
10    import javax.xml.bind.annotation.XmlAccessType;
11    import javax.xml.bind.annotation.XmlAccessorType;
12    import javax.xml.bind.annotation.XmlAnyElement;
13    import javax.xml.bind.annotation.XmlElement;
14    import javax.xml.bind.annotation.XmlRootElement;
15    import javax.xml.bind.annotation.XmlType;
16   
17    import org.apache.commons.lang.StringUtils;
18    import org.apache.commons.lang.builder.EqualsBuilder;
19    import org.apache.commons.lang.builder.HashCodeBuilder;
20    import org.apache.commons.lang.builder.ToStringBuilder;
21    import org.kuali.rice.core.api.CoreConstants;
22    import org.kuali.rice.core.api.mo.ModelBuilder;
23    import org.kuali.rice.core.api.mo.ModelObjectComplete;
24   
25    import org.kuali.rice.krms.api.LogicalOperator;
26   
27    /**
28    * Concrete model object implementation of KRMS Proposition.
29    * Immutable.
30    * Instances of Proposition can be (un)marshalled to and from XML.
31    *
32    * There are three main types of Propositions:
33    * 1. Compound Propositions - a proposition consisting of other propositions
34    * and a boolean algebra operator (AND, OR) defining how to evaluate those propositions.
35    * 2. Parameterized Propositions - a proposition which is parameterized by some set of values,
36    * evaluation logic is implemented by hand and returns true or false
37    * 3. Simple Propositions - a proposition of the form lhs op rhs where
38    * lhs=left-hand side, rhs=right-hand side, and op=operator
39    * Propositions are reference by a rule or another proposition (in the case of compound propositions).
40    * Propositions are never re-used across multiple rules.
41    * Each proposition can have zero or more parameters. The proposition parameter is the primary
42    * data element used to define the proposition. (@see PropositionParameter)
43    *
44    * @see PropositonContract
45    * @see PropositionParameterContract
46    */
47    @XmlRootElement(name = Proposition.Constants.ROOT_ELEMENT_NAME)
48    @XmlAccessorType(XmlAccessType.NONE)
49    @XmlType(name = Proposition.Constants.TYPE_NAME, propOrder = {
50    Proposition.Elements.PROP_ID,
51    Proposition.Elements.DESC,
52    Proposition.Elements.TYPE_ID,
53    Proposition.Elements.PROP_TYPE_CODE,
54    "parameters", // xml element name differs from class property name
55    Proposition.Elements.CMPND_OP_CODE,
56    "compoundComponents", // xml element name differs from class property name
57    CoreConstants.CommonElements.FUTURE_ELEMENTS
58    })
 
59    public final class Proposition implements PropositionContract, ModelObjectComplete{
60    private static final long serialVersionUID = 2783959459503209577L;
61   
62    @XmlElement(name = Elements.PROP_ID, required=true)
63    private String propId;
64   
65    @XmlElement(name = Elements.DESC, required=true)
66    private String description;
67   
68    @XmlElement(name = Elements.TYPE_ID, required=true)
69    private String typeId;
70   
71    @XmlElement(name = Elements.PROP_TYPE_CODE, required=true)
72    private String propositionTypeCode;
73   
74    @XmlElement(name = Elements.PARAMETERS, required=false)
75    private List<PropositionParameter> parameters;
76   
77    @XmlElement(name = Elements.CMPND_OP_CODE, required=false)
78    private String compoundOpCode;
79   
80    @XmlElement(name = Elements.CMPND_COMPONENTS, required=false)
81    private List<Proposition> compoundComponents;
82   
83    @SuppressWarnings("unused")
84    @XmlAnyElement
85    private final Collection<org.w3c.dom.Element> _futureElements = null;
86   
87   
88    /**
89    * This constructor should never be called. It is only present for use during JAXB unmarshalling.
90    */
 
91  0 toggle private Proposition() {
92  0 this.propId = null;
93  0 this.description = null;
94  0 this.typeId = null;
95  0 this.propositionTypeCode = null;
96  0 this.parameters = null;
97  0 this.compoundOpCode = null;
98  0 this.compoundComponents = null;
99    }
100   
101    /**
102    * Constructs a KRMS Proposition from the given builder.
103    * This constructor is private and should only ever be invoked from the builder.
104    *
105    * @param builder the Builder from which to construct the KRMS Proposition
106    */
 
107  0 toggle private Proposition(Builder builder) {
108  0 this.propId = builder.getPropId();
109  0 this.description = builder.getDescription();
110  0 this.typeId = builder.getTypeId();
111  0 this.propositionTypeCode = builder.getPropositionTypeCode();
112   
113    // Build parameter list
114  0 List<PropositionParameter> paramList = new ArrayList<PropositionParameter>();
115  0 for (PropositionParameter.Builder b : builder.parameters){
116  0 paramList.add(b.build());
117    }
118  0 this.parameters = Collections.unmodifiableList(paramList);
119   
120    // Build Compound Proposition properties
121  0 this.compoundOpCode = builder.getCompoundOpCode();
122  0 List <Proposition> componentList = new ArrayList<Proposition>();
123  0 if (builder.compoundComponents != null){
124  0 for (Proposition.Builder b : builder.compoundComponents){
125  0 componentList.add(b.build());
126    }
127    }
128  0 this.compoundComponents = Collections.unmodifiableList(componentList);
129    }
130   
 
131  0 toggle @Override
132    public String getPropId() {
133  0 return this.propId;
134    }
135   
 
136  0 toggle @Override
137    public String getDescription() {
138  0 return this.description;
139    }
140   
 
141  0 toggle @Override
142    public String getTypeId() {
143  0 return this.typeId;
144    }
145   
 
146  0 toggle @Override
147    public String getPropositionTypeCode() {
148  0 return this.propositionTypeCode;
149    }
150   
 
151  0 toggle @Override
152    public List<PropositionParameter> getParameters() {
153  0 return this.parameters;
154    }
155   
 
156  0 toggle @Override
157    public String getCompoundOpCode() {
158  0 return this.compoundOpCode;
159    }
160   
 
161  0 toggle @Override
162    public List<Proposition> getCompoundComponents() {
163  0 return this.compoundComponents;
164    }
165   
166    /**
167    * This builder is used to construct instances of KRMS Proposition. It enforces the constraints of the {@link PropositionContract}.
168    */
 
169    public static class Builder implements PropositionContract, ModelBuilder, Serializable {
170    private static final long serialVersionUID = -6889320709850568900L;
171   
172    private String propId;
173    private String description;
174    private String typeId;
175    private String propositionTypeCode;
176    private List<PropositionParameter.Builder> parameters;
177    private String compoundOpCode;
178    private List<Proposition.Builder> compoundComponents;
179   
180    /**
181    * Private constructor for creating a builder with all of it's required attributes.
182    */
 
183  0 toggle private Builder(String propId, String desc, String typeId, String propTypeCode, List<PropositionParameter.Builder> parameters) {
184  0 setPropId(propId);
185  0 setDescription(desc);
186  0 setTypeId(typeId);
187  0 setPropositionTypeCode(propTypeCode);
188  0 setParameters(parameters);
189    }
190   
 
191  0 toggle public Builder compoundOpCode(String opCode){
192  0 setCompoundOpCode(opCode);
193  0 return this;
194    }
195   
 
196  0 toggle public Builder compoundComponents (List<Proposition.Builder> components){
197  0 setCompoundComponents(components);
198  0 return this;
199    }
200   
 
201  0 toggle public static Builder create(String propId, String desc, String typeId, String propTypeCode, List<PropositionParameter.Builder> parameters){
202  0 return new Builder(propId, desc, typeId, propTypeCode, parameters);
203    }
204    /**
205    * Creates a builder by populating it with data from the given {@link PropositionContract}.
206    *
207    * @param contract the contract from which to populate this builder
208    * @return an instance of the builder populated with data from the contract
209    */
 
210  0 toggle public static Builder create(PropositionContract contract) {
211  0 if (contract == null) {
212  0 throw new IllegalArgumentException("contract is null");
213    }
214  0 List <PropositionParameter.Builder> paramBuilderList = new ArrayList<PropositionParameter.Builder>();
215  0 if (contract.getParameters() != null){
216  0 for (PropositionParameterContract paramContract : contract.getParameters()){
217  0 PropositionParameter.Builder myBuilder = PropositionParameter.Builder.create(paramContract);
218  0 paramBuilderList.add(myBuilder);
219    }
220    }
221  0 List <Proposition.Builder> componentBuilderList = new ArrayList<Proposition.Builder>();
222  0 if (contract.getCompoundComponents() != null) {
223  0 for (PropositionContract cContract : contract.getCompoundComponents()){
224  0 Proposition.Builder pBuilder = Proposition.Builder.create(cContract);
225  0 componentBuilderList.add(pBuilder);
226    }
227    }
228  0 Builder builder = new Builder(contract.getPropId(), contract.getDescription(),
229    contract.getTypeId(), contract.getPropositionTypeCode(), paramBuilderList)
230    .compoundOpCode(contract.getCompoundOpCode())
231    .compoundComponents(componentBuilderList);
232  0 return builder;
233    }
234   
235    /**
236    * Sets the value of the id on this builder to the given value.
237    *
238    * @param id the id value to set, must not be null or blank
239    * @throws IllegalArgumentException if the id is null or blank
240    */
241   
 
242  0 toggle public void setPropId(String propId) {
243  0 if (StringUtils.isBlank(propId)) {
244  0 throw new IllegalArgumentException("propId is blank");
245    }
246  0 this.propId = propId;
247    }
248   
 
249  0 toggle public void setDescription(String desc) {
250  0 if (StringUtils.isBlank(desc)) {
251  0 throw new IllegalArgumentException("description is blank");
252    }
253  0 this.description = desc;
254    }
255   
 
256  0 toggle public void setTypeId(String typeId) {
257  0 if (StringUtils.isBlank(typeId)) {
258  0 throw new IllegalArgumentException("KRMS type id is blank");
259    }
260    // TODO: check against valid values ?
261  0 this.typeId = typeId;
262    }
263   
 
264  0 toggle public void setPropositionTypeCode(String propTypeCode) {
265  0 if (StringUtils.isBlank(propTypeCode)) {
266  0 throw new IllegalArgumentException("proposition type code is blank");
267    }
268  0 if (!PropositionTypes.VALID_TYPE_CODES.contains(propTypeCode)) {
269  0 throw new IllegalArgumentException("invalid proposition type code");
270    }
271  0 this.propositionTypeCode = propTypeCode;
272    }
273   
 
274  0 toggle public void setParameters(List<PropositionParameter.Builder> parameters){
275    // compound propositions have empty parameter lists
276    // Simple propositions must have a non-empty parameter list
277  0 if (parameters == null || parameters.isEmpty()){
278  0 if (PropositionTypes.COMPOUND.code().equals( this.propositionTypeCode)){
279  0 this.parameters = Collections.unmodifiableList(new ArrayList<PropositionParameter.Builder>());
280  0 return;
281    } else {
282  0 throw new IllegalArgumentException("no proposition parameters are specified");
283    }
284    }
285  0 this.parameters = Collections.unmodifiableList(parameters);
286    }
287   
 
288  0 toggle public void setCompoundOpCode(String opCode){
289  0 if (StringUtils.isBlank(opCode)){ return; }
290  0 if (!LogicalOperator.OP_CODES.contains(opCode)){
291  0 throw new IllegalArgumentException("invalid opCode value");
292    }
293  0 this.compoundOpCode = opCode;
294    }
295   
 
296  0 toggle public void setCompoundComponents(List<Proposition.Builder> components){
297  0 if (components == null || components.isEmpty()){
298  0 this.compoundComponents = Collections.unmodifiableList(new ArrayList<Proposition.Builder>());
299  0 return;
300    }
301  0 this.compoundComponents = Collections.unmodifiableList(components);
302    }
303   
304   
 
305  0 toggle @Override
306    public String getPropId() {
307  0 return propId;
308    }
309   
 
310  0 toggle @Override
311    public String getDescription() {
312  0 return description;
313    }
314   
 
315  0 toggle @Override
316    public String getTypeId() {
317  0 return typeId;
318    }
319   
 
320  0 toggle @Override
321    public String getPropositionTypeCode() {
322  0 return propositionTypeCode;
323    }
324   
 
325  0 toggle @Override
326    public List<PropositionParameter.Builder> getParameters() {
327  0 return parameters;
328    }
329   
 
330  0 toggle @Override
331    public String getCompoundOpCode() {
332  0 return compoundOpCode;
333    }
334   
 
335  0 toggle @Override
336    public List<Proposition.Builder> getCompoundComponents() {
337  0 return compoundComponents;
338    }
339   
340    /**
341    * Builds an instance of a Proposition based on the current state of the builder.
342    *
343    * @return the fully-constructed Proposition
344    */
 
345  0 toggle @Override
346    public Proposition build() {
347  0 return new Proposition(this);
348    }
349   
350    }
 
351  0 toggle @Override
352    public int hashCode() {
353  0 return HashCodeBuilder.reflectionHashCode(this, Constants.HASH_CODE_EQUALS_EXCLUDE);
354    }
355   
 
356  0 toggle @Override
357    public boolean equals(Object obj) {
358  0 return EqualsBuilder.reflectionEquals(obj, this, Constants.HASH_CODE_EQUALS_EXCLUDE);
359    }
360   
 
361  0 toggle @Override
362    public String toString() {
363  0 return ToStringBuilder.reflectionToString(this);
364    }
365   
366    /**
367    * Defines some internal constants used on this class.
368    */
 
369    static class Constants {
370    final static String ROOT_ELEMENT_NAME = "Proposition";
371    final static String TYPE_NAME = "PropositionType";
372    final static String[] HASH_CODE_EQUALS_EXCLUDE = { CoreConstants.CommonElements.FUTURE_ELEMENTS };
373    }
374   
375    /**
376    * A private class which exposes constants which define the XML element names to use
377    * when this object is marshalled to XML.
378    */
 
379    public static class Elements {
380    final static String PROP_ID = "propId";
381    final static String DESC = "description";
382    final static String TYPE_ID = "typeId";
383    final static String PROP_TYPE_CODE = "propositionTypeCode";
384    final static String PARAMETERS = "parameter";
385    final static String CMPND_OP_CODE = "compoundOpCode";
386    final static String CMPND_COMPONENTS = "proposition";
387    }
388   
389    /**
390    * This enumeration identifies the valid Proposition type codes
391    * The PropositionType enumeration lists the appropriate types of propositions
392    * The valid types are:
393    * Compound Propositions - a proposition consisting of other propositions and a boolean algebra operator (AND, OR) defining how to evaluate those propositions
394    * Parameterized Propositions - a proposition which is parameterized by some set of values, evaluation logic is implemented by hand and returns true or false
395    * Simple Propositions - a proposition of the form lhs op rhs where lhs=left-hand side, rhs=right-hand side, and op=operator
396    */
 
397    public enum PropositionTypes {
398    SIMPLE("S"),
399    PARAMETERIZED("P"),
400    COMPOUND("C");
401   
402    private final String code;
 
403  0 toggle private PropositionTypes(String code){
404  0 this.code = code;
405    }
406    public static final Collection<Proposition.PropositionTypes> VALID_TYPES =
407    Collections.unmodifiableCollection(Arrays.asList(SIMPLE, PARAMETERIZED, COMPOUND));
408   
409    public static final Collection<String> VALID_TYPE_CODES =
410    Collections.unmodifiableCollection(Arrays.asList(SIMPLE.code(), PARAMETERIZED.code(), COMPOUND.code()));
411   
 
412  0 toggle public String code(){
413  0 return code;
414    }
 
415  0 toggle @Override
416    public String toString() {
417  0 return code;
418    }
419    }
420    }