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: import org.apache.velocity.exception.MethodInvocationException;
026:
027: /**
028: * Please look at the Parser.jjt file which is
029: * what controls the generation of this class.
030: *
031: * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
032: * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
033: * @version $Id: ASTAndNode.java 463298 2006-10-12 16:10:32Z henning $
034: */
035: public class ASTAndNode extends SimpleNode {
036: /**
037: * @param id
038: */
039: public ASTAndNode(int id) {
040: super (id);
041: }
042:
043: /**
044: * @param p
045: * @param id
046: */
047: public ASTAndNode(Parser p, int id) {
048: super (p, id);
049: }
050:
051: /**
052: * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.ParserVisitor, java.lang.Object)
053: */
054: public Object jjtAccept(ParserVisitor visitor, Object data) {
055: return visitor.visit(this , data);
056: }
057:
058: /**
059: * Returns the value of the expression.
060: * Since the value of the expression is simply the boolean
061: * result of evaluate(), lets return that.
062: * @param context
063: * @return The value of the expression.
064: * @throws MethodInvocationException
065: */
066: public Object value(InternalContextAdapter context)
067: throws MethodInvocationException {
068: // TODO: JDK 1.4+ -> valueOf()
069: return new Boolean(evaluate(context));
070: }
071:
072: /**
073: * logical and :
074: * null && right = false
075: * left && null = false
076: * null && null = false
077: * @param context
078: * @return True if both sides are true.
079: * @throws MethodInvocationException
080: */
081: public boolean evaluate(InternalContextAdapter context)
082: throws MethodInvocationException {
083: Node left = jjtGetChild(0);
084: Node right = jjtGetChild(1);
085:
086: /*
087: * if either is null, lets log and bail
088: */
089:
090: if (left == null || right == null) {
091: log.error((left == null ? "Left" : "Right")
092: + " side of '&&' operation is null."
093: + " Operation not possible. "
094: + context.getCurrentTemplateName() + " [line "
095: + getLine() + ", column " + getColumn() + "]");
096: return false;
097: }
098:
099: /*
100: * short circuit the test. Don't eval the RHS if the LHS is false
101: */
102:
103: if (left.evaluate(context)) {
104: if (right.evaluate(context)) {
105: return true;
106: }
107: }
108:
109: return false;
110: }
111: }
|