View Javadoc

1   package org.apache.velocity.runtime.parser.node;
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  import org.apache.velocity.context.InternalContextAdapter;
23  import org.apache.velocity.runtime.parser.Parser;
24  import org.apache.velocity.runtime.parser.ParserVisitor;
25  
26  import org.apache.velocity.exception.MethodInvocationException;
27  
28  import org.apache.velocity.util.TemplateNumber;
29  
30  /**
31   *  Handles <code>arg1  != arg2</code>
32   *
33   *  This operator requires that the LHS and RHS are both of the
34   *  same Class OR both are subclasses of java.lang.Number
35   *
36   *  @author <a href="mailto:wglass@forio.com">Will Glass-Husain</a>
37   *  @author <a href="mailto:pero@antaramusic.de">Peter Romianowski</a>
38   */
39  public class ASTNENode extends SimpleNode
40  {
41      /**
42       * @param id
43       */
44      public ASTNENode(int id)
45      {
46          super(id);
47      }
48  
49      /**
50       * @param p
51       * @param id
52       */
53      public ASTNENode(Parser p, int id)
54      {
55          super(p, id);
56      }
57  
58      /**
59       * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.ParserVisitor, java.lang.Object)
60       */
61      public Object jjtAccept(ParserVisitor visitor, Object data)
62      {
63          return visitor.visit(this, data);
64      }
65  
66      /**
67       * @see org.apache.velocity.runtime.parser.node.SimpleNode#evaluate(org.apache.velocity.context.InternalContextAdapter)
68       */
69      public boolean evaluate(  InternalContextAdapter context)
70          throws MethodInvocationException
71      {
72          Object left = jjtGetChild(0).value( context );
73          Object right = jjtGetChild(1).value( context );
74  
75          /*
76           *  null check
77           */
78  
79          if ( left == null || right == null)
80          {
81              log.error((left == null ? "Left" : "Right")
82                             + " side ("
83                             + jjtGetChild( (left == null? 0 : 1) ).literal()
84                             + ") of '!=' operation has null value."
85                             + " Operation not possible. "
86                             + context.getCurrentTemplateName() + " [line " + getLine()
87                             + ", column " + getColumn() + "]");
88              return false;
89  
90          }
91  
92          /*
93           *  convert to Number if applicable
94           */
95          if (left instanceof TemplateNumber)
96          {
97             left = ( (TemplateNumber) left).getAsNumber();
98          }
99          if (right instanceof TemplateNumber)
100         {
101            right = ( (TemplateNumber) right).getAsNumber();
102         }
103 
104        /*
105         * If comparing Numbers we do not care about the Class.
106         */
107        if (left instanceof Number && right instanceof Number)
108        {
109             return MathUtils.compare ( (Number)left,(Number)right) != 0;
110        }
111 
112 
113        /**
114         * assume that if one class is a subclass of the other
115         * that we should use the equals operator
116         */
117 
118         if (left.getClass().isAssignableFrom(right.getClass()) ||
119                 right.getClass().isAssignableFrom(left.getClass()) )
120         {
121             return !left.equals( right );
122         }
123         else
124         {
125             /**
126              * Compare the String representations
127              */
128             if ((left.toString() == null) || (right.toString() == null))
129             {
130         	boolean culprit =  (left.toString() == null);
131                 log.error((culprit ? "Left" : "Right")
132                         + " string side "
133                         + "String representation ("
134                         + jjtGetChild((culprit ? 0 : 1) ).literal()
135                         + ") of '!=' operation has null value."
136                         + " Operation not possible. "
137                         + context.getCurrentTemplateName() + " [line " + getLine()
138                         + ", column " + getColumn() + "]");
139                 return false;
140             }
141 
142             else
143             {
144                 return !left.toString().equals(right.toString());
145             }
146 
147         }
148 
149     }
150 
151     /**
152      * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter)
153      */
154     public Object value(InternalContextAdapter context)
155         throws MethodInvocationException
156     {
157         boolean val = evaluate(context);
158 
159         return val ? Boolean.TRUE : Boolean.FALSE;
160     }
161 
162 }