001: package org.apache.velocity.runtime.parser.node;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import org.apache.velocity.context.InternalContextAdapter;
023: import org.apache.velocity.runtime.parser.Parser;
024: import org.apache.velocity.runtime.parser.ParserVisitor;
025:
026: import org.apache.velocity.exception.MethodInvocationException;
027:
028: import org.apache.velocity.util.TemplateNumber;
029:
030: /**
031: * Handles <code>arg1 != arg2</code>
032: *
033: * This operator requires that the LHS and RHS are both of the
034: * same Class OR both are subclasses of java.lang.Number
035: *
036: * @author <a href="mailto:wglass@forio.com">Will Glass-Husain</a>
037: * @author <a href="mailto:pero@antaramusic.de">Peter Romianowski</a>
038: */
039: public class ASTNENode extends SimpleNode {
040: /**
041: * @param id
042: */
043: public ASTNENode(int id) {
044: super (id);
045: }
046:
047: /**
048: * @param p
049: * @param id
050: */
051: public ASTNENode(Parser p, int id) {
052: super (p, id);
053: }
054:
055: /**
056: * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.ParserVisitor, java.lang.Object)
057: */
058: public Object jjtAccept(ParserVisitor visitor, Object data) {
059: return visitor.visit(this , data);
060: }
061:
062: /**
063: * @see org.apache.velocity.runtime.parser.node.SimpleNode#evaluate(org.apache.velocity.context.InternalContextAdapter)
064: */
065: public boolean evaluate(InternalContextAdapter context)
066: throws MethodInvocationException {
067: Object left = jjtGetChild(0).value(context);
068: Object right = jjtGetChild(1).value(context);
069:
070: /*
071: * null check
072: */
073:
074: if (left == null || right == null) {
075: log.error((left == null ? "Left" : "Right") + " side ("
076: + jjtGetChild((left == null ? 0 : 1)).literal()
077: + ") of '!=' operation has null value."
078: + " Operation not possible. "
079: + context.getCurrentTemplateName() + " [line "
080: + getLine() + ", column " + getColumn() + "]");
081: return false;
082:
083: }
084:
085: /*
086: * convert to Number if applicable
087: */
088: if (left instanceof TemplateNumber) {
089: left = ((TemplateNumber) left).getAsNumber();
090: }
091: if (right instanceof TemplateNumber) {
092: right = ((TemplateNumber) right).getAsNumber();
093: }
094:
095: /*
096: * If comparing Numbers we do not care about the Class.
097: */
098: if (left instanceof Number && right instanceof Number) {
099: return MathUtils.compare((Number) left, (Number) right) != 0;
100: }
101:
102: /**
103: * assume that if one class is a subclass of the other
104: * that we should use the equals operator
105: */
106:
107: if (left.getClass().isAssignableFrom(right.getClass())
108: || right.getClass().isAssignableFrom(left.getClass())) {
109: return !left.equals(right);
110: } else {
111: /**
112: * Compare the String representations
113: */
114: if ((left.toString() == null) || (right.toString() == null)) {
115: boolean culprit = (left.toString() == null);
116: log.error((culprit ? "Left" : "Right")
117: + " string side " + "String representation ("
118: + jjtGetChild((culprit ? 0 : 1)).literal()
119: + ") of '!=' operation has null value."
120: + " Operation not possible. "
121: + context.getCurrentTemplateName() + " [line "
122: + getLine() + ", column " + getColumn() + "]");
123: return false;
124: }
125:
126: else {
127: return !left.toString().equals(right.toString());
128: }
129:
130: }
131:
132: }
133:
134: /**
135: * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter)
136: */
137: public Object value(InternalContextAdapter context)
138: throws MethodInvocationException {
139: boolean val = evaluate(context);
140:
141: return val ? Boolean.TRUE : Boolean.FALSE;
142: }
143:
144: }
|