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