001    /**
002     * Copyright 2005-2014 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.rice.krms.framework.engine;
017    
018    /**
019     * <p>Enumeration for simple collection operators used by {@link CollectionOfComparablesTermBasedProposition}.  The
020     * operators encapsulate logic for how to collate results and when to short circuit as a collection is being
021     * processed.  Correct usage is best summarized by this code block:</p>
022     * <pre>
023     * for (Comparable<T> item : comparableItems) {
024     *     collatedResult = collectionOper.reduce(compare(item, compareValue), collatedResult);
025     *     if (collectionOper.shortCircuit(collatedResult)) break;
026     * }
027     * </pre>
028     * 
029     * @author Kuali Rice Team (rice.collab@kuali.org)
030     *
031     */
032    public enum CollectionOperator {
033    
034            ONE_OR_MORE(false) {
035                    @Override
036                    public boolean reduce(boolean elementResult, boolean collatedResult) {
037                            return elementResult || collatedResult;
038                    }
039                    
040                    @Override
041                    public boolean shortCircuit(boolean collatedResult) {
042                            return collatedResult;
043                    }
044            },
045            
046            ALL(true) {
047                    @Override
048                    public boolean reduce(boolean elementResult, boolean collatedResult) {
049                            return elementResult && collatedResult;
050                    }
051    
052                    @Override
053                    public boolean shortCircuit(boolean collatedResult) {
054                            return !collatedResult;
055                    }
056            },
057            
058            NONE(true) {
059                    @Override
060                    public boolean reduce(boolean elementResult, boolean collatedResult) {
061                            return !elementResult && collatedResult;
062                    }
063    
064                    @Override
065                    public boolean shortCircuit(boolean collatedResult) {
066                            return !collatedResult;
067                    }
068            };
069            
070            private final boolean initialCollationResult;
071            
072            private CollectionOperator(boolean initialCollationResult) {
073                    this.initialCollationResult = initialCollationResult;
074            }
075            
076            /**
077             * This method takes the collated result thus far and the result for the next element,
078             * and produces the next collated result.
079             * 
080             * @return the new collated result
081             */
082            public abstract boolean reduce(boolean elementResult, boolean collatedResult);
083            
084            /**
085             * This method lets the engine know if it can short circuit its iteration through the list based on the 
086             * collated result.  The condition when short circuiting can be done varies with the operator.
087             * 
088             * @param collatedResult
089             * @return true if short circuiting can be done to optimize processing
090             */
091            public abstract boolean shortCircuit(boolean collatedResult);
092            
093            /**
094             * when the result for the first item in the collection is calculated, there isn't yet a collated result 
095             * to use in the {@link #reduce(boolean, boolean)} method.  Different operators require different
096             * initial values to function correctly, so this property holds the correct initial collated value for the 
097             * given operator instance.
098             */
099            public boolean getInitialCollatedResult() {
100                    return initialCollationResult;
101            }
102            
103    }