* You should use {@link FieldType#createFieldType} to instantiate one of these field if you have a {@link Field}.
*/
public FieldType(ConnectionSource connectionSource, String tableName, Field field, DatabaseFieldConfig fieldConfig,
Class<?> parentClass) throws SQLException {
this.connectionSource = connectionSource;
DatabaseType databaseType = connectionSource.getDatabaseType();
this.field = field;
Class<?> clazz = field.getType();
DataPersister dataPersister;
if (fieldConfig.getDataPersister() == null) {
Class<? extends DataPersister> persisterClass = fieldConfig.getPersisterClass();
if (persisterClass == null || persisterClass == VoidType.class) {
dataPersister = DataPersisterManager.lookupForField(field);
} else {
Method method;
try {
method = persisterClass.getDeclaredMethod("getSingleton");
} catch (Exception e) {
throw SqlExceptionUtil.create("Could not find getSingleton static method on class "
+ persisterClass, e);
}
Object result;
try {
result = (DataPersister) method.invoke(null);
} catch (InvocationTargetException e) {
throw SqlExceptionUtil.create("Could not run getSingleton method on class " + persisterClass,
e.getTargetException());
} catch (Exception e) {
throw SqlExceptionUtil.create("Could not run getSingleton method on class " + persisterClass, e);
}
if (result == null) {
throw new SQLException("Static getSingleton method should not return null on class "
+ persisterClass);
}
try {
dataPersister = (DataPersister) result;
} catch (Exception e) {
throw new SQLException(
"Could not cast result of static getSingleton method to DataPersister from class "
+ persisterClass);
}
}
} else {
dataPersister = fieldConfig.getDataPersister();
if (!dataPersister.isValidForField(field)) {
throw new IllegalArgumentException("Field class " + clazz + " for field " + this
+ " is not valid for data persister " + dataPersister);
}
}
String defaultFieldName = field.getName();
if (fieldConfig.isForeign() || fieldConfig.isForeignAutoRefresh()) {
if (dataPersister != null && dataPersister.isPrimitive()) {
throw new IllegalArgumentException("Field " + this + " is a primitive class " + clazz
+ " but marked as foreign");
}
defaultFieldName = defaultFieldName + FOREIGN_ID_FIELD_SUFFIX;
} else if (fieldConfig.isForeignCollection()) {
if (clazz != Collection.class && !ForeignCollection.class.isAssignableFrom(clazz)) {
throw new SQLException("Field class for '" + field.getName() + "' must be of class "
+ ForeignCollection.class.getSimpleName() + " or Collection.");
}
Type type = field.getGenericType();
if (!(type instanceof ParameterizedType)) {
throw new SQLException("Field class for '" + field.getName() + "' must be a parameterized Collection.");
}
Type[] genericArguments = ((ParameterizedType) type).getActualTypeArguments();
if (genericArguments.length == 0) {
// i doubt this will ever be reached
throw new SQLException("Field class for '" + field.getName()
+ "' must be a parameterized Collection with at least 1 type.");
}
} else if (dataPersister == null && (!fieldConfig.isForeignCollection())) {
if (byte[].class.isAssignableFrom(clazz)) {
throw new SQLException("ORMLite can't store unknown class " + clazz + " for field '" + field.getName()
+ "'. byte[] fields must specify dataType=DataType.BYTE_ARRAY or SERIALIZABLE");
} else if (Serializable.class.isAssignableFrom(clazz)) {
throw new SQLException("ORMLite can't store unknown class " + clazz + " for field '" + field.getName()
+ "'. Serializable fields must specify dataType=DataType.SERIALIZABLE");
} else {
throw new IllegalArgumentException("ORMLite does not know how to store field class " + clazz
+ " for field " + this);
}
}
if (fieldConfig.getColumnName() == null) {
this.dbColumnName = defaultFieldName;
} else {
this.dbColumnName = fieldConfig.getColumnName();
}
this.fieldConfig = fieldConfig;
if (fieldConfig.isId()) {
if (fieldConfig.isGeneratedId() || fieldConfig.getGeneratedIdSequence() != null) {
throw new IllegalArgumentException("Must specify one of id, generatedId, and generatedIdSequence with "
+ field.getName());
}
this.isId = true;
this.isGeneratedId = false;
this.generatedIdSequence = null;
} else if (fieldConfig.isGeneratedId()) {
if (fieldConfig.getGeneratedIdSequence() != null) {
throw new IllegalArgumentException("Must specify one of id, generatedId, and generatedIdSequence with "
+ field.getName());
}
this.isId = true;
this.isGeneratedId = true;
if (databaseType.isIdSequenceNeeded()) {
this.generatedIdSequence = databaseType.generateIdSequenceName(tableName, this);
} else {
this.generatedIdSequence = null;
}
} else if (fieldConfig.getGeneratedIdSequence() != null) {
this.isId = true;
this.isGeneratedId = true;
String seqName = fieldConfig.getGeneratedIdSequence();
if (databaseType.isEntityNamesMustBeUpCase()) {
seqName = seqName.toUpperCase();
}
this.generatedIdSequence = seqName;
} else {
this.isId = false;