blob: e348daccccf5806c810603693af62f2b69635c48 [file] [log] [blame]
package org.apache.commons.ognl;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/**
* An <code>Evaluation</code> is and object that holds a node being evaluated and the source from which that node will
* take extract its value. It refers to child evaluations that occur as a result of the nodes' evaluation.
*/
public class Evaluation
{
private SimpleNode node;
private Object source;
private boolean setOperation;
private Object result;
private Throwable exception;
private Evaluation parent;
private Evaluation next;
private Evaluation previous;
private Evaluation firstChild;
private Evaluation lastChild;
/**
* Constructs a new "get" <code>Evaluation</code> from the node and source given.
*/
public Evaluation( SimpleNode node, Object source )
{
this.node = node;
this.source = source;
}
/**
* Constructs a new <code>Evaluation</code> from the node and source given. If <code>setOperation</code> is true
* this <code>Evaluation</code> represents a "set" as opposed to a "get".
*/
public Evaluation( SimpleNode node, Object source, boolean setOperation )
{
this( node, source );
this.setOperation = setOperation;
}
/**
* Returns the <code>SimpleNode</code> for this <code>Evaluation</code>
*/
public SimpleNode getNode()
{
return node;
}
/**
* Sets the node of the evaluation. Normally applications do not need to set this. Notable exceptions to this rule
* are custom evaluators that choose between navigable objects (as in a multi-root evaluator where the navigable
* node is chosen at runtime).
*/
public void setNode( SimpleNode value )
{
node = value;
}
/**
* Returns the source object on which this Evaluation operated.
*/
public Object getSource()
{
return source;
}
/**
* Sets the source of the evaluation. Normally applications do not need to set this. Notable exceptions to this rule
* are custom evaluators that choose between navigable objects (as in a multi-root evaluator where the navigable
* node is chosen at runtime).
*/
public void setSource( Object value )
{
source = value;
}
/**
* Returns true if this Evaluation represents a set operation.
*/
public boolean isSetOperation()
{
return setOperation;
}
/**
* Marks the Evaluation as a set operation if the value is true, else marks it as a get operation.
*/
public void setSetOperation( boolean value )
{
setOperation = value;
}
/**
* Returns the result of the Evaluation, or null if it was a set operation.
*/
public Object getResult()
{
return result;
}
/**
* Sets the result of the Evaluation. This method is normally only used interally and should not be set without
* knowledge of what you are doing.
*/
public void setResult( Object value )
{
result = value;
}
/**
* Returns the exception that occurred as a result of evaluating the Evaluation, or null if no exception occurred.
*/
public Throwable getException()
{
return exception;
}
/**
* Sets the exception that occurred as a result of evaluating the Evaluation. This method is normally only used
* interally and should not be set without knowledge of what you are doing.
*/
public void setException( Throwable value )
{
exception = value;
}
/**
* Returns the parent evaluation of this evaluation. If this returns null then it is is the root evaluation of a
* tree.
*/
public Evaluation getParent()
{
return parent;
}
/**
* Returns the next sibling of this evaluation. Returns null if this is the last in a chain of evaluations.
*/
public Evaluation getNext()
{
return next;
}
/**
* Returns the previous sibling of this evaluation. Returns null if this is the first in a chain of evaluations.
*/
public Evaluation getPrevious()
{
return previous;
}
/**
* Returns the first child of this evaluation. Returns null if there are no children.
*/
public Evaluation getFirstChild()
{
return firstChild;
}
/**
* Returns the last child of this evaluation. Returns null if there are no children.
*/
public Evaluation getLastChild()
{
return lastChild;
}
/**
* Gets the first descendent. In any Evaluation tree this will the Evaluation that was first executed.
*/
public Evaluation getFirstDescendant()
{
if ( firstChild != null )
{
return firstChild.getFirstDescendant();
}
return this;
}
/**
* Gets the last descendent. In any Evaluation tree this will the Evaluation that was most recently executing.
*/
public Evaluation getLastDescendant()
{
if ( lastChild != null )
{
return lastChild.getLastDescendant();
}
return this;
}
/**
* Adds a child to the list of children of this evaluation. The parent of the child is set to the receiver and the
* children references are modified in the receiver to reflect the new child. The lastChild of the receiver is set
* to the child, and the firstChild is set also if child is the first (or only) child.
*/
public void addChild( Evaluation child )
{
if ( firstChild == null )
{
firstChild = child;
lastChild = child;
}
else
{
if ( firstChild == lastChild )
{
firstChild.next = child;
lastChild = child;
lastChild.previous = firstChild;
}
else
{
child.previous = lastChild;
lastChild.next = child;
lastChild = child;
}
}
child.parent = this;
}
/**
* Reinitializes this Evaluation to the parameters specified.
*/
public void init( SimpleNode node, Object source, boolean setOperation )
{
this.node = node;
this.source = source;
this.setOperation = setOperation;
result = null;
exception = null;
parent = null;
next = null;
previous = null;
firstChild = null;
lastChild = null;
}
/**
* Resets this Evaluation to the initial state.
*/
public void reset()
{
init( null, null, false );
}
/**
* Produces a String value for the Evaluation. If compact is true then a more compact form of the description only
* including the node type and unique identifier is shown, else a full description including source and result are
* shown. If showChildren is true the child evaluations are printed using the depth string given as a prefix.
*/
public String toString( boolean compact, boolean showChildren, String depth )
{
StringBuilder stringResult;
if ( compact )
{
stringResult = new StringBuilder(depth + "<" + node.getClass().getName() + " " + System.identityHashCode(this) + ">");
}
else
{
String ss = ( source != null ) ? source.getClass().getName() : "null", rs =
( result != null ) ? result.getClass().getName() : "null";
stringResult = new StringBuilder(depth + "<" + node.getClass().getName() + ": [" + (setOperation ? "set" : "get") + "] source = " + ss
+ ", result = " + result + " [" + rs + "]>");
}
if ( showChildren )
{
Evaluation child = firstChild;
stringResult.append("\n");
while ( child != null )
{
stringResult.append(child.toString(compact, depth + " "));
child = child.next;
}
}
return stringResult.toString();
}
/**
* Produces a String value for the Evaluation. If compact is true then a more compact form of the description only
* including the node type and unique identifier is shown, else a full description including source and result are
* shown. Child evaluations are printed using the depth string given as a prefix.
*/
public String toString( boolean compact, String depth )
{
return toString( compact, true, depth );
}
/**
* Returns a String description of the Evaluation.
*/
@Override
public String toString()
{
return toString( false, "" );
}
}