blob: b1ec399dfe9eeff2028102fe2b3c8d1af7e2e890 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 University of Illinois All rights reserved. This program
* and the accompanying materials are made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Albert L. Rossi - design and implementation
******************************************************************************/
package org.eclipse.ptp.rm.jaxb.core.data.impl;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.ptp.rm.jaxb.core.IAssign;
import org.eclipse.ptp.rm.jaxb.core.IJAXBNonNLSConstants;
import org.eclipse.ptp.rm.jaxb.core.data.Test;
import org.eclipse.ptp.rm.jaxb.core.data.Test.Else;
import org.eclipse.ptp.rm.jaxb.core.messages.Messages;
import org.eclipse.ptp.rm.jaxb.core.utils.CoreExceptionUtils;
public class TestImpl implements IJAXBNonNLSConstants {
private static final short sEQ = 0;
private static final short sLT = 1;
private static final short sGT = 2;
private static final short sLE = 3;
private static final short sGE = 4;
private static final short sAND = 5;
private static final short sOR = 6;
private static final short sNOT = 7;
private final String uuid;
private final short op;
private final List<String> values;
private List<TestImpl> children;
private List<IAssign> ifcond;
private List<IAssign> elsecond;
private Object target;
public TestImpl(String uuid, Test test) {
this.uuid = uuid;
op = getOp(test.getOp());
values = test.getValue();
List<Test> tests = test.getTest();
if (!tests.isEmpty()) {
children = new ArrayList<TestImpl>();
for (Test t : tests) {
children.add(new TestImpl(uuid, t));
}
}
List<Object> listif = test.getAddOrAppendOrPut();
if (!listif.isEmpty()) {
ifcond = new ArrayList<IAssign>();
for (Object o : listif) {
AbstractAssign.add(uuid, o, ifcond);
}
}
Else listelse = test.getElse();
if (listelse != null) {
elsecond = new ArrayList<IAssign>();
for (Object o : listelse.getAddOrAppendOrPut()) {
AbstractAssign.add(uuid, o, elsecond);
}
}
}
public boolean doTest() throws Throwable {
boolean result = false;
validate(op);
switch (op) {
case sEQ:
result = evaluateEquals(values.get(0), values.get(1));
break;
case sLT:
result = evaluateLessThan(values.get(0), values.get(1));
break;
case sGT:
result = evaluateLessThan(values.get(1), values.get(0));
break;
case sLE:
result = evaluateLessThanOrEquals(values.get(0), values.get(1));
break;
case sGE:
result = evaluateLessThanOrEquals(values.get(1), values.get(0));
break;
case sNOT:
return !children.get(0).doTest();
case sAND:
result = true;
for (TestImpl t : children) {
result = result && t.doTest();
if (!result) {
break;
}
}
break;
case sOR:
result = false;
for (TestImpl t : children) {
result = result || t.doTest();
if (result) {
break;
}
}
break;
}
if (target != null) {
if (result) {
doAssign(ifcond);
} else {
doAssign(elsecond);
}
}
return result;
}
public void setTarget(Object target) {
this.target = target;
if (children != null) {
for (TestImpl t : children) {
t.setTarget(target);
}
}
}
/*
* These will be using only preassigned values, so the tokens[] param is
* null
*/
private void doAssign(List<IAssign> assign) throws Throwable {
if (assign != null) {
for (IAssign a : assign) {
a.setTarget(target);
a.assign(null);
}
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private int evaluateComparable(String string1, String string2) throws Throwable {
Object value1 = AbstractAssign.normalizedValue(target, uuid, string1, true);
Object value2 = AbstractAssign.normalizedValue(target, uuid, string2, true);
if (value1 == null || value2 == null) {
return 1;
}
if (!(value1 instanceof Comparable) || !(value2 instanceof Comparable)) {
return 1;
}
Comparable c1 = (Comparable) value1;
Comparable c2 = (Comparable) value2;
return c1.compareTo(c2);
}
private boolean evaluateEquals(String string1, String string2) throws Throwable {
Object value1 = AbstractAssign.normalizedValue(target, uuid, string1, true);
Object value2 = AbstractAssign.normalizedValue(target, uuid, string2, true);
if (value1 == null) {
return value2 == null;
}
return value1.equals(value2);
}
private boolean evaluateLessThan(String string1, String string2) throws Throwable {
return evaluateComparable(string1, string2) < 0;
}
private boolean evaluateLessThanOrEquals(String string1, String string2) throws Throwable {
return evaluateComparable(string1, string2) <= 0;
}
private String getOp(short op) {
if (sEQ == op) {
return xEQ;
}
if (sLT == op) {
return xLT;
}
if (sGT == op) {
return xGT;
}
if (sLE == op) {
return xLE;
}
if (sGE == op) {
return xGE;
}
if (sAND == op) {
return AND;
}
if (sOR == op) {
return OR;
}
if (sNOT == op) {
return NOT;
}
return EQ;
}
private short getOp(String op) {
if (xEQ.equalsIgnoreCase(op)) {
return sEQ;
}
if (xLT.equalsIgnoreCase(op)) {
return sLT;
}
if (xGT.equalsIgnoreCase(op)) {
return sGT;
}
if (xLE.equalsIgnoreCase(op)) {
return sLE;
}
if (xGE.equalsIgnoreCase(op)) {
return sGE;
}
if (AND.equalsIgnoreCase(op)) {
return sAND;
}
if (OR.equalsIgnoreCase(op)) {
return sOR;
}
if (NOT.equalsIgnoreCase(op)) {
return sNOT;
}
return sEQ;
}
private void validate(short op) throws Throwable {
switch (op) {
case sEQ:
case sLT:
case sGT:
case sLE:
case sGE:
if (values == null || values.size() != 2) {
throw CoreExceptionUtils.newException(Messages.MalformedExpressionError + getOp(op), null);
}
break;
case sNOT:
if (children == null || children.size() != 1) {
throw CoreExceptionUtils.newException(Messages.MalformedExpressionError + getOp(op), null);
}
break;
case sAND:
case sOR:
if (children == null || children.size() <= 1) {
throw CoreExceptionUtils.newException(Messages.MalformedExpressionError + getOp(op), null);
}
break;
}
}
}