package org.odata4j.core;
import java.io.InputStream;
import java.math.BigDecimal;
import java.sql.Blob;
import org.joda.time.DateTime;
import org.joda.time.LocalDateTime;
import org.joda.time.LocalTime;
import org.odata4j.edm.EdmSimpleType;
import org.odata4j.internal.InternalUtil;
import org.odata4j.internal.TypeConverter;
import org.odata4j.repack.org.apache.commons.codec.binary.Base64;
import org.odata4j.repack.org.apache.commons.codec.binary.Hex;
/**
* A static factory to create immutable {@link OSimpleObject} instances.
*/
public class OSimpleObjects {
private OSimpleObjects() {}
/** Creates a new {@link OSimpleObject} instance given a type and value. */
@SuppressWarnings("unchecked")
public static <T> OSimpleObject<T> create(EdmSimpleType<T> type, Object value) {
if (type == EdmSimpleType.STRING) {
String sValue = null;
if (value != null) {
sValue = value.toString();
}
return (OSimpleObject<T>) Impl.create(EdmSimpleType.STRING, sValue);
} else if (type == EdmSimpleType.BOOLEAN) {
Boolean bValue = (Boolean) value;
return (OSimpleObject<T>) Impl.create(EdmSimpleType.BOOLEAN, bValue);
} else if (type == EdmSimpleType.INT16) {
Short sValue = null;
if (value != null) {
if (value instanceof Number) {
sValue = ((Number) value).shortValue();
} else {
sValue = Short.valueOf(value.toString());
}
}
return (OSimpleObject<T>) Impl.create(EdmSimpleType.INT16, sValue);
} else if (type == EdmSimpleType.INT32) {
Integer iValue = null;
if (value != null) {
if (value instanceof Number) {
iValue = ((Number) value).intValue();
} else {
iValue = Integer.valueOf(value.toString());
}
}
return (OSimpleObject<T>) Impl.create(EdmSimpleType.INT32, iValue);
} else if (type == EdmSimpleType.INT64) {
Long iValue = null;
if (value != null) {
if (value instanceof Number) {
iValue = ((Number) value).longValue();
} else {
iValue = Long.valueOf(value.toString());
}
}
return (OSimpleObject<T>) Impl.create(EdmSimpleType.INT64, iValue);
} else if (type == EdmSimpleType.BYTE) {
UnsignedByte bValue = (UnsignedByte) value;
return (OSimpleObject<T>) Impl.create(EdmSimpleType.BYTE, bValue);
} else if (type == EdmSimpleType.SBYTE) {
Byte bValue = (Byte) value;
return (OSimpleObject<T>) Impl.create(EdmSimpleType.SBYTE, bValue);
} else if (type == EdmSimpleType.DECIMAL) {
BigDecimal dValue = (BigDecimal) value;
return (OSimpleObject<T>) Impl.create(EdmSimpleType.DECIMAL, dValue);
} else if (type == EdmSimpleType.DATETIME) {
LocalDateTime ldtValue = TypeConverter.convert(value, LocalDateTime.class);
return (OSimpleObject<T>) Impl.create(EdmSimpleType.DATETIME, ldtValue);
} else if (type == EdmSimpleType.TIME) {
LocalTime ltValue = TypeConverter.convert(value, LocalTime.class);
return (OSimpleObject<T>) Impl.create(EdmSimpleType.TIME, ltValue);
} else if (type == EdmSimpleType.BINARY) {
byte[] bValue = (byte[]) value;
return (OSimpleObject<T>) Impl.create(EdmSimpleType.BINARY, bValue);
} else if (type == EdmSimpleType.STREAM) {
if (value instanceof InputStream) {
InputStream bValue = (InputStream) value;
return (OSimpleObject<T>) Impl.create(EdmSimpleType.INPUTSTREAM, bValue);
}
Blob bValue = (Blob) value;
return (OSimpleObject<T>) Impl.create(EdmSimpleType.STREAM, bValue);
} else if (type == EdmSimpleType.DOUBLE) {
Double dValue = null;
if (value != null) {
if (value instanceof Number) {
dValue = ((Number) value).doubleValue();
} else {
dValue = Double.valueOf(value.toString());
}
}
return (OSimpleObject<T>) Impl.create(EdmSimpleType.DOUBLE, dValue);
} else if (type == EdmSimpleType.SINGLE) {
Float fValue = null;
if (value != null) {
if (value instanceof Number) {
fValue = ((Number) value).floatValue();
} else {
fValue = Float.valueOf(value.toString());
}
}
return (OSimpleObject<T>) Impl.create(EdmSimpleType.SINGLE, fValue);
} else if (type == EdmSimpleType.GUID) {
Guid gValue = TypeConverter.convert(value, Guid.class);
return (OSimpleObject<T>) Impl.create(EdmSimpleType.GUID, gValue);
} else if (type == EdmSimpleType.DATETIMEOFFSET) {
DateTime dtValue = (DateTime) value;
return (OSimpleObject<T>) Impl.create(EdmSimpleType.DATETIMEOFFSET, dtValue);
} else {
throw new UnsupportedOperationException("Implement " + type);
}
}
/** Parses a string value into a new {@link OSimpleObject} given an edm type. */
@SuppressWarnings("unchecked")
public static <V> OSimpleObject<V> parse(EdmSimpleType<V> type, String value) {
if (value == null)
return (OSimpleObject<V>) Impl.create(type, null);
if (EdmSimpleType.GUID.equals(type))
return (OSimpleObject<V>) Impl.create(EdmSimpleType.GUID, Guid.fromString(value));
if (EdmSimpleType.BOOLEAN.equals(type))
return (OSimpleObject<V>) Impl.create(EdmSimpleType.BOOLEAN, Boole.fromString(value).toBoolean());
if (EdmSimpleType.BYTE.equals(type))
return (OSimpleObject<V>) Impl.create(EdmSimpleType.BYTE, UnsignedByte.parseUnsignedByte(value));
if (EdmSimpleType.SBYTE.equals(type))
return (OSimpleObject<V>) Impl.create(EdmSimpleType.SBYTE, Byte.parseByte(value));
if (EdmSimpleType.INT16.equals(type))
return (OSimpleObject<V>) Impl.create(EdmSimpleType.INT16, Short.parseShort(value));
if (EdmSimpleType.INT32.equals(type))
return (OSimpleObject<V>) Impl.create(EdmSimpleType.INT32, Integer.parseInt(value));
if (EdmSimpleType.INT64.equals(type))
return (OSimpleObject<V>) Impl.create(EdmSimpleType.INT64, Long.parseLong(value));
if (EdmSimpleType.SINGLE.equals(type)) {
if (value.equals(ODataConstants.NaN_value)) {
return (OSimpleObject<V>) Impl.create(EdmSimpleType.SINGLE, Float.NaN);
}
else {
return (OSimpleObject<V>) Impl.create(EdmSimpleType.SINGLE, Float.parseFloat(value));
}
}
if (EdmSimpleType.DOUBLE.equals(type)) {
if (value.equals(ODataConstants.NaN_value)) {
return (OSimpleObject<V>) Impl.create(EdmSimpleType.DOUBLE, Double.NaN);
} else {
return (OSimpleObject<V>) Impl.create(EdmSimpleType.DOUBLE, Double.parseDouble(value));
}
}
if (EdmSimpleType.DECIMAL.equals(type))
return (OSimpleObject<V>) Impl.create(EdmSimpleType.DECIMAL, new BigDecimal(value));
if (EdmSimpleType.BINARY.equals(type))
return (OSimpleObject<V>) Impl.create(EdmSimpleType.BINARY, new Base64().decode(value));
if (EdmSimpleType.DATETIME.equals(type))
return (OSimpleObject<V>) Impl.create(EdmSimpleType.DATETIME, InternalUtil.parseDateTimeFromXml(value));
if (EdmSimpleType.DATETIMEOFFSET.equals(type))
return (OSimpleObject<V>) Impl.create(EdmSimpleType.DATETIMEOFFSET, InternalUtil.parseDateTimeOffsetFromXml(value));
if (EdmSimpleType.TIME.equals(type))
return (OSimpleObject<V>) Impl.create(EdmSimpleType.TIME, InternalUtil.parseTime(value));
if (EdmSimpleType.STRING.equals(type))
return (OSimpleObject<V>) Impl.create(EdmSimpleType.STRING, value);
throw new UnsupportedOperationException("type:" + type);
}
/** Returns a human-readable string value for a given object. */
public static String getValueDisplayString(Object value) {
if (value instanceof byte[])
value = "0x" + Hex.encodeHexString((byte[]) value);
return value == null ? "null" : value.toString();
}
private static class Impl<V> implements OSimpleObject<V> {
private final EdmSimpleType<V> type;
private final V value;
private Impl(EdmSimpleType<V> type, V value) {
this.type = type;
this.value = value;
}
private static <V> Impl<V> create(EdmSimpleType<V> type, V value) {
return new Impl<V>(type, value);
}
@Override
public V getValue() {
return value;
}
@Override
public EdmSimpleType<V> getType() {
return type;
}
@Override
public String toString() {
return getValueDisplayString(value);
}
}
}