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 */
017package org.apache.commons.el;
018
019import java.math.BigDecimal;
020
021import javax.servlet.jsp.el.ELException;
022
023import org.apache.commons.logging.Log;
024import 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
034public 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}