package io.ebeaninternal.server.deploy.meta;
import io.ebean.annotation.CreatedTimestamp;
import io.ebean.annotation.DocCode;
import io.ebean.annotation.DocProperty;
import io.ebean.annotation.DocSortable;
import io.ebean.annotation.Formula;
import io.ebean.annotation.Platform;
import io.ebean.annotation.SoftDelete;
import io.ebean.annotation.UpdatedTimestamp;
import io.ebean.annotation.WhenCreated;
import io.ebean.annotation.WhenModified;
import io.ebean.annotation.Where;
import io.ebean.annotation.WhoCreated;
import io.ebean.annotation.WhoModified;
import io.ebean.config.ScalarTypeConverter;
import io.ebean.config.dbplatform.DbDefaultValue;
import io.ebean.config.dbplatform.DbEncrypt;
import io.ebean.config.dbplatform.DbEncryptFunction;
import io.ebean.core.type.ScalarType;
import io.ebean.util.AnnotationUtil;
import io.ebeaninternal.server.core.InternString;
import io.ebeaninternal.server.deploy.BeanProperty;
import io.ebeaninternal.server.deploy.DbMigrationInfo;
import io.ebeaninternal.server.deploy.DeployDocPropertyOptions;
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty;
import io.ebeaninternal.server.el.ElPropertyValue;
import io.ebeaninternal.server.properties.BeanPropertyGetter;
import io.ebeaninternal.server.properties.BeanPropertySetter;
import io.ebeaninternal.server.type.ScalarTypeWrapper;
import io.ebeanservice.docstore.api.mapping.DocPropertyOptions;
import javax.persistence.EmbeddedId;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.Version;
import javax.validation.constraints.Size;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
Description of a property of a bean. Includes its deployment information such
as database column mapping information.
/**
* Description of a property of a bean. Includes its deployment information such
* as database column mapping information.
*/
public class DeployBeanProperty {
private static final int ID_ORDER = 1000000;
private static final int UNIDIRECTIONAL_ORDER = 100000;
private static final int AUDITCOLUMN_ORDER = -1000000;
private static final int VERSIONCOLUMN_ORDER = -1000000;
private static final Set<Class<?>> PRIMITIVE_NUMBER_TYPES = new HashSet<>();
static {
PRIMITIVE_NUMBER_TYPES.add(float.class);
PRIMITIVE_NUMBER_TYPES.add(double.class);
PRIMITIVE_NUMBER_TYPES.add(long.class);
PRIMITIVE_NUMBER_TYPES.add(int.class);
PRIMITIVE_NUMBER_TYPES.add(short.class);
}
Flag to mark this at part of the unique id.
/**
* Flag to mark this at part of the unique id.
*/
private boolean id;
boolean importedPrimaryKey;
Flag to mark the property as embedded. This could be on
BeanPropertyAssocOne rather than here. Put it here for checking Id type
(embedded or not).
/**
* Flag to mark the property as embedded. This could be on
* BeanPropertyAssocOne rather than here. Put it here for checking Id type
* (embedded or not).
*/
private boolean embedded;
Flag indicating if this the version property.
/**
* Flag indicating if this the version property.
*/
private boolean versionColumn;
private boolean fetchEager = true;
Set if this property is nullable.
/**
* Set if this property is nullable.
*/
private boolean nullable = true;
private boolean unique;
private boolean discriminator;
The length or precision of the DB column.
/**
* The length or precision of the DB column.
*/
private int dbLength;
private int dbScale;
private String dbColumnDefn;
private boolean isTransient;
private boolean localEncrypted;
private boolean jsonSerialize = true;
private boolean jsonDeserialize = true;
private boolean dbEncrypted;
private DbEncryptFunction dbEncryptFunction;
private int dbEncryptedType;
private String dbBind = "?";
Is this property include in database resultSet.
/**
* Is this property include in database resultSet.
*/
private boolean dbRead;
Include this in DB insert.
/**
* Include this in DB insert.
*/
private boolean dbInsertable;
Include this in a DB update.
/**
* Include this in a DB update.
*/
private boolean dbUpdateable;
private DeployTableJoin secondaryTableJoin;
private String secondaryTableJoinPrefix;
Set to true if this property is based on a secondary table.
/**
* Set to true if this property is based on a secondary table.
*/
private String secondaryTable;
The type that owns this property.
/**
* The type that owns this property.
*/
private Class<?> owningType;
True if the property is a Clob, Blob LongVarchar or LongVarbinary.
/**
* True if the property is a Clob, Blob LongVarchar or LongVarbinary.
*/
private boolean lob;
private boolean naturalKey;
The logical bean property name.
/**
* The logical bean property name.
*/
private String name;
The reflected field.
/**
* The reflected field.
*/
private Field field;
The bean type.
/**
* The bean type.
*/
private final Class<?> propertyType;
private final Type genericType;
Set for Non-JDBC types to provide logical to db type conversion.
/**
* Set for Non-JDBC types to provide logical to db type conversion.
*/
private ScalarType<?> scalarType;
The database column. This can include quoted identifiers.
/**
* The database column. This can include quoted identifiers.
*/
private String dbColumn;
private String aggregationPrefix;
private String aggregation;
private String aggregationParsed;
private String sqlFormulaSelect;
private String sqlFormulaJoin;
The jdbc data type this maps to.
/**
* The jdbc data type this maps to.
*/
private int dbType;
private final DeployDocPropertyOptions docMapping = new DeployDocPropertyOptions();
private int propertyIndex;
private BeanPropertyGetter getter;
private BeanPropertySetter setter;
Generator for insert or update timestamp etc.
/**
* Generator for insert or update timestamp etc.
*/
private GeneratedProperty generatedProperty;
final DeployBeanDescriptor<?> desc;
private boolean undirectionalShadow;
private boolean elementProperty;
private int sortOrder;
private boolean excludedFromHistory;
private boolean tenantId;
private boolean draft;
private boolean draftOnly;
private boolean draftDirty;
private boolean draftReset;
private boolean softDelete;
private boolean unmappedJson;
private String dbComment;
private String dbColumnDefault;
private List<DbMigrationInfo> dbMigrationInfos;
private Set<Annotation> metaAnnotations;
public DeployBeanProperty(DeployBeanDescriptor<?> desc, Class<?> propertyType, ScalarType<?> scalarType, ScalarTypeConverter<?, ?> typeConverter) {
this.desc = desc;
this.propertyType = propertyType;
this.genericType = null;
this.scalarType = wrapScalarType(propertyType, scalarType, typeConverter);
this.dbType = (scalarType == null) ? 0 : scalarType.getJdbcType();
}
public DeployBeanProperty(DeployBeanDescriptor<?> desc, Class<?> propertyType, Type genericType) {
this.desc = desc;
this.propertyType = propertyType;
this.genericType = genericType;
}
Wrap the ScalarType using a ScalarTypeConverter.
/**
* Wrap the ScalarType using a ScalarTypeConverter.
*/
@SuppressWarnings({"unchecked"})
private ScalarType<?> wrapScalarType(Class<?> propertyType, ScalarType<?> scalarType, ScalarTypeConverter<?, ?> typeConverter) {
if (typeConverter == null) {
return scalarType;
}
return new ScalarTypeWrapper(propertyType, scalarType, typeConverter);
}
public int getSortOverride() {
if (field == null) {
return 0;
}
if (AnnotationUtil.get(field, Id.class) != null) {
return ID_ORDER;
} else if (AnnotationUtil.get(field, EmbeddedId.class) != null) {
return ID_ORDER;
} else if (undirectionalShadow) {
return UNIDIRECTIONAL_ORDER;
} else if (isAuditProperty()) {
return AUDITCOLUMN_ORDER;
} else if (AnnotationUtil.get(field, Version.class) != null) {
return VERSIONCOLUMN_ORDER;
} else if (AnnotationUtil.get(field, SoftDelete.class) != null) {
return VERSIONCOLUMN_ORDER;
}
return 0;
}
private boolean isAuditProperty() {
return (AnnotationUtil.has(field, WhenCreated.class)
|| AnnotationUtil.has(field, WhenModified.class)
|| AnnotationUtil.has(field, WhoModified.class)
|| AnnotationUtil.has(field, WhoCreated.class)
|| AnnotationUtil.has(field, UpdatedTimestamp.class)
|| AnnotationUtil.has(field, CreatedTimestamp.class));
}
public String getFullBeanName() {
return desc.getFullName() + "." + name;
}
public DeployBeanDescriptor<?> getDesc() {
return desc;
}
Return the DB column length for character columns.
Note if there is no length explicitly defined then the scalarType is
checked to see if that has one (primarily to support putting a length on
Enum types).
/**
* Return the DB column length for character columns.
* <p>
* Note if there is no length explicitly defined then the scalarType is
* checked to see if that has one (primarily to support putting a length on
* Enum types).
* </p>
*/
public int getDbLength() {
if (dbLength == 0 && scalarType != null) {
return scalarType.getLength();
}
return dbLength;
}
public boolean isJsonSerialize() {
return jsonSerialize;
}
public void setJsonSerialize(boolean jsonSerialize) {
this.jsonSerialize = jsonSerialize;
}
public boolean isJsonDeserialize() {
return jsonDeserialize;
}
public void setJsonDeserialize(boolean jsonDeserialize) {
this.jsonDeserialize = jsonDeserialize;
}
Return the sortOrder for the properties.
/**
* Return the sortOrder for the properties.
*/
int getSortOrder() {
return sortOrder;
}
Set the sortOrder for the properties.
/**
* Set the sortOrder for the properties.
*/
public void setSortOrder(int sortOrder) {
this.sortOrder = sortOrder;
}
Return true if this is a placeholder property for a unidirectional relationship.
/**
* Return true if this is a placeholder property for a unidirectional relationship.
*/
public boolean isUndirectionalShadow() {
return undirectionalShadow;
}
Mark this property as a placeholder for a unidirectional relationship.
/**
* Mark this property as a placeholder for a unidirectional relationship.
*/
public void setUndirectionalShadow() {
this.undirectionalShadow = true;
}
Mark this property as mapping to the discriminator column.
/**
* Mark this property as mapping to the discriminator column.
*/
void setDiscriminator() {
this.discriminator = true;
}
Return true if this property maps to the inheritance discriminator column.s
/**
* Return true if this property maps to the inheritance discriminator column.s
*/
public boolean isDiscriminator() {
return discriminator;
}
Return true if the property is encrypted in java rather than in the DB.
/**
* Return true if the property is encrypted in java rather than in the DB.
*/
public boolean isLocalEncrypted() {
return localEncrypted;
}
Set to true when the property is encrypted in java rather than in the DB.
/**
* Set to true when the property is encrypted in java rather than in the DB.
*/
public void setLocalEncrypted() {
this.localEncrypted = true;
}
Set the DB column length for character columns.
/**
* Set the DB column length for character columns.
*/
public void setDbLength(int dbLength) {
this.dbLength = dbLength;
}
Return the Db scale for numeric columns.
/**
* Return the Db scale for numeric columns.
*/
public int getDbScale() {
return dbScale;
}
Set the Db scale for numeric columns.
/**
* Set the Db scale for numeric columns.
*/
public void setDbScale(int dbScale) {
this.dbScale = dbScale;
}
Return the DB column definition if defined.
/**
* Return the DB column definition if defined.
*/
public String getDbColumnDefn() {
return dbColumnDefn;
}
Set a specific DB column definition.
/**
* Set a specific DB column definition.
*/
public void setDbColumnDefn(String dbColumnDefn) {
if (dbColumnDefn == null || dbColumnDefn.trim().isEmpty()) {
this.dbColumnDefn = null;
} else {
this.dbColumnDefn = InternString.intern(dbColumnDefn);
}
}
Return the scalarType. This returns null for native JDBC types, otherwise
it is used to convert between logical types and jdbc types.
/**
* Return the scalarType. This returns null for native JDBC types, otherwise
* it is used to convert between logical types and jdbc types.
*/
public ScalarType<?> getScalarType() {
return scalarType;
}
public void setScalarType(ScalarType<?> scalarType) {
this.scalarType = scalarType;
}
public int getPropertyIndex() {
return propertyIndex;
}
public void setPropertyIndex(int propertyIndex) {
this.propertyIndex = propertyIndex;
}
public BeanPropertyGetter getGetter() {
return getter;
}
public BeanPropertySetter getSetter() {
if (elementProperty) {
return new BeanPropertyElementSetter(sortOrder);
} else {
return setter;
}
}
Set to the owning type form a Inheritance heirarchy.
/**
* Set to the owning type form a Inheritance heirarchy.
*/
public void setOwningType(Class<?> owningType) {
this.owningType = owningType;
}
public Class<?> getOwningType() {
return owningType;
}
Return true if this is local to this type - aka not from a super type.
/**
* Return true if this is local to this type - aka not from a super type.
*/
public boolean isLocal() {
return owningType == null || owningType.equals(desc.getBeanType());
}
Set the getter used to read the property value from a bean.
/**
* Set the getter used to read the property value from a bean.
*/
public void setGetter(BeanPropertyGetter getter) {
this.getter = getter;
}
Set the setter used to set the property value to a bean.
/**
* Set the setter used to set the property value to a bean.
*/
public void setSetter(BeanPropertySetter setter) {
this.setter = setter;
}
Return the name of the property.
/**
* Return the name of the property.
*/
public String getName() {
return name;
}
Set the name of the property.
/**
* Set the name of the property.
*/
public void setName(String name) {
this.name = InternString.intern(name);
}
Return the bean Field associated with this property.
/**
* Return the bean Field associated with this property.
*/
public Field getField() {
return field;
}
Set the bean Field associated with this property.
/**
* Set the bean Field associated with this property.
*/
public void setField(Field field) {
this.field = field;
}
public boolean isNaturalKey() {
return naturalKey;
}
void setNaturalKey() {
this.naturalKey = true;
}
Return the GeneratedValue. Used to generate update timestamp etc.
/**
* Return the GeneratedValue. Used to generate update timestamp etc.
*/
public GeneratedProperty getGeneratedProperty() {
return generatedProperty;
}
Set the GeneratedValue. Used to generate update timestamp etc.
/**
* Set the GeneratedValue. Used to generate update timestamp etc.
*/
public void setGeneratedProperty(GeneratedProperty generatedValue) {
this.generatedProperty = generatedValue;
}
Return true if this property is mandatory.
/**
* Return true if this property is mandatory.
*/
public boolean isNullable() {
return nullable;
}
Set the not nullable of this property.
/**
* Set the not nullable of this property.
*/
public void setNullable(boolean isNullable) {
this.nullable = isNullable;
}
Return true if the DB column is unique.
/**
* Return true if the DB column is unique.
*/
public boolean isUnique() {
return unique;
}
Set to true if the DB column is unique.
/**
* Set to true if the DB column is unique.
*/
public void setUnique(boolean unique) {
this.unique = unique;
}
Return true if this is a version column used for concurrency checking.
/**
* Return true if this is a version column used for concurrency checking.
*/
public boolean isVersionColumn() {
return versionColumn;
}
Set if this is a version column used for concurrency checking.
/**
* Set if this is a version column used for concurrency checking.
*/
public void setVersionColumn() {
this.versionColumn = true;
}
Return true if this should be eager fetched by default.
/**
* Return true if this should be eager fetched by default.
*/
public boolean isFetchEager() {
return fetchEager;
}
Set the default fetch type for this property.
/**
* Set the default fetch type for this property.
*/
public void setFetchType(FetchType fetchType) {
this.fetchEager = FetchType.EAGER == fetchType;
}
Return the formula this property is based on.
/**
* Return the formula this property is based on.
*/
public String getSqlFormulaSelect() {
return sqlFormulaSelect;
}
public String getSqlFormulaJoin() {
return sqlFormulaJoin;
}
The property is based on a formula.
/**
* The property is based on a formula.
*/
public void setSqlFormula(String formulaSelect, String formulaJoin) {
this.sqlFormulaSelect = formulaSelect;
this.sqlFormulaJoin = formulaJoin.isEmpty() ? null : formulaJoin;
this.dbRead = true;
this.dbInsertable = false;
this.dbUpdateable = false;
}
public void setImportedPrimaryKey() {
this.importedPrimaryKey = true;
}
Set to true if this is part of the primary key.
/**
* Set to true if this is part of the primary key.
*/
public void setImportedPrimaryKeyColumn(DeployBeanProperty primaryKey) {
this.importedPrimaryKey = true;
}
public boolean isAggregation() {
return aggregation != null;
}
Get the raw/logical aggregation formula.
/**
* Get the raw/logical aggregation formula.
*/
public String getRawAggregation() {
return aggregation;
}
Get the parsed aggregation formula with table alias placeholders.
/**
* Get the parsed aggregation formula with table alias placeholders.
*/
public String parseAggregation() {
if (aggregation != null) {
int pos = aggregation.indexOf('(');
if (pos > -1) {
// check for recursive property name and formula
String maybePropertyName = aggregation.substring(pos + 1, aggregation.length() - 1);
if (name.equals(maybePropertyName)) {
// e.g. bean property cost mapped to sum(cost)
return aggregationJoin(pos, dbColumn);
} else {
DeployBeanProperty other = desc.getBeanProperty(maybePropertyName);
if (other != null) {
// e.g. bean property maxKms mapped to sum(totalKms) where totalKms is another property
return aggregationJoin(pos, other.getDbColumnRaw());
}
}
}
aggregationParsed = desc.parse(aggregation);
}
return aggregationParsed;
}
Simple aggregation parsing like sum(someProperty)
/**
* Simple aggregation parsing like sum(someProperty)
*/
private String aggregationJoin(int pos, String dbColumn) {
String p0 = aggregation.substring(0, pos + 1);
aggregationParsed = p0 + "${ta}." + dbColumn + aggregation.substring(aggregation.length() - 1);
return aggregationParsed;
}
public void setAggregation(String aggregation) {
this.aggregation = aggregation;
this.dbRead = true;
this.dbInsertable = false;
this.dbUpdateable = false;
}
Set the path to the aggregation.
/**
* Set the path to the aggregation.
*/
public void setAggregationPrefix(String prefix) {
this.aggregationPrefix = prefix;
this.aggregation = (prefix == null) ? aggregation : aggregation.replace(aggregationPrefix, "u1");
}
public String getElPrefix() {
if (aggregation != null) {
return aggregationPrefix;
} else {
return secondaryTableJoinPrefix;
}
}
public String getElPlaceHolder() {
if (aggregation != null) {
return aggregationParsed;
} else if (sqlFormulaSelect != null) {
return sqlFormulaSelect;
} else {
if (secondaryTableJoinPrefix != null) {
return "${" + secondaryTableJoinPrefix + "}" + getDbColumn();
}
// prepend table alias placeholder
return ElPropertyValue.ROOT_ELPREFIX + getDbColumn();
}
}
The database column name this is mapped to.
/**
* The database column name this is mapped to.
*/
public String getDbColumn() {
if (sqlFormulaSelect != null) {
return sqlFormulaSelect;
}
if (aggregation != null) {
return aggregation;
}
return dbColumn;
}
Return the DB column without any aggregation parsing.
/**
* Return the DB column without any aggregation parsing.
*/
private String getDbColumnRaw() {
return dbColumn;
}
Set the database column name this is mapped to.
/**
* Set the database column name this is mapped to.
*/
public void setDbColumn(String dbColumn) {
this.dbColumn = InternString.intern(dbColumn);
}
Return the database jdbc data type this is mapped to.
/**
* Return the database jdbc data type this is mapped to.
*/
public int getDbType() {
return dbType;
}
Set the database jdbc data type this is mapped to.
/**
* Set the database jdbc data type this is mapped to.
*/
public void setDbType(int dbType) {
this.dbType = dbType;
this.lob = BeanProperty.isLobType(dbType);
}
Return true if this is mapped to a Clob Blob LongVarchar or
LongVarbinary.
/**
* Return true if this is mapped to a Clob Blob LongVarchar or
* LongVarbinary.
*/
public boolean isLob() {
return lob;
}
boolean isDbNumberType() {
return isNumericType(dbType);
}
private boolean isNumericType(int type) {
switch (type) {
case Types.BIGINT:
case Types.DECIMAL:
case Types.TINYINT:
case Types.SMALLINT:
case Types.REAL:
case Types.NUMERIC:
case Types.INTEGER:
case Types.FLOAT:
case Types.DOUBLE:
return true;
default:
return false;
}
}
Return true if this property is based on a secondary table.
/**
* Return true if this property is based on a secondary table.
*/
public boolean isSecondaryTable() {
return secondaryTable != null;
}
Return the secondary table this property is associated with.
/**
* Return the secondary table this property is associated with.
*/
public String getSecondaryTable() {
return secondaryTable;
}
Set to true if this property is included in persisting.
/**
* Set to true if this property is included in persisting.
*/
public void setSecondaryTable(String secondaryTable) {
this.secondaryTable = secondaryTable;
this.dbInsertable = false;
this.dbUpdateable = false;
}
/**
*
*/
public String getSecondaryTableJoinPrefix() {
return secondaryTableJoinPrefix;
}
public DeployTableJoin getSecondaryTableJoin() {
return secondaryTableJoin;
}
public void setSecondaryTableJoin(DeployTableJoin secondaryTableJoin, String prefix) {
this.secondaryTableJoin = secondaryTableJoin;
this.secondaryTableJoinPrefix = prefix;
}
Return the DB Bind parameter. Typically is "?" but can be different for
encrypted bind.
/**
* Return the DB Bind parameter. Typically is "?" but can be different for
* encrypted bind.
*/
public String getDbBind() {
return dbBind;
}
Return true if this property is encrypted in the DB.
/**
* Return true if this property is encrypted in the DB.
*/
public boolean isDbEncrypted() {
return dbEncrypted;
}
public DbEncryptFunction getDbEncryptFunction() {
return dbEncryptFunction;
}
public void setDbEncryptFunction(DbEncryptFunction dbEncryptFunction, DbEncrypt dbEncrypt, int dbLen) {
this.dbEncryptFunction = dbEncryptFunction;
this.dbEncrypted = true;
this.dbBind = dbEncryptFunction.getEncryptBindSql();
this.dbEncryptedType = isLob() ? Types.BLOB : dbEncrypt.getEncryptDbType();
if (dbLen > 0) {
setDbLength(dbLen);
}
}
Return the DB type for the encrypted property. This can differ from the
logical type (String encrypted and stored in a VARBINARY)
/**
* Return the DB type for the encrypted property. This can differ from the
* logical type (String encrypted and stored in a VARBINARY)
*/
public int getDbEncryptedType() {
return dbEncryptedType;
}
Return true if this property is included in database queries.
/**
* Return true if this property is included in database queries.
*/
public boolean isDbRead() {
return dbRead;
}
Set to true if this property is included in database queries.
/**
* Set to true if this property is included in database queries.
*/
public void setDbRead(boolean isDBRead) {
this.dbRead = isDBRead;
}
public boolean isDbInsertable() {
return dbInsertable;
}
public void setDbInsertable(boolean insertable) {
this.dbInsertable = insertable;
}
public boolean isDbUpdateable() {
return dbUpdateable;
}
public void setDbUpdateable(boolean updateable) {
this.dbUpdateable = updateable;
}
Return true if the property is transient.
/**
* Return true if the property is transient.
*/
public boolean isTransient() {
return isTransient;
}
Mark the property explicitly as a transient property.
/**
* Mark the property explicitly as a transient property.
*/
public void setTransient() {
this.isTransient = true;
}
Return the property type.
/**
* Return the property type.
*/
public Class<?> getPropertyType() {
return propertyType;
}
Return the generic type for this property.
/**
* Return the generic type for this property.
*/
public Type getGenericType() {
return genericType;
}
Return true if this is part of the primary key.
/**
* Return true if this is part of the primary key.
*/
public boolean isImportedPrimaryKey() {
return importedPrimaryKey;
}
Return true if this is included in the unique id.
/**
* Return true if this is included in the unique id.
*/
public boolean isId() {
return id;
}
Set to true if this is included in the unique id.
/**
* Set to true if this is included in the unique id.
*/
public void setId() {
this.id = true;
}
Return true if this is an Embedded property. In this case it shares the
table and pk of its owner object.
/**
* Return true if this is an Embedded property. In this case it shares the
* table and pk of its owner object.
*/
public boolean isEmbedded() {
return embedded;
}
Set to true if this is an embedded property.
/**
* Set to true if this is an embedded property.
*/
public void setEmbedded() {
this.embedded = true;
}
@Override
public String toString() {
return desc.getFullName() + "." + name;
}
public boolean isExcludedFromHistory() {
return excludedFromHistory;
}
public void setExcludedFromHistory() {
this.excludedFromHistory = true;
}
public void setDraft() {
this.draft = true;
this.isTransient = true;
}
public boolean isDraft() {
return draft;
}
public void setDraftOnly() {
this.draftOnly = true;
}
public boolean isDraftOnly() {
return draftOnly;
}
public void setDraftDirty() {
this.draftOnly = true;
this.draftDirty = true;
this.nullable = false;
}
public boolean isDraftDirty() {
return draftDirty;
}
public void setDraftReset() {
this.draftReset = true;
}
public boolean isDraftReset() {
return draftReset;
}
Primitive boolean check so see if not null default false should be applied.
/**
* Primitive boolean check so see if not null default false should be applied.
*/
public void checkPrimitiveBoolean() {
if (boolean.class.equals(propertyType) && !softDelete) {
this.nullable = false;
if (dbColumnDefault == null) {
this.dbColumnDefault = DbDefaultValue.FALSE;
}
} else if (!id && !versionColumn && PRIMITIVE_NUMBER_TYPES.contains(propertyType)) {
this.nullable = false;
}
}
public void setSoftDelete() {
this.softDelete = true;
this.nullable = false;
this.dbColumnDefault = DbDefaultValue.FALSE;
}
public boolean isSoftDelete() {
return softDelete;
}
public void setUnmappedJson() {
this.unmappedJson = true;
this.isTransient = true;
}
public boolean isUnmappedJson() {
return unmappedJson;
}
public void setDbComment(String dbComment) {
this.dbComment = dbComment;
}
public String getDbComment() {
return dbComment;
}
public void setDocProperty(DocProperty docProperty) {
docMapping.setDocProperty(docProperty);
}
public void setDocSortable(DocSortable docSortable) {
docMapping.setDocSortable(docSortable);
}
public void setDocCode(DocCode docCode) {
docMapping.setDocCode(docCode);
}
public DocPropertyOptions getDocPropertyOptions() {
return docMapping.create();
}
Return the DB Column default taking into account literal translation.
/**
* Return the DB Column default taking into account literal translation.
*/
public String getDbColumnDefaultSqlLiteral() {
return DbDefaultValue.toSqlLiteral(dbColumnDefault, propertyType, dbType);
}
public void setDbColumnDefault(String dbColumnDefault) {
this.dbColumnDefault = dbColumnDefault;
}
public void setTenantId() {
this.tenantId = true;
this.nullable = false;
this.dbInsertable = true;
this.dbUpdateable = false;
}
public boolean isTenantId() {
return tenantId;
}
public boolean isIdClass() {
return desc.isIdClass();
}
public void addDbMigrationInfo(DbMigrationInfo info) {
if (dbMigrationInfos == null) {
dbMigrationInfos = new ArrayList<>();
}
dbMigrationInfos.add(info);
}
public List<DbMigrationInfo> getDbMigrationInfos() {
return dbMigrationInfos;
}
Set when this property is part of a 'element bean' used with ElementCollection.
/**
* Set when this property is part of a 'element bean' used with ElementCollection.
*/
public void setElementProperty() {
this.elementProperty = true;
}
Returns the jackson annotated field, if jackson is present.
/**
* Returns the jackson annotated field, if jackson is present.
*/
public Object /*AnnotatedField*/ getJacksonField() {
com.fasterxml.jackson.databind.introspect.AnnotatedClass jac =
(com.fasterxml.jackson.databind.introspect.AnnotatedClass) getDesc().getJacksonAnnotatedClass();
for (com.fasterxml.jackson.databind.introspect.AnnotatedField candidate : jac.fields()) {
if (candidate.getName().equals(getName())) {
return candidate;
}
}
return null;
}
public void initMetaAnnotations(Set<Class<?>> metaAnnotationsFilter) {
metaAnnotations = AnnotationUtil.metaFindAllFor(field, metaAnnotationsFilter);
}
@SuppressWarnings("unchecked")
public <A extends Annotation> A getMetaAnnotation(Class<A> annotationType) {
for (Annotation ann : metaAnnotations) {
if (ann.annotationType() == annotationType) {
return (A) ann;
}
}
return null;
}
@SuppressWarnings("unchecked")
public <A extends Annotation> List<A> getMetaAnnotations(Class<A> annotationType) {
List<A> result = new ArrayList<>();
for (Annotation ann : metaAnnotations) {
if (ann.annotationType() == annotationType) {
result.add((A) ann);
}
}
return result;
}
public List<Size> getMetaAnnotationSize() {
final List<Size> size = getMetaAnnotations(Size.class);
final List<Size.List> lists = getMetaAnnotations(Size.List.class);
for (Size.List list : lists) {
Collections.addAll(size, list.value());
}
return size;
}
public Formula getMetaAnnotationFormula(Platform platform) {
Formula fallback = null;
for (Annotation ann : metaAnnotations) {
if (ann.annotationType() == Formula.class) {
Formula formula = (Formula) ann;
final Platform[] platforms = formula.platforms();
if (platforms.length == 0) {
fallback = formula;
} else if (matchPlatform(platforms, platform)) {
return formula;
}
} else if (ann.annotationType() == Formula.List.class) {
Formula.List formulaList = (Formula.List) ann;
for (Formula formula : formulaList.value()) {
final Platform[] platforms = formula.platforms();
if (platforms.length == 0) {
fallback = formula;
} else if (matchPlatform(platforms, platform)) {
return formula;
}
}
}
}
return fallback;
}
public Where getMetaAnnotationWhere(Platform platform) {
Where fallback = null;
for (Annotation ann : metaAnnotations) {
if (ann.annotationType() == Where.class) {
Where where = (Where) ann;
final Platform[] platforms = where.platforms();
if (platforms.length == 0) {
fallback = where;
} else if (matchPlatform(where.platforms(), platform)) {
return where;
}
} else if (ann.annotationType() == Where.List.class) {
Where.List whereList = (Where.List) ann;
for (Where where : whereList.value()) {
final Platform[] platforms = where.platforms();
if (platforms.length == 0) {
fallback = where;
} else if (matchPlatform(where.platforms(), platform)) {
return where;
}
}
}
}
return fallback;
}
private boolean matchPlatform(Platform[] platforms, Platform match) {
for (Platform platform : platforms) {
if (platform == match) {
return true;
}
}
return false;
}
}