summaryrefslogtreecommitdiffstats
path: root/src/main/java/net/sf/antcontrib/math
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/net/sf/antcontrib/math')
-rw-r--r--src/main/java/net/sf/antcontrib/math/Evaluateable.java28
-rw-r--r--src/main/java/net/sf/antcontrib/math/Math.java584
-rw-r--r--src/main/java/net/sf/antcontrib/math/MathTask.java133
-rw-r--r--src/main/java/net/sf/antcontrib/math/Numeric.java95
-rw-r--r--src/main/java/net/sf/antcontrib/math/Operation.java167
5 files changed, 1007 insertions, 0 deletions
diff --git a/src/main/java/net/sf/antcontrib/math/Evaluateable.java b/src/main/java/net/sf/antcontrib/math/Evaluateable.java
new file mode 100644
index 0000000..2e56967
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/math/Evaluateable.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2001-2004 Ant-Contrib project. All rights reserved.
+ *
+ * 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 net.sf.antcontrib.math;
+
+/**
+ * An object which can evaluate to a numeric value.
+ *
+ * @author inger
+ */
+
+
+public interface Evaluateable
+{
+ Number evaluate();
+}
diff --git a/src/main/java/net/sf/antcontrib/math/Math.java b/src/main/java/net/sf/antcontrib/math/Math.java
new file mode 100644
index 0000000..984a2ce
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/math/Math.java
@@ -0,0 +1,584 @@
+/*
+ * Copyright (c) 2001-2004 Ant-Contrib project. All rights reserved.
+ *
+ * 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 net.sf.antcontrib.math;
+
+import org.apache.tools.ant.BuildException;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+
+/**
+ * Utility class for executing calculations.
+ *
+ * @author inger
+ */
+
+
+public class Math
+{
+ public static final Number evaluate(String operation,
+ String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ if (datatype == null)
+ datatype = "double";
+
+ try
+ {
+ operation = operation.toLowerCase();
+
+ Method m = Math.class.getDeclaredMethod(operation,
+ new Class[]{
+ String.class,
+ Boolean.TYPE,
+ operands.getClass()
+ });
+ Number n = (Number) m.invoke(null,
+ new Object[]{
+ datatype,
+ strict ? Boolean.TRUE : Boolean.FALSE,
+ operands
+ });
+
+ return n;
+ }
+ catch (NoSuchMethodException e)
+ {
+ e.printStackTrace();
+ }
+ catch (IllegalAccessException e)
+ {
+ e.printStackTrace();
+ }
+ catch (InvocationTargetException e)
+ {
+ e.getTargetException().printStackTrace();
+ }
+ return null;
+ }
+
+ public static final Number add(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ Number result = null;
+
+ Number numbers[] = new Number[operands.length];
+ for (int i = 0; i < operands.length; i++)
+ numbers[i] = operands[i].evaluate();
+
+ if (datatype.equalsIgnoreCase("int"))
+ {
+ int sum = 0;
+ for (int i = 0; i < numbers.length; i++)
+ sum += numbers[i].intValue();
+ result = new Integer(sum);
+ }
+ else if (datatype.equalsIgnoreCase("long"))
+ {
+ long sum = 0;
+ for (int i = 0; i < numbers.length; i++)
+ sum += numbers[i].longValue();
+ result = new Long(sum);
+ }
+ else if (datatype.equalsIgnoreCase("float"))
+ {
+ float sum = 0;
+ for (int i = 0; i < numbers.length; i++)
+ sum += numbers[i].floatValue();
+ result = new Float(sum);
+ }
+ else if (datatype.equalsIgnoreCase("double"))
+ {
+ double sum = 0;
+ for (int i = 0; i < numbers.length; i++)
+ sum += numbers[i].doubleValue();
+ result = new Double(sum);
+ }
+ return result;
+ }
+
+ public static final Number subtract(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ Number result = null;
+
+ Number numbers[] = new Number[operands.length];
+ for (int i = 0; i < operands.length; i++)
+ numbers[i] = operands[i].evaluate();
+
+ if (datatype.equalsIgnoreCase("int"))
+ {
+ int sum = numbers[0].intValue();
+ for (int i = 1; i < numbers.length; i++)
+ sum -= numbers[i].intValue();
+ result = new Integer(sum);
+ }
+ else if (datatype.equalsIgnoreCase("long"))
+ {
+ long sum = numbers[0].longValue();
+ for (int i = 1; i < numbers.length; i++)
+ sum -= numbers[i].longValue();
+ result = new Long(sum);
+ }
+ else if (datatype.equalsIgnoreCase("float"))
+ {
+ float sum = numbers[0].floatValue();
+ for (int i = 1; i < numbers.length; i++)
+ sum -= numbers[i].floatValue();
+ result = new Float(sum);
+ }
+ else if (datatype.equalsIgnoreCase("double"))
+ {
+ double sum = numbers[0].doubleValue();
+ for (int i = 1; i < numbers.length; i++)
+ sum -= numbers[i].doubleValue();
+ result = new Double(sum);
+ }
+ return result;
+ }
+
+ public static final Number multiply(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ Number result = null;
+
+ Number numbers[] = new Number[operands.length];
+ for (int i = 0; i < operands.length; i++)
+ numbers[i] = operands[i].evaluate();
+
+ if (datatype.equalsIgnoreCase("int"))
+ {
+ int sum = 1;
+ for (int i = 0; i < numbers.length; i++)
+ sum *= numbers[i].intValue();
+ result = new Integer(sum);
+ }
+ else if (datatype.equalsIgnoreCase("long"))
+ {
+ long sum = 1;
+ for (int i = 0; i < numbers.length; i++)
+ sum *= numbers[i].longValue();
+ result = new Long(sum);
+ }
+ else if (datatype.equalsIgnoreCase("float"))
+ {
+ float sum = 1;
+ for (int i = 0; i < numbers.length; i++)
+ sum *= numbers[i].floatValue();
+ result = new Float(sum);
+ }
+ else if (datatype.equalsIgnoreCase("double"))
+ {
+ double sum = 1;
+ for (int i = 0; i < numbers.length; i++)
+ sum *= numbers[i].doubleValue();
+ result = new Double(sum);
+ }
+ return result;
+ }
+
+ public static final Number divide(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ Number result = null;
+
+ Number numbers[] = new Number[operands.length];
+ for (int i = 0; i < operands.length; i++)
+ numbers[i] = operands[i].evaluate();
+
+ if (datatype.equalsIgnoreCase("int"))
+ {
+ int sum = numbers[0].intValue();
+ for (int i = 1; i < numbers.length; i++)
+ sum /= numbers[i].intValue();
+ result = new Integer(sum);
+ }
+ else if (datatype.equalsIgnoreCase("long"))
+ {
+ long sum = numbers[0].longValue();
+ for (int i = 1; i < numbers.length; i++)
+ sum /= numbers[i].longValue();
+ result = new Long(sum);
+ }
+ else if (datatype.equalsIgnoreCase("float"))
+ {
+ float sum = numbers[0].floatValue();
+ for (int i = 1; i < numbers.length; i++)
+ sum /= numbers[i].floatValue();
+ result = new Float(sum);
+ }
+ else if (datatype.equalsIgnoreCase("double"))
+ {
+ double sum = numbers[0].doubleValue();
+ for (int i = 1; i < numbers.length; i++)
+ sum /= numbers[i].doubleValue();
+ result = new Double(sum);
+ }
+ return result;
+ }
+
+ public static final Number mod(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ Number result = null;
+
+ Number numbers[] = new Number[operands.length];
+ for (int i = 0; i < operands.length; i++)
+ numbers[i] = operands[i].evaluate();
+
+ if (datatype.equalsIgnoreCase("int"))
+ {
+ int sum = numbers[0].intValue();
+ for (int i = 1; i < numbers.length; i++)
+ sum %= numbers[i].intValue();
+ result = new Integer(sum);
+ }
+ else if (datatype.equalsIgnoreCase("long"))
+ {
+ long sum = numbers[0].longValue();
+ for (int i = 1; i < numbers.length; i++)
+ sum %= numbers[i].longValue();
+ result = new Long(sum);
+ }
+ else if (datatype.equalsIgnoreCase("float"))
+ {
+ float sum = numbers[0].floatValue();
+ for (int i = 1; i < numbers.length; i++)
+ sum %= numbers[i].floatValue();
+ result = new Float(sum);
+ }
+ else if (datatype.equalsIgnoreCase("double"))
+ {
+ double sum = numbers[0].doubleValue();
+ for (int i = 1; i < numbers.length; i++)
+ sum %= numbers[i].doubleValue();
+ result = new Double(sum);
+ }
+ return result;
+ }
+
+ public static final Number convert(Number n, String datatype)
+ {
+ if (datatype == null)
+ datatype = "double";
+ if (datatype.equals("int"))
+ return new Integer(n.intValue());
+ if (datatype.equals("long"))
+ return new Long(n.longValue());
+ if (datatype.equals("float"))
+ return new Float(n.floatValue());
+ if (datatype.equals("double"))
+ return new Double(n.doubleValue());
+ throw new BuildException("Invalid datatype.");
+ }
+
+ public static final Number execute(String method,
+ String datatype,
+ boolean strict,
+ Class paramTypes[],
+ Object params[])
+ {
+ try
+ {
+ Class c = null;
+ if (strict)
+ {
+ c = Thread.currentThread().getContextClassLoader().loadClass("java.lang.StrictMath");
+ }
+ else
+ {
+ c = Thread.currentThread().getContextClassLoader().loadClass("java.lang.Math");
+ }
+
+ Method m = c.getDeclaredMethod(method, paramTypes);
+ Number n = (Number) m.invoke(null, params);
+ return convert(n, datatype);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new BuildException(e);
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new BuildException(e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new BuildException(e);
+ }
+ catch (InvocationTargetException e)
+ {
+ throw new BuildException(e);
+ }
+ }
+
+ public static final Number random(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ return execute("random",
+ datatype,
+ strict,
+ new Class[0],
+ new Object[0]);
+ }
+
+ public static Class getPrimitiveClass(String datatype)
+ {
+ if (datatype == null)
+ return Double.TYPE;
+ if (datatype.equals("int"))
+ return Integer.TYPE;
+ if (datatype.equals("long"))
+ return Long.TYPE;
+ if (datatype.equals("float"))
+ return Float.TYPE;
+ if (datatype.equals("double"))
+ return Double.TYPE;
+ throw new BuildException("Invalid datatype.");
+
+ }
+
+ public static final Number abs(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ Object ops[] = new Object[]{convert(operands[0].evaluate(), datatype)};
+ Class params[] = new Class[]{getPrimitiveClass(datatype)};
+
+ return execute("abs",
+ datatype,
+ strict,
+ params,
+ ops);
+ }
+
+ private static final Number doOneDoubleArg(String operation,
+ String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ Object ops[] = new Object[]{convert(operands[0].evaluate(),
+ "double")};
+ Class params[] = new Class[]{Double.TYPE};
+
+ return execute(operation,
+ datatype,
+ strict,
+ params,
+ ops);
+ }
+
+ public static final Number acos(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ return doOneDoubleArg("acos", datatype, strict, operands);
+ }
+
+ public static final Number asin(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ return doOneDoubleArg("asin", datatype, strict, operands);
+ }
+
+ public static final Number atan(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ return doOneDoubleArg("atan", datatype, strict, operands);
+ }
+
+ public static final Number atan2(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ Object ops[] = new Object[]{convert(operands[0].evaluate(),
+ "double"),
+ convert(operands[1].evaluate(),
+ "double")};
+ Class params[] = new Class[]{Double.TYPE,
+ Double.TYPE};
+
+ return execute("atan2",
+ datatype,
+ strict,
+ params,
+ ops);
+ }
+
+ public static final Number sin(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ return doOneDoubleArg("sin", datatype, strict, operands);
+ }
+
+ public static final Number tan(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ return doOneDoubleArg("sin", datatype, strict, operands);
+ }
+
+ public static final Number cos(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ return doOneDoubleArg("cos", datatype, strict, operands);
+ }
+
+ public static final Number ceil(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ return doOneDoubleArg("ceil", datatype, strict, operands);
+ }
+
+ public static final Number floor(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ return doOneDoubleArg("floor", datatype, strict, operands);
+ }
+
+ public static final Number exp(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ return doOneDoubleArg("exp", datatype, strict, operands);
+ }
+
+ public static final Number rint(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ return doOneDoubleArg("rint", datatype, strict, operands);
+ }
+
+ public static final Number round(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ Object ops[] = new Object[]{convert(operands[0].evaluate(),
+ datatype)};
+ Class params[] = new Class[]{getPrimitiveClass(datatype)};
+
+ return execute("round",
+ datatype,
+ strict,
+ params,
+ ops);
+ }
+
+ public static final Number sqrt(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ return doOneDoubleArg("sqrt", datatype, strict, operands);
+ }
+
+ public static final Number degrees(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ return todegrees(datatype, strict, operands);
+ }
+
+ public static final Number todegrees(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ return doOneDoubleArg("toDegrees", datatype, strict, operands);
+ }
+
+ public static final Number radians(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ return toradians(datatype, strict, operands);
+ }
+
+ public static final Number toradians(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ return doOneDoubleArg("toRadians", datatype, strict, operands);
+ }
+
+ public static final Number ieeeremainder(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ Object ops[] = new Object[]{convert(operands[0].evaluate(),
+ "double"),
+ convert(operands[1].evaluate(),
+ "double")};
+ Class params[] = new Class[]{Double.TYPE,
+ Double.TYPE};
+
+ return execute("IEEERemainder",
+ datatype,
+ strict,
+ params,
+ ops);
+ }
+
+ public static final Number min(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ Object ops[] = new Object[]{convert(operands[0].evaluate(),
+ datatype),
+ convert(operands[1].evaluate(),
+ datatype)};
+ Class params[] = new Class[]{getPrimitiveClass(datatype),
+ getPrimitiveClass(datatype)};
+
+ return execute("min",
+ datatype,
+ strict,
+ params,
+ ops);
+ }
+
+ public static final Number max(String datatype,
+ boolean strict,
+ Evaluateable operands[])
+ {
+ Object ops[] = new Object[]{convert(operands[0].evaluate(),
+ datatype),
+ convert(operands[1].evaluate(),
+ datatype)};
+ Class params[] = new Class[]{getPrimitiveClass(datatype),
+ getPrimitiveClass(datatype)};
+
+ return execute("max",
+ datatype,
+ strict,
+ params,
+ ops);
+ }
+
+}
diff --git a/src/main/java/net/sf/antcontrib/math/MathTask.java b/src/main/java/net/sf/antcontrib/math/MathTask.java
new file mode 100644
index 0000000..3250a62
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/math/MathTask.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2001-2004 Ant-Contrib project. All rights reserved.
+ *
+ * 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 net.sf.antcontrib.math;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.DynamicConfigurator;
+
+/**
+ * Task for mathematical operations.
+ *
+ * @author inger
+ */
+
+
+public class MathTask
+ extends Task
+ implements DynamicConfigurator
+{
+ // storage for result
+ private String result = null;
+ private Operation operation = null;
+ private Operation locOperation = null;
+ private String datatype = null;
+ private boolean strict = false;
+
+ public MathTask()
+ {
+ super();
+ }
+
+ public void execute()
+ throws BuildException
+ {
+ Operation op = locOperation;
+ if (op == null)
+ op = operation;
+
+ Number res = op.evaluate();
+
+ if (datatype != null)
+ res = Math.convert(res, datatype);
+ getProject().setUserProperty(result, res.toString());
+ }
+
+ public void setDynamicAttribute(String s, String s1)
+ throws BuildException {
+ throw new BuildException("No dynamic attributes for this task");
+ }
+
+ public Object createDynamicElement(String name)
+ throws BuildException {
+ Operation op = new Operation();
+ op.setOperation(name);
+ operation = op;
+ return op;
+ }
+
+ public void setResult(String result)
+ {
+ this.result = result;
+ }
+
+ public void setDatatype(String datatype)
+ {
+ this.datatype = datatype;
+ }
+
+ public void setStrict(boolean strict)
+ {
+ this.strict = strict;
+ }
+
+ private Operation getLocalOperation()
+ {
+ if (locOperation == null)
+ {
+ locOperation = new Operation();
+ locOperation.setDatatype(datatype);
+ locOperation.setStrict(strict);
+ }
+ return locOperation;
+ }
+
+ public void setOperation(String operation)
+ {
+ getLocalOperation().setOperation(operation);
+ }
+
+ public void setDataType(String dataType)
+ {
+ getLocalOperation().setDatatype(dataType);
+ }
+
+ public void setOperand1(String operand1)
+ {
+ getLocalOperation().setArg1(operand1);
+ }
+
+ public void setOperand2(String operand2)
+ {
+ getLocalOperation().setArg2(operand2);
+ }
+
+ public Operation createOperation()
+ {
+ if (locOperation != null || operation != null)
+ throw new BuildException("Only 1 operation can be specified");
+ this.operation = new Operation();
+ this.operation.setStrict(strict);
+ this.operation.setDatatype(datatype);
+ return this.operation;
+ }
+
+ // conform to old task
+ public Operation createOp()
+ {
+ return createOperation();
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/math/Numeric.java b/src/main/java/net/sf/antcontrib/math/Numeric.java
new file mode 100644
index 0000000..1164e14
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/math/Numeric.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2001-2004 Ant-Contrib project. All rights reserved.
+ *
+ * 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 net.sf.antcontrib.math;
+
+import org.apache.tools.ant.BuildException;
+
+
+/**
+ * A numeric value that implements Evaluateable.
+ *
+ * @author inger
+ */
+
+
+public class Numeric
+ implements Evaluateable
+{
+ private String datatype;
+ private String value;
+
+ /**
+ * Set the value for this number. This string must parse to the set
+ * datatype, for example, setting value to "7.992" and datatype to INT
+ * will cause a number format exception to be thrown. Supports two special
+ * numbers, "E" and "PI".
+ *
+ * @param value the value for this number
+ */
+ public void setValue(String value)
+ {
+ if (value.equals("E"))
+ value = String.valueOf(java.lang.Math.E);
+ else if (value.equals("PI"))
+ value = String.valueOf(java.lang.Math.PI);
+ this.value = value;
+ }
+
+ /**
+ * @return the value for this number as a Number. Cast as appropriate to
+ * Integer, Long, Float, or Double.
+ */
+ public Number evaluate()
+ {
+ if (datatype == null)
+ datatype = "double";
+ if (datatype.equals("int"))
+ return new Integer(value);
+ if (datatype.equals("long"))
+ return new Long(value);
+ if (datatype.equals("float"))
+ return new Float(value);
+ if (datatype.equals("double"))
+ return new Double(value);
+ throw new BuildException("Invalid datatype.");
+ }
+
+ /**
+ * Sets the datatype of this number. Allowed values are
+ * "int", "long", "float", or "double".
+ */
+ public void setDatatype(String p)
+ {
+ datatype = p;
+ }
+
+ /**
+ * @return the datatype as one of the defined types.
+ */
+ public String getDatatype()
+ {
+ if (datatype == null)
+ datatype = "double";
+ return datatype;
+ }
+
+ public String toString()
+ {
+ return "Numeric[value=" + value
+ + ";datatype=" + datatype
+ + "]";
+ }
+}
diff --git a/src/main/java/net/sf/antcontrib/math/Operation.java b/src/main/java/net/sf/antcontrib/math/Operation.java
new file mode 100644
index 0000000..8727a10
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/math/Operation.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2001-2004 Ant-Contrib project. All rights reserved.
+ *
+ * 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 net.sf.antcontrib.math;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DynamicConfigurator;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Vector;
+
+/**
+ * Class to represent a mathematical operation.
+ *
+ * @author inger
+ */
+
+
+public class Operation
+ implements Evaluateable, DynamicConfigurator {
+ private String operation = "add";
+ private Vector operands = new Vector();
+ private String datatype = "double";
+ private boolean strict = false;
+
+ private boolean hasLocalOperands = false;
+ private Numeric localOperands[] = new Numeric[5];
+
+ public void setDynamicAttribute(String s, String s1)
+ throws BuildException {
+ throw new BuildException("no dynamic attributes for this element");
+ }
+
+ public Object createDynamicElement(String name)
+ throws BuildException {
+ Operation op = new Operation();
+ op.setOperation(name);
+ operands.add(op);
+ return op;
+ }
+
+ private void setLocalOperand(String value, int index) {
+ hasLocalOperands = true;
+ localOperands[index - 1] = new Numeric();
+ localOperands[index - 1].setValue(value);
+ }
+
+ public void setArg1(String value) {
+ setLocalOperand(value, 1);
+ }
+
+ public void setArg2(String value) {
+ setLocalOperand(value, 2);
+ }
+
+ public void setArg3(String value) {
+ setLocalOperand(value, 3);
+ }
+
+ public void setArg4(String value) {
+ setLocalOperand(value, 4);
+ }
+
+ public void setArg5(String value) {
+ setLocalOperand(value, 5);
+ }
+
+ public void addConfiguredNumeric(Numeric numeric) {
+ if (hasLocalOperands)
+ throw new BuildException("Cannot combine operand attributes with subelements");
+
+ operands.add(numeric);
+ }
+
+ public void addConfiguredOperation(Operation operation) {
+ if (hasLocalOperands)
+ throw new BuildException("Cannot combine operand attributes with subelements");
+
+ operands.add(operation);
+ }
+
+ public void addConfiguredNum(Numeric numeric) {
+ if (hasLocalOperands)
+ throw new BuildException("Cannot combine operand attributes with subelements");
+
+ operands.add(numeric);
+ }
+
+ public void addConfiguredOp(Operation operation) {
+ if (hasLocalOperands)
+ throw new BuildException("Cannot combine operand attributes with subelements");
+
+ operands.add(operation);
+ }
+
+ public void setOp(String operation) {
+ setOperation(operation);
+ }
+
+ public void setOperation(String operation) {
+ if (operation.equals("+"))
+ this.operation = "add";
+ else if (operation.equals("-"))
+ this.operation = "subtract";
+ else if (operation.equals("*"))
+ this.operation = "multiply";
+ else if (operation.equals("/"))
+ this.operation = "divide";
+ else if (operation.equals("%"))
+ this.operation = "mod";
+ else
+ this.operation = operation;
+ }
+
+ public void setDatatype(String datatype) {
+ this.datatype = datatype;
+ }
+
+ public void setStrict(boolean strict) {
+ this.strict = strict;
+ }
+
+ public Number evaluate() {
+ Evaluateable ops[] = null;
+
+ if (hasLocalOperands) {
+ List localOps = new ArrayList();
+ for (int i = 0; i < localOperands.length; i++) {
+ if (localOperands[i] != null)
+ localOps.add(localOperands[i]);
+ }
+
+ ops = (Evaluateable[]) localOps.toArray(new Evaluateable[localOps.size()]);
+ }
+ else {
+ ops = (Evaluateable[]) operands.toArray(new Evaluateable[operands.size()]);
+ }
+
+ return Math.evaluate(operation,
+ datatype,
+ strict,
+ ops);
+ }
+
+ public String toString() {
+ return "Operation[operation=" + operation
+ + ";datatype=" + datatype
+ + ";strict=" + strict
+ + ";localoperands=" + Arrays.asList(localOperands)
+ + ";operands=" + operands
+ + "]";
+ }
+}