/** * */ package ecologylab.serialization.types; import ecologylab.generic.ReflectionTools; import ecologylab.serialization.annotations.simpl_inherit; import ecologylab.serialization.annotations.simpl_scalar; /** * Re-usable unit of the cross-language S.IM.PL type system. * * This is the base class for ScalarType and CollectionType. * * @author andruid */ @simpl_inherit public abstract class SimplType<T> extends SimplBaseType implements CrossLanguageTypeConstants { private Class<? extends T> javaClass; /** * Short name of the type: without package. */ @simpl_scalar String simpleName; /** * Fully qualified name of the Java type that this represents, including package. */ @simpl_scalar private String javaTypeName; /** * Name for declaring the type in C#. */ @simpl_scalar private String cSharpTypeName; /** * Name for declaring the type in Objective C. */ @simpl_scalar private String objectiveCTypeName; @simpl_scalar private String dbTypeName; /** * Package name, for non primitives. */ @simpl_scalar private String packageName; /** * Empty constructor for S.IM.PL Serialization. */ public SimplType() { } protected SimplType(Class<? extends T> javaClass, boolean isScalar, String cSharpTypeName, String objectiveCTypeName, String dbTypeName) { this(javaClass.isPrimitive() ? javaClass.getName() : deriveCrossPlatformName(javaClass, isScalar), javaClass, cSharpTypeName, objectiveCTypeName, dbTypeName); } /** * Run-time constructor. Create object for cross-platform type representation. * Register this in TypeRegistry appropriate (collection() or scalar()). * * @param javaClass TODO * @param cSharpTypeName Name for declaring the type in C#. * @param objectiveCTypeName Name for declaring the type in Objective C. * @param dbTypeName TODO */ protected SimplType(String name, Class<? extends T> javaClass, String cSharpTypeName, String objectiveCTypeName, String dbTypeName) { super(name); this.javaClass = javaClass; this.simpleName = javaClass.getSimpleName(); this.javaTypeName = javaClass.getName(); this.cSharpTypeName = cSharpTypeName; this.objectiveCTypeName = objectiveCTypeName; if (!javaClass.isPrimitive() && javaClass.getPackage() != null) this.packageName = javaClass.getPackage().getName(); this.dbTypeName = dbTypeName; TypeRegistry.registerSimplType(this); //System.out.println("simpl type registered: " + this); } /** * The full, qualified name of the class that this describes * @return */ @Override public String getJavaTypeName() { return javaTypeName; } public String getJavaPackageName() { if (packageName == null) { String javaTypeName = this.getJavaTypeName(); if (javaTypeName != null) { int pos = javaTypeName.lastIndexOf('.'); packageName = pos > 0 ? javaTypeName.substring(0, pos) : JAVA_PRIMITIVE_PACKAGE_NAME; } } return packageName; } /** * The name to use when declaring a field in C# cross-compilation. * * @return cSharpTypeName, if one was passed in explicitly. otherwise, null. */ @Override public String getCSharpTypeName() { return cSharpTypeName != null ? cSharpTypeName : javaTypeName; } private String cSharpNamespace; /** * The namespace to use in C# cross-compilation. */ @Override public String getCSharpNamespace() { if (cSharpNamespace == null) { String csTypeName = this.getCSharpTypeName(); if (csTypeName != null) { // TODO use a look-up table to handle specific built-in types, int pos = csTypeName.lastIndexOf('.'); cSharpNamespace = pos > 0 ? csTypeName.substring(0, pos) : CSHARP_PRIMITIVE_NAMESPACE; } } return cSharpNamespace; } /** * The name to use when declaring a field in Objective C cross-compilation. * * @return objectiveCTypeName, if one was passed in explicitly. otherwise, null. */ @Override public String getObjectiveCTypeName() { return objectiveCTypeName; } /** * * * @return Name of this type for database columns. */ @Override public String getDbTypeName() { return dbTypeName; } /** * @return the simpleName */ public String getSimpleName() { return simpleName; } /** * Use the field in this, if it is set, or do something smart to derive a type name for C#. * * @return never null; some kind of a type name String. */ abstract public String deriveCSharpTypeName(); /** * Use the field in this, if it is set, or do something smart to derive a type name for C#. * * @return never null; some kind of a type name String. */ abstract public String deriveObjectiveCTypeName(); abstract boolean isScalar(); static String deriveCrossPlatformName(Class javaClass, boolean isScalar) { String javaClassName = javaClass.getName(); return javaClassName.startsWith("java") ? (isScalar ? SIMPL_SCALAR_TYPES_PREFIX : SIMPL_COLLECTION_TYPES_PREFIX) + javaClass.getSimpleName() : javaClassName; } @Override public String toString() { return getSimpleName() + ": crossPlatform=" + getName() + "\tjava=" + javaTypeName + "\tsimple=" + simpleName; } public T getInstance() { return ReflectionTools.getInstance(javaClass); } public Class getJavaClass() { return javaClass; } }