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: /**
023: * Handles modulus division<br><br>
024: *
025: * Please look at the Parser.jjt file which is
026: * what controls the generation of this class.
027: *
028: * @author <a href="mailto:wglass@forio.com">Will Glass-Husain</a>
029: * @author <a href="mailto:pero@antaramusic.de">Peter Romianowski</a>
030: * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
031: * @version $Id: ASTModNode.java 463298 2006-10-12 16:10:32Z henning $
032: */
033: import org.apache.velocity.context.InternalContextAdapter;
034: import org.apache.velocity.exception.MethodInvocationException;
035: import org.apache.velocity.runtime.parser.Parser;
036: import org.apache.velocity.runtime.parser.ParserVisitor;
037: import org.apache.velocity.util.TemplateNumber;
038:
039: /**
040: *
041: */
042: public class ASTModNode extends SimpleNode {
043: /**
044: * @param id
045: */
046: public ASTModNode(int id) {
047: super (id);
048: }
049:
050: /**
051: * @param p
052: * @param id
053: */
054: public ASTModNode(Parser p, int id) {
055: super (p, id);
056: }
057:
058: /**
059: * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.ParserVisitor, java.lang.Object)
060: */
061: public Object jjtAccept(ParserVisitor visitor, Object data) {
062: return visitor.visit(this , data);
063: }
064:
065: /**
066: * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter)
067: */
068: public Object value(InternalContextAdapter context)
069: throws MethodInvocationException {
070: /*
071: * get the two args
072: */
073:
074: Object left = jjtGetChild(0).value(context);
075: Object right = jjtGetChild(1).value(context);
076:
077: /*
078: * if either is null, lets log and bail
079: */
080:
081: if (left == null || right == null) {
082: log.error((left == null ? "Left" : "Right") + " side ("
083: + jjtGetChild((left == null ? 0 : 1)).literal()
084: + ") of modulus operation has null value."
085: + " Operation not possible. "
086: + context.getCurrentTemplateName() + " [line "
087: + getLine() + ", column " + getColumn() + "]");
088: return null;
089: }
090:
091: /*
092: * convert to Number if applicable
093: */
094: if (left instanceof TemplateNumber) {
095: left = ((TemplateNumber) left).getAsNumber();
096: }
097: if (right instanceof TemplateNumber) {
098: right = ((TemplateNumber) right).getAsNumber();
099: }
100:
101: /*
102: * Both values must be a number.
103: */
104: if (!(left instanceof Number) || !(right instanceof Number)) {
105:
106: log.error((!(left instanceof Number) ? "Left" : "Right")
107: + " side "
108: + " of modulus operation is not a Number. "
109: + context.getCurrentTemplateName() + " [line "
110: + getLine() + ", column " + getColumn() + "]");
111: return null;
112:
113: }
114:
115: /*
116: * check for divide / modulo by 0
117: */
118: if (MathUtils.isZero((Number) right)) {
119:
120: log
121: .error("Right side of modulus operation is zero. Must be non-zero. "
122: + context.getCurrentTemplateName()
123: + " [line "
124: + getLine()
125: + ", column "
126: + getColumn() + "]");
127: return null;
128:
129: }
130:
131: return MathUtils.modulo((Number) left, (Number) right);
132:
133: }
134: }
|