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

cn.leancloud.ops.NumericOperation Maven / Gradle / Ivy

package cn.leancloud.ops;

import java.util.HashMap;
import java.util.Map;

public abstract class NumericOperation extends BaseOperation {
  public NumericOperation(String op, String field, Object value) {
    super(op, field, value, false);
    if (getValue() instanceof Number) {
      // ok
    } else {
      throw new IllegalArgumentException("Value is not number!");
    }
  }

  public Object apply(Object obj) {
    Number init;
    if (null == obj) {
      init = 0;
    } else if (obj instanceof Number) {
      init = (Number) obj;
    } else {
      LOGGER.w("cannot apply AddOperation on non number attribute. targetValueType=" + obj.getClass().getSimpleName());
      return obj;
    }
    Number result = 0;
    if (this instanceof DecrementOperation) {
      result = subNumbers(init, (Number) this.value);
    } else if (this instanceof IncrementOperation) {
      result = addNumbers(init, (Number) this.value);
    } else if (this instanceof BitXOROperation) {
      result = calculateLongs(init, (Number)this.value, 'X');
    } else if (this instanceof BitAndOperation) {
      result = calculateLongs(init, (Number)this.value, 'A');
    } else if (this instanceof BitOrOperation) {
      result = calculateLongs(init, (Number)this.value, 'O');
    }
    return result;
  }

  public Map encode() {
    Map opMap = new HashMap();
    opMap.put(BaseOperation.KEY_OP, this.getOperation());
    if (this instanceof IncrementOperation || this instanceof DecrementOperation) {
      // {"balance":{"__op":"Decrement","amount": 30}}
      // {"balance":{"__op":"Increment","amount": 30}}
      opMap.put(BaseOperation.KEY_AMOUNT, this.getValue());
    } else {
      // {"balance":{"__op":"BitAnd","value": 30}}
      opMap.put(BaseOperation.KEY_VALUE, this.getValue());
    }
    Map result = new HashMap();
    result.put(getField(), opMap);
    return result;
  }

  @Override
  protected ObjectFieldOperation mergeWithPrevious(ObjectFieldOperation other) {
    if (other instanceof SetOperation || other instanceof DeleteOperation) {
      return other;
    } else if (other instanceof NumericOperation) {
      return new CompoundOperation(this.field, other, this);
    } else if (other instanceof CompoundOperation) {
      return ((CompoundOperation) other).mergeWithPrevious(this);
    } else {
      reportIllegalOperations(this, other);
    }

    return NullOperation.gInstance;
  }

  protected static Long calculateLongs(Number a, Number b, char op) {
    Long first = a.longValue();
    Long second = b.longValue();
    Long result = 0l;
    switch (op) {
      case 'A':
        result = first & second;
        break;
      case 'O':
        result = first | second;
        break;
      case 'X':
        result = first ^ second;
        break;
      default:
        break;
    }
    return result;
  }

  protected static Number addNumbers(Number a, Number b) {
    if(a instanceof Double || b instanceof Double) {
      return a.doubleValue() + b.doubleValue();
    } else if(a instanceof Float || b instanceof Float) {
      return  a.floatValue() + b.floatValue();
    } else if(a instanceof Long || b instanceof Long) {
      return a.longValue() + b.longValue();
    } else {
      return a.intValue() + b.intValue();
    }
  }

  protected static Number subNumbers(Number a, Number b) {
    if(a instanceof Double || b instanceof Double) {
      return a.doubleValue() - b.doubleValue();
    } else if(a instanceof Float || b instanceof Float) {
      return a.floatValue() - b.floatValue();
    } else if(a instanceof Long || b instanceof Long) {
      return a.longValue() - b.longValue();
    } else {
      return a.intValue() - b.intValue();
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy