All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.activiti.engine.impl.juel.NumberOperations Maven / Gradle / Ivy

There is a newer version: 7.1.0.M6
Show newest version
/*
 * Based on JUEL 2.2.1 code, 2006-2009 Odysseus Software GmbH
 *
 * Licensed 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.
 */
package org.activiti.engine.impl.juel;

import java.math.BigDecimal;
import java.math.BigInteger;

import org.activiti.engine.impl.javax.el.ELException;

/**
 * Arithmetic Operations as specified in chapter 1.7.
 * 
 * @author Christoph Beck
 */
public class NumberOperations {
  private final static Long LONG_ZERO = Long.valueOf(0L);

  private final static boolean isDotEe(String value) {
    int length = value.length();
    for (int i = 0; i < length; i++) {
      switch (value.charAt(i)) {
      case '.':
      case 'E':
      case 'e':
        return true;
      }
    }
    return false;
  }

  private final static boolean isDotEe(Object value) {
    return value instanceof String && isDotEe((String) value);
  }

  private static final boolean isFloatOrDouble(Object value) {
    return value instanceof Float || value instanceof Double;
  }

  private static final boolean isFloatOrDoubleOrDotEe(Object value) {
    return isFloatOrDouble(value) || isDotEe(value);
  }

  private static final boolean isBigDecimalOrBigInteger(Object value) {
    return value instanceof BigDecimal || value instanceof BigInteger;
  }

  private static final boolean isBigDecimalOrFloatOrDoubleOrDotEe(Object value) {
    return value instanceof BigDecimal || isFloatOrDoubleOrDotEe(value);
  }

  public static final Number add(TypeConverter converter, Object o1, Object o2) {
    if (o1 == null && o2 == null) {
      return LONG_ZERO;
    }
    if (o1 instanceof BigDecimal || o2 instanceof BigDecimal) {
      return converter.convert(o1, BigDecimal.class).add(converter.convert(o2, BigDecimal.class));
    }
    if (isFloatOrDoubleOrDotEe(o1) || isFloatOrDoubleOrDotEe(o2)) {
      if (o1 instanceof BigInteger || o2 instanceof BigInteger) {
        return converter.convert(o1, BigDecimal.class).add(converter.convert(o2, BigDecimal.class));
      }
      return converter.convert(o1, Double.class) + converter.convert(o2, Double.class);
    }
    if (o1 instanceof BigInteger || o2 instanceof BigInteger) {
      return converter.convert(o1, BigInteger.class).add(converter.convert(o2, BigInteger.class));
    }
    return converter.convert(o1, Long.class) + converter.convert(o2, Long.class);
  }

  public static final Number sub(TypeConverter converter, Object o1, Object o2) {
    if (o1 == null && o2 == null) {
      return LONG_ZERO;
    }
    if (o1 instanceof BigDecimal || o2 instanceof BigDecimal) {
      return converter.convert(o1, BigDecimal.class).subtract(converter.convert(o2, BigDecimal.class));
    }
    if (isFloatOrDoubleOrDotEe(o1) || isFloatOrDoubleOrDotEe(o2)) {
      if (o1 instanceof BigInteger || o2 instanceof BigInteger) {
        return converter.convert(o1, BigDecimal.class).subtract(converter.convert(o2, BigDecimal.class));
      }
      return converter.convert(o1, Double.class) - converter.convert(o2, Double.class);
    }
    if (o1 instanceof BigInteger || o2 instanceof BigInteger) {
      return converter.convert(o1, BigInteger.class).subtract(converter.convert(o2, BigInteger.class));
    }
    return converter.convert(o1, Long.class) - converter.convert(o2, Long.class);
  }

  public static final Number mul(TypeConverter converter, Object o1, Object o2) {
    if (o1 == null && o2 == null) {
      return LONG_ZERO;
    }
    if (o1 instanceof BigDecimal || o2 instanceof BigDecimal) {
      return converter.convert(o1, BigDecimal.class).multiply(converter.convert(o2, BigDecimal.class));
    }
    if (isFloatOrDoubleOrDotEe(o1) || isFloatOrDoubleOrDotEe(o2)) {
      if (o1 instanceof BigInteger || o2 instanceof BigInteger) {
        return converter.convert(o1, BigDecimal.class).multiply(converter.convert(o2, BigDecimal.class));
      }
      return converter.convert(o1, Double.class) * converter.convert(o2, Double.class);
    }
    if (o1 instanceof BigInteger || o2 instanceof BigInteger) {
      return converter.convert(o1, BigInteger.class).multiply(converter.convert(o2, BigInteger.class));
    }
    return converter.convert(o1, Long.class) * converter.convert(o2, Long.class);
  }

  public static final Number div(TypeConverter converter, Object o1, Object o2) {
    if (o1 == null && o2 == null) {
      return LONG_ZERO;
    }
    if (isBigDecimalOrBigInteger(o1) || isBigDecimalOrBigInteger(o2)) {
      return converter.convert(o1, BigDecimal.class).divide(converter.convert(o2, BigDecimal.class), BigDecimal.ROUND_HALF_UP);
    }
    return converter.convert(o1, Double.class) / converter.convert(o2, Double.class);
  }

  public static final Number mod(TypeConverter converter, Object o1, Object o2) {
    if (o1 == null && o2 == null) {
      return LONG_ZERO;
    }
    if (isBigDecimalOrFloatOrDoubleOrDotEe(o1) || isBigDecimalOrFloatOrDoubleOrDotEe(o2)) {
      return converter.convert(o1, Double.class) % converter.convert(o2, Double.class);
    }
    if (o1 instanceof BigInteger || o2 instanceof BigInteger) {
      return converter.convert(o1, BigInteger.class).remainder(converter.convert(o2, BigInteger.class));
    }
    return converter.convert(o1, Long.class) % converter.convert(o2, Long.class);
  }

  public static final Number neg(TypeConverter converter, Object value) {
    if (value == null) {
      return LONG_ZERO;
    }
    if (value instanceof BigDecimal) {
      return ((BigDecimal) value).negate();
    }
    if (value instanceof BigInteger) {
      return ((BigInteger) value).negate();
    }
    if (value instanceof Double) {
      return Double.valueOf(-((Double) value).doubleValue());
    }
    if (value instanceof Float) {
      return Float.valueOf(-((Float) value).floatValue());
    }
    if (value instanceof String) {
      if (isDotEe((String) value)) {
        return Double.valueOf(-converter.convert(value, Double.class).doubleValue());
      }
      return Long.valueOf(-converter.convert(value, Long.class).longValue());
    }
    if (value instanceof Long) {
      return Long.valueOf(-((Long) value).longValue());
    }
    if (value instanceof Integer) {
      return Integer.valueOf(-((Integer) value).intValue());
    }
    if (value instanceof Short) {
      return Short.valueOf((short) -((Short) value).shortValue());
    }
    if (value instanceof Byte) {
      return Byte.valueOf((byte) -((Byte) value).byteValue());
    }
    throw new ELException(LocalMessages.get("error.negate", value.getClass()));
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy