001/**
002 * Copyright 2005-2016 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 */
016package org.kuali.rice.krms.framework.engine.expression;
017
018import org.kuali.rice.krms.api.engine.expression.ComparisonOperatorService;
019
020import java.util.Iterator;
021import java.util.LinkedList;
022import java.util.List;
023
024/**
025 * {@link ComparisonOperatorService} Implementation.
026 * @author Kuali Rice Team (rice.collab@kuali.org)
027 */
028public class ComparisonOperatorServiceImpl implements ComparisonOperatorService {
029
030    private List<EngineComparatorExtension> operators = new LinkedList<EngineComparatorExtension>();
031
032    private List<StringCoercionExtension> stringCoercionExtensions = new LinkedList<StringCoercionExtension>();
033
034    private ComparisonOperatorServiceImpl() {}
035
036    /**
037     * Factory method for getting a {@link ComparisonOperatorService}
038     * @return a {@link ComparisonOperatorService}
039     */
040    public static ComparisonOperatorService getInstance() {
041        return new ComparisonOperatorServiceImpl();
042    }
043
044    @Override
045    public List<StringCoercionExtension> getStringCoercionExtensions() {
046        return stringCoercionExtensions;
047    }
048
049    @Override
050    public void setStringCoercionExtensions(List<StringCoercionExtension> stringCoercionExtensions) {
051        this.stringCoercionExtensions = stringCoercionExtensions;
052    }
053
054    @Override
055    public List<EngineComparatorExtension> getOperators() {
056        return operators;
057    }
058
059    @Override
060    public void setOperators(List<EngineComparatorExtension> operators) {
061        this.operators = operators;
062    }
063
064    /**
065     * Returns the {@link EngineComparatorExtension} that can compare the lhs and rhs objects.  If none, then returns the
066     * {@link DefaultComparisonOperator}
067     * @param lhs left hand side object
068     * @param rhs right hand side object
069     * @return an EngineComparatorExtension that can compare the lhs and rhs
070     */
071    @Override
072    public EngineComparatorExtension findComparatorExtension(Object lhs, Object rhs) {
073        EngineComparatorExtension extension;
074        Iterator<EngineComparatorExtension> opIter = operators.iterator();
075        while (opIter.hasNext()) {
076            extension = opIter.next();
077            if (extension.canCompare(lhs, rhs)) {
078                return extension;
079            }
080        }
081        return new DefaultComparisonOperator();
082    }
083
084    @Override
085    public int compare(Object lhs, Object rhs) {
086        return findComparatorExtension(lhs, rhs).compare(lhs, rhs);
087    }
088
089    @Override
090    public boolean canCompare(Object lhs, Object rhs) {
091        return findComparatorExtension(lhs, rhs) != null;
092    }
093
094    /**
095     * Returns the {@link EngineComparatorExtension} that can coerce the lhs and rhs objects.  If none, then returns the
096     * {@link DefaultComparisonOperator}, which also handles default coercion
097     * @param type class type to attempt to coerce to
098     * @param value value to attempt to coerce the given type with
099     * @return an EngineComparatorExtension that can coerce the type and value
100     */
101    @Override
102    public StringCoercionExtension findStringCoercionExtension(String type, String value) {
103        StringCoercionExtension extension;
104        Iterator<StringCoercionExtension> opIter = stringCoercionExtensions.iterator();
105        while (opIter.hasNext()) {
106            extension = opIter.next();
107            if (extension.canCoerce(type, value)) {
108                return extension;
109            }
110        }
111        return new DefaultComparisonOperator(); // default coercion is also in the DefaultComparisonOperator
112    }
113
114    @Override
115    public boolean canCoerce(String type, String value) {
116        return findStringCoercionExtension(type, value) != null;
117    }
118
119    @Override
120    public Object coerce(String type, String value) {
121        return findStringCoercionExtension(type, value).coerce(type, value);
122    }
123}