001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.el;
018
019 import java.math.BigInteger;
020
021 import javax.servlet.jsp.el.ELException;
022
023 import org.apache.commons.logging.Log;
024 import org.apache.commons.logging.LogFactory;
025
026 /**
027 *
028 * <p>The implementation of the modulus operator
029 *
030 * @author Nathan Abramson - Art Technology Group
031 * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: bayard $
032 **/
033
034 public class ModulusOperator
035 extends BinaryOperator
036 {
037
038 //-------------------------------------
039 // Constants
040 //-------------------------------------
041 private static Log log = LogFactory.getLog(ModulusOperator.class);
042
043 //-------------------------------------
044 // Singleton
045 //-------------------------------------
046
047 public static final ModulusOperator SINGLETON =
048 new ModulusOperator ();
049
050 //-------------------------------------
051 /**
052 *
053 * Constructor
054 **/
055 public ModulusOperator ()
056 {
057 }
058
059 //-------------------------------------
060 // Expression methods
061 //-------------------------------------
062 /**
063 *
064 * Returns the symbol representing the operator
065 **/
066 public String getOperatorSymbol ()
067 {
068 return "%";
069 }
070
071 //-------------------------------------
072 /**
073 *
074 * Applies the operator to the given value
075 **/
076 public Object apply (Object pLeft, Object pRight)
077 throws ELException
078 {
079 if (pLeft == null &&
080 pRight == null) {
081 if (log.isWarnEnabled()) {
082 log.warn(
083 MessageUtil.getMessageWithArgs(
084 Constants.ARITH_OP_NULL, getOperatorSymbol()));
085 }
086 return PrimitiveObjects.getInteger (0);
087 }
088
089 if ((pLeft != null &&
090 (Coercions.isFloatingPointType (pLeft) ||
091 Coercions.isFloatingPointString (pLeft))) ||
092 Coercions.isBigDecimal(pLeft) ||
093 (pRight != null &&
094 (Coercions.isFloatingPointType (pRight) ||
095 Coercions.isFloatingPointString (pRight) ||
096 Coercions.isBigDecimal(pRight)))) {
097 double left =
098 Coercions.coerceToPrimitiveNumber (pLeft, Double.class).
099 doubleValue ();
100 double right =
101 Coercions.coerceToPrimitiveNumber (pRight, Double.class).
102 doubleValue ();
103
104 try {
105 return PrimitiveObjects.getDouble (left % right);
106 }
107 catch (Exception exc) {
108 if (log.isErrorEnabled()) {
109 String message = MessageUtil.getMessageWithArgs(
110 Constants.ARITH_ERROR,
111 getOperatorSymbol(),
112 "" + left,
113 "" + right);
114 log.error(message);
115 throw new ELException(message);
116 }
117 return PrimitiveObjects.getInteger (0);
118 }
119 }
120 else if (Coercions.isBigInteger(pLeft) || Coercions.isBigInteger(pRight)) {
121 BigInteger left = (BigInteger)
122 Coercions.coerceToPrimitiveNumber(pLeft, BigInteger.class);
123 BigInteger right = (BigInteger)
124 Coercions.coerceToPrimitiveNumber(pRight, BigInteger.class);
125
126 try {
127 return left.remainder(right);
128 } catch (Exception exc) {
129 if (log.isErrorEnabled()) {
130 String message = MessageUtil.getMessageWithArgs(
131 Constants.ARITH_ERROR,
132 getOperatorSymbol(),
133 "" + left,
134 "" + right);
135 log.error(message);
136 throw new ELException(message);
137 }
138 return PrimitiveObjects.getInteger(0);
139 }
140 }
141 else {
142 long left =
143 Coercions.coerceToPrimitiveNumber (pLeft, Long.class).
144 longValue ();
145 long right =
146 Coercions.coerceToPrimitiveNumber (pRight, Long.class).
147 longValue ();
148
149 try {
150 return PrimitiveObjects.getLong (left % right);
151 }
152 catch (Exception exc) {
153 if (log.isErrorEnabled()) {
154 String message = MessageUtil.getMessageWithArgs(
155 Constants.ARITH_ERROR,
156 getOperatorSymbol(),
157 "" + left,
158 "" + right);
159 log.error(message);
160 throw new ELException(message);
161 }
162 return PrimitiveObjects.getInteger (0);
163 }
164 }
165 }
166
167 //-------------------------------------
168 }