/* * © Copyright FOCONIS AG, 2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * */ package org.openntf.formula.function; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.openntf.formula.DateTime; import org.openntf.formula.FormulaContext; import org.openntf.formula.Function; import org.openntf.formula.FunctionSet; import org.openntf.formula.ValueHolder; import org.openntf.formula.impl.ParameterCollectionBoolean; import org.openntf.formula.impl.ParameterCollectionDouble; import org.openntf.formula.impl.ParameterCollectionInt; /** * This class implements the default arithmetic, boolean and compare operators. * * As Operations are used at most, this is implemented to be (or to try to be) as fast as possible * * @author Roland Praml, Foconis AG * */ public class OperatorsBool extends OperatorsAbstract { public static abstract class Computer { public Computer(final String im) { } public abstract boolean compute(double v1, double v2); public abstract boolean compute(boolean b1, boolean b2); public abstract boolean compute(int v1, int v2); } /** * The Factory that returns a set of operators */ public static class Functions extends FunctionSet { private static final Map<String, Function> functionSet = new HashMap<String, Function>(16); private static void add(final Function f) { functionSet.put(f.getImage().toLowerCase(), f); } @Override public Map<String, Function> getFunctions() { return functionSet; } static { // Define the computers Computer or = new Computer("|") { @Override public boolean compute(final int v1, final int v2) { return (v1 != 0) | (v2 != 0); } @Override public boolean compute(final double v1, final double v2) { return ((int) v1 != 0) | ((int) v2 != 0); } @Override public boolean compute(final boolean b1, final boolean b2) { return b1 | b2; } }; // Define the computers Computer and = new Computer("&") { @Override public boolean compute(final int v1, final int v2) { return (v1 != 0) & (v2 != 0); } @Override public boolean compute(final double v1, final double v2) { return ((int) v1 != 0) & ((int) v2 != 0); } @Override public boolean compute(final boolean b1, final boolean b2) { return b1 & b2; } }; add(new OperatorsBool(and, "&")); add(new OperatorsBool(or, "|")); } } private Computer computer; /** * The constructor. Operators shoud be constructed via Operator.Factory * * @param operation * @param image */ private OperatorsBool(final Computer computer, final String image) { super(image); this.computer = computer; this.isPermutative = false; } // ----------- Strings @Override protected ValueHolder evaluateString(final FormulaContext ctx, final ValueHolder[] params) { throw new UnsupportedOperationException("'" + getImage() + "' is not supported for STRING"); } @Override protected ValueHolder evaluateString(final FormulaContext ctx, final String s1, final String s2) { throw new UnsupportedOperationException("'" + getImage() + "' is not supported for STRING"); } // ----------- Numbers @Override protected ValueHolder evaluateNumber(final FormulaContext ctx, final ValueHolder[] params) { Collection<double[]> values = new ParameterCollectionDouble(params, isPermutative); for (double[] value : values) if (computer.compute(value[0], value[1])) return ctx.TRUE; return ctx.FALSE; } @Override protected ValueHolder evaluateNumber(final FormulaContext ctx, final double d1, final double d2) { return computer.compute(d1, d2) ? ctx.TRUE : ctx.FALSE; } // ----------- Integers @Override protected ValueHolder evaluateInt(final FormulaContext ctx, final ValueHolder[] params) { Collection<int[]> values = new ParameterCollectionInt(params, isPermutative); for (int[] value : values) if (computer.compute(value[0], value[1])) return ctx.TRUE; return ctx.FALSE; } @Override protected ValueHolder evaluateInt(final FormulaContext ctx, final int i1, final int i2) { return computer.compute(i1, i2) ? ctx.TRUE : ctx.FALSE; } // ----------- DateTimes @Override protected ValueHolder evaluateDateTime(final FormulaContext ctx, final ValueHolder[] params) { throw new UnsupportedOperationException("'" + getImage() + "' is not supported for DATETIME"); } @Override protected ValueHolder evaluateDateTime(final FormulaContext ctx, final DateTime dt1, final DateTime dt2) { throw new UnsupportedOperationException("'" + getImage() + "' is not supported for STRING"); } // ----------- Numbers @Override protected ValueHolder evaluateBoolean(final FormulaContext ctx, final ValueHolder[] params) { Collection<boolean[]> values = new ParameterCollectionBoolean(params, isPermutative); for (boolean[] value : values) if (computer.compute(value[0], value[1])) return ctx.TRUE; return ctx.FALSE; } @Override protected ValueHolder evaluateBoolean(final FormulaContext ctx, final boolean b1, final boolean b2) { return computer.compute(b1, b2) ? ctx.TRUE : ctx.FALSE; } }