Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (C) 2015 Archie L. Cobbs. All rights reserved.
*/
package org.jsimpledb.parse.expr;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.NavigableSet;
import java.util.Set;
import org.jsimpledb.parse.ParseSession;
import org.jsimpledb.util.NavigableSets;
/**
* {@link Value} implementation superclass with implementations for all methods other than {@link #get get()}.
*/
public abstract class AbstractValue implements Value {
protected AbstractValue() {
}
@Override
public Class> getType(ParseSession session) {
return Object.class;
}
@Override
public Object checkNotNull(ParseSession session, String operation) {
final Object value = this.get(session);
if (value == null)
throw new EvalException("invalid " + operation + " operation on null value");
return value;
}
@Override
public boolean checkBoolean(ParseSession session, String operation) {
return this.checkType(session, operation, Boolean.class);
}
@Override
public Number checkNumeric(ParseSession session, String operation) {
return AbstractValue.checkNumeric(session, this.get(session), operation);
}
@Override
public int checkIntegral(ParseSession session, String operation) {
final Object value = this.checkNotNull(session, operation);
if (value instanceof Character)
return (int)(Character)value;
if (!(value instanceof Byte) && !(value instanceof Short) && !(value instanceof Integer))
throw new EvalException("invalid " + operation + " operation on " + AbstractValue.describeType(value, "non-integral"));
return ((Number)value).intValue();
}
@Override
public T checkType(ParseSession session, String operation, Class type) {
Preconditions.checkArgument(type != null, "null type");
final Object value = this.checkNotNull(session, operation);
if (!type.isInstance(value)) {
throw new EvalException("invalid " + operation + " operation on "
+ AbstractValue.describeType(value, "non-" + type.getSimpleName()));
}
return type.cast(value);
}
@Override
public Value xxcrement(ParseSession session, String operation, boolean increment) {
final int amount = increment ? 1 : -1;
final LValue thisLValue = this.asLValue(operation);
final Object value = this.get(session);
Object num = value instanceof Character ? value : AbstractValue.checkNumeric(session, value, operation);
if (num instanceof Byte)
num = (byte)((Byte)num + (byte)amount);
else if (num instanceof Character)
num = (char)((Character)num + (char)amount);
else if (num instanceof Short)
num = (short)((Short)num + (short)amount);
else if (num instanceof Integer)
num = (Integer)num + amount;
else if (num instanceof Float)
num = (Float)num + (float)amount;
else if (num instanceof Long)
num = (Long)num + (long)amount;
else if (num instanceof Double)
num = (Double)num + (double)amount;
else if (num instanceof BigInteger)
num = ((BigInteger)num).add(increment ? BigInteger.ONE : BigInteger.ONE.negate());
else if (num instanceof BigDecimal)
num = ((BigDecimal)num).add(increment ? BigDecimal.ONE : BigDecimal.ONE.negate());
else
throw new EvalException("invalid " + operation + " operation on " + AbstractValue.describeType(num));
final Value result = new ConstValue(num);
thisLValue.set(session, result);
return result;
}
@Override
public Value negate(ParseSession session) {
final Number num = AbstractValue.promoteNumeric(session, this.get(session), "negate");
if (num instanceof BigDecimal)
return new ConstValue(((BigDecimal)num).negate());
if (num instanceof Double)
return new ConstValue(-(Double)num);
if (num instanceof Float)
return new ConstValue(-(Float)num);
if (num instanceof BigInteger)
return new ConstValue(((BigInteger)num).negate());
if (num instanceof Long)
return new ConstValue(-(Long)num);
if (num instanceof Integer)
return new ConstValue(-(Integer)num);
throw new EvalException("invalid negate operation on " + AbstractValue.describeType(num));
}
@Override
public Value invert(ParseSession session) {
final Number num = AbstractValue.promoteNumeric(session, this.get(session), "invert");
if (num instanceof Integer)
return new ConstValue(~(Integer)num);
if (num instanceof Long)
return new ConstValue(~(Long)num);
throw new EvalException("invalid invert operation on " + AbstractValue.describeType(num));
}
@Override
public Value multiply(ParseSession session, Value that) {
final Object thisValue = this.checkNotNull(session, "multiply");
final Object thatValue = that.checkNotNull(session, "multiply");
final Number lnum = AbstractValue.promoteNumeric(session, thisValue, "multiply", thatValue);
final Number rnum = AbstractValue.promoteNumeric(session, thatValue, "multiply", thisValue);
if (lnum instanceof BigDecimal)
return new ConstValue(((BigDecimal)lnum).multiply((BigDecimal)rnum));
if (lnum instanceof Double)
return new ConstValue((Double)lnum * (Double)rnum);
if (lnum instanceof Float)
return new ConstValue((Float)lnum * (Float)rnum);
if (lnum instanceof BigInteger)
return new ConstValue(((BigInteger)lnum).multiply((BigInteger)rnum));
if (lnum instanceof Long)
return new ConstValue((Long)lnum * (Long)rnum);
if (lnum instanceof Integer)
return new ConstValue((Integer)lnum * (Integer)rnum);
throw new EvalException("invalid multiply operation on values of type "
+ lnum.getClass().getName() + " and " + rnum.getClass().getName());
}
@Override
public Value divide(ParseSession session, Value that) {
final Object thisValue = this.checkNotNull(session, "divide");
final Object thatValue = that.checkNotNull(session, "divide");
final Number lnum = AbstractValue.promoteNumeric(session, thisValue, "divide", thatValue);
final Number rnum = AbstractValue.promoteNumeric(session, thatValue, "divide", thisValue);
if (lnum instanceof BigDecimal)
return new ConstValue(((BigDecimal)lnum).divide((BigDecimal)rnum));
if (lnum instanceof Double)
return new ConstValue((Double)lnum / (Double)rnum);
if (lnum instanceof Float)
return new ConstValue((Float)lnum / (Float)rnum);
if (lnum instanceof BigInteger)
return new ConstValue(((BigInteger)lnum).divide((BigInteger)rnum));
if (lnum instanceof Long)
return new ConstValue((Long)lnum / (Long)rnum);
if (lnum instanceof Integer)
return new ConstValue((Integer)lnum / (Integer)rnum);
throw new EvalException("invalid divide operation on values of type "
+ lnum.getClass().getName() + " and " + rnum.getClass().getName());
}
@Override
public Value mod(ParseSession session, Value that) {
final Object thisValue = this.checkNotNull(session, "modulo");
final Object thatValue = that.checkNotNull(session, "modulo");
final Number lnum = AbstractValue.promoteNumeric(session, thisValue, "modulo", thatValue);
final Number rnum = AbstractValue.promoteNumeric(session, thatValue, "modulo", thisValue);
if (lnum instanceof Double)
return new ConstValue((Double)lnum % (Double)rnum);
if (lnum instanceof Float)
return new ConstValue((Float)lnum % (Float)rnum);
if (lnum instanceof BigInteger)
return new ConstValue(((BigInteger)lnum).mod((BigInteger)rnum));
if (lnum instanceof Long)
return new ConstValue((Long)lnum % (Long)rnum);
if (lnum instanceof Integer)
return new ConstValue((Integer)lnum % (Integer)rnum);
throw new EvalException("invalid modulo operation on values of type "
+ lnum.getClass().getName() + " and " + rnum.getClass().getName());
}
@Override
public Value add(ParseSession session, Value that) {
// Handle String concatenation
final Object thisValue = this.get(session);
final Object thatValue = that.get(session);
if (thisValue == null || thatValue == null || thisValue instanceof String || thatValue instanceof String)
return new ConstValue(String.valueOf(thisValue) + String.valueOf(thatValue));
// Handle numeric
final Number lnum = AbstractValue.promoteNumeric(session, thisValue, "add", thatValue);
final Number rnum = AbstractValue.promoteNumeric(session, thatValue, "add", thisValue);
if (lnum instanceof BigDecimal)
return new ConstValue(((BigDecimal)lnum).add((BigDecimal)rnum));
if (lnum instanceof Double)
return new ConstValue((Double)lnum + (Double)rnum);
if (lnum instanceof Float)
return new ConstValue((Float)lnum + (Float)rnum);
if (lnum instanceof BigInteger)
return new ConstValue(((BigInteger)lnum).add((BigInteger)rnum));
if (lnum instanceof Long)
return new ConstValue((Long)lnum + (Long)rnum);
if (lnum instanceof Integer)
return new ConstValue((Integer)lnum + (Integer)rnum);
throw new EvalException("invalid add operation on values of type "
+ lnum.getClass().getName() + " and " + rnum.getClass().getName());
}
@Override
@SuppressWarnings("unchecked")
public Value subtract(ParseSession session, Value that) {
// Handle NavigableSet with equal comparators XXX might not have compatible elements
final Object thisValue = this.checkNotNull(session, "subtract");
final Object thatValue = that.checkNotNull(session, "subtract");
if (thisValue instanceof NavigableSet
&& thatValue instanceof NavigableSet
&& (((NavigableSet>)thisValue).comparator() != null ?
((NavigableSet>)thisValue).comparator().equals(((NavigableSet>)thatValue).comparator()) :
((NavigableSet>)thatValue).comparator() == null))
return new ConstValue(NavigableSets.difference((NavigableSet