/**
* Copyright (c) 2014-2017 by the respective copyright holders.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.smarthome.core.library.types;
import java.math.BigDecimal;
import java.util.IllegalFormatConversionException;
import org.eclipse.smarthome.core.library.internal.StateConverterUtil;
import org.eclipse.smarthome.core.types.Command;
import org.eclipse.smarthome.core.types.Convertible;
import org.eclipse.smarthome.core.types.PrimitiveType;
import org.eclipse.smarthome.core.types.State;
import org.eclipse.smarthome.core.types.UnDefType;
/**
* The decimal type uses a BigDecimal internally and thus can be used for
* integers, longs and floating point numbers alike.
*
* @author Kai Kreuzer - Initial contribution and API
*
*/
public class DecimalType extends Number implements PrimitiveType, State, Command, Comparable<DecimalType>, Convertible {
private static final long serialVersionUID = 4226845847123464690L;
final static public DecimalType ZERO = new DecimalType(0);
protected BigDecimal value;
public DecimalType() {
this.value = BigDecimal.ZERO;
}
public DecimalType(BigDecimal value) {
this.value = value;
}
public DecimalType(long value) {
this.value = BigDecimal.valueOf(value);
}
public DecimalType(double value) {
this.value = BigDecimal.valueOf(value);
}
public DecimalType(String value) {
this.value = new BigDecimal(value);
}
@Override
public String toString() {
return toFullString();
}
@Override
public String toFullString() {
return value.toPlainString();
}
public static DecimalType valueOf(String value) {
return new DecimalType(value);
}
@Override
public String format(String pattern) {
// The value could be an integer value. Try to convert to BigInteger in
// order to have access to more conversion formats.
try {
return String.format(pattern, value.toBigIntegerExact());
} catch (ArithmeticException ae) {
// Could not convert to integer value without loss of
// information. Fall through to default behavior.
} catch (IllegalFormatConversionException ifce) {
// The conversion is not valid for the type BigInteger. This
// happens, if the format is like "%.1f" but the value is an
// integer. Fall through to default behavior.
}
return String.format(pattern, value);
}
public BigDecimal toBigDecimal() {
return value;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof DecimalType)) {
return false;
}
DecimalType other = (DecimalType) obj;
if (value == null) {
if (other.value != null) {
return false;
}
} else if (value.compareTo(other.value) != 0) {
return false;
}
return true;
}
@Override
public int compareTo(DecimalType o) {
return value.compareTo(o.toBigDecimal());
}
@Override
public double doubleValue() {
return value.doubleValue();
}
@Override
public float floatValue() {
return value.floatValue();
}
@Override
public int intValue() {
return value.intValue();
}
@Override
public long longValue() {
return value.longValue();
}
@Override
public State as(Class<? extends State> target) {
if (target == OnOffType.class) {
return equals(ZERO) ? OnOffType.OFF : OnOffType.ON;
} else if (target == PercentType.class) {
return new PercentType(toBigDecimal().multiply(BigDecimal.valueOf(100)));
} else if (target == UpDownType.class) {
if (equals(ZERO)) {
return UpDownType.UP;
} else if (toBigDecimal().compareTo(BigDecimal.valueOf(1)) == 0) {
return UpDownType.DOWN;
} else {
return UnDefType.UNDEF;
}
} else if (target == OpenClosedType.class) {
if (equals(ZERO)) {
return OpenClosedType.CLOSED;
} else if (toBigDecimal().compareTo(BigDecimal.valueOf(1)) == 0) {
return OpenClosedType.OPEN;
} else {
return UnDefType.UNDEF;
}
} else if (target == HSBType.class) {
return new HSBType(DecimalType.ZERO, PercentType.ZERO,
new PercentType(this.toBigDecimal().multiply(BigDecimal.valueOf(100))));
} else {
return StateConverterUtil.defaultConversion(this, target);
}
}
}