Return-Path: Delivered-To: apmail-velocity-commits-archive@locus.apache.org Received: (qmail 86483 invoked from network); 1 Sep 2008 20:27:04 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 1 Sep 2008 20:27:04 -0000 Received: (qmail 83930 invoked by uid 500); 1 Sep 2008 20:27:02 -0000 Delivered-To: apmail-velocity-commits-archive@velocity.apache.org Received: (qmail 83896 invoked by uid 500); 1 Sep 2008 20:27:02 -0000 Mailing-List: contact commits-help@velocity.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@velocity.apache.org Delivered-To: mailing list commits@velocity.apache.org Received: (qmail 83887 invoked by uid 99); 1 Sep 2008 20:27:02 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 01 Sep 2008 13:27:02 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 01 Sep 2008 20:26:12 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id AA2CA2388986; Mon, 1 Sep 2008 13:26:12 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r691048 - in /velocity/engine/trunk/src: java/org/apache/velocity/exception/ java/org/apache/velocity/runtime/ java/org/apache/velocity/runtime/parser/node/ test/org/apache/velocity/test/ Date: Mon, 01 Sep 2008 20:26:12 -0000 To: commits@velocity.apache.org From: nbubna@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080901202612.AA2CA2388986@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: nbubna Date: Mon Sep 1 13:26:11 2008 New Revision: 691048 URL: http://svn.apache.org/viewvc?rev=691048&view=rev Log: VELOCITY-467 refactor math node classes to simplify addition of option to be strict about math (throwing exceptions for null operands and div by zero) Added: velocity/engine/trunk/src/java/org/apache/velocity/exception/MathException.java (with props) velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java (with props) velocity/engine/trunk/src/test/org/apache/velocity/test/StrictMathTestCase.java (with props) Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeConstants.java velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTAddNode.java velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTDivNode.java velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTEQNode.java velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTModNode.java velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMulNode.java velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTNENode.java velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTSubtractNode.java velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/SimpleNode.java Added: velocity/engine/trunk/src/java/org/apache/velocity/exception/MathException.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/exception/MathException.java?rev=691048&view=auto ============================================================================== --- velocity/engine/trunk/src/java/org/apache/velocity/exception/MathException.java (added) +++ velocity/engine/trunk/src/java/org/apache/velocity/exception/MathException.java Mon Sep 1 13:26:11 2008 @@ -0,0 +1,35 @@ +package org.apache.velocity.exception; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Separate exception class to distinguish math problems. + * + * @author Nathan Bubna + * @since 1.6 + * @version $Id: MathException.java 685685 2008-08-13 21:43:27Z nbubna $ + */ +public class MathException extends VelocityException +{ + public MathException(final String exceptionMessage) + { + super(exceptionMessage); + } +} Propchange: velocity/engine/trunk/src/java/org/apache/velocity/exception/MathException.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: velocity/engine/trunk/src/java/org/apache/velocity/exception/MathException.java ------------------------------------------------------------------------------ svn:executable = * Propchange: velocity/engine/trunk/src/java/org/apache/velocity/exception/MathException.java ------------------------------------------------------------------------------ svn:keywords = Revision Propchange: velocity/engine/trunk/src/java/org/apache/velocity/exception/MathException.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeConstants.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeConstants.java?rev=691048&r1=691047&r2=691048&view=diff ============================================================================== --- velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeConstants.java (original) +++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/RuntimeConstants.java Mon Sep 1 13:26:11 2008 @@ -297,6 +297,9 @@ /** A comma separated list of classes to restrict access to in the SecureIntrospector. */ String INTROSPECTOR_RESTRICT_CLASSES = "introspector.restrict.classes"; + /** Switch for ignoring nulls in math equations vs throwing exceptions. */ + String STRICT_MATH = "runtime.strict.math"; + /** * The parser.pool.class property specifies the name of the {@link org.apache.velocity.util.SimplePool} * implementation to use. Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTAddNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTAddNode.java?rev=691048&r1=691047&r2=691048&view=diff ============================================================================== --- velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTAddNode.java (original) +++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTAddNode.java Mon Sep 1 13:26:11 2008 @@ -19,6 +19,9 @@ * under the License. */ +import org.apache.velocity.context.InternalContextAdapter; +import org.apache.velocity.runtime.parser.Parser; + /** * Handles number addition of nodes.

