001: //--------------------------------------------------------------------------
002: // Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
003: // All rights reserved.
004: //
005: // Redistribution and use in source and binary forms, with or without
006: // modification, are permitted provided that the following conditions are
007: // met:
008: //
009: // Redistributions of source code must retain the above copyright notice,
010: // this list of conditions and the following disclaimer.
011: // Redistributions in binary form must reproduce the above copyright
012: // notice, this list of conditions and the following disclaimer in the
013: // documentation and/or other materials provided with the distribution.
014: // Neither the name of the Drew Davidson nor the names of its contributors
015: // may be used to endorse or promote products derived from this software
016: // without specific prior written permission.
017: //
018: // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
019: // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
020: // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
021: // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
022: // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
023: // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
024: // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
025: // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
026: // AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
027: // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
028: // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
029: // DAMAGE.
030: //--------------------------------------------------------------------------
031: package ognl;
032:
033: /**
034: An <code>Evaluation</code> is and object that holds a node being evaluated
035: and the source from which that node will take extract its
036: value. It refers to child evaluations that occur as
037: a result of the nodes' evaluation.
038: */
039: public class Evaluation extends Object {
040: private SimpleNode node;
041: private Object source;
042: private boolean setOperation;
043: private Object result;
044: private Throwable exception;
045: private Evaluation parent;
046: private Evaluation next;
047: private Evaluation previous;
048: private Evaluation firstChild;
049: private Evaluation lastChild;
050:
051: /**
052: Constructs a new "get" <code>Evaluation</code> from the node and source given.
053: */
054: public Evaluation(SimpleNode node, Object source) {
055: super ();
056: this .node = node;
057: this .source = source;
058: }
059:
060: /**
061: Constructs a new <code>Evaluation</code> from the node and source given.
062: If <code>setOperation</code> is true this <code>Evaluation</code> represents
063: a "set" as opposed to a "get".
064: */
065: public Evaluation(SimpleNode node, Object source,
066: boolean setOperation) {
067: this (node, source);
068: this .setOperation = setOperation;
069: }
070:
071: /**
072: Returns the <code>SimpleNode</code> for this <code>Evaluation</code>
073: */
074: public SimpleNode getNode() {
075: return node;
076: }
077:
078: /**
079: Sets the node of the evaluation. Normally applications do not need to
080: set this. Notable exceptions to this rule are custom evaluators that
081: choose between navigable objects (as in a multi-root evaluator where
082: the navigable node is chosen at runtime).
083: */
084: public void setNode(SimpleNode value) {
085: node = value;
086: }
087:
088: /**
089: Returns the source object on which this Evaluation operated.
090: */
091: public Object getSource() {
092: return source;
093: }
094:
095: /**
096: Sets the source of the evaluation. Normally applications do not need to
097: set this. Notable exceptions to this rule are custom evaluators that
098: choose between navigable objects (as in a multi-root evaluator where
099: the navigable node is chosen at runtime).
100: */
101: public void setSource(Object value) {
102: source = value;
103: }
104:
105: /**
106: Returns true if this Evaluation represents a set operation.
107: */
108: public boolean isSetOperation() {
109: return setOperation;
110: }
111:
112: /**
113: Marks the Evaluation as a set operation if the value is true, else
114: marks it as a get operation.
115: */
116: public void setSetOperation(boolean value) {
117: setOperation = value;
118: }
119:
120: /**
121: Returns the result of the Evaluation, or null if it was a set operation.
122: */
123: public Object getResult() {
124: return result;
125: }
126:
127: /**
128: Sets the result of the Evaluation. This method is normally only used
129: interally and should not be set without knowledge of what you are doing.
130: */
131: public void setResult(Object value) {
132: result = value;
133: }
134:
135: /**
136: Returns the exception that occurred as a result of evaluating the
137: Evaluation, or null if no exception occurred.
138: */
139: public Throwable getException() {
140: return exception;
141: }
142:
143: /**
144: Sets the exception that occurred as a result of evaluating the
145: Evaluation. This method is normally only used interally and
146: should not be set without knowledge of what you are doing.
147: */
148: public void setException(Throwable value) {
149: exception = value;
150: }
151:
152: /**
153: Returns the parent evaluation of this evaluation. If this returns
154: null then it is is the root evaluation of a tree.
155: */
156: public Evaluation getParent() {
157: return parent;
158: }
159:
160: /**
161: Returns the next sibling of this evaluation. Returns null if
162: this is the last in a chain of evaluations.
163: */
164: public Evaluation getNext() {
165: return next;
166: }
167:
168: /**
169: Returns the previous sibling of this evaluation. Returns null if
170: this is the first in a chain of evaluations.
171: */
172: public Evaluation getPrevious() {
173: return previous;
174: }
175:
176: /**
177: Returns the first child of this evaluation. Returns null if
178: there are no children.
179: */
180: public Evaluation getFirstChild() {
181: return firstChild;
182: }
183:
184: /**
185: Returns the last child of this evaluation. Returns null if
186: there are no children.
187: */
188: public Evaluation getLastChild() {
189: return lastChild;
190: }
191:
192: /**
193: Gets the first descendent. In any Evaluation tree this will the
194: Evaluation that was first executed.
195: */
196: public Evaluation getFirstDescendant() {
197: if (firstChild != null) {
198: return firstChild.getFirstDescendant();
199: }
200: return this ;
201: }
202:
203: /**
204: Gets the last descendent. In any Evaluation tree this will the
205: Evaluation that was most recently executing.
206: */
207: public Evaluation getLastDescendant() {
208: if (lastChild != null) {
209: return lastChild.getLastDescendant();
210: }
211: return this ;
212: }
213:
214: /**
215: Adds a child to the list of children of this evaluation. The
216: parent of the child is set to the receiver and the children
217: references are modified in the receiver to reflect the new child.
218: The lastChild of the receiver is set to the child, and the
219: firstChild is set also if child is the first (or only) child.
220: */
221: public void addChild(Evaluation child) {
222: if (firstChild == null) {
223: firstChild = lastChild = child;
224: } else {
225: if (firstChild == lastChild) {
226: firstChild.next = child;
227: lastChild = child;
228: lastChild.previous = firstChild;
229: } else {
230: child.previous = lastChild;
231: lastChild.next = child;
232: lastChild = child;
233: }
234: }
235: child.parent = this ;
236: }
237:
238: /**
239: Reinitializes this Evaluation to the parameters specified.
240: */
241: public void init(SimpleNode node, Object source,
242: boolean setOperation) {
243: this .node = node;
244: this .source = source;
245: this .setOperation = setOperation;
246: result = null;
247: exception = null;
248: parent = null;
249: next = null;
250: previous = null;
251: firstChild = null;
252: lastChild = null;
253: }
254:
255: /**
256: Resets this Evaluation to the initial state.
257: */
258: public void reset() {
259: init(null, null, false);
260: }
261:
262: /**
263: Produces a String value for the Evaluation. If compact is
264: true then a more compact form of the description only including
265: the node type and unique identifier is shown, else a full
266: description including source and result are shown. If showChildren
267: is true the child evaluations are printed using the depth string
268: given as a prefix.
269: */
270: public String toString(boolean compact, boolean showChildren,
271: String depth) {
272: String stringResult;
273:
274: if (compact) {
275: stringResult = depth + "<" + node.getClass().getName()
276: + " " + System.identityHashCode(this ) + ">";
277: } else {
278: String ss = (source != null) ? source.getClass().getName()
279: : "null", rs = (result != null) ? result.getClass()
280: .getName() : "null";
281:
282: stringResult = depth + "<" + node.getClass().getName()
283: + ": [" + (setOperation ? "set" : "get")
284: + "] source = " + ss + ", result = " + result
285: + " [" + rs + "]>";
286: }
287: if (showChildren) {
288: Evaluation child = firstChild;
289:
290: stringResult += "\n";
291: while (child != null) {
292: stringResult += child.toString(compact, depth + " ");
293: child = child.next;
294: }
295: }
296: return stringResult;
297: }
298:
299: /**
300: Produces a String value for the Evaluation. If compact is
301: true then a more compact form of the description only including
302: the node type and unique identifier is shown, else a full
303: description including source and result are shown. Child
304: evaluations are printed using the depth string given as a prefix.
305: */
306: public String toString(boolean compact, String depth) {
307: return toString(compact, true, depth);
308: }
309:
310: /**
311: Returns a String description of the Evaluation.
312: */
313: public String toString() {
314: return toString(false, "");
315: }
316: }
|