001: /*
002: * <copyright>
003: *
004: * Copyright 1997-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.lib.contract.lang.op.reflect;
028:
029: import java.util.*;
030: import java.lang.reflect.*;
031:
032: import org.cougaar.lib.contract.lang.*;
033: import org.cougaar.lib.contract.lang.op.OpCodes;
034: import org.cougaar.lib.contract.lang.op.constant.ConstantOp;
035:
036: /**
037: * "field" <code>Op</code>.
038: **/
039:
040: public final class FieldOp extends OpImpl {
041:
042: public Field field;
043:
044: public FieldOp() {
045: }
046:
047: public final int getID() {
048: return OpCodes.FIELD_ID;
049: }
050:
051: /**
052: * <code>ReflectOp</code> should use <tt>parseField</tt>.
053: */
054: public final Op parse(final OpParser p) throws ParseException {
055: throw new ParseException(
056: "Internal use should be \"parseField\"");
057: }
058:
059: /**
060: * Parse the arguments for the given <code>Field</code>.
061: */
062: public final Op parseField(final Field field, final OpParser p)
063: throws ParseException {
064:
065: // get field type
066: Class retClass = field.getType();
067:
068: // should be single argument
069: p.setTypeList(retClass);
070: Op u = p.nextOp();
071: if (u != null) {
072: throw new ParseException(
073: "Field \""
074: + field.getName()
075: + "\" expecting zero arguments but given additional "
076: + u.getClass().getName());
077: }
078:
079: // check for constant
080: int fmods = field.getModifiers();
081: if (((fmods & Modifier.STATIC) != 0)
082: && ((fmods & Modifier.FINAL) != 0)) {
083: // get field value
084: Object fval;
085: try {
086: fval = field.get(null);
087: } catch (Exception e) {
088: throw new ParseException("Field \""
089: + ReflectOp.toString(field, true)
090: + "\" fetch resulted in Exception: " + e);
091: }
092: if ((fval == null) || (retClass == String.class)
093: || (retClass.isPrimitive())) {
094: // create constant op
095: return new ConstantOp(retClass, fval);
096: } else {
097: // keep as a field reference for ConstantOp.accept,
098: // otherwise one would be unable to re-parse the
099: // toString.
100: }
101: }
102:
103: // (field)
104: this .field = field;
105: return this ;
106: }
107:
108: public final boolean isReturnBoolean() {
109: return (getReturnClass() == Boolean.TYPE);
110: }
111:
112: public final Class getReturnClass() {
113: return field.getType();
114: }
115:
116: public final boolean execute(final Object o) {
117: Object ret = operate(o);
118: return ((Boolean) ret).booleanValue();
119: }
120:
121: public final Object operate(final Object o) {
122: try {
123: return field.get(o);
124: } catch (Exception e) {
125: throw new RuntimeException("Field \""
126: + getFieldString(true)
127: + "\" fetch resulted in Exception: " + e);
128: }
129: }
130:
131: public final String getFieldString(boolean verbose) {
132: return ReflectOp.toString(field, verbose);
133: }
134:
135: public final void accept(TreeVisitor visitor) {
136: // (field)
137: visitor.visitWord(getFieldString(visitor.isVerbose()));
138: visitor.visitEnd();
139: }
140: }
|