mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Remove LDAP feature support
This commit is contained in:
@@ -13,7 +13,6 @@ import javax.persistence.Table;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
import com.avaje.ebean.annotation.LdapDomain;
|
||||
import com.avaje.ebean.config.CompoundType;
|
||||
import com.avaje.ebean.config.ScalarTypeConverter;
|
||||
import com.avaje.ebean.config.ServerConfig;
|
||||
@@ -409,10 +408,6 @@ public class BootupClasses implements ClassPathSearchMatcher {
|
||||
if (ann != null) {
|
||||
return true;
|
||||
}
|
||||
ann = cls.getAnnotation(LdapDomain.class);
|
||||
if (ann != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,11 +10,11 @@ import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
import javax.management.InstanceAlreadyExistsException;
|
||||
import javax.management.MBeanServer;
|
||||
@@ -58,7 +58,6 @@ import com.avaje.ebean.cache.ServerCacheManager;
|
||||
import com.avaje.ebean.config.EncryptKeyManager;
|
||||
import com.avaje.ebean.config.GlobalProperties;
|
||||
import com.avaje.ebean.config.dbplatform.DatabasePlatform;
|
||||
import com.avaje.ebean.config.ldap.LdapConfig;
|
||||
import com.avaje.ebean.event.BeanPersistController;
|
||||
import com.avaje.ebean.event.BeanQueryAdapter;
|
||||
import com.avaje.ebean.text.csv.CsvReader;
|
||||
@@ -68,8 +67,8 @@ import com.avaje.ebeaninternal.api.LoadBeanRequest;
|
||||
import com.avaje.ebeaninternal.api.LoadManyRequest;
|
||||
import com.avaje.ebeaninternal.api.ScopeTrans;
|
||||
import com.avaje.ebeaninternal.api.SpiBackgroundExecutor;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanPlugin;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.api.SpiQuery;
|
||||
import com.avaje.ebeaninternal.api.SpiQuery.Mode;
|
||||
import com.avaje.ebeaninternal.api.SpiQuery.Type;
|
||||
@@ -88,10 +87,6 @@ import com.avaje.ebeaninternal.server.deploy.DeployNamedUpdate;
|
||||
import com.avaje.ebeaninternal.server.deploy.InheritInfo;
|
||||
import com.avaje.ebeaninternal.server.el.ElFilter;
|
||||
import com.avaje.ebeaninternal.server.jmx.MAdminAutofetch;
|
||||
import com.avaje.ebeaninternal.server.ldap.DefaultLdapOrmQuery;
|
||||
import com.avaje.ebeaninternal.server.ldap.LdapOrmQueryEngine;
|
||||
import com.avaje.ebeaninternal.server.ldap.LdapOrmQueryRequest;
|
||||
import com.avaje.ebeaninternal.server.ldap.expression.LdapExpressionFactory;
|
||||
import com.avaje.ebeaninternal.server.lib.ShutdownManager;
|
||||
import com.avaje.ebeaninternal.server.loadcontext.DLoadContext;
|
||||
import com.avaje.ebeaninternal.server.query.CQuery;
|
||||
@@ -158,8 +153,6 @@ public final class DefaultServer implements SpiEbeanServer {
|
||||
private final boolean vanillaMode;
|
||||
private final boolean vanillaRefMode;
|
||||
|
||||
private final LdapOrmQueryEngine ldapQueryEngine;
|
||||
|
||||
/**
|
||||
* Handles the save, delete, updateSql CallableSql.
|
||||
*/
|
||||
@@ -182,8 +175,6 @@ public final class DefaultServer implements SpiEbeanServer {
|
||||
@Deprecated
|
||||
private DdlGenerator ddlGenerator;
|
||||
|
||||
private final ExpressionFactory ldapExpressionFactory = new LdapExpressionFactory();
|
||||
|
||||
private final ExpressionFactory expressionFactory;
|
||||
|
||||
private final SpiBackgroundExecutor backgroundExecutor;
|
||||
@@ -266,13 +257,6 @@ public final class DefaultServer implements SpiEbeanServer {
|
||||
this.beanLoader = new DefaultBeanLoader(this, config.getDebugLazyLoad());
|
||||
this.jsonContext = config.createJsonContext(this);
|
||||
|
||||
LdapConfig ldapConfig = config.getServerConfig().getLdapConfig();
|
||||
if (ldapConfig == null) {
|
||||
this.ldapQueryEngine = null;
|
||||
} else {
|
||||
this.ldapQueryEngine = new LdapOrmQueryEngine(ldapConfig.isVanillaMode(), ldapConfig.getContextFactory());
|
||||
}
|
||||
|
||||
loadAndInitializePlugins(config);
|
||||
|
||||
ShutdownManager.register(new Shutdown());
|
||||
@@ -1036,9 +1020,6 @@ public final class DefaultServer implements SpiEbeanServer {
|
||||
DeployNamedQuery defaultSqlSelect = desc.getNamedQuery("default");
|
||||
return new DefaultOrmQuery<T>(beanType, this, expressionFactory, defaultSqlSelect);
|
||||
|
||||
case LDAP:
|
||||
return new DefaultLdapOrmQuery<T>(beanType, this, ldapExpressionFactory, query);
|
||||
|
||||
default:
|
||||
return new DefaultOrmQuery<T>(beanType, this, expressionFactory, query);
|
||||
}
|
||||
@@ -1128,10 +1109,6 @@ public final class DefaultServer implements SpiEbeanServer {
|
||||
|
||||
public <T> SpiOrmQueryRequest<T> createQueryRequest(BeanDescriptor<T> desc, SpiQuery<T> query, Transaction t) {
|
||||
|
||||
if (desc.isLdapEntityType()) {
|
||||
return new LdapOrmQueryRequest<T>(query, desc, ldapQueryEngine);
|
||||
}
|
||||
|
||||
if (desc.isAutoFetchTunable() && !query.isSqlSelect()) {
|
||||
// its a tunable query
|
||||
if (autoFetchManager.tuneQuery(query)) {
|
||||
|
||||
@@ -7,8 +7,6 @@ import com.avaje.ebean.cache.ServerCacheManager;
|
||||
import com.avaje.ebean.config.ExternalTransactionManager;
|
||||
import com.avaje.ebean.config.ServerConfig;
|
||||
import com.avaje.ebean.config.dbplatform.DatabasePlatform;
|
||||
import com.avaje.ebean.config.ldap.LdapConfig;
|
||||
import com.avaje.ebean.config.ldap.LdapContextFactory;
|
||||
import com.avaje.ebean.text.json.JsonContext;
|
||||
import com.avaje.ebean.text.json.JsonValueAdapter;
|
||||
import com.avaje.ebeaninternal.api.ClassUtil;
|
||||
@@ -177,12 +175,8 @@ public class InternalConfiguration {
|
||||
}
|
||||
|
||||
public Persister createPersister(SpiEbeanServer server) {
|
||||
LdapContextFactory ldapCtxFactory = null;
|
||||
LdapConfig ldapConfig = serverConfig.getLdapConfig();
|
||||
if (ldapConfig != null) {
|
||||
ldapCtxFactory = ldapConfig.getContextFactory();
|
||||
}
|
||||
return new DefaultPersister(server, serverConfig.isValidateOnSave(), binder, beanDescriptorManager, pstmtBatch, ldapCtxFactory);
|
||||
|
||||
return new DefaultPersister(server, serverConfig.isValidateOnSave(), binder, beanDescriptorManager, pstmtBatch);
|
||||
}
|
||||
|
||||
public PstmtBatch getPstmtBatch() {
|
||||
|
||||
@@ -15,11 +15,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.naming.InvalidNameException;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.BasicAttribute;
|
||||
import javax.naming.directory.BasicAttributes;
|
||||
import javax.naming.ldap.LdapName;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebean.InvalidValue;
|
||||
@@ -66,7 +61,6 @@ import com.avaje.ebeaninternal.server.el.ElComparatorProperty;
|
||||
import com.avaje.ebeaninternal.server.el.ElPropertyChainBuilder;
|
||||
import com.avaje.ebeaninternal.server.el.ElPropertyDeploy;
|
||||
import com.avaje.ebeaninternal.server.el.ElPropertyValue;
|
||||
import com.avaje.ebeaninternal.server.ldap.LdapPersistenceException;
|
||||
import com.avaje.ebeaninternal.server.persist.DmlUtil;
|
||||
import com.avaje.ebeaninternal.server.query.CQueryPlan;
|
||||
import com.avaje.ebeaninternal.server.query.SplitName;
|
||||
@@ -125,9 +119,6 @@ public class BeanDescriptor<T> {
|
||||
*/
|
||||
private final String sequenceName;
|
||||
|
||||
private final String ldapBaseDn;
|
||||
private final String[] ldapObjectclasses;
|
||||
|
||||
/**
|
||||
* SQL used to return last inserted id. Used for Identity columns where
|
||||
* getGeneratedKeys is not supported.
|
||||
@@ -422,8 +413,6 @@ public class BeanDescriptor<T> {
|
||||
|
||||
this.idType = deploy.getIdType();
|
||||
this.idGenerator = deploy.getIdGenerator();
|
||||
this.ldapBaseDn = deploy.getLdapBaseDn();
|
||||
this.ldapObjectclasses = deploy.getLdapObjectclasses();
|
||||
this.sequenceName = deploy.getSequenceName();
|
||||
this.selectLastInsertedId = deploy.getSelectLastInsertedId();
|
||||
this.lazyFetchIncludes = InternString.intern(deploy.getLazyFetchIncludes());
|
||||
@@ -717,55 +706,6 @@ public class BeanDescriptor<T> {
|
||||
return !beanType.equals(factoryType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the LDAP objectClasses to the attributes.
|
||||
*/
|
||||
public void setLdapObjectClasses(Attributes attributes) {
|
||||
|
||||
if (ldapObjectclasses != null) {
|
||||
BasicAttribute ocAttrs = new BasicAttribute("objectclass");
|
||||
for (int i = 0; i < ldapObjectclasses.length; i++) {
|
||||
ocAttrs.add(ldapObjectclasses[i]);
|
||||
}
|
||||
attributes.put(ocAttrs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Attributes with the objectclass.
|
||||
*/
|
||||
public Attributes createAttributes() {
|
||||
|
||||
Attributes attrs = new BasicAttributes(true);
|
||||
setLdapObjectClasses(attrs);
|
||||
return attrs;
|
||||
}
|
||||
|
||||
public String getLdapBaseDn() {
|
||||
return ldapBaseDn;
|
||||
}
|
||||
|
||||
public LdapName createLdapNameById(Object id) throws InvalidNameException {
|
||||
|
||||
LdapName baseDn = new LdapName(ldapBaseDn);
|
||||
idBinder.createLdapNameById(baseDn, id);
|
||||
return baseDn;
|
||||
}
|
||||
|
||||
public LdapName createLdapName(Object bean) {
|
||||
|
||||
try {
|
||||
LdapName name = new LdapName(ldapBaseDn);
|
||||
if (bean != null) {
|
||||
idBinder.createLdapNameByBean(name, bean);
|
||||
}
|
||||
return name;
|
||||
|
||||
} catch (InvalidNameException e) {
|
||||
throw new LdapPersistenceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public SqlUpdate deleteById(Object id, List<Object> idList) {
|
||||
if (id != null) {
|
||||
return deleteById(id);
|
||||
|
||||
@@ -11,9 +11,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attribute;
|
||||
import javax.naming.directory.BasicAttribute;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebean.InvalidValue;
|
||||
@@ -21,7 +18,6 @@ import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.config.EncryptKey;
|
||||
import com.avaje.ebean.config.dbplatform.DbEncryptFunction;
|
||||
import com.avaje.ebean.config.dbplatform.DbType;
|
||||
import com.avaje.ebean.config.ldap.LdapAttributeAdapter;
|
||||
import com.avaje.ebean.text.StringFormatter;
|
||||
import com.avaje.ebean.text.StringParser;
|
||||
import com.avaje.ebean.text.TextException;
|
||||
@@ -32,7 +28,6 @@ import com.avaje.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty
|
||||
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
|
||||
import com.avaje.ebeaninternal.server.el.ElPropertyChainBuilder;
|
||||
import com.avaje.ebeaninternal.server.el.ElPropertyValue;
|
||||
import com.avaje.ebeaninternal.server.ldap.LdapPersistenceException;
|
||||
import com.avaje.ebeaninternal.server.lib.util.StringHelper;
|
||||
import com.avaje.ebeaninternal.server.query.SqlBeanLoad;
|
||||
import com.avaje.ebeaninternal.server.reflect.BeanReflectGetter;
|
||||
@@ -233,11 +228,6 @@ public class BeanProperty implements ElPropertyValue {
|
||||
@SuppressWarnings("rawtypes")
|
||||
final ScalarType scalarType;
|
||||
|
||||
/**
|
||||
* For LDAP attributes that have custom conversion.
|
||||
*/
|
||||
final LdapAttributeAdapter ldapAttributeAdapter;
|
||||
|
||||
final Validator[] validators;
|
||||
|
||||
final boolean hasLocalValidators;
|
||||
@@ -343,7 +333,6 @@ public class BeanProperty implements ElPropertyValue {
|
||||
this.defaultValue = deploy.getDefaultValue();
|
||||
this.dbType = deploy.getDbType();
|
||||
this.scalarType = deploy.getScalarType();
|
||||
this.ldapAttributeAdapter = deploy.getLdapAttributeAdapter();
|
||||
this.lob = isLobType(dbType);
|
||||
this.propertyType = deploy.getPropertyType();
|
||||
this.field = deploy.getField();
|
||||
@@ -429,7 +418,6 @@ public class BeanProperty implements ElPropertyValue {
|
||||
this.defaultValue = source.getDefaultValue();
|
||||
this.dbType = source.getDbType();
|
||||
this.scalarType = source.scalarType;
|
||||
this.ldapAttributeAdapter = source.ldapAttributeAdapter;
|
||||
this.lob = isLobType(dbType);
|
||||
this.propertyType = source.getPropertyType();
|
||||
this.field = source.getField();
|
||||
@@ -765,35 +753,6 @@ public class BeanProperty implements ElPropertyValue {
|
||||
return local;
|
||||
}
|
||||
|
||||
public Attribute createAttribute(Object bean) {
|
||||
Object v = getValue(bean);
|
||||
if (v == null) {
|
||||
return null;
|
||||
}
|
||||
if (ldapAttributeAdapter != null) {
|
||||
return ldapAttributeAdapter.createAttribute(v);
|
||||
}
|
||||
Object ldapValue = scalarType.toJdbcType(v);
|
||||
return new BasicAttribute(dbColumn, ldapValue);
|
||||
}
|
||||
|
||||
public void setAttributeValue(Object bean, Attribute attr) {
|
||||
try {
|
||||
if (attr != null) {
|
||||
Object beanValue;
|
||||
if (ldapAttributeAdapter != null) {
|
||||
beanValue = ldapAttributeAdapter.readAttribute(attr);
|
||||
} else {
|
||||
beanValue = scalarType.toBeanType(attr.get());
|
||||
}
|
||||
|
||||
setValue(bean, beanValue);
|
||||
}
|
||||
} catch (NamingException e) {
|
||||
throw new LdapPersistenceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of the property without interception or
|
||||
* PropertyChangeSupport.
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.deploy;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attribute;
|
||||
import javax.naming.directory.BasicAttribute;
|
||||
|
||||
import com.avaje.ebean.bean.BeanCollectionAdd;
|
||||
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanPropertySimpleCollection;
|
||||
import com.avaje.ebeaninternal.server.ldap.LdapPersistenceException;
|
||||
import com.avaje.ebeaninternal.server.type.ScalarType;
|
||||
|
||||
public class BeanPropertySimpleCollection<T> extends BeanPropertyAssocMany<T> {
|
||||
@@ -25,56 +16,4 @@ public class BeanPropertySimpleCollection<T> extends BeanPropertyAssocMany<T> {
|
||||
super.initialise();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attribute createAttribute(Object bean) {
|
||||
Object v = getValue(bean);
|
||||
if (v == null){
|
||||
return null;
|
||||
}
|
||||
if (ldapAttributeAdapter != null){
|
||||
return ldapAttributeAdapter.createAttribute(v);
|
||||
}
|
||||
|
||||
BasicAttribute attrs = new BasicAttribute(getDbColumn());
|
||||
|
||||
Iterator<?> it = help.getIterator(v);
|
||||
if (it != null){
|
||||
while (it.hasNext()) {
|
||||
Object beanValue = it.next();
|
||||
Object attrValue = collectionScalarType.toJdbcType(beanValue);
|
||||
attrs.add(attrValue);
|
||||
}
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttributeValue(Object bean, Attribute attr) {
|
||||
try {
|
||||
if (attr != null){
|
||||
Object beanValue;
|
||||
if (ldapAttributeAdapter != null){
|
||||
beanValue = ldapAttributeAdapter.readAttribute(attr);
|
||||
|
||||
} else {
|
||||
boolean vanilla = true;
|
||||
beanValue = help.createEmpty(vanilla);
|
||||
BeanCollectionAdd collAdd = help.getBeanCollectionAdd(beanValue, mapKey);
|
||||
|
||||
NamingEnumeration<?> en = attr.getAll();
|
||||
while (en.hasMoreElements()) {
|
||||
Object attrValue = (Object) en.nextElement();
|
||||
Object collValue = collectionScalarType.toBeanType(attrValue);
|
||||
collAdd.addBean(collValue);
|
||||
}
|
||||
}
|
||||
|
||||
setValue(bean, beanValue);
|
||||
}
|
||||
} catch (NamingException e) {
|
||||
throw new LdapPersistenceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -97,10 +97,6 @@ public class DeployBeanDescriptor<T> {
|
||||
*/
|
||||
private String sequenceName;
|
||||
|
||||
private String ldapBaseDn;
|
||||
|
||||
private String[] ldapObjectclasses;
|
||||
|
||||
/**
|
||||
* Used with Identity columns but no getGeneratedKeys support.
|
||||
*/
|
||||
@@ -419,22 +415,6 @@ public class DeployBeanDescriptor<T> {
|
||||
this.concurrencyMode = concurrencyMode;
|
||||
}
|
||||
|
||||
public String getLdapBaseDn() {
|
||||
return ldapBaseDn;
|
||||
}
|
||||
|
||||
public void setLdapBaseDn(String ldapBaseDn) {
|
||||
this.ldapBaseDn = ldapBaseDn;
|
||||
}
|
||||
|
||||
public String[] getLdapObjectclasses() {
|
||||
return ldapObjectclasses;
|
||||
}
|
||||
|
||||
public void setLdapObjectclasses(String[] ldapObjectclasses) {
|
||||
this.ldapObjectclasses = ldapObjectclasses;
|
||||
}
|
||||
|
||||
public boolean isUpdateChangesOnly() {
|
||||
return updateChangesOnly;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import com.avaje.ebean.annotation.UpdatedTimestamp;
|
||||
import com.avaje.ebean.config.ScalarTypeConverter;
|
||||
import com.avaje.ebean.config.dbplatform.DbEncrypt;
|
||||
import com.avaje.ebean.config.dbplatform.DbEncryptFunction;
|
||||
import com.avaje.ebean.config.ldap.LdapAttributeAdapter;
|
||||
import com.avaje.ebean.validation.factory.Validator;
|
||||
import com.avaje.ebeaninternal.server.core.InternString;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor.EntityType;
|
||||
@@ -91,8 +90,6 @@ public class DeployBeanProperty {
|
||||
|
||||
private boolean unique;
|
||||
|
||||
private LdapAttributeAdapter ldapAttributeAdapter;
|
||||
|
||||
/**
|
||||
* The length or precision of the DB column.
|
||||
*/
|
||||
@@ -592,20 +589,6 @@ public class DeployBeanProperty {
|
||||
this.unique = unique;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the LdapAttributeAdapter.
|
||||
*/
|
||||
public LdapAttributeAdapter getLdapAttributeAdapter() {
|
||||
return ldapAttributeAdapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the LdapAttributeAdapter.
|
||||
*/
|
||||
public void setLdapAttributeAdapter(LdapAttributeAdapter ldapAttributeAdapter) {
|
||||
this.ldapAttributeAdapter = ldapAttributeAdapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this is a version column used for concurrency checking.
|
||||
*/
|
||||
|
||||
@@ -10,7 +10,6 @@ import javax.persistence.MapKey;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OrderBy;
|
||||
|
||||
import com.avaje.ebean.annotation.LdapAttribute;
|
||||
import com.avaje.ebean.annotation.PrivateOwned;
|
||||
import com.avaje.ebean.annotation.Where;
|
||||
import com.avaje.ebean.bean.BeanCollection.ModifyListenMode;
|
||||
@@ -108,11 +107,6 @@ public class AnnotationAssocManys extends AnnotationParser {
|
||||
prop.getTableJoin().addJoinColumn(true, joinTable.joinColumns(), beanTable);
|
||||
}
|
||||
}
|
||||
LdapAttribute ldapAttribute = get(prop, LdapAttribute.class);
|
||||
if (ldapAttribute != null) {
|
||||
// read ldap specific property settings
|
||||
readLdapAttribute(ldapAttribute, prop);
|
||||
}
|
||||
|
||||
if (prop.getMappedBy() != null){
|
||||
// the join is derived by reversing the join information
|
||||
|
||||
@@ -12,7 +12,6 @@ import javax.xml.bind.annotation.XmlType;
|
||||
import com.avaje.ebean.Query.UseIndex;
|
||||
import com.avaje.ebean.annotation.CacheStrategy;
|
||||
import com.avaje.ebean.annotation.EntityConcurrencyMode;
|
||||
import com.avaje.ebean.annotation.LdapDomain;
|
||||
import com.avaje.ebean.annotation.NamedUpdate;
|
||||
import com.avaje.ebean.annotation.NamedUpdates;
|
||||
import com.avaje.ebean.annotation.UpdateMode;
|
||||
@@ -54,14 +53,6 @@ public class AnnotationClass extends AnnotationParser {
|
||||
descriptor.setBaseTable(tableName);
|
||||
}
|
||||
}
|
||||
|
||||
private String[] parseLdapObjectclasses(String objectclasses) {
|
||||
|
||||
if (objectclasses == null || objectclasses.length() == 0){
|
||||
return null;
|
||||
}
|
||||
return objectclasses.split(",");
|
||||
}
|
||||
|
||||
private boolean isXmlElement(Class<?> cls) {
|
||||
XmlRootElement rootElement = cls.getAnnotation(XmlRootElement.class);
|
||||
@@ -76,14 +67,6 @@ public class AnnotationClass extends AnnotationParser {
|
||||
}
|
||||
|
||||
private void read(Class<?> cls) {
|
||||
|
||||
LdapDomain ldapDomain = cls.getAnnotation(LdapDomain.class);
|
||||
if (ldapDomain != null) {
|
||||
descriptor.setName(cls.getSimpleName());
|
||||
descriptor.setEntityType(EntityType.LDAP);
|
||||
descriptor.setLdapBaseDn(ldapDomain.baseDn());
|
||||
descriptor.setLdapObjectclasses(parseLdapObjectclasses(ldapDomain.objectclass()));
|
||||
}
|
||||
|
||||
Entity entity = cls.getAnnotation(Entity.class);
|
||||
if (entity != null){
|
||||
|
||||
@@ -29,8 +29,6 @@ import com.avaje.ebean.annotation.EmbeddedColumns;
|
||||
import com.avaje.ebean.annotation.Encrypted;
|
||||
import com.avaje.ebean.annotation.Expose;
|
||||
import com.avaje.ebean.annotation.Formula;
|
||||
import com.avaje.ebean.annotation.LdapAttribute;
|
||||
import com.avaje.ebean.annotation.LdapId;
|
||||
import com.avaje.ebean.annotation.UpdatedTimestamp;
|
||||
import com.avaje.ebean.config.EncryptDeploy;
|
||||
import com.avaje.ebean.config.EncryptDeploy.Mode;
|
||||
@@ -65,451 +63,438 @@ import com.avaje.ebeaninternal.server.type.ScalarTypeLdapTimestamp;
|
||||
*/
|
||||
public class AnnotationFields extends AnnotationParser {
|
||||
|
||||
/**
|
||||
* By default we lazy load Lob properties.
|
||||
*/
|
||||
private FetchType defaultLobFetchType = FetchType.LAZY;
|
||||
|
||||
private GeneratedPropertyFactory generatedPropFactory = new GeneratedPropertyFactory();
|
||||
/**
|
||||
* By default we lazy load Lob properties.
|
||||
*/
|
||||
private FetchType defaultLobFetchType = FetchType.LAZY;
|
||||
|
||||
public AnnotationFields(DeployBeanInfo<?> info) {
|
||||
super(info);
|
||||
|
||||
if (GlobalProperties.getBoolean("ebean.lobEagerFetch", false)) {
|
||||
defaultLobFetchType = FetchType.EAGER;
|
||||
}
|
||||
}
|
||||
private GeneratedPropertyFactory generatedPropFactory = new GeneratedPropertyFactory();
|
||||
|
||||
/**
|
||||
* Read the field level deployment annotations.
|
||||
*/
|
||||
public void parse() {
|
||||
public AnnotationFields(DeployBeanInfo<?> info) {
|
||||
super(info);
|
||||
|
||||
Iterator<DeployBeanProperty> it = descriptor.propertiesAll();
|
||||
while (it.hasNext()) {
|
||||
DeployBeanProperty prop = it.next();
|
||||
if (prop instanceof DeployBeanPropertyAssoc<?>) {
|
||||
readAssocOne(prop);
|
||||
} else {
|
||||
readField(prop);
|
||||
}
|
||||
if (GlobalProperties.getBoolean("ebean.lobEagerFetch", false)) {
|
||||
defaultLobFetchType = FetchType.EAGER;
|
||||
}
|
||||
}
|
||||
|
||||
readValidations(prop);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Read the field level deployment annotations.
|
||||
*/
|
||||
public void parse() {
|
||||
|
||||
/**
|
||||
* Read the Id marker annotations on EmbeddedId properties.
|
||||
*/
|
||||
private void readAssocOne(DeployBeanProperty prop) {
|
||||
Iterator<DeployBeanProperty> it = descriptor.propertiesAll();
|
||||
while (it.hasNext()) {
|
||||
DeployBeanProperty prop = it.next();
|
||||
if (prop instanceof DeployBeanPropertyAssoc<?>) {
|
||||
readAssocOne(prop);
|
||||
} else {
|
||||
readField(prop);
|
||||
}
|
||||
|
||||
Id id = get(prop, Id.class);
|
||||
if (id != null) {
|
||||
prop.setId(true);
|
||||
prop.setNullable(false);
|
||||
}
|
||||
readValidations(prop);
|
||||
}
|
||||
}
|
||||
|
||||
EmbeddedId embeddedId = get(prop, EmbeddedId.class);
|
||||
if (embeddedId != null) {
|
||||
prop.setId(true);
|
||||
prop.setNullable(false);
|
||||
prop.setEmbedded(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void readField(DeployBeanProperty prop) {
|
||||
/**
|
||||
* Read the Id marker annotations on EmbeddedId properties.
|
||||
*/
|
||||
private void readAssocOne(DeployBeanProperty prop) {
|
||||
|
||||
// all Enums will have a ScalarType assigned...
|
||||
boolean isEnum = prop.getPropertyType().isEnum();
|
||||
Enumerated enumerated = get(prop, Enumerated.class);
|
||||
if (isEnum || enumerated != null) {
|
||||
util.setEnumScalarType(enumerated, prop);
|
||||
}
|
||||
Id id = get(prop, Id.class);
|
||||
if (id != null) {
|
||||
prop.setId(true);
|
||||
prop.setNullable(false);
|
||||
}
|
||||
|
||||
// its persistent and assumed to be on the base table
|
||||
// rather than on a secondary table
|
||||
prop.setDbRead(true);
|
||||
prop.setDbInsertable(true);
|
||||
prop.setDbUpdateable(true);
|
||||
EmbeddedId embeddedId = get(prop, EmbeddedId.class);
|
||||
if (embeddedId != null) {
|
||||
prop.setId(true);
|
||||
prop.setNullable(false);
|
||||
prop.setEmbedded(true);
|
||||
}
|
||||
|
||||
Column column = get(prop, Column.class);
|
||||
if (column != null) {
|
||||
readColumn(column, prop);
|
||||
}
|
||||
Expose expose = get(prop, Expose.class);
|
||||
if (expose != null) {
|
||||
prop.setExposeSerialize(expose.serialize());
|
||||
prop.setExposeDeserialize(expose.deserialize());
|
||||
}
|
||||
|
||||
LdapAttribute ldapAttribute = get(prop, LdapAttribute.class);
|
||||
if (ldapAttribute != null) {
|
||||
// read ldap specific property settings
|
||||
readLdapAttribute(ldapAttribute, prop);
|
||||
}
|
||||
|
||||
if (prop.getDbColumn() == null){
|
||||
if (EntityType.LDAP.equals(descriptor.getEntityType())) {
|
||||
// just use matching for now. Could consider an LdapNamingConvention later.
|
||||
prop.setDbColumn(prop.getName());
|
||||
} else {
|
||||
// No @Column annotation or @Column.name() not set
|
||||
// Use the NamingConvention to set the DB column name
|
||||
String dbColumn = namingConvention.getColumnFromProperty(beanType, prop.getName());
|
||||
prop.setDbColumn(dbColumn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GeneratedValue gen = get(prop, GeneratedValue.class);
|
||||
if (gen != null) {
|
||||
readGenValue(gen, prop);
|
||||
}
|
||||
private void readField(DeployBeanProperty prop) {
|
||||
|
||||
Id id = (Id) get(prop, Id.class);
|
||||
if (id != null) {
|
||||
readId(id, prop);
|
||||
}
|
||||
LdapId ldapId = (LdapId)get(prop, LdapId.class);
|
||||
if (ldapId != null) {
|
||||
prop.setId(true);
|
||||
prop.setNullable(false);
|
||||
}
|
||||
|
||||
|
||||
// determine the JDBC type using Lob/Temporal
|
||||
// otherwise based on the property Class
|
||||
Lob lob = get(prop, Lob.class);
|
||||
Temporal temporal = get(prop, Temporal.class);
|
||||
if (temporal != null) {
|
||||
readTemporal(temporal, prop);
|
||||
// all Enums will have a ScalarType assigned...
|
||||
boolean isEnum = prop.getPropertyType().isEnum();
|
||||
Enumerated enumerated = get(prop, Enumerated.class);
|
||||
if (isEnum || enumerated != null) {
|
||||
util.setEnumScalarType(enumerated, prop);
|
||||
}
|
||||
|
||||
} else if (lob != null) {
|
||||
util.setLobType(prop);
|
||||
}
|
||||
// its persistent and assumed to be on the base table
|
||||
// rather than on a secondary table
|
||||
prop.setDbRead(true);
|
||||
prop.setDbInsertable(true);
|
||||
prop.setDbUpdateable(true);
|
||||
|
||||
Formula formula = get(prop, Formula.class);
|
||||
if (formula != null) {
|
||||
prop.setSqlFormula(formula.select(), formula.join());
|
||||
}
|
||||
Column column = get(prop, Column.class);
|
||||
if (column != null) {
|
||||
readColumn(column, prop);
|
||||
}
|
||||
Expose expose = get(prop, Expose.class);
|
||||
if (expose != null) {
|
||||
prop.setExposeSerialize(expose.serialize());
|
||||
prop.setExposeDeserialize(expose.deserialize());
|
||||
}
|
||||
|
||||
Version version = get(prop, Version.class);
|
||||
if (version != null) {
|
||||
// explicitly specify a version column
|
||||
prop.setVersionColumn(true);
|
||||
generatedPropFactory.setVersion(prop);
|
||||
}
|
||||
if (prop.getDbColumn() == null) {
|
||||
if (EntityType.LDAP.equals(descriptor.getEntityType())) {
|
||||
// just use matching for now. Could consider an LdapNamingConvention
|
||||
// later.
|
||||
prop.setDbColumn(prop.getName());
|
||||
} else {
|
||||
// No @Column annotation or @Column.name() not set
|
||||
// Use the NamingConvention to set the DB column name
|
||||
String dbColumn = namingConvention.getColumnFromProperty(beanType, prop.getName());
|
||||
prop.setDbColumn(dbColumn);
|
||||
}
|
||||
}
|
||||
|
||||
Basic basic = get(prop, Basic.class);
|
||||
if (basic != null) {
|
||||
prop.setFetchType(basic.fetch());
|
||||
if (!basic.optional()) {
|
||||
prop.setNullable(false);
|
||||
}
|
||||
} else if (prop.isLob()){
|
||||
// use the default Lob fetchType
|
||||
prop.setFetchType(defaultLobFetchType);
|
||||
}
|
||||
|
||||
CreatedTimestamp ct = get(prop, CreatedTimestamp.class);
|
||||
if (ct != null) {
|
||||
generatedPropFactory.setInsertTimestamp(prop);
|
||||
}
|
||||
|
||||
UpdatedTimestamp ut = get(prop, UpdatedTimestamp.class);
|
||||
if (ut != null) {
|
||||
generatedPropFactory.setUpdateTimestamp(prop);
|
||||
}
|
||||
|
||||
NotNull notNull = get(prop, NotNull.class);
|
||||
if (notNull != null) {
|
||||
// explicitly specify a version column
|
||||
prop.setNullable(false);
|
||||
}
|
||||
|
||||
Length length = get(prop, Length.class);
|
||||
if (length != null) {
|
||||
if (length.max() < Integer.MAX_VALUE){
|
||||
// explicitly specify a version column
|
||||
prop.setDbLength(length.max());
|
||||
}
|
||||
}
|
||||
|
||||
EmbeddedColumns columns = get(prop, EmbeddedColumns.class);
|
||||
if (columns != null) {
|
||||
if (prop instanceof DeployBeanPropertyCompound){
|
||||
DeployBeanPropertyCompound p = (DeployBeanPropertyCompound)prop;
|
||||
|
||||
// convert into a Map
|
||||
String propColumns = columns.columns();
|
||||
Map<String, String> propMap = StringHelper.delimitedToMap(propColumns, ",", "=");
|
||||
|
||||
p.getDeployEmbedded().putAll(propMap);
|
||||
|
||||
CtCompoundType<?> compoundType = p.getCompoundType();
|
||||
if (compoundType == null){
|
||||
throw new RuntimeException("No registered CtCompoundType for "+p.getPropertyType());
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new RuntimeException("Can't use EmbeddedColumns on ScalarType "+prop.getFullBeanName());
|
||||
}
|
||||
}
|
||||
|
||||
// Want to process last so we can use with @Formula
|
||||
Transient t = get(prop, Transient.class);
|
||||
if (t != null) {
|
||||
// it is not a persistent property.
|
||||
prop.setDbRead(false);
|
||||
prop.setDbInsertable(false);
|
||||
prop.setDbUpdateable(false);
|
||||
prop.setTransient(true);
|
||||
}
|
||||
|
||||
if (!prop.isTransient()){
|
||||
|
||||
EncryptDeploy encryptDeploy = util.getEncryptDeploy(info.getDescriptor().getBaseTableFull(), prop.getDbColumn());
|
||||
if (encryptDeploy == null || encryptDeploy.getMode().equals(Mode.MODE_ANNOTATION)){
|
||||
Encrypted encrypted = get(prop, Encrypted.class);
|
||||
if (encrypted != null) {
|
||||
setEncryption(prop, encrypted.dbEncryption(), encrypted.dbLength());
|
||||
}
|
||||
} else if (Mode.MODE_ENCRYPT.equals(encryptDeploy.getMode())) {
|
||||
setEncryption(prop, encryptDeploy.isDbEncrypt(), encryptDeploy.getDbLength());
|
||||
}
|
||||
}
|
||||
|
||||
if (EntityType.LDAP.equals(descriptor.getEntityType())){
|
||||
adjustTypesForLdap(prop);
|
||||
}
|
||||
}
|
||||
|
||||
private static final ScalarTypeLdapBoolean LDAP_BOOLEAN_SCALARTYPE = new ScalarTypeLdapBoolean();
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private void adjustTypesForLdap(DeployBeanProperty prop) {
|
||||
|
||||
Class<?> pt = prop.getPropertyType();
|
||||
if (boolean.class.equals(pt) || Boolean.class.equals(pt)){
|
||||
prop.setScalarType(LDAP_BOOLEAN_SCALARTYPE);
|
||||
|
||||
} else {
|
||||
ScalarType<?> sqlScalarType = prop.getScalarType();
|
||||
int sqlType = sqlScalarType.getJdbcType();
|
||||
if (sqlType == Types.TIMESTAMP){
|
||||
// Use LDAP Timestamp String format
|
||||
prop.setScalarType(new ScalarTypeLdapTimestamp(sqlScalarType));
|
||||
|
||||
} else if (sqlType == Types.DATE){
|
||||
// Use LDAP Timestamp String format
|
||||
prop.setScalarType(new ScalarTypeLdapDate(sqlScalarType));
|
||||
|
||||
} else {
|
||||
// Just using string parsing for all other types
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setEncryption(DeployBeanProperty prop, boolean dbEncString, int dbLen) {
|
||||
|
||||
util.checkEncryptKeyManagerDefined(prop.getFullBeanName());
|
||||
|
||||
ScalarType<?> st = prop.getScalarType();
|
||||
if (byte[].class.equals(st.getType())){
|
||||
// Always using Java client encryption rather than DB for encryption
|
||||
// of binary data (partially as this is not supported on all db's etc)
|
||||
// This could be reviewed at a later stage.
|
||||
ScalarTypeBytesBase baseType = (ScalarTypeBytesBase)st;
|
||||
DataEncryptSupport support = createDataEncryptSupport(prop);
|
||||
ScalarTypeBytesEncrypted encryptedScalarType = new ScalarTypeBytesEncrypted(baseType, support);
|
||||
prop.setScalarType(encryptedScalarType);
|
||||
prop.setLocalEncrypted(true);
|
||||
return;
|
||||
|
||||
}
|
||||
if (dbEncString){
|
||||
|
||||
DbEncrypt dbEncrypt = util.getDbPlatform().getDbEncrypt();
|
||||
|
||||
if (dbEncrypt != null){
|
||||
// check if we have a DB encryption function for this type
|
||||
int jdbcType = prop.getScalarType().getJdbcType();
|
||||
DbEncryptFunction dbEncryptFunction = dbEncrypt.getDbEncryptFunction(jdbcType);
|
||||
if (dbEncryptFunction != null){
|
||||
// Use DB functions to encrypt and decrypt
|
||||
prop.setDbEncryptFunction(dbEncryptFunction, dbEncrypt, dbLen);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prop.setScalarType(createScalarType(prop, st));
|
||||
prop.setLocalEncrypted(true);
|
||||
if (dbLen > 0){
|
||||
prop.setDbLength(dbLen);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private ScalarTypeEncryptedWrapper<?> createScalarType(DeployBeanProperty prop, ScalarType<?> st ) {
|
||||
|
||||
// Use Java Encryptor wrapping the logical scalar type
|
||||
DataEncryptSupport support = createDataEncryptSupport(prop);
|
||||
ScalarTypeBytesBase byteType = getDbEncryptType(prop);
|
||||
|
||||
return new ScalarTypeEncryptedWrapper(st, byteType, support);
|
||||
}
|
||||
|
||||
private ScalarTypeBytesBase getDbEncryptType(DeployBeanProperty prop) {
|
||||
int dbType = prop.isLob() ? Types.BLOB : Types.VARBINARY;
|
||||
return (ScalarTypeBytesBase)util.getTypeManager().getScalarType(dbType);
|
||||
}
|
||||
|
||||
private DataEncryptSupport createDataEncryptSupport(DeployBeanProperty prop) {
|
||||
|
||||
String table = info.getDescriptor().getBaseTable();
|
||||
String column = prop.getDbColumn();
|
||||
|
||||
return util.createDataEncryptSupport(table, column);
|
||||
}
|
||||
|
||||
|
||||
private void readId(Id id, DeployBeanProperty prop) {
|
||||
|
||||
prop.setId(true);
|
||||
prop.setNullable(false);
|
||||
|
||||
if (prop.getPropertyType().equals(UUID.class)){
|
||||
// An Id of type UUID
|
||||
if (descriptor.getIdGeneratorName() == null){
|
||||
// Without a generator explicitly specified
|
||||
// so will use the default one AUTO_UUID
|
||||
descriptor.setIdGeneratorName(UuidIdGenerator.AUTO_UUID);
|
||||
descriptor.setIdType(IdType.GENERATOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readGenValue(GeneratedValue gen, DeployBeanProperty prop) {
|
||||
|
||||
String genName = gen.generator();
|
||||
|
||||
SequenceGenerator sequenceGenerator = find(prop, SequenceGenerator.class);
|
||||
if (sequenceGenerator != null) {
|
||||
if (sequenceGenerator.name().equals(genName)) {
|
||||
genName = sequenceGenerator.sequenceName();
|
||||
}
|
||||
}
|
||||
|
||||
GenerationType strategy = gen.strategy();
|
||||
|
||||
if (strategy == GenerationType.IDENTITY) {
|
||||
descriptor.setIdType(IdType.IDENTITY);
|
||||
|
||||
} else if (strategy == GenerationType.SEQUENCE) {
|
||||
descriptor.setIdType(IdType.SEQUENCE);
|
||||
if (genName != null && genName.length() > 0) {
|
||||
descriptor.setIdGeneratorName(genName);
|
||||
}
|
||||
|
||||
} else if (strategy == GenerationType.AUTO) {
|
||||
if (prop.getPropertyType().equals(UUID.class)){
|
||||
descriptor.setIdGeneratorName(UuidIdGenerator.AUTO_UUID);
|
||||
descriptor.setIdType(IdType.GENERATOR);
|
||||
|
||||
} else {
|
||||
// use DatabasePlatform defaults
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readTemporal(Temporal temporal, DeployBeanProperty prop) {
|
||||
|
||||
TemporalType type = temporal.value();
|
||||
if (type.equals(TemporalType.DATE)) {
|
||||
prop.setDbType(Types.DATE);
|
||||
|
||||
} else if (type.equals(TemporalType.TIMESTAMP)) {
|
||||
prop.setDbType(Types.TIMESTAMP);
|
||||
|
||||
} else if (type.equals(TemporalType.TIME)) {
|
||||
prop.setDbType(Types.TIME);
|
||||
|
||||
} else {
|
||||
throw new PersistenceException("Unhandled type " + type);
|
||||
}
|
||||
}
|
||||
GeneratedValue gen = get(prop, GeneratedValue.class);
|
||||
if (gen != null) {
|
||||
readGenValue(gen, prop);
|
||||
}
|
||||
|
||||
Id id = (Id) get(prop, Id.class);
|
||||
if (id != null) {
|
||||
readId(id, prop);
|
||||
}
|
||||
|
||||
private void readColumn(Column columnAnn, DeployBeanProperty prop) {
|
||||
// determine the JDBC type using Lob/Temporal
|
||||
// otherwise based on the property Class
|
||||
Lob lob = get(prop, Lob.class);
|
||||
Temporal temporal = get(prop, Temporal.class);
|
||||
if (temporal != null) {
|
||||
readTemporal(temporal, prop);
|
||||
|
||||
if (!isEmpty(columnAnn.name())){
|
||||
String dbColumn = databasePlatform.convertQuotedIdentifiers(columnAnn.name());
|
||||
prop.setDbColumn(dbColumn);
|
||||
}
|
||||
} else if (lob != null) {
|
||||
util.setLobType(prop);
|
||||
}
|
||||
|
||||
prop.setDbInsertable(columnAnn.insertable());
|
||||
prop.setDbUpdateable(columnAnn.updatable());
|
||||
prop.setNullable(columnAnn.nullable());
|
||||
prop.setUnique(columnAnn.unique());
|
||||
if (columnAnn.precision() > 0){
|
||||
prop.setDbLength(columnAnn.precision());
|
||||
} else if (columnAnn.length() != 255){
|
||||
// set default 255 on DbTypeMap
|
||||
prop.setDbLength(columnAnn.length());
|
||||
}
|
||||
prop.setDbScale(columnAnn.scale());
|
||||
prop.setDbColumnDefn(columnAnn.columnDefinition());
|
||||
Formula formula = get(prop, Formula.class);
|
||||
if (formula != null) {
|
||||
prop.setSqlFormula(formula.select(), formula.join());
|
||||
}
|
||||
|
||||
String baseTable = descriptor.getBaseTable();
|
||||
String tableName = columnAnn.table();
|
||||
if (tableName.equals("") || tableName.equalsIgnoreCase(baseTable)) {
|
||||
// its a base table property...
|
||||
} else {
|
||||
// its on a secondary table...
|
||||
prop.setSecondaryTable(tableName);
|
||||
//DeployTableJoin tableJoin = info.getTableJoin(tableName);
|
||||
//tableJoin.addProperty(prop);
|
||||
}
|
||||
}
|
||||
Version version = get(prop, Version.class);
|
||||
if (version != null) {
|
||||
// explicitly specify a version column
|
||||
prop.setVersionColumn(true);
|
||||
generatedPropFactory.setVersion(prop);
|
||||
}
|
||||
|
||||
Basic basic = get(prop, Basic.class);
|
||||
if (basic != null) {
|
||||
prop.setFetchType(basic.fetch());
|
||||
if (!basic.optional()) {
|
||||
prop.setNullable(false);
|
||||
}
|
||||
} else if (prop.isLob()) {
|
||||
// use the default Lob fetchType
|
||||
prop.setFetchType(defaultLobFetchType);
|
||||
}
|
||||
|
||||
CreatedTimestamp ct = get(prop, CreatedTimestamp.class);
|
||||
if (ct != null) {
|
||||
generatedPropFactory.setInsertTimestamp(prop);
|
||||
}
|
||||
|
||||
private void readValidations(DeployBeanProperty prop) {
|
||||
UpdatedTimestamp ut = get(prop, UpdatedTimestamp.class);
|
||||
if (ut != null) {
|
||||
generatedPropFactory.setUpdateTimestamp(prop);
|
||||
}
|
||||
|
||||
Field field = prop.getField();
|
||||
if (field != null) {
|
||||
Annotation[] fieldAnnotations = field.getAnnotations();
|
||||
for (int i = 0; i < fieldAnnotations.length; i++) {
|
||||
readValidations(prop, fieldAnnotations[i]);
|
||||
}
|
||||
}
|
||||
NotNull notNull = get(prop, NotNull.class);
|
||||
if (notNull != null) {
|
||||
// explicitly specify a version column
|
||||
prop.setNullable(false);
|
||||
}
|
||||
|
||||
Method readMethod = prop.getReadMethod();
|
||||
if (readMethod != null) {
|
||||
Annotation[] methAnnotations = readMethod.getAnnotations();
|
||||
for (int i = 0; i < methAnnotations.length; i++) {
|
||||
readValidations(prop, methAnnotations[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Length length = get(prop, Length.class);
|
||||
if (length != null) {
|
||||
if (length.max() < Integer.MAX_VALUE) {
|
||||
// explicitly specify a version column
|
||||
prop.setDbLength(length.max());
|
||||
}
|
||||
}
|
||||
|
||||
private void readValidations(DeployBeanProperty prop, Annotation ann) {
|
||||
Class<?> type = ann.annotationType();
|
||||
if (type.equals(Patterns.class)){
|
||||
// treating this as a special case for now...
|
||||
Patterns patterns = (Patterns)ann;
|
||||
Pattern[] patternsArray = patterns.patterns();
|
||||
for (int i = 0; i < patternsArray.length; i++) {
|
||||
util.createValidator(prop, patternsArray[i]);
|
||||
}
|
||||
EmbeddedColumns columns = get(prop, EmbeddedColumns.class);
|
||||
if (columns != null) {
|
||||
if (prop instanceof DeployBeanPropertyCompound) {
|
||||
DeployBeanPropertyCompound p = (DeployBeanPropertyCompound) prop;
|
||||
|
||||
} else {
|
||||
// convert into a Map
|
||||
String propColumns = columns.columns();
|
||||
Map<String, String> propMap = StringHelper.delimitedToMap(propColumns, ",", "=");
|
||||
|
||||
ValidatorMeta meta = type.getAnnotation(ValidatorMeta.class);
|
||||
if (meta != null) {
|
||||
util.createValidator(prop, ann);
|
||||
}
|
||||
}
|
||||
}
|
||||
p.getDeployEmbedded().putAll(propMap);
|
||||
|
||||
CtCompoundType<?> compoundType = p.getCompoundType();
|
||||
if (compoundType == null) {
|
||||
throw new RuntimeException("No registered CtCompoundType for " + p.getPropertyType());
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new RuntimeException("Can't use EmbeddedColumns on ScalarType "
|
||||
+ prop.getFullBeanName());
|
||||
}
|
||||
}
|
||||
|
||||
// Want to process last so we can use with @Formula
|
||||
Transient t = get(prop, Transient.class);
|
||||
if (t != null) {
|
||||
// it is not a persistent property.
|
||||
prop.setDbRead(false);
|
||||
prop.setDbInsertable(false);
|
||||
prop.setDbUpdateable(false);
|
||||
prop.setTransient(true);
|
||||
}
|
||||
|
||||
if (!prop.isTransient()) {
|
||||
|
||||
EncryptDeploy encryptDeploy = util.getEncryptDeploy(info.getDescriptor().getBaseTableFull(),
|
||||
prop.getDbColumn());
|
||||
if (encryptDeploy == null || encryptDeploy.getMode().equals(Mode.MODE_ANNOTATION)) {
|
||||
Encrypted encrypted = get(prop, Encrypted.class);
|
||||
if (encrypted != null) {
|
||||
setEncryption(prop, encrypted.dbEncryption(), encrypted.dbLength());
|
||||
}
|
||||
} else if (Mode.MODE_ENCRYPT.equals(encryptDeploy.getMode())) {
|
||||
setEncryption(prop, encryptDeploy.isDbEncrypt(), encryptDeploy.getDbLength());
|
||||
}
|
||||
}
|
||||
|
||||
if (EntityType.LDAP.equals(descriptor.getEntityType())) {
|
||||
adjustTypesForLdap(prop);
|
||||
}
|
||||
}
|
||||
|
||||
private static final ScalarTypeLdapBoolean LDAP_BOOLEAN_SCALARTYPE = new ScalarTypeLdapBoolean();
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private void adjustTypesForLdap(DeployBeanProperty prop) {
|
||||
|
||||
Class<?> pt = prop.getPropertyType();
|
||||
if (boolean.class.equals(pt) || Boolean.class.equals(pt)) {
|
||||
prop.setScalarType(LDAP_BOOLEAN_SCALARTYPE);
|
||||
|
||||
} else {
|
||||
ScalarType<?> sqlScalarType = prop.getScalarType();
|
||||
int sqlType = sqlScalarType.getJdbcType();
|
||||
if (sqlType == Types.TIMESTAMP) {
|
||||
// Use LDAP Timestamp String format
|
||||
prop.setScalarType(new ScalarTypeLdapTimestamp(sqlScalarType));
|
||||
|
||||
} else if (sqlType == Types.DATE) {
|
||||
// Use LDAP Timestamp String format
|
||||
prop.setScalarType(new ScalarTypeLdapDate(sqlScalarType));
|
||||
|
||||
} else {
|
||||
// Just using string parsing for all other types
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setEncryption(DeployBeanProperty prop, boolean dbEncString, int dbLen) {
|
||||
|
||||
util.checkEncryptKeyManagerDefined(prop.getFullBeanName());
|
||||
|
||||
ScalarType<?> st = prop.getScalarType();
|
||||
if (byte[].class.equals(st.getType())) {
|
||||
// Always using Java client encryption rather than DB for encryption
|
||||
// of binary data (partially as this is not supported on all db's etc)
|
||||
// This could be reviewed at a later stage.
|
||||
ScalarTypeBytesBase baseType = (ScalarTypeBytesBase) st;
|
||||
DataEncryptSupport support = createDataEncryptSupport(prop);
|
||||
ScalarTypeBytesEncrypted encryptedScalarType = new ScalarTypeBytesEncrypted(baseType, support);
|
||||
prop.setScalarType(encryptedScalarType);
|
||||
prop.setLocalEncrypted(true);
|
||||
return;
|
||||
|
||||
}
|
||||
if (dbEncString) {
|
||||
|
||||
DbEncrypt dbEncrypt = util.getDbPlatform().getDbEncrypt();
|
||||
|
||||
if (dbEncrypt != null) {
|
||||
// check if we have a DB encryption function for this type
|
||||
int jdbcType = prop.getScalarType().getJdbcType();
|
||||
DbEncryptFunction dbEncryptFunction = dbEncrypt.getDbEncryptFunction(jdbcType);
|
||||
if (dbEncryptFunction != null) {
|
||||
// Use DB functions to encrypt and decrypt
|
||||
prop.setDbEncryptFunction(dbEncryptFunction, dbEncrypt, dbLen);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prop.setScalarType(createScalarType(prop, st));
|
||||
prop.setLocalEncrypted(true);
|
||||
if (dbLen > 0) {
|
||||
prop.setDbLength(dbLen);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private ScalarTypeEncryptedWrapper<?> createScalarType(DeployBeanProperty prop, ScalarType<?> st) {
|
||||
|
||||
// Use Java Encryptor wrapping the logical scalar type
|
||||
DataEncryptSupport support = createDataEncryptSupport(prop);
|
||||
ScalarTypeBytesBase byteType = getDbEncryptType(prop);
|
||||
|
||||
return new ScalarTypeEncryptedWrapper(st, byteType, support);
|
||||
}
|
||||
|
||||
private ScalarTypeBytesBase getDbEncryptType(DeployBeanProperty prop) {
|
||||
int dbType = prop.isLob() ? Types.BLOB : Types.VARBINARY;
|
||||
return (ScalarTypeBytesBase) util.getTypeManager().getScalarType(dbType);
|
||||
}
|
||||
|
||||
private DataEncryptSupport createDataEncryptSupport(DeployBeanProperty prop) {
|
||||
|
||||
String table = info.getDescriptor().getBaseTable();
|
||||
String column = prop.getDbColumn();
|
||||
|
||||
return util.createDataEncryptSupport(table, column);
|
||||
}
|
||||
|
||||
private void readId(Id id, DeployBeanProperty prop) {
|
||||
|
||||
prop.setId(true);
|
||||
prop.setNullable(false);
|
||||
|
||||
if (prop.getPropertyType().equals(UUID.class)) {
|
||||
// An Id of type UUID
|
||||
if (descriptor.getIdGeneratorName() == null) {
|
||||
// Without a generator explicitly specified
|
||||
// so will use the default one AUTO_UUID
|
||||
descriptor.setIdGeneratorName(UuidIdGenerator.AUTO_UUID);
|
||||
descriptor.setIdType(IdType.GENERATOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readGenValue(GeneratedValue gen, DeployBeanProperty prop) {
|
||||
|
||||
String genName = gen.generator();
|
||||
|
||||
SequenceGenerator sequenceGenerator = find(prop, SequenceGenerator.class);
|
||||
if (sequenceGenerator != null) {
|
||||
if (sequenceGenerator.name().equals(genName)) {
|
||||
genName = sequenceGenerator.sequenceName();
|
||||
}
|
||||
}
|
||||
|
||||
GenerationType strategy = gen.strategy();
|
||||
|
||||
if (strategy == GenerationType.IDENTITY) {
|
||||
descriptor.setIdType(IdType.IDENTITY);
|
||||
|
||||
} else if (strategy == GenerationType.SEQUENCE) {
|
||||
descriptor.setIdType(IdType.SEQUENCE);
|
||||
if (genName != null && genName.length() > 0) {
|
||||
descriptor.setIdGeneratorName(genName);
|
||||
}
|
||||
|
||||
} else if (strategy == GenerationType.AUTO) {
|
||||
if (prop.getPropertyType().equals(UUID.class)) {
|
||||
descriptor.setIdGeneratorName(UuidIdGenerator.AUTO_UUID);
|
||||
descriptor.setIdType(IdType.GENERATOR);
|
||||
|
||||
} else {
|
||||
// use DatabasePlatform defaults
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readTemporal(Temporal temporal, DeployBeanProperty prop) {
|
||||
|
||||
TemporalType type = temporal.value();
|
||||
if (type.equals(TemporalType.DATE)) {
|
||||
prop.setDbType(Types.DATE);
|
||||
|
||||
} else if (type.equals(TemporalType.TIMESTAMP)) {
|
||||
prop.setDbType(Types.TIMESTAMP);
|
||||
|
||||
} else if (type.equals(TemporalType.TIME)) {
|
||||
prop.setDbType(Types.TIME);
|
||||
|
||||
} else {
|
||||
throw new PersistenceException("Unhandled type " + type);
|
||||
}
|
||||
}
|
||||
|
||||
private void readColumn(Column columnAnn, DeployBeanProperty prop) {
|
||||
|
||||
if (!isEmpty(columnAnn.name())) {
|
||||
String dbColumn = databasePlatform.convertQuotedIdentifiers(columnAnn.name());
|
||||
prop.setDbColumn(dbColumn);
|
||||
}
|
||||
|
||||
prop.setDbInsertable(columnAnn.insertable());
|
||||
prop.setDbUpdateable(columnAnn.updatable());
|
||||
prop.setNullable(columnAnn.nullable());
|
||||
prop.setUnique(columnAnn.unique());
|
||||
if (columnAnn.precision() > 0) {
|
||||
prop.setDbLength(columnAnn.precision());
|
||||
} else if (columnAnn.length() != 255) {
|
||||
// set default 255 on DbTypeMap
|
||||
prop.setDbLength(columnAnn.length());
|
||||
}
|
||||
prop.setDbScale(columnAnn.scale());
|
||||
prop.setDbColumnDefn(columnAnn.columnDefinition());
|
||||
|
||||
String baseTable = descriptor.getBaseTable();
|
||||
String tableName = columnAnn.table();
|
||||
if (tableName.equals("") || tableName.equalsIgnoreCase(baseTable)) {
|
||||
// its a base table property...
|
||||
} else {
|
||||
// its on a secondary table...
|
||||
prop.setSecondaryTable(tableName);
|
||||
// DeployTableJoin tableJoin = info.getTableJoin(tableName);
|
||||
// tableJoin.addProperty(prop);
|
||||
}
|
||||
}
|
||||
|
||||
private void readValidations(DeployBeanProperty prop) {
|
||||
|
||||
Field field = prop.getField();
|
||||
if (field != null) {
|
||||
Annotation[] fieldAnnotations = field.getAnnotations();
|
||||
for (int i = 0; i < fieldAnnotations.length; i++) {
|
||||
readValidations(prop, fieldAnnotations[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Method readMethod = prop.getReadMethod();
|
||||
if (readMethod != null) {
|
||||
Annotation[] methAnnotations = readMethod.getAnnotations();
|
||||
for (int i = 0; i < methAnnotations.length; i++) {
|
||||
readValidations(prop, methAnnotations[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readValidations(DeployBeanProperty prop, Annotation ann) {
|
||||
Class<?> type = ann.annotationType();
|
||||
if (type.equals(Patterns.class)) {
|
||||
// treating this as a special case for now...
|
||||
Patterns patterns = (Patterns) ann;
|
||||
Pattern[] patternsArray = patterns.patterns();
|
||||
for (int i = 0; i < patternsArray.length; i++) {
|
||||
util.createValidator(prop, patternsArray[i]);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
ValidatorMeta meta = type.getAnnotation(ValidatorMeta.class);
|
||||
if (meta != null) {
|
||||
util.createValidator(prop, ann);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,66 +1,40 @@
|
||||
package com.avaje.ebeaninternal.server.deploy.parse;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebean.annotation.LdapAttribute;
|
||||
import com.avaje.ebean.config.ldap.LdapAttributeAdapter;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanCascadeInfo;
|
||||
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
|
||||
|
||||
/**
|
||||
* Base class for reading deployment annotations.
|
||||
*/
|
||||
public abstract class AnnotationParser extends AnnotationBase {
|
||||
|
||||
protected final DeployBeanInfo<?> info;
|
||||
|
||||
protected final DeployBeanDescriptor<?> descriptor;
|
||||
|
||||
protected final Class<?> beanType;
|
||||
|
||||
public AnnotationParser(DeployBeanInfo<?> info){
|
||||
super(info.getUtil());
|
||||
this.info = info;
|
||||
this.beanType = info.getDescriptor().getBeanType();
|
||||
this.descriptor = info.getDescriptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* read the deployment annotations.
|
||||
*/
|
||||
public abstract void parse();
|
||||
|
||||
/**
|
||||
* Helper method to set cascade types to the CascadeInfo on BeanProperty.
|
||||
*/
|
||||
protected void setCascadeTypes(CascadeType[] cascadeTypes, BeanCascadeInfo cascadeInfo) {
|
||||
if (cascadeTypes != null && cascadeTypes.length > 0) {
|
||||
cascadeInfo.setTypes(cascadeTypes);
|
||||
}
|
||||
}
|
||||
|
||||
protected void readLdapAttribute(LdapAttribute ldapAttribute, DeployBeanProperty prop) {
|
||||
protected final DeployBeanInfo<?> info;
|
||||
|
||||
if (!isEmpty(ldapAttribute.name())){
|
||||
prop.setDbColumn(ldapAttribute.name());
|
||||
}
|
||||
prop.setDbInsertable(ldapAttribute.insertable());
|
||||
prop.setDbUpdateable(ldapAttribute.updatable());
|
||||
protected final DeployBeanDescriptor<?> descriptor;
|
||||
|
||||
Class<?> adapterCls = ldapAttribute.adapter();
|
||||
|
||||
if (adapterCls != null && !void.class.equals(adapterCls)){
|
||||
try {
|
||||
LdapAttributeAdapter adapter = (LdapAttributeAdapter)adapterCls.newInstance();
|
||||
prop.setLdapAttributeAdapter(adapter);
|
||||
} catch (Exception e){
|
||||
String msg= "Error creating LdapAttributeAdapter for ["+prop.getFullBeanName()+"] "
|
||||
+"with class ["+adapterCls+"] using the default constructor.";
|
||||
throw new PersistenceException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected final Class<?> beanType;
|
||||
|
||||
public AnnotationParser(DeployBeanInfo<?> info) {
|
||||
super(info.getUtil());
|
||||
this.info = info;
|
||||
this.beanType = info.getDescriptor().getBeanType();
|
||||
this.descriptor = info.getDescriptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* read the deployment annotations.
|
||||
*/
|
||||
public abstract void parse();
|
||||
|
||||
/**
|
||||
* Helper method to set cascade types to the CascadeInfo on BeanProperty.
|
||||
*/
|
||||
protected void setCascadeTypes(CascadeType[] cascadeTypes, BeanCascadeInfo cascadeInfo) {
|
||||
if (cascadeTypes != null && cascadeTypes.length > 0) {
|
||||
cascadeInfo.setTypes(cascadeTypes);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import com.avaje.ebean.bean.BeanCollection;
|
||||
import com.avaje.ebean.bean.BeanCollection.ModifyListenMode;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.bean.EntityBeanIntercept;
|
||||
import com.avaje.ebean.config.ldap.LdapContextFactory;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.api.SpiTransaction;
|
||||
import com.avaje.ebeaninternal.api.SpiUpdate;
|
||||
@@ -41,8 +40,6 @@ import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocOne;
|
||||
import com.avaje.ebeaninternal.server.deploy.IntersectionRow;
|
||||
import com.avaje.ebeaninternal.server.deploy.ManyType;
|
||||
import com.avaje.ebeaninternal.server.ldap.DefaultLdapPersister;
|
||||
import com.avaje.ebeaninternal.server.ldap.LdapPersistBeanRequest;
|
||||
|
||||
/**
|
||||
* Persister implementation using DML.
|
||||
@@ -69,8 +66,6 @@ public final class DefaultPersister implements Persister {
|
||||
*/
|
||||
private final PersistExecute persistExecute;
|
||||
|
||||
private final DefaultLdapPersister ldapPersister;
|
||||
|
||||
private final SpiEbeanServer server;
|
||||
|
||||
private final BeanDescriptorManager beanDescriptorManager;
|
||||
@@ -79,16 +74,14 @@ public final class DefaultPersister implements Persister {
|
||||
private final boolean defaultDeleteMissingChildren;
|
||||
|
||||
public DefaultPersister(SpiEbeanServer server, boolean validate,
|
||||
Binder binder, BeanDescriptorManager descMgr, PstmtBatch pstmtBatch, LdapContextFactory contextFactory) {
|
||||
Binder binder, BeanDescriptorManager descMgr, PstmtBatch pstmtBatch) {
|
||||
|
||||
this.server = server;
|
||||
this.beanDescriptorManager = descMgr;
|
||||
|
||||
this.persistExecute = new DefaultPersistExecute(validate, binder, pstmtBatch);
|
||||
this.ldapPersister = new DefaultLdapPersister(contextFactory);
|
||||
|
||||
this.defaultUpdateNullProperties = server.isDefaultUpdateNullProperties();
|
||||
this.defaultDeleteMissingChildren = server.isDefaultDeleteMissingChildren();
|
||||
|
||||
this.defaultUpdateNullProperties = server.isDefaultUpdateNullProperties();
|
||||
this.defaultDeleteMissingChildren = server.isDefaultDeleteMissingChildren();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,16 +231,9 @@ public final class DefaultPersister implements Persister {
|
||||
}
|
||||
}
|
||||
|
||||
PersistRequestBean<?> req;
|
||||
if (descriptor.isLdapEntityType()) {
|
||||
req = new LdapPersistBeanRequest(server, bean, parentBean, mgr, ldapPersister, updateProps, mode);
|
||||
|
||||
} else {
|
||||
// special constructor for force 'stateless' Update mode ...
|
||||
req = new PersistRequestBean(server, bean, parentBean, mgr, (SpiTransaction) t, persistExecute, updateProps, mode);
|
||||
req.setStatelessUpdate(true, deleteMissingChildren, updateNullProperties);
|
||||
}
|
||||
|
||||
PersistRequestBean<?> req = new PersistRequestBean(server, bean, parentBean, mgr, (SpiTransaction) t, persistExecute, updateProps, mode);
|
||||
req.setStatelessUpdate(true, deleteMissingChildren, updateNullProperties);
|
||||
|
||||
try {
|
||||
req.initTransIfRequired();
|
||||
update(req);
|
||||
@@ -1349,9 +1335,6 @@ public final class DefaultPersister implements Persister {
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private PersistRequestBean<?> createRequest(Object bean, Transaction t, Object parentBean, BeanManager<?> mgr) {
|
||||
|
||||
if (mgr.isLdapEntityType()) {
|
||||
return new LdapPersistBeanRequest(server, bean, parentBean, mgr, ldapPersister);
|
||||
}
|
||||
return new PersistRequestBean(server, bean, parentBean, mgr, (SpiTransaction) t, persistExecute);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user