View Javadoc

1   /**
2    * Copyright 2005-2013 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.framework.engine;
17  
18  import java.util.ArrayList;
19  import java.util.Collections;
20  import java.util.List;
21  
22  import org.kuali.rice.krms.api.engine.ExecutionEnvironment;
23  import org.kuali.rice.krms.api.engine.ResultEvent;
24  import org.kuali.rice.krms.api.engine.ExecutionFlag;
25  import org.kuali.rice.krms.api.repository.LogicalOperator;
26  import org.kuali.rice.krms.framework.engine.result.BasicResult;
27  
28  /**
29   *
30   * An implementation of {@link Proposition} which holds other Propositions and a {@link LogicalOperator}.
31   *
32   * @author Kuali Rice Team (rice.collab@kuali.org)
33   */
34  public final class CompoundProposition implements Proposition {
35  	
36      private static final ResultLogger LOG = ResultLogger.getInstance();
37      
38  	private final LogicalOperator logicalOperator;
39  	private final List<Proposition> propositions;
40  
41      /**
42       * Create a CompoundProposition with the given values
43       * @param logicalOperator {@link LogicalOperator} to set logicalOperator to
44       * @param propositions to set the propositions to
45       */
46  	public CompoundProposition(LogicalOperator logicalOperator, List<Proposition> propositions) {
47  				
48  		if (propositions == null || propositions.isEmpty()) {
49  			throw new IllegalArgumentException("Propositions must be non-null and non-empty.");
50  		}
51  		if (logicalOperator == null) {
52  			throw new IllegalArgumentException("Logical operator must be non-null.");
53  		}
54  		this.logicalOperator = logicalOperator;
55  		this.propositions = new ArrayList<Proposition>(propositions);
56  	}
57  	
58  	@Override
59  	public PropositionResult evaluate(ExecutionEnvironment environment) {
60  		
61  		PropositionResult result = evaluateInner(environment);
62  		
63  		// handle compound proposition result logging
64  		if (LOG.isEnabled(environment)) { 
65              LOG.logResult(new BasicResult(ResultEvent.PROPOSITION_EVALUATED, this, environment, result.getResult()));
66          }
67  		
68  		return result;
69  	}
70  
71      /**
72       * Evaluates then {@link ExecutionEnvironment}
73       *
74       * @param environment {@link ExecutionEnvironment} to use for evaluation
75       * @return PropositionResult {@link PropositionResult} the results of the evaluation
76       * @throws IllegalStateException if the logicalOperator is invalid.
77       */
78  	
79      private PropositionResult evaluateInner(ExecutionEnvironment environment) {
80      	
81      	boolean collatedResult;
82      	boolean evaluateAll = environment.getExecutionOptions().getFlag(ExecutionFlag.EVALUATE_ALL_PROPOSITIONS);
83      	
84          if (logicalOperator == LogicalOperator.AND) {
85  
86              collatedResult = true;
87  
88  			for (Proposition proposition : propositions) {
89  				
90  				PropositionResult singleResult = proposition.evaluate(environment);
91  				logPropositionResult(proposition, singleResult, environment);
92  								
93  				if (!singleResult.getResult()) {
94  					collatedResult = false;
95  					if(!evaluateAll) break;
96  				}
97  			}
98  			
99  			return new PropositionResult(collatedResult);
100 			
101 		} else if (logicalOperator == LogicalOperator.OR) {
102 			
103 		    collatedResult = false;
104 			
105 			for (Proposition proposition : propositions) {
106 				
107 			    PropositionResult singleResult = proposition.evaluate(environment);
108 				logPropositionResult(proposition, singleResult, environment);
109 				
110 				if (singleResult.getResult()) {
111 					collatedResult = true;
112 					if(!evaluateAll) break;
113 				}
114 			}
115 			
116 			return new PropositionResult(collatedResult);
117 		}
118 		throw new IllegalStateException("Invalid logical operator: " + logicalOperator);
119     }
120     
121     /*
122      * Logs only if the proposition is not compound
123      * and have the compound proposition log its own result
124      * @param proposition {@link Proposition} to log.  Compound Propositions will not log.
125      * @param propositionResult {@link PropositionResult} to log the result and execution details of
126      * @param environment {@link ExecutionEnvironment} to log
127      */
128     
129     public void logPropositionResult(Proposition proposition, PropositionResult propositionResult, ExecutionEnvironment environment) {
130     	    	
131     	if(!proposition.isCompound()) {
132             LOG.logResult(new BasicResult(propositionResult.getExecutionDetails(), ResultEvent.PROPOSITION_EVALUATED, proposition, environment, propositionResult.getResult()));
133     	}
134     	
135     }
136 
137     /**
138      * Returns an unmodifiableList of {@link Proposition}s.
139      * @return an unmodifiableList of {@link Proposition}s
140      */
141     @Override
142     public List<Proposition> getChildren() {
143         return Collections.unmodifiableList(propositions);
144     }
145     
146     @Override
147     public boolean isCompound() {
148         return true;
149     }
150 
151 }