package org.odata4j.edm; import java.io.InputStream; import java.math.BigDecimal; import java.sql.Blob; import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Set; import java.util.UUID; import javax.sql.rowset.serial.SerialBlob; import org.core4j.Enumerable; import org.joda.time.DateTime; import org.joda.time.Instant; import org.joda.time.LocalDateTime; import org.joda.time.LocalTime; import org.odata4j.core.Guid; import org.odata4j.core.UnsignedByte; /** * Primitive types in the EDM type system. * Simple types are exposed as constants and associated with one or more java-types. * * @see <a href="http://msdn.microsoft.com/en-us/library/bb399213.aspx">[msdn] Simple Types (EDM)</a> */ public class EdmSimpleType<V> extends EdmType { private static Set<EdmSimpleType<?>> all = new HashSet<EdmSimpleType<?>>(); // http://msdn.microsoft.com/en-us/library/bb399213.aspx public static final EdmSimpleType<byte[]> BINARY = newSimple("Edm.Binary", byte[].class, Byte[].class); public static final EdmSimpleType<Blob> STREAM = newSimple("Edm.Stream", Blob.class, Blob.class, SerialBlob.class); public static final EdmSimpleType<Boolean> BOOLEAN = newSimple("Edm.Boolean", Boolean.class, boolean.class); public static final EdmSimpleType<UnsignedByte> BYTE = newSimple("Edm.Byte", UnsignedByte.class); public static final EdmSimpleType<LocalDateTime> DATETIME = newSimple("Edm.DateTime", LocalDateTime.class, Instant.class, Date.class, Calendar.class, Timestamp.class, java.sql.Date.class); // possible, but not default: Time.class public static final EdmSimpleType<DateTime> DATETIMEOFFSET = newSimple("Edm.DateTimeOffset", DateTime.class); public static final EdmSimpleType<BigDecimal> DECIMAL = newSimple("Edm.Decimal", BigDecimal.class); public static final EdmSimpleType<Double> DOUBLE = newSimple("Edm.Double", Double.class, double.class); public static final EdmSimpleType<Guid> GUID = newSimple("Edm.Guid", Guid.class, UUID.class); public static final EdmSimpleType<Short> INT16 = newSimple("Edm.Int16", Short.class, short.class); public static final EdmSimpleType<Integer> INT32 = newSimple("Edm.Int32", Integer.class, int.class); public static final EdmSimpleType<Long> INT64 = newSimple("Edm.Int64", Long.class, long.class); public static final EdmSimpleType<Byte> SBYTE = newSimple("Edm.SByte", Byte.class, byte.class); public static final EdmSimpleType<Float> SINGLE = newSimple("Edm.Single", Float.class, float.class); public static final EdmSimpleType<String> STRING = newSimple("Edm.String", String.class, char.class, Character.class); public static final EdmSimpleType<LocalTime> TIME = newSimple("Edm.Time", LocalTime.class, Time.class); // possible, but not default: Date.class, Calendar.class, Timestamp.class public static final EdmSimpleType<InputStream> INPUTSTREAM = newSimple("Edm.Stream", InputStream.class, InputStream.class); private static <V> EdmSimpleType<V> newSimple(String typeString, Class<V> canonicalJavaType, Class<?>... alternateJavaTypes) { EdmSimpleType<V> rt = new EdmSimpleType<V>(typeString, canonicalJavaType, alternateJavaTypes); all.add(rt); return rt; } /** * Immutable set of all edm simple types. */ public static final Set<EdmSimpleType<?>> ALL = Collections.unmodifiableSet(all); private final Class<V> canonicalJavaType; private final Set<Class<?>> javaTypes; private EdmSimpleType(String fullyQualifiedTypeName, Class<V> canonicalJavaType, Class<?>... alternateJavaTypes) { super(fullyQualifiedTypeName); this.canonicalJavaType = canonicalJavaType; this.javaTypes = Enumerable.<Class<?>> create(canonicalJavaType).concat(alternateJavaTypes).toSet(); } @Override public boolean isSimple() { return true; } public Class<V> getCanonicalJavaType() { return canonicalJavaType; } /** * Gets all java-types associated with this edm-type. * * @return the associated java-types. */ public Set<Class<?>> getJavaTypes() { return javaTypes; } /** * Finds the edm simple type for a given java-type. * * @param javaType the java-type * @return the associated edm simple type, else null */ @SuppressWarnings("unchecked") public static <V> EdmSimpleType<V> forJavaType(Class<?> javaType) { for (EdmSimpleType<?> simple : ALL) if (simple.getJavaTypes().contains(javaType)) return (EdmSimpleType<V>) simple; return null; } public static EdmType.Builder<?, ?> newBuilder(EdmType type) { return new Builder(type); } private static class Builder extends EdmType.Builder<EdmType, Builder> { private Builder(EdmType type) { super(type); } @Override Builder newBuilder(EdmType type, BuilderContext context) { return new Builder(type); } @Override public EdmType build() { return (EdmType) _build(); } @Override protected EdmType buildImpl() { // should never get here return null; } } }