* @@ -31,15 +34,7 @@ * @author Geir Magnusson Jr. * @version $Id$ */ -import org.apache.velocity.context.InternalContextAdapter; -import org.apache.velocity.exception.MethodInvocationException; -import org.apache.velocity.runtime.parser.Parser; -import org.apache.velocity.util.TemplateNumber; - -/** - * - */ -public class ASTAddNode extends SimpleNode +public class ASTAddNode extends ASTMathNode { /** * @param id @@ -58,84 +53,24 @@ super(p, id); } - /** - * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) - */ - public Object jjtAccept(ParserVisitor visitor, Object data) - { - return visitor.visit(this, data); - } - - /** - * computes the sum of the two nodes. - * @param context - * @return result or null - * @throws MethodInvocationException - */ - public Object value( InternalContextAdapter context) - throws MethodInvocationException + //@Override + protected Object handleSpecial(Object left, Object right, InternalContextAdapter context) { /* - * get the two addends - */ - - Object left = jjtGetChild(0).value(context); - Object right = jjtGetChild(1).value(context); - - /* - * if either is null, lets log and bail - */ - - if (left == null || right == null) - { - log.error((left == null ? "Left" : "Right") - + " side (" - + jjtGetChild( (left == null? 0 : 1) ).literal() - + ") of addition operation has null value." - + " Operation not possible. " - + context.getCurrentTemplateName() + " [line " + getLine() - + ", column " + getColumn() + "]"); - return null; - } - - /* - * convert to Number if applicable - */ - if (left instanceof TemplateNumber) - { - left = ( (TemplateNumber) left).getAsNumber(); - } - if (right instanceof TemplateNumber) - { - right = ( (TemplateNumber) right).getAsNumber(); - } - - /* - * Arithmetic operation. - */ - if (left instanceof Number && right instanceof Number) - { - return MathUtils.add((Number)left, (Number)right); - } - - /* * shall we try for strings? */ if (left instanceof String || right instanceof String) { return left.toString().concat(right.toString()); } - /* - * if not a Number or Strings, not much we can do right now - */ - log.error((!(left instanceof Number || left instanceof String) ? "Left" : "Right") - + " side of addition operation is not a valid type. " - + "Currently only Strings, numbers (1,2,3...) and Number type are supported. " - + context.getCurrentTemplateName() + " [line " + getLine() - + ", column " + getColumn() + "]"); - return null; } + + public Number perform(Number left, Number right, InternalContextAdapter context) + { + return MathUtils.add(left, right); + } + } Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTDivNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTDivNode.java?rev=691048&r1=691047&r2=691048&view=diff ============================================================================== --- velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTDivNode.java (original) +++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTDivNode.java Mon Sep 1 13:26:11 2008 @@ -20,9 +20,8 @@ */ import org.apache.velocity.context.InternalContextAdapter; -import org.apache.velocity.exception.MethodInvocationException; +import org.apache.velocity.exception.MathException; import org.apache.velocity.runtime.parser.Parser; -import org.apache.velocity.util.TemplateNumber; /** * Handles number division of nodes

@@ -36,7 +35,7 @@ * @author Geir Magnusson Jr. * @version $Id$ */ -public class ASTDivNode extends SimpleNode +public class ASTDivNode extends ASTMathNode { /** * @param id @@ -55,84 +54,26 @@ super(p, id); } - /** - * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) - */ - public Object jjtAccept(ParserVisitor visitor, Object data) - { - return visitor.visit(this, data); - } - - /** - * computes the result of the division. - * @param context - * @return result or null - * @throws MethodInvocationException - */ - public Object value( InternalContextAdapter context) - throws MethodInvocationException + public Number perform(Number left, Number right, InternalContextAdapter context) { /* - * get the two args - */ - - Object left = jjtGetChild(0).value( context ); - Object right = jjtGetChild(1).value( context ); - - /* - * if either is null, lets log and bail - */ - - if (left == null || right == null) - { - log.error((left == null ? "Left" : "Right") - + " side (" - + jjtGetChild( (left == null? 0 : 1) ).literal() - + ") of division operation has null value." - + " Operation not possible. " - + context.getCurrentTemplateName() - + " [line " + getLine() - + ", column " + getColumn() + "]"); - return null; - } - - /* - * convert to Number if applicable - */ - if (left instanceof TemplateNumber) - { - left = ( (TemplateNumber) left).getAsNumber(); - } - if (right instanceof TemplateNumber) - { - right = ( (TemplateNumber) right).getAsNumber(); - } - - /* - * if not a Number, not much we can do either + * check for divide by 0 */ - if ( !( left instanceof Number ) || !( right instanceof Number )) + if (MathUtils.isZero(right)) { - log.error((!(left instanceof Number) ? "Left" : "Right") - + " side of division operation is not a number. " - + context.getCurrentTemplateName() + " [line " + getLine() - + ", column " + getColumn() + "]"); - - return null; - } - - /* - * check for divide by 0 - */ - if ( MathUtils.isZero ( (Number)right ) ) - { - log.error("Right side of division operation is zero. Must be non-zero. " - + context.getCurrentTemplateName() + " [line " + getLine() - + ", column " + getColumn() + "]"); - - return null; + String msg = "Right side of division operation is zero. Must be non-zero. " + + getLocation(context); + if (strictMode) + { + log.error(msg); + throw new MathException(msg); + } + else + { + log.debug(msg); + return null; + } } - - return MathUtils.divide( (Number)left, (Number)right ); + return MathUtils.divide(left, right); } } Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTEQNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTEQNode.java?rev=691048&r1=691047&r2=691048&view=diff ============================================================================== --- velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTEQNode.java (original) +++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTEQNode.java Mon Sep 1 13:26:11 2008 @@ -156,12 +156,6 @@ return jjtGetChild(left ? 0 : 1).literal(); } - private String getLocation(InternalContextAdapter context) - { - return context.getCurrentTemplateName() + " [line " + getLine() - + ", column " + getColumn() + "]"; - } - /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) */ Added: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java?rev=691048&view=auto ============================================================================== --- velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java (added) +++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java Mon Sep 1 13:26:11 2008 @@ -0,0 +1,156 @@ +package org.apache.velocity.runtime.parser.node; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.velocity.context.InternalContextAdapter; +import org.apache.velocity.exception.MathException; +import org.apache.velocity.exception.MethodInvocationException; +import org.apache.velocity.exception.TemplateInitException; +import org.apache.velocity.runtime.RuntimeConstants; +import org.apache.velocity.runtime.parser.Parser; +import org.apache.velocity.util.TemplateNumber; + +/** + * Helps handle math

+ * + * Please look at the Parser.jjt file which is + * what controls the generation of this class. + * + * @author Will Glass-Husain + * @author Peter Romianowski + * @author Jason van Zyl + * @author Geir Magnusson Jr. + * @author Nathan Bubna + * @version $Id: ASTMathNode.java 517553 2007-03-13 06:09:58Z wglass $ + */ +public abstract class ASTMathNode extends SimpleNode +{ + protected boolean strictMode = false; + + public ASTMathNode(int id) + { + super(id); + } + + public ASTMathNode(Parser p, int id) + { + super(p, id); + } + + /** + * {@inheritDoc} + */ + public Object init(InternalContextAdapter context, Object data) throws TemplateInitException + { + super.init(context, data); + strictMode = rsvc.getBoolean(RuntimeConstants.STRICT_MATH, false); + return data; + } + + /** + * {@inheritDoc} + */ + public Object jjtAccept(ParserVisitor visitor, Object data) + { + return visitor.visit(this, data); + } + + /** + * gets the two args and performs the operation on them + * + * @param context + * @return result or null + * @throws MethodInvocationException + */ + public Object value(InternalContextAdapter context) throws MethodInvocationException + { + Object left = jjtGetChild(0).value(context); + Object right = jjtGetChild(1).value(context); + + /* + * should we do anything special here? + */ + Object special = handleSpecial(left, right, context); + if (special != null) + { + return special; + } + + /* + * convert to Number if applicable + */ + if (left instanceof TemplateNumber) + { + left = ((TemplateNumber)left).getAsNumber(); + } + if (right instanceof TemplateNumber) + { + right = ((TemplateNumber)right).getAsNumber(); + } + + /* + * if not a Number, not much we can do + */ + if (!(left instanceof Number) || !(right instanceof Number)) + { + boolean wrongright = (left instanceof Number); + boolean wrongtype = wrongright ? right != null : left != null; + String msg = (wrongright ? "Right" : "Left") + + " side of math operation (" + + jjtGetChild(wrongright ? 1 : 0).literal() + ") " + + (wrongtype ? "is not a Number. " : "has a null value. ") + + getLocation(context); + if (strictMode) + { + log.error(msg); + throw new MathException(msg); + } + else + { + log.debug(msg); + return null; + } + } + + return perform((Number)left, (Number)right, context); + } + + /** + * Extension hook to allow special behavior by subclasses + * If this method returns a non-null value, that is returned, + * rather than the result of the math operation. + * @see ASTAddNode#handleSpecial + */ + protected Object handleSpecial(Object left, Object right, InternalContextAdapter context) + { + // do nothing, this is an extension hook + return null; + } + + /** + * Performs the math operation represented by this node. + */ + public abstract Number perform(Number left, Number right, InternalContextAdapter context); + +} + + + + Propchange: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java ------------------------------------------------------------------------------ svn:executable = * Propchange: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java ------------------------------------------------------------------------------ svn:keywords = Revision Propchange: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTModNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTModNode.java?rev=691048&r1=691047&r2=691048&view=diff ============================================================================== --- velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTModNode.java (original) +++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTModNode.java Mon Sep 1 13:26:11 2008 @@ -19,6 +19,10 @@ * under the License. */ +import org.apache.velocity.context.InternalContextAdapter; +import org.apache.velocity.exception.MathException; +import org.apache.velocity.runtime.parser.Parser; + /** * Handles modulus division

* @@ -30,15 +34,7 @@ * @author Geir Magnusson Jr. * @version $Id$ */ -import org.apache.velocity.context.InternalContextAdapter; -import org.apache.velocity.exception.MethodInvocationException; -import org.apache.velocity.runtime.parser.Parser; -import org.apache.velocity.util.TemplateNumber; - -/** - * - */ -public class ASTModNode extends SimpleNode +public class ASTModNode extends ASTMathNode { /** * @param id @@ -57,85 +53,27 @@ super(p, id); } - /** - * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) - */ - public Object jjtAccept(ParserVisitor visitor, Object data) - { - return visitor.visit(this, data); - } - - /** - * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) - */ - public Object value( InternalContextAdapter context) - throws MethodInvocationException + public Number perform(Number left, Number right, InternalContextAdapter context) { /* - * get the two args - */ - - Object left = jjtGetChild(0).value( context ); - Object right = jjtGetChild(1).value( context ); - - /* - * if either is null, lets log and bail - */ - - if (left == null || right == null) - { - log.error((left == null ? "Left" : "Right") - + " side (" - + jjtGetChild( (left == null? 0 : 1) ).literal() - + ") of modulus operation has null value." - + " Operation not possible. " - + context.getCurrentTemplateName() + " [line " + getLine() - + ", column " + getColumn() + "]"); - return null; - } - - /* - * convert to Number if applicable - */ - if (left instanceof TemplateNumber) - { - left = ( (TemplateNumber) left).getAsNumber(); - } - if (right instanceof TemplateNumber) - { - right = ( (TemplateNumber) right).getAsNumber(); - } - - /* - * Both values must be a number. + * check for divide / modulo by 0 */ - if ( ! (left instanceof Number) || ! (right instanceof Number) ) + if (MathUtils.isZero(right)) { - - log.error((!(left instanceof Number) ? "Left" : "Right") - + " side " - + " of modulus operation is not a Number. " - + context.getCurrentTemplateName() + " [line " + getLine() - + ", column " + getColumn() + "]"); - return null; - + String msg = "Right side of modulus operation is zero. Must be non-zero. " + + getLocation(context); + if (strictMode) + { + log.error(msg); + throw new MathException(msg); + } + else + { + log.debug(msg); + return null; + } } - - /* - * check for divide / modulo by 0 - */ - if ( MathUtils.isZero ( (Number) right ) ) - { - - log.error("Right side of modulus operation is zero. Must be non-zero. " - + context.getCurrentTemplateName() + " [line " + getLine() - + ", column " + getColumn() + "]"); - return null; - - } - - return MathUtils.modulo ((Number)left, (Number)right); - + return MathUtils.modulo(left, right); } } Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMulNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMulNode.java?rev=691048&r1=691047&r2=691048&view=diff ============================================================================== --- velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMulNode.java (original) +++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTMulNode.java Mon Sep 1 13:26:11 2008 @@ -20,9 +20,7 @@ */ import org.apache.velocity.context.InternalContextAdapter; -import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.runtime.parser.Parser; -import org.apache.velocity.util.TemplateNumber; /** * Handles multiplication

@@ -36,7 +34,7 @@ * @author Geir Magnusson Jr. * @version $Id$ */ -public class ASTMulNode extends SimpleNode +public class ASTMulNode extends ASTMathNode { /** * @param id @@ -55,73 +53,9 @@ super(p, id); } - /** - * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) - */ - public Object jjtAccept(ParserVisitor visitor, Object data) + public Number perform(Number left, Number right, InternalContextAdapter context) { - return visitor.visit(this, data); - } - - /** - * computes the product of the two args. - * @param context - * @return result or null - * @throws MethodInvocationException - */ - public Object value( InternalContextAdapter context ) - throws MethodInvocationException - { - /* - * get the two args - */ - - Object left = jjtGetChild(0).value( context ); - Object right = jjtGetChild(1).value( context ); - - /* - * if either is null, lets log and bail - */ - - if (left == null || right == null) - { - log.error((left == null ? "Left" : "Right") - + " side (" - + jjtGetChild( (left == null? 0 : 1) ).literal() - + ") of multiplication operation has null value." - + " Operation not possible. " - + context.getCurrentTemplateName() + " [line " + getLine() - + ", column " + getColumn() + "]"); - return null; - } - - /* - * convert to Number if applicable - */ - if (left instanceof TemplateNumber) - { - left = ( (TemplateNumber) left).getAsNumber(); - } - if (right instanceof TemplateNumber) - { - right = ( (TemplateNumber) right).getAsNumber(); - } - - /* - * if not a Number, not much we can do either - */ - - if ( !( left instanceof Number ) || !( right instanceof Number )) - { - log.error((!(left instanceof Number) ? "Left" : "Right") - + " side of multiplication operation is not a Number. " - + context.getCurrentTemplateName() + " [line " + getLine() - + ", column " + getColumn() + "]"); - - return null; - } - - return MathUtils.multiply( (Number)left, (Number)right); + return MathUtils.multiply(left, right); } } Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTNENode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTNENode.java?rev=691048&r1=691047&r2=691048&view=diff ============================================================================== --- velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTNENode.java (original) +++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTNENode.java Mon Sep 1 13:26:11 2008 @@ -141,12 +141,6 @@ return jjtGetChild(left ? 0 : 1).literal(); } - private String getLocation(InternalContextAdapter context) - { - return context.getCurrentTemplateName() + " [line " + getLine() - + ", column " + getColumn() + "]"; - } - /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) */ Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTSubtractNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTSubtractNode.java?rev=691048&r1=691047&r2=691048&view=diff ============================================================================== --- velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTSubtractNode.java (original) +++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTSubtractNode.java Mon Sep 1 13:26:11 2008 @@ -20,9 +20,7 @@ */ import org.apache.velocity.context.InternalContextAdapter; -import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.runtime.parser.Parser; -import org.apache.velocity.util.TemplateNumber; /** * Handles subtraction of nodes (in #set() )

@@ -36,7 +34,7 @@ * @author Geir Magnusson Jr. * @version $Id$ */ -public class ASTSubtractNode extends SimpleNode +public class ASTSubtractNode extends ASTMathNode { /** * @param id @@ -55,71 +53,9 @@ super(p, id); } - /** - * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) - */ - public Object jjtAccept(ParserVisitor visitor, Object data) - { - return visitor.visit(this, data); - } - - /** - * computes the value of the subtraction. - * @param context - * @return result or null - * @throws MethodInvocationException - */ - public Object value( InternalContextAdapter context) - throws MethodInvocationException + public Number perform(Number left, Number right, InternalContextAdapter context) { - /* - * get the two args - */ - - Object left = jjtGetChild(0).value( context ); - Object right = jjtGetChild(1).value( context ); - - /* - * if either is null, lets log and bail - */ - - if (left == null || right == null) - { - log.error((left == null ? "Left" : "Right") - + " side (" - + jjtGetChild( (left == null? 0 : 1) ).literal() - + ") of subtraction operation has null value." - + " Operation not possible. " - + context.getCurrentTemplateName() + " [line " + getLine() - + ", column " + getColumn() + "]"); - return null; - } - - /* - * convert to Number if applicable - */ - if (left instanceof TemplateNumber) - { - left = ( (TemplateNumber) left).getAsNumber(); - } - if (right instanceof TemplateNumber) - { - right = ( (TemplateNumber) right).getAsNumber(); - } - - /* - * if not a Number, not much we can do either - */ - if ( !( left instanceof Number ) || !( right instanceof Number )) - { - log.error((!(left instanceof Number) ? "Left" : "Right") - + " side of subtraction operation is not a Number. " - + context.getCurrentTemplateName() + " [line " + getLine() - + ", column " + getColumn() + "]"); - return null; - } - - return MathUtils.subtract ( (Number)left,(Number)right); + return MathUtils.subtract(left, right); } } Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/SimpleNode.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/SimpleNode.java?rev=691048&r1=691047&r2=691048&view=diff ============================================================================== --- velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/SimpleNode.java (original) +++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/SimpleNode.java Mon Sep 1 13:26:11 2008 @@ -246,6 +246,17 @@ } } + /** + * Return a string that tells the current location of this node. + */ + protected String getLocation(InternalContextAdapter context) + { + return new StrBuilder(50) + .append(context.getCurrentTemplateName()) + .append(" [line ").append(getLine()) + .append(", column ").append(getColumn()).append("]").toString(); + } + // All additional methods /** Added: velocity/engine/trunk/src/test/org/apache/velocity/test/StrictMathTestCase.java URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/test/org/apache/velocity/test/StrictMathTestCase.java?rev=691048&view=auto ============================================================================== --- velocity/engine/trunk/src/test/org/apache/velocity/test/StrictMathTestCase.java (added) +++ velocity/engine/trunk/src/test/org/apache/velocity/test/StrictMathTestCase.java Mon Sep 1 13:26:11 2008 @@ -0,0 +1,111 @@ +package org.apache.velocity.test; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.velocity.VelocityContext; +import org.apache.velocity.exception.MathException; +import org.apache.velocity.runtime.RuntimeConstants; + +/** + * This class tests support for strict math mode. + */ +public class StrictMathTestCase extends BaseEvalTestCase +{ + public StrictMathTestCase(String name) + { + super(name); + } + + public void setUp() throws Exception + { + super.setUp(); + engine.setProperty(RuntimeConstants.STRICT_MATH, true); + context.put("num", new Integer(5)); + context.put("zero", new Integer(0)); + } + + public boolean nullmath(String operation) + { + try + { + evaluate("#set( $foo = $null "+operation+" $num )"); + fail("Doing "+operation+" with $null left side should have thrown a MathException"); + } + catch (MathException me) + { + // success! + } + try + { + evaluate("#set( $foo = $num "+operation+" $null )"); + fail("Doing "+operation+" with $null right side should have thrown a MathException"); + return false; + } + catch (MathException me) + { + // success! + return true; + } + } + + public boolean imaginarymath(String operation) + { + try + { + evaluate("#set( $foo = $num "+operation+" $zero )"); + fail("Doing "+operation+" with $zero right side should have thrown a MathException"); + return false; + } + catch (MathException me) + { + // success! + return true; + } + } + + + public void testAdd() + { + assertTrue(nullmath("+")); + } + + public void testSub() + { + assertTrue(nullmath("-")); + } + + public void testMul() + { + assertTrue(nullmath("*")); + } + + public void testMod() + { + assertTrue(nullmath("%")); + assertTrue(imaginarymath("%")); + } + + public void testDiv() + { + assertTrue(nullmath("/")); + assertTrue(imaginarymath("/")); + } + +} Propchange: velocity/engine/trunk/src/test/org/apache/velocity/test/StrictMathTestCase.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: velocity/engine/trunk/src/test/org/apache/velocity/test/StrictMathTestCase.java ------------------------------------------------------------------------------ svn:executable = * Propchange: velocity/engine/trunk/src/test/org/apache/velocity/test/StrictMathTestCase.java ------------------------------------------------------------------------------ svn:keywords = Revision Propchange: velocity/engine/trunk/src/test/org/apache/velocity/test/StrictMathTestCase.java ------------------------------------------------------------------------------ svn:mime-type = text/plain