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 }