001: /*
002: * <copyright>
003: *
004: * Copyright 2002-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.core.adaptivity;
028:
029: import java.util.ArrayList;
030: import java.util.Iterator;
031: import java.util.List;
032: import java.util.ListIterator;
033:
034: /**
035: * Holds a parsed expression for testing the values of Conditions. The
036: * expression is inserted in reverse Polish or postfix notation, but
037: * read out in the opposite (prefix) order.
038: **/
039:
040: public class ConstrainingClause implements java.io.Serializable {
041:
042: public static final ConstrainingClause TRUE_CLAUSE;
043: public static final ConstrainingClause FALSE_CLAUSE;
044: static {
045: TRUE_CLAUSE = new ConstrainingClause();
046: TRUE_CLAUSE.push(BooleanOperator.TRUE);
047: FALSE_CLAUSE = new ConstrainingClause();
048: FALSE_CLAUSE.push(BooleanOperator.FALSE);
049: }
050:
051: private List list = new ArrayList();
052:
053: /**
054: * Append an operator or operand onto the list. It is assumed that
055: * the caller is constructing a well-formed expression.
056: * @param o a String, Operator, ConstraintOpValue, or
057: * ConstrainingClause. If another ConstrainingClause is pushed, its
058: * entire contents is appended, otherwise the item itself is
059: * appended.
060: **/
061: public void push(Object o) {
062: if (o instanceof ConstrainingClause) {
063: list.addAll(((ConstrainingClause) o).list);
064: } else {
065: list.add(o);
066: }
067: }
068:
069: /**
070: * Gets an iterator over the contents in prefix order.
071: * @return an iterator that can walk the clause for evaluation. The
072: * iterator runs through the contents in the reverse order from
073: * which the information was appended. This has the effect of
074: * turning the reverse Polish (postfix) entry order into forward
075: * Polish (prefix) order.
076: **/
077: public Iterator iterator() {
078: return new Iterator() {
079: private ListIterator iter = list.listIterator(list.size());
080:
081: public boolean hasNext() {
082: return iter.hasPrevious();
083: }
084:
085: public Object next() {
086: return iter.previous();
087: }
088:
089: public void remove() {
090: throw new UnsupportedOperationException();
091: }
092: };
093: }
094:
095: public int hashCode() {
096: return list.hashCode();
097: }
098:
099: public boolean equals(Object o) {
100: if (o instanceof ConstrainingClause)
101: return list.equals(((ConstrainingClause) o).list);
102: return false;
103: }
104:
105: /**
106: * Print this clause in infix notation with liberal parentheses
107: **/
108: private String toString(Iterator x) {
109: if (!x.hasNext())
110: return "";
111: String r = null;
112: String l = null;
113: StringBuffer buf = new StringBuffer();
114: Object o = x.next();
115: if (o instanceof ConstraintOpValue) {
116: buf.append('(').append(toString(x)).append(' ').append(o)
117: .append(')');
118: } else if (o instanceof Operator) {
119: Operator op = (Operator) o;
120: switch (op.getOperandCount()) {
121: case 2:
122: r = toString(x);
123: l = toString(x);
124: break;
125: case 1:
126: r = toString(x);
127: break;
128: default:
129: }
130: buf.append('(');
131: if (l != null)
132: buf.append(l).append(' ');
133: buf.append(op);
134: if (r != null)
135: buf.append(' ').append(r);
136: buf.append(')');
137: } else {
138: buf.append(o);
139: }
140: return buf.toString();
141: }
142:
143: /**
144: * Gets the expression in infix format.
145: * @return a string representation of the expression using infix
146: * notation. Parentheses are inserted liberally to make operator
147: * precedence clear.
148: **/
149: public String toString() {
150: return toString(iterator());
151: }
152: }
|