/*
* $Id$
* This file is a part of the Arakhne Foundation Classes, http://www.arakhne.org/afc
*
* Copyright (c) 2000-2012 Stephane GALLAND.
* Copyright (c) 2005-10, Multiagent Team, Laboratoire Systemes et Transports,
* Universite de Technologie de Belfort-Montbeliard.
* Copyright (c) 2013-2016 The original authors, and other authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.arakhne.afc.attrs.attr;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.eclipse.xtext.xbase.lib.Pure;
import org.arakhne.afc.math.geometry.d2.Point2D;
import org.arakhne.afc.math.geometry.d2.Tuple2D;
import org.arakhne.afc.math.geometry.d2.d.Point2d;
import org.arakhne.afc.math.geometry.d3.Point3D;
import org.arakhne.afc.math.geometry.d3.Tuple3D;
import org.arakhne.afc.math.geometry.d3.d.Point3d;
import org.arakhne.afc.ui.vector.Color;
import org.arakhne.afc.ui.vector.Colors;
import org.arakhne.afc.ui.vector.Image;
import org.arakhne.afc.ui.vector.VectorToolkit;
import org.arakhne.afc.vmutil.locale.Locale;
/**
* List of supported types for the metadata.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
@SuppressWarnings("deprecation")
public enum AttributeType {
/** Represents an enumeration.
* @see Enum
*/
ENUMERATION {
@Override
public Object getDefaultValue() {
return null;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public Object cast(Object obj) {
if (obj == null || obj instanceof NullAttribute) {
return null;
}
if (obj instanceof CharSequence) {
final String enumStr = obj.toString();
final int index = enumStr.lastIndexOf('.');
if (index > 0) {
final String enumName = enumStr.substring(0, index);
final String constantName = enumStr.substring(index + 1);
try {
final Class type = Class.forName(enumName);
if (Enum.class.isAssignableFrom(type)) {
final Enum<?> v = Enum.valueOf(type, constantName.toUpperCase());
if (v != null) {
return v;
}
}
} catch (Throwable exception) {
//
}
}
}
return Enum.class.cast(obj);
}
@Override
public boolean isNumberType() {
return false;
}
@Override
public boolean isNullAllowed() {
return true;
}
@Override
public boolean isBaseType() {
return false;
}
@Override
public boolean isAssignableFrom(AttributeType type) {
return type == ENUMERATION || type == STRING || type == OBJECT;
}
},
/** Represents a Java type.
*/
TYPE {
@Override
public Object getDefaultValue() {
return Object.class;
}
@Override
public Object cast(Object obj) {
if (obj == null) {
throw new NullPointerException();
}
if (obj instanceof NullAttribute) {
return null;
}
if (obj instanceof CharSequence) {
try {
return Class.forName(((CharSequence) obj).toString());
} catch (ClassNotFoundException e) {
//
}
}
return Class.class.cast(obj);
}
@Override
public boolean isNumberType() {
return false;
}
@Override
public boolean isNullAllowed() {
return false;
}
@Override
public boolean isBaseType() {
return false;
}
@Override
public boolean isAssignableFrom(AttributeType type) {
return type == TYPE || type == STRING || type == OBJECT;
}
},
/** Represents an unique universal identifier.
*/
UUID {
@Override
public Object getDefaultValue() {
return java.util.UUID.fromString("00000000-0000-0000-0000-000000000000"); //$NON-NLS-1$
}
@Override
public Object cast(Object obj) {
if (obj == null) {
throw new NullPointerException();
}
if (obj instanceof NullAttribute) {
return null;
}
return java.util.UUID.class.cast(obj);
}
@Override
public boolean isNumberType() {
return false;
}
@Override
public boolean isNullAllowed() {
return false;
}
@Override
public boolean isBaseType() {
return false;
}
@Override
public boolean isAssignableFrom(AttributeType type) {
return true;
}
},
/** Represents an integer.
*/
INTEGER {
@Override
public Object getDefaultValue() {
return Long.valueOf(0);
}
@Override
public Object cast(Object obj) {
if (obj == null) {
throw new NullPointerException();
}
if (obj instanceof NullAttribute) {
return null;
}
final long value;
if (obj instanceof Enum<?>) {
value = ((Enum<?>) obj).ordinal();
} else {
value = ((Number) obj).longValue();
}
return Long.valueOf(value);
}
@Override
public boolean isNumberType() {
return true;
}
@Override
public boolean isNullAllowed() {
return false;
}
@Override
public boolean isBaseType() {
return true;
}
@Override
@SuppressWarnings("checkstyle:booleanexpressioncomplexity")
public boolean isAssignableFrom(AttributeType type) {
return type == INTEGER || type == REAL || type == TIMESTAMP || type == STRING
|| type == DATE || type == BOOLEAN || type == COLOR || type == ENUMERATION || type == OBJECT;
}
},
/** Represents a floating number.
*/
REAL {
@Override
public Object getDefaultValue() {
return Double.valueOf(0);
}
@Override
public Object cast(Object obj) {
if (obj == null) {
throw new NullPointerException();
}
if (obj instanceof NullAttribute) {
return null;
}
final double value;
if (obj instanceof Enum<?>) {
value = ((Enum<?>) obj).ordinal();
} else {
value = ((Number) obj).doubleValue();
}
return Double.valueOf(value);
}
@Override
public boolean isNumberType() {
return true;
}
@Override
public boolean isNullAllowed() {
return false;
}
@Override
public boolean isBaseType() {
return true;
}
@Override
@SuppressWarnings("checkstyle:booleanexpressioncomplexity")
public boolean isAssignableFrom(AttributeType type) {
return type == INTEGER || type == REAL || type == TIMESTAMP || type == STRING
|| type == DATE || type == BOOLEAN || type == COLOR || type == ENUMERATION || type == OBJECT;
}
},
/** Represents a date.
*/
DATE {
@Override
public Object getDefaultValue() {
return new Date();
}
@Override
public Object cast(Object obj) {
if (obj == null) {
throw new NullPointerException();
}
if (obj instanceof NullAttribute) {
return null;
}
if (obj instanceof Number) {
return new Date(((Number) obj).longValue());
}
if (obj instanceof Calendar) {
return ((Calendar) obj).getTime();
}
return Date.class.cast(obj);
}
@Override
public boolean isNumberType() {
return false;
}
@Override
public boolean isNullAllowed() {
return false;
}
@Override
public boolean isBaseType() {
return false;
}
@Override
public boolean isAssignableFrom(AttributeType type) {
return type == DATE || type == REAL || type == INTEGER || type == TIMESTAMP || type == STRING || type == OBJECT;
}
},
/** Represents a boolean value.
*/
BOOLEAN {
@Override
public Object getDefaultValue() {
return Boolean.FALSE;
}
@Override
public Object cast(Object obj) {
if (obj == null) {
throw new NullPointerException();
}
if (obj instanceof NullAttribute) {
return null;
}
return Boolean.class.cast(obj);
}
@Override
public boolean isNumberType() {
return false;
}
@Override
public boolean isNullAllowed() {
return false;
}
@Override
public boolean isBaseType() {
return true;
}
@Override
public boolean isAssignableFrom(AttributeType type) {
return type == BOOLEAN || type == STRING || type == INTEGER || type == TIMESTAMP || type == REAL || type == OBJECT;
}
},
/** Represents an Internet address.
* @see Inet4Address
* @see Inet6Address
* @see InetSocketAddress
*/
INET_ADDRESS {
@Override
public Object getDefaultValue() {
try {
return InetAddress.getLocalHost();
} catch (UnknownHostException exception) {
return null;
}
}
@Override
public Object cast(Object obj) {
if (obj == null || obj instanceof NullAttribute) {
return null;
}
if (obj instanceof InetSocketAddress) {
return ((InetSocketAddress) obj).getAddress();
}
if (obj instanceof java.net.URL) {
final java.net.URL url = (java.net.URL) obj;
try {
return InetAddress.getByName(url.getHost());
} catch (UnknownHostException exception) {
//
}
}
if (obj instanceof java.net.URI) {
final java.net.URI uri = (java.net.URI) obj;
try {
return InetAddress.getByName(uri.getHost());
} catch (UnknownHostException exception) {
//
}
}
if (obj instanceof CharSequence) {
return getInetAddressFromCharacterSequence(obj);
}
return InetAddress.class.cast(obj);
}
private InetAddress getInetAddressFromCharacterSequence(Object obj) {
try {
final String ipStr = obj.toString();
final int index = ipStr.lastIndexOf("/"); //$NON-NLS-1$
if (index >= 0) {
return InetAddress.getByName(ipStr.substring(index + 1));
}
return InetAddress.getByName(ipStr);
} catch (UnknownHostException exception) {
//
}
return null;
}
@Override
public boolean isNumberType() {
return false;
}
@Override
public boolean isNullAllowed() {
return true;
}
@Override
public boolean isBaseType() {
return false;
}
@Override
public boolean isAssignableFrom(AttributeType type) {
return type == INET_ADDRESS || type == STRING || type == URL || type == URI || type == OBJECT;
}
},
/** Represents a color value.
* @deprecated No replacement
*/
@Deprecated
COLOR {
@Override
public Object getDefaultValue() {
return Colors.BLACK;
}
@Override
public Object cast(Object obj) {
if (obj == null) {
throw new NullPointerException();
}
if (obj instanceof NullAttribute) {
return null;
}
if (obj instanceof Number) {
return VectorToolkit.color(((Number) obj).intValue());
}
return Color.class.cast(obj);
}
@Override
public boolean isNumberType() {
return false;
}
@Override
public boolean isNullAllowed() {
return false;
}
@Override
public boolean isBaseType() {
return false;
}
@Override
@SuppressWarnings("checkstyle:booleanexpressioncomplexity")
public boolean isAssignableFrom(AttributeType type) {
return type == COLOR || type == POINT || type == POINT3D || type == STRING || type == INTEGER
|| type == REAL || type == TIMESTAMP || type == DATE || type == OBJECT;
}
},
/** Represents an URL.
* @see java.net.URL
*/
URL {
@Override
public Object getDefaultValue() {
return null;
}
@Override
public Object cast(Object obj) {
if (obj == null || obj instanceof NullAttribute) {
return null;
}
if (obj instanceof java.net.URI) {
try {
return ((java.net.URI) obj).toURL();
} catch (MalformedURLException e) {
//
}
}
if (obj instanceof InetAddress) {
try {
return new java.net.URL(AttributeConstants.DEFAULT_SCHEME.name(),
((InetAddress) obj).getHostAddress(), ""); //$NON-NLS-1$
} catch (MalformedURLException e) {
//
}
}
if (obj instanceof InetSocketAddress) {
try {
return new java.net.URL(AttributeConstants.DEFAULT_SCHEME.name(),
((InetSocketAddress) obj).getAddress().getHostAddress(), ""); //$NON-NLS-1$
} catch (MalformedURLException e) {
//
}
}
return java.net.URL.class.cast(obj);
}
@Override
public boolean isNumberType() {
return false;
}
@Override
public boolean isNullAllowed() {
return true;
}
@Override
public boolean isBaseType() {
return false;
}
@Override
public boolean isAssignableFrom(AttributeType type) {
return type == URI || type == URL || type == INET_ADDRESS || type == STRING || type == OBJECT;
}
},
/** Represents an URI.
* @see java.net.URI
*/
URI {
@Override
public Object getDefaultValue() {
return null;
}
@Override
public Object cast(Object obj) {
if (obj == null || obj instanceof NullAttribute) {
return null;
}
if (obj instanceof java.net.URL) {
try {
return ((java.net.URL) obj).toURI();
} catch (URISyntaxException e) {
//
}
}
if (obj instanceof InetAddress) {
try {
return new java.net.URI(AttributeConstants.DEFAULT_SCHEME.name(),
((InetAddress) obj).getHostAddress(), ""); //$NON-NLS-1$
} catch (URISyntaxException e) {
//
}
}
if (obj instanceof InetSocketAddress) {
try {
return new java.net.URI(AttributeConstants.DEFAULT_SCHEME.name(),
((InetSocketAddress) obj).getAddress().getHostAddress(), ""); //$NON-NLS-1$
} catch (URISyntaxException e) {
//
}
}
return java.net.URI.class.cast(obj);
}
@Override
public boolean isNumberType() {
return false;
}
@Override
public boolean isNullAllowed() {
return true;
}
@Override
public boolean isBaseType() {
return false;
}
@Override
public boolean isAssignableFrom(AttributeType type) {
return type == URI || type == URL || type == INET_ADDRESS || type == STRING || type == UUID || type == OBJECT;
}
},
/** Represents a timestamp value.
*/
TIMESTAMP {
@Override
public Object getDefaultValue() {
return new Timestamp(System.currentTimeMillis());
}
@Override
public Object cast(Object obj) {
if (obj == null) {
throw new NullPointerException();
}
if (obj instanceof NullAttribute) {
return null;
}
if (obj instanceof Calendar) {
return ((Calendar) obj).getTimeInMillis();
}
if (obj instanceof Date) {
return ((Date) obj).getTime();
}
if (obj instanceof Number && !(obj instanceof Timestamp)) {
return ((Number) obj).longValue();
}
return Timestamp.class.cast(obj);
}
@Override
public boolean isNumberType() {
return true;
}
@Override
public boolean isNullAllowed() {
return false;
}
@Override
public boolean isBaseType() {
return true;
}
@Override
@SuppressWarnings("checkstyle:booleanexpressioncomplexity")
public boolean isAssignableFrom(AttributeType type) {
return type == INTEGER || type == REAL || type == TIMESTAMP || type == STRING || type == DATE
|| type == BOOLEAN || type == COLOR || type == OBJECT;
}
},
/** Represents a 3d point value.
*/
POINT3D {
@Override
public Object getDefaultValue() {
return new Point3d();
}
@Override
public Object cast(Object obj) {
if (obj == null) {
throw new NullPointerException();
}
if (obj instanceof NullAttribute) {
return null;
}
if (obj instanceof Tuple3D && !(obj instanceof Point3D)) {
return new Point3d((Tuple3D<?>) obj);
}
return Point3D.class.cast(obj);
}
@Override
public boolean isNumberType() {
return false;
}
@Override
public boolean isNullAllowed() {
return false;
}
@Override
public boolean isBaseType() {
return false;
}
@Override
@SuppressWarnings("checkstyle:booleanexpressioncomplexity")
public boolean isAssignableFrom(AttributeType type) {
return type == POINT || type == POINT3D || type == COLOR || type == REAL || type == INTEGER
|| type == TIMESTAMP || type == DATE || type == STRING || type == OBJECT;
}
},
/** Represents a 2d point value.
*/
POINT {
@Override
public Object getDefaultValue() {
return new Point2d();
}
@Override
public Object cast(Object obj) {
if (obj == null) {
throw new NullPointerException();
}
if (obj instanceof NullAttribute) {
return null;
}
if (obj instanceof Tuple2D && !(obj instanceof Point2D)) {
return new Point2d((Tuple2D<?>) obj);
}
return Point2D.class.cast(obj);
}
@Override
public boolean isNumberType() {
return false;
}
@Override
public boolean isNullAllowed() {
return false;
}
@Override
public boolean isBaseType() {
return false;
}
@Override
@SuppressWarnings("checkstyle:booleanexpressioncomplexity")
public boolean isAssignableFrom(AttributeType type) {
return type == POINT || type == POINT3D || type == COLOR || type == REAL || type == INTEGER
|| type == TIMESTAMP || type == DATE || type == STRING || type == OBJECT;
}
},
/** Represents a list of 3d points.
*/
POLYLINE3D {
@Override
public Object getDefaultValue() {
return new Point3D[0];
}
@Override
public Object cast(Object obj) {
if (obj == null) {
throw new NullPointerException();
}
if (obj instanceof NullAttribute) {
return null;
}
if (obj.getClass().isArray()) {
final Class<?> elementType = obj.getClass().getComponentType();
if (Tuple3D.class.isAssignableFrom(elementType)
&& !Point3D.class.isAssignableFrom(elementType)) {
final int length = Array.getLength(obj);
final Point3D<?, ?>[] tab = new Point3D[length];
for (int i = 0; i < length; ++i) {
tab[i] = new Point3d((Tuple3D<?>) Array.get(obj, i));
}
return tab;
}
}
return Point3D[].class.cast(obj);
}
@Override
public boolean isNumberType() {
return false;
}
@Override
public boolean isNullAllowed() {
return false;
}
@Override
public boolean isBaseType() {
return false;
}
@Override
public boolean isAssignableFrom(AttributeType type) {
return type == POLYLINE || type == POLYLINE3D || type == POINT || type == POINT3D || type == STRING || type == OBJECT;
}
},
/** Represents a list of 2d points.
*/
POLYLINE {
@Override
public Object getDefaultValue() {
return new Point2D[0];
}
@Override
public Object cast(Object obj) {
if (obj == null) {
throw new NullPointerException();
}
if (obj instanceof NullAttribute) {
return null;
}
if (obj.getClass().isArray()) {
final Class<?> elementType = obj.getClass().getComponentType();
if (Tuple2D.class.isAssignableFrom(elementType)
&& !Point2D.class.isAssignableFrom(elementType)) {
final int length = Array.getLength(obj);
final Point2D<?, ?>[] tab = new Point2D[length];
for (int i = 0; i < length; ++i) {
tab[i] = new Point2d((Tuple2D<?>) Array.get(obj, i));
}
return tab;
}
}
return Point2D[].class.cast(obj);
}
@Override
public boolean isNumberType() {
return false;
}
@Override
public boolean isNullAllowed() {
return false;
}
@Override
public boolean isBaseType() {
return false;
}
@Override
public boolean isAssignableFrom(AttributeType type) {
return type == POLYLINE || type == POLYLINE3D || type == POINT || type == POINT3D || type == STRING || type == OBJECT;
}
},
/** Represents an image value.
* @deprecated No replacement
*/
@Deprecated
IMAGE {
@Override
public Object getDefaultValue() {
return null;
}
@Override
public Object cast(Object obj) {
if (obj == null || obj instanceof NullAttribute) {
return null;
}
return Image.class.cast(obj);
}
@Override
public boolean isNumberType() {
return false;
}
@Override
public boolean isNullAllowed() {
return true;
}
@Override
public boolean isBaseType() {
return false;
}
@Override
public boolean isAssignableFrom(AttributeType type) {
return type == IMAGE || type == OBJECT;
}
},
/** Represents a string.
*/
STRING {
@Override
public Object getDefaultValue() {
return new String();
}
@Override
public Object cast(Object obj) {
if (obj == null) {
return ""; //$NON-NLS-1$
}
if (obj instanceof NullAttribute) {
return null;
}
if (obj instanceof Enum<?>) {
final Enum<?> enumValue = (Enum<?>) obj;
return enumValue.getClass().getCanonicalName()
+ "." //$NON-NLS-1$
+ enumValue.name();
}
return obj.toString();
}
@Override
public boolean isNumberType() {
return false;
}
@Override
public boolean isNullAllowed() {
return false;
}
@Override
public boolean isBaseType() {
return true;
}
@Override
public boolean isAssignableFrom(AttributeType type) {
return true;
}
},
/** Represents a java-object value.
*/
OBJECT {
@Override
public Object getDefaultValue() {
return null;
}
@Override
public Object cast(Object obj) {
if (obj instanceof NullAttribute) {
return null;
}
return obj;
}
@Override
public boolean isNumberType() {
return false;
}
@Override
public boolean isNullAllowed() {
return true;
}
@Override
public boolean isBaseType() {
return false;
}
@Override
public boolean isAssignableFrom(AttributeType type) {
return true;
}
};
private static final String NAME_RESOURCE_FILE;
private String localizedName;
static {
final String pName = AttributeType.class.getPackage().getName();
NAME_RESOURCE_FILE = pName + ".types"; //$NON-NLS-1$
}
/** Replies the name of this type (localized).
*
* @return the localized name of this type.
*/
@Pure
public String getLocalizedName() {
if (this.localizedName == null) {
this.localizedName = Locale.getStringWithDefaultFrom(NAME_RESOURCE_FILE, name(), null);
if (this.localizedName == null) {
this.localizedName = Locale.getStringFrom(NAME_RESOURCE_FILE, "OTHER"); //$NON-NLS-1$
}
}
return this.localizedName;
}
/** Replies the name of this type (localized).
*
* @return the localized name of this type.
* @deprecated since 13.0, see {@link #getLocalizedName()}
*/
@Pure
@Deprecated
public String getName() {
return getLocalizedName();
}
@Pure
@Override
public String toString() {
return getLocalizedName();
}
/** Replies the Attribute type that corresponds to the
* specified internal code.
*
* @param type is an integer representing an attribute type.
* @return the type that corresponds to the given integer.
*/
@Pure
public static AttributeType fromInteger(int type) {
final AttributeType[] vals = values();
if ((type >= 0) && (type < vals.length)) {
return vals[type];
}
return OBJECT;
}
/** Replies the Attribute type that corresponds to the
* specified value.
*
* @param value is the value to test.
* @return the type that corresponds to the given value.
*/
@Pure
public static AttributeType fromValue(Object value) {
if (value != null) {
if (value instanceof NullAttribute) {
return ((NullAttribute) value).getType();
}
return fromClass(value.getClass());
}
return OBJECT;
}
/** Replies the Attribute type that corresponds to the
* specified type.
*
* @param type is the type to test.
* @return the type that corresponds to the given value.
*/
@Pure
@SuppressWarnings({"checkstyle:returncount", "checkstyle:cyclomaticcomplexity", "checkstyle:npathcomplexity"})
public static AttributeType fromClass(Class<?> type) {
if (type != null) {
if (byte.class.isAssignableFrom(type)) {
return INTEGER;
}
if (Byte.class.isAssignableFrom(type)) {
return INTEGER;
}
if (short.class.isAssignableFrom(type)) {
return INTEGER;
}
if (Short.class.isAssignableFrom(type)) {
return INTEGER;
}
if (int.class.isAssignableFrom(type)) {
return INTEGER;
}
if (Integer.class.isAssignableFrom(type)) {
return INTEGER;
}
if (long.class.isAssignableFrom(type)) {
return INTEGER;
}
if (Long.class.isAssignableFrom(type)) {
return INTEGER;
}
if (BigInteger.class.isAssignableFrom(type)) {
return INTEGER;
}
if (AtomicInteger.class.isAssignableFrom(type)) {
return INTEGER;
}
if (AtomicLong.class.isAssignableFrom(type)) {
return INTEGER;
}
if (Timestamp.class.isAssignableFrom(type)) {
return TIMESTAMP;
}
if (float.class.isAssignableFrom(type)) {
return REAL;
}
if (double.class.isAssignableFrom(type)) {
return REAL;
}
if (Number.class.isAssignableFrom(type)) {
return REAL;
}
if (char.class.isAssignableFrom(type)) {
return STRING;
}
if (Character.class.isAssignableFrom(type)) {
return STRING;
}
if (CharSequence.class.isAssignableFrom(type)) {
return STRING;
}
if (boolean.class.isAssignableFrom(type)) {
return BOOLEAN;
}
if (Boolean.class.isAssignableFrom(type)) {
return BOOLEAN;
}
if (Date.class.isAssignableFrom(type)) {
return DATE;
}
if (Calendar.class.isAssignableFrom(type)) {
return DATE;
}
if (Tuple3D.class.isAssignableFrom(type)) {
return POINT3D;
}
if (org.arakhne.afc.math.generic.Tuple3D.class.isAssignableFrom(type)) {
return POINT3D;
}
if (Tuple2D.class.isAssignableFrom(type)) {
return POINT;
}
if (org.arakhne.afc.math.generic.Tuple2D.class.isAssignableFrom(type)) {
return POINT;
}
if (Color.class.isAssignableFrom(type)) {
return COLOR;
}
if (UUID.class.isAssignableFrom(type)) {
return UUID;
}
if (java.net.URL.class.isAssignableFrom(type)) {
return URL;
}
if (java.net.URI.class.isAssignableFrom(type)) {
return URI;
}
if (Image.class.isAssignableFrom(type)) {
return IMAGE;
}
if (InetAddress.class.isAssignableFrom(type)) {
return INET_ADDRESS;
}
if (InetSocketAddress.class.isAssignableFrom(type)) {
return INET_ADDRESS;
}
if (type.isArray()) {
final Class<?> elementType = type.getComponentType();
if (Point2D.class.isAssignableFrom(elementType)) {
return POLYLINE;
}
if (org.arakhne.afc.math.generic.Point2D.class.isAssignableFrom(elementType)) {
return POLYLINE;
}
if (Point3D.class.isAssignableFrom(elementType)) {
return POLYLINE3D;
}
if (org.arakhne.afc.math.generic.Point3D.class.isAssignableFrom(elementType)) {
return POLYLINE3D;
}
}
if (Enum.class.isAssignableFrom(type)) {
return ENUMERATION;
}
if (Class.class.isAssignableFrom(type)) {
return TYPE;
}
}
return OBJECT;
}
/** Replies if the specified value is an instanceof the type..
*
* @param value is the value to test.
* @return <code>true</code> if the given value is an instance of
* this attribute type, otherwise <code>false</code>.
*/
@Pure
public boolean instanceOf(Object value) {
return this == fromValue(value);
}
/** Replies the default value for the specified type.
*
* @return the default value.
*/
@Pure
public abstract Object getDefaultValue();
/**
* Replies if this attribute type is
* a base type, ie. a number, a boolean
* or a string.
*
* @return <code>true</code> if this type is a base type,
* otherwise <code>false</code>
*/
@Pure
public abstract boolean isBaseType();
/**
* Replies if this attribute type is
* a number type.
* A number type is always a base type.
*
* @return <code>true</code> if this type is a number type,
* otherwise <code>false</code>
* @since 4.0
*/
@Pure
public abstract boolean isNumberType();
/**
* Replies if a null value is allowed for this attribute type.
*
* @return <code>true</code> if this type allows <code>null</code> value,
* otherwise <code>false</code>
*/
@Pure
public abstract boolean isNullAllowed();
/** Replies if a value of the given attribute type may
* be cast to a value of this attribute type.
*
* <p>Caution: even if isAssignableFrom is replying <code>true</code>,
* the {@link AttributeValue#cast(AttributeType)} and
* {@link AttributeValue#castAndSet(AttributeType, Object)} may fail
* if the target type does not support a specifical value of the
* source type. The isAssignableFrom function replies <code>true</code>
* if a least one value of the source type is assignable to a value
* of the target type.
*
* @param type the type.
* @return <code>true</code> if a value of the given
* {@code type} may be cast to a value of <code>this</code>;
* otherwise <code>false</code>.
* @since 4.0
*/
@Pure
public abstract boolean isAssignableFrom(AttributeType type);
/** Cast the specified value to corresponds to the
* default storage standard for attributes.
*
* @param obj is the object to cast
* @return the casted value
* @throws ClassCastException if is impossible to cast.
* @throws NullPointerException if null value is not allowed.
*/
@Pure
public abstract Object cast(Object obj);
}