Commits

Anonymous committed 67de2fd

Fixes OGNl-121.

Comments (0)

Files changed (1)

src/java/ognl/SimpleNode.java

  * @author Luke Blanshard (blanshlu@netscape.net)
  * @author Drew Davidson (drew@ognl.org)
  */
-public abstract class SimpleNode implements Node, Serializable
-{
+public abstract class SimpleNode implements Node, Serializable {
 
     protected Node _parent;
     protected Node[] _children;
     protected OgnlParser _parser;
 
     private boolean _constantValueCalculated;
-    private boolean _hasConstantValue;
+    private volatile boolean _hasConstantValue;
     private Object _constantValue;
-    
+
     private ExpressionAccessor _accessor;
-    
+
     public SimpleNode(int i)
     {
         _id = i;
 
     public void jjtAddChild(Node n, int i)
     {
-        if (_children == null)
-        {
+        if (_children == null) {
             _children = new Node[i + 1];
-        } else if (i >= _children.length)
-        {
+        } else if (i >= _children.length) {
             Node c[] = new Node[i + 1];
             System.arraycopy(_children, 0, c, 0, _children.length);
             _children = c;
     {
         return prefix + OgnlParserTreeConstants.jjtNodeName[_id] + " " + toString();
     }
-    
+
     public String toGetSourceString(OgnlContext context, Object target)
     {
         return toString();
     }
-    
+
     public String toSetSourceString(OgnlContext context, Object target)
     {
         return toString();
     }
-    
+
     /*
-     * Override this method if you want to customize how the node dumps out its children.
-     */
+    * Override this method if you want to customize how the node dumps out its children.
+    */
 
     public void dump(PrintWriter writer, String prefix)
     {
         writer.println(toString(prefix));
-        if (_children != null) {
-            for(int i = 0; i < _children.length; ++i) {
+
+        if (_children != null)
+        {
+            for (int i = 0; i < _children.length; ++i)
+            {
                 SimpleNode n = (SimpleNode) _children[i];
-                if (n != null) {
+                if (n != null)
+                {
                     n.dump(writer, prefix + "  ");
                 }
             }
     {
         int result = -1;
 
-        if (_parent != null) {
+        if (_parent != null)
+        {
             int icount = _parent.jjtGetNumChildren();
 
-            for(int i = 0; i < icount; i++) {
-                if (_parent.jjtGetChild(i) == this) {
+            for (int i = 0; i < icount; i++)
+            {
+                if (_parent.jjtGetChild(i) == this)
+                {
                     result = i;
                     break;
                 }
             }
         }
+        
         return result;
     }
 
         Node result = null;
         int i = getIndexInParent();
 
-        if (i >= 0) {
+        if (i >= 0)
+        {
             int icount = _parent.jjtGetNumChildren();
 
-            if (i < icount) {
+            if (i < icount)
+            {
                 result = _parent.jjtGetChild(i + 1);
             }
         }
     }
 
     protected Object evaluateGetValueBody(OgnlContext context, Object source)
-        throws OgnlException
+            throws OgnlException
     {
         context.setCurrentObject(source);
         context.setCurrentNode(this);
-        
-        if (!_constantValueCalculated) {
 
+        if (!_constantValueCalculated)
+        {
             _constantValueCalculated = true;
-            _hasConstantValue = isConstant(context);
+            boolean constant = isConstant(context);
 
-            if (_hasConstantValue) {
+            if (constant)
+            {
                 _constantValue = getValueBody(context, source);
             }
+
+            _hasConstantValue = constant;
         }
-        
+
         return _hasConstantValue ? _constantValue : getValueBody(context, source);
     }
 
     protected void evaluateSetValueBody(OgnlContext context, Object target, Object value)
-        throws OgnlException
+            throws OgnlException
     {
         context.setCurrentObject(target);
         context.setCurrentNode(this);
     }
 
     public final Object getValue(OgnlContext context, Object source)
-        throws OgnlException
+            throws OgnlException
     {
         Object result = null;
-        
+
         if (context.getTraceEvaluations()) {
 
             EvaluationPool pool = OgnlRuntime.getEvaluationPool();
             context.pushEvaluation(evaluation);
             try {
                 result = evaluateGetValueBody(context, source);
-            } catch (OgnlException ex) {
+            }
+            catch (OgnlException ex) {
                 evalException = ex;
                 throw ex;
-            } catch (RuntimeException ex) {
+            }
+            catch (RuntimeException ex) {
                 evalException = ex;
                 throw ex;
             } finally {
                     eval.setException(evalException);
                 }
                 if ((evalException == null) && (context.getRootEvaluation() == null)
-                        && !context.getKeepLastEvaluation()) {
+                    && !context.getKeepLastEvaluation()) {
                     pool.recycleAll(eval);
                 }
             }
         } else {
             result = evaluateGetValueBody(context, source);
         }
-        
+
         return result;
     }
 
-    /**
-     * Subclasses implement this method to do the actual work of extracting the appropriate value
-     * from the source object.
-     */
+    /** Subclasses implement this method to do the actual work of extracting the appropriate value from the source object. */
     protected abstract Object getValueBody(OgnlContext context, Object source)
-        throws OgnlException;
+            throws OgnlException;
 
     public final void setValue(OgnlContext context, Object target, Object value)
-        throws OgnlException
+            throws OgnlException
     {
-        if (context.getTraceEvaluations()) {
+        if (context.getTraceEvaluations())
+        {
             EvaluationPool pool = OgnlRuntime.getEvaluationPool();
             Throwable evalException = null;
             Evaluation evaluation = pool.create(this, target, true);
             context.pushEvaluation(evaluation);
             try {
                 evaluateSetValueBody(context, target, value);
-            } catch (OgnlException ex) {
+            }
+            catch (OgnlException ex) {
                 evalException = ex;
                 ex.setEvaluation(evaluation);
                 throw ex;
-            } catch (RuntimeException ex) {
+            }
+            catch (RuntimeException ex) {
                 evalException = ex;
                 throw ex;
             } finally {
                     eval.setException(evalException);
                 }
                 if ((evalException == null) && (context.getRootEvaluation() == null)
-                        && !context.getKeepLastEvaluation()) {
+                    && !context.getKeepLastEvaluation()) {
                     pool.recycleAll(eval);
                 }
             }
     }
 
     /**
-     * Subclasses implement this method to do the actual work of setting the appropriate value in
-     * the target object. The default implementation throws an
+     * Subclasses implement this method to do the actual work of setting the appropriate value in the target object. The default implementation throws an
      * <code>InappropriateExpressionException</code>, meaning that it cannot be a set expression.
      */
     protected void setValueBody(OgnlContext context, Object target, Object value)
-        throws OgnlException
+            throws OgnlException
     {
         throw new InappropriateExpressionException(this);
     }
 
-    /**
-     * Returns true iff this node is constant without respect to the children.
-     */
+    /** Returns true iff this node is constant without respect to the children. */
     public boolean isNodeConstant(OgnlContext context)
-        throws OgnlException
+            throws OgnlException
     {
         return false;
     }
 
     public boolean isConstant(OgnlContext context)
-        throws OgnlException
+            throws OgnlException
     {
         return isNodeConstant(context);
     }
 
     public boolean isNodeSimpleProperty(OgnlContext context)
-        throws OgnlException
+            throws OgnlException
     {
         return false;
     }
 
     public boolean isSimpleProperty(OgnlContext context)
-        throws OgnlException
+            throws OgnlException
     {
         return isNodeSimpleProperty(context);
     }
 
     public boolean isSimpleNavigationChain(OgnlContext context)
-        throws OgnlException
+            throws OgnlException
     {
         return isSimpleProperty(context);
     }
 
     /**
-     * This method may be called from subclasses' jjtClose methods. It flattens the tree under this
-     * node by eliminating any children that are of the same class as this node and copying their
-     * children to this node.
+     * This method may be called from subclasses' jjtClose methods. It flattens the tree under this node by eliminating any children that are of the same class as this
+     * node and copying their children to this node.
      */
     protected void flattenTree()
     {
         boolean shouldFlatten = false;
         int newSize = 0;
 
-        for(int i = 0; i < _children.length; ++i)
-            if (_children[i].getClass() == getClass()) {
+        for (int i = 0; i < _children.length; ++i)
+            if (_children[i].getClass() == getClass())
+            {
                 shouldFlatten = true;
                 newSize += _children[i].jjtGetNumChildren();
-            } else ++newSize;
+            } else
+                ++newSize;
 
-        if (shouldFlatten) {
+        if (shouldFlatten)
+        {
             Node[] newChildren = new Node[newSize];
             int j = 0;
 
-            for(int i = 0; i < _children.length; ++i) {
+            for (int i = 0; i < _children.length; ++i)
+            {
                 Node c = _children[i];
-                if (c.getClass() == getClass()) {
-                    for(int k = 0; k < c.jjtGetNumChildren(); ++k)
+                if (c.getClass() == getClass())
+                {
+                    for (int k = 0; k < c.jjtGetNumChildren(); ++k)
                         newChildren[j++] = c.jjtGetChild(k);
-                } else newChildren[j++] = c;
+
+                } else
+                    newChildren[j++] = c;
             }
 
-            if (j != newSize) throw new Error("Assertion error: " + j + " != " + newSize);
+            if (j != newSize)
+                throw new Error("Assertion error: " + j + " != " + newSize);
 
-            this._children = newChildren;
+            _children = newChildren;
         }
     }
-    
+
     public ExpressionAccessor getAccessor()
     {
         return _accessor;
     }
-    
+
     public void setAccessor(ExpressionAccessor accessor)
     {
         _accessor = accessor;