View Javadoc

1   package org.apache.commons.ognl;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  /**
23   * An <code>Evaluation</code> is and object that holds a node being evaluated and the source from which that node will
24   * take extract its value. It refers to child evaluations that occur as a result of the nodes' evaluation.
25   */
26  public class Evaluation
27  {
28      private SimpleNode node;
29  
30      private Object source;
31  
32      private boolean setOperation;
33  
34      private Object result;
35  
36      private Throwable exception;
37  
38      private Evaluation parent;
39  
40      private Evaluation next;
41  
42      private Evaluation previous;
43  
44      private Evaluation firstChild;
45  
46      private Evaluation lastChild;
47  
48      /**
49       * Constructs a new "get" <code>Evaluation</code> from the node and source given.
50       */
51      public Evaluation( SimpleNode node, Object source )
52      {
53          super();
54          this.node = node;
55          this.source = source;
56      }
57  
58      /**
59       * Constructs a new <code>Evaluation</code> from the node and source given. If <code>setOperation</code> is true
60       * this <code>Evaluation</code> represents a "set" as opposed to a "get".
61       */
62      public Evaluation( SimpleNode node, Object source, boolean setOperation )
63      {
64          this( node, source );
65          this.setOperation = setOperation;
66      }
67  
68      /**
69       * Returns the <code>SimpleNode</code> for this <code>Evaluation</code>
70       */
71      public SimpleNode getNode()
72      {
73          return node;
74      }
75  
76      /**
77       * Sets the node of the evaluation. Normally applications do not need to set this. Notable exceptions to this rule
78       * are custom evaluators that choose between navigable objects (as in a multi-root evaluator where the navigable
79       * node is chosen at runtime).
80       */
81      public void setNode( SimpleNode value )
82      {
83          node = value;
84      }
85  
86      /**
87       * Returns the source object on which this Evaluation operated.
88       */
89      public Object getSource()
90      {
91          return source;
92      }
93  
94      /**
95       * Sets the source of the evaluation. Normally applications do not need to set this. Notable exceptions to this rule
96       * are custom evaluators that choose between navigable objects (as in a multi-root evaluator where the navigable
97       * node is chosen at runtime).
98       */
99      public void setSource( Object value )
100     {
101         source = value;
102     }
103 
104     /**
105      * Returns true if this Evaluation represents a set operation.
106      */
107     public boolean isSetOperation()
108     {
109         return setOperation;
110     }
111 
112     /**
113      * Marks the Evaluation as a set operation if the value is true, else marks it as a get operation.
114      */
115     public void setSetOperation( boolean value )
116     {
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     {
125         return result;
126     }
127 
128     /**
129      * Sets the result of the Evaluation. This method is normally only used interally and should not be set without
130      * knowledge of what you are doing.
131      */
132     public void setResult( Object value )
133     {
134         result = value;
135     }
136 
137     /**
138      * Returns the exception that occurred as a result of evaluating the Evaluation, or null if no exception occurred.
139      */
140     public Throwable getException()
141     {
142         return exception;
143     }
144 
145     /**
146      * Sets the exception that occurred as a result of evaluating the Evaluation. This method is normally only used
147      * interally and should not be set without knowledge of what you are doing.
148      */
149     public void setException( Throwable value )
150     {
151         exception = value;
152     }
153 
154     /**
155      * Returns the parent evaluation of this evaluation. If this returns null then it is is the root evaluation of a
156      * tree.
157      */
158     public Evaluation getParent()
159     {
160         return parent;
161     }
162 
163     /**
164      * Returns the next sibling of this evaluation. Returns null if this is the last in a chain of evaluations.
165      */
166     public Evaluation getNext()
167     {
168         return next;
169     }
170 
171     /**
172      * Returns the previous sibling of this evaluation. Returns null if this is the first in a chain of evaluations.
173      */
174     public Evaluation getPrevious()
175     {
176         return previous;
177     }
178 
179     /**
180      * Returns the first child of this evaluation. Returns null if there are no children.
181      */
182     public Evaluation getFirstChild()
183     {
184         return firstChild;
185     }
186 
187     /**
188      * Returns the last child of this evaluation. Returns null if there are no children.
189      */
190     public Evaluation getLastChild()
191     {
192         return lastChild;
193     }
194 
195     /**
196      * Gets the first descendent. In any Evaluation tree this will the Evaluation that was first executed.
197      */
198     public Evaluation getFirstDescendant()
199     {
200         if ( firstChild != null )
201         {
202             return firstChild.getFirstDescendant();
203         }
204         return this;
205     }
206 
207     /**
208      * Gets the last descendent. In any Evaluation tree this will the Evaluation that was most recently executing.
209      */
210     public Evaluation getLastDescendant()
211     {
212         if ( lastChild != null )
213         {
214             return lastChild.getLastDescendant();
215         }
216         return this;
217     }
218 
219     /**
220      * Adds a child to the list of children of this evaluation. The parent of the child is set to the receiver and the
221      * children references are modified in the receiver to reflect the new child. The lastChild of the receiver is set
222      * to the child, and the firstChild is set also if child is the first (or only) child.
223      */
224     public void addChild( Evaluation child )
225     {
226         if ( firstChild == null )
227         {
228             firstChild = child;
229             lastChild = child;
230         }
231         else
232         {
233             if ( firstChild == lastChild )
234             {
235                 firstChild.next = child;
236                 lastChild = child;
237                 lastChild.previous = firstChild;
238             }
239             else
240             {
241                 child.previous = lastChild;
242                 lastChild.next = child;
243                 lastChild = child;
244             }
245         }
246         child.parent = this;
247     }
248 
249     /**
250      * Reinitializes this Evaluation to the parameters specified.
251      */
252     public void init( SimpleNode node, Object source, boolean setOperation )
253     {
254         this.node = node;
255         this.source = source;
256         this.setOperation = setOperation;
257         result = null;
258         exception = null;
259         parent = null;
260         next = null;
261         previous = null;
262         firstChild = null;
263         lastChild = null;
264     }
265 
266     /**
267      * Resets this Evaluation to the initial state.
268      */
269     public void reset()
270     {
271         init( null, null, false );
272     }
273 
274     /**
275      * Produces a String value for the Evaluation. If compact is true then a more compact form of the description only
276      * including the node type and unique identifier is shown, else a full description including source and result are
277      * shown. If showChildren is true the child evaluations are printed using the depth string given as a prefix.
278      */
279     public String toString( boolean compact, boolean showChildren, String depth )
280     {
281         String stringResult;
282 
283         if ( compact )
284         {
285             stringResult = depth + "<" + node.getClass().getName() + " " + System.identityHashCode( this ) + ">";
286         }
287         else
288         {
289             String ss = ( source != null ) ? source.getClass().getName() : "null", rs =
290                 ( result != null ) ? result.getClass().getName() : "null";
291 
292             stringResult =
293                 depth + "<" + node.getClass().getName() + ": [" + ( setOperation ? "set" : "get" ) + "] source = " + ss
294                     + ", result = " + result + " [" + rs + "]>";
295         }
296         if ( showChildren )
297         {
298             Evaluation child = firstChild;
299 
300             stringResult += "\n";
301             while ( child != null )
302             {
303                 stringResult += child.toString( compact, depth + "  " );
304                 child = child.next;
305             }
306         }
307         return stringResult;
308     }
309 
310     /**
311      * Produces a String value for the Evaluation. If compact is true then a more compact form of the description only
312      * including the node type and unique identifier is shown, else a full description including source and result are
313      * shown. Child evaluations are printed using the depth string given as a prefix.
314      */
315     public String toString( boolean compact, String depth )
316     {
317         return toString( compact, true, depth );
318     }
319 
320     /**
321      * Returns a String description of the Evaluation.
322      */
323     @Override
324     public String toString()
325     {
326         return toString( false, "" );
327     }
328 }