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