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.BigDecimal;
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 divide 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 DivideOperator
035      extends BinaryOperator
036    {
037        //-------------------------------------
038        // Constants
039        //-------------------------------------
040        private static Log log = LogFactory.getLog(DivideOperator.class);
041        
042      //-------------------------------------
043      // Singleton
044      //-------------------------------------
045    
046      public static final DivideOperator SINGLETON =
047        new DivideOperator ();
048    
049      //-------------------------------------
050      /**
051       *
052       * Constructor
053       **/
054      public DivideOperator ()
055      {
056      }
057    
058      //-------------------------------------
059      // Expression methods
060      //-------------------------------------
061      /**
062       *
063       * Returns the symbol representing the operator
064       **/
065      public String getOperatorSymbol ()
066      {
067        return "/";
068      }
069    
070      //-------------------------------------
071      /**
072       *
073       * Applies the operator to the given value
074       **/
075      public Object apply (Object pLeft,
076                           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,
085                        getOperatorSymbol()));
086            }     
087          return PrimitiveObjects.getInteger (0);
088        }
089    
090        if (Coercions.isBigDecimal(pLeft) ||
091            Coercions.isBigInteger(pLeft) ||
092            Coercions.isBigDecimal(pRight) ||
093            Coercions.isBigInteger(pRight)) {
094    
095            BigDecimal left = (BigDecimal)
096                Coercions.coerceToPrimitiveNumber(pLeft, BigDecimal.class);
097            BigDecimal right = (BigDecimal)
098                Coercions.coerceToPrimitiveNumber(pRight, BigDecimal.class);
099    
100            try {
101                return left.divide(right, BigDecimal.ROUND_HALF_UP);
102            } catch (Exception exc) {
103                if (log.isErrorEnabled()) {
104                    String message = MessageUtil.getMessageWithArgs(
105                        Constants.ARITH_ERROR,
106                        getOperatorSymbol(),
107                        "" + left,
108                        "" + right); 
109                    log.error(message);
110                    throw new ELException(message);
111                }            
112                return PrimitiveObjects.getInteger(0);
113            }
114        } else {
115    
116            double left =
117                Coercions.coerceToPrimitiveNumber(pLeft, Double.class).
118                doubleValue();
119            double right =
120                Coercions.coerceToPrimitiveNumber(pRight, Double.class).
121                doubleValue();
122    
123            try {
124                return PrimitiveObjects.getDouble(left / right);
125            } catch (Exception exc) {
126                if (log.isErrorEnabled()) {
127                    String message = MessageUtil.getMessageWithArgs(
128                        Constants.ARITH_ERROR,
129                        getOperatorSymbol(),
130                        "" + left,
131                        "" + right);
132                    log.error(message);
133                    throw new ELException(message);
134                }         
135                return PrimitiveObjects.getInteger(0);
136            }
137        }
138      }
139    
140      //-------------------------------------
141    }