/*
* © 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.HashMap;
import java.util.Map;
import org.openntf.formula.FormulaContext;
import org.openntf.formula.Function;
import org.openntf.formula.FunctionSet;
import org.openntf.formula.ValueHolder;
import org.openntf.formula.ValueHolder.DataType;
import org.openntf.formula.impl.AtFunction;
/**
* 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 abstract class Negators extends AtFunction {
/**
* 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 {
add(new Negators(" -") { // the space is to distinguish to Op.SUB
@Override
protected int compute(final FormulaContext ctx, final int i) {
return -i;
}
@Override
protected double compute(final FormulaContext ctx, final double d) {
return -d;
}
@Override
protected boolean compute(final FormulaContext ctx, final boolean b) {
return !b;
}
});
add(new Negators(" !") {
@Override
protected int compute(final FormulaContext ctx, final int i) {
return i == 0 ? 1 : 0;
}
@Override
protected double compute(final FormulaContext ctx, final double d) {
return (int) d == 0 ? 1.0D : 0.0D;
}
@Override
protected boolean compute(final FormulaContext ctx, final boolean b) {
return !b;
}
});
}
}
/**
* The constructor. Operators shoud be constructed via Operator.Factory
*
*/
public Negators(final String image) {
super(image);
}
/**
* Evaluates the operator
*/
public ValueHolder evaluate(final FormulaContext ctx, final ValueHolder[] params) {
ValueHolder v1 = params[0]; // Fetch first element to determine operation
if (v1.dataType == DataType.ERROR) {
return v1;
}
ValueHolder ret = v1.newInstance(v1.size);
switch (v1.dataType) {
case INTEGER:
for (int i = 0; i < v1.size; i++) {
ret.add(compute(ctx, v1.getInt(i)));
}
return ret;
case BOOLEAN:
for (int i = 0; i < v1.size; i++) {
ret.add(compute(ctx, v1.getBoolean(i)));
}
return ret;
case DOUBLE:
for (int i = 0; i < v1.size; i++) {
ret.add(compute(ctx, v1.getDouble(i)));
}
return ret;
default:
break;
}
throw new IllegalArgumentException("Operation '" + getImage() + " " + v1.dataType + "' is not supported.");
}
protected abstract boolean compute(FormulaContext ctx, boolean b);
protected abstract int compute(FormulaContext ctx, int i);
protected abstract double compute(FormulaContext ctx, double d);
/* -------------------------------------------------- */
public boolean checkParamCount(final int i) {
// ensured by parser
return true;
}
}