[seam-commits] Seam SVN: r7710 - in trunk/src/main/org/jboss/seam: util and 1 other directory.
seam-commits at lists.jboss.org
seam-commits at lists.jboss.org
Wed Mar 26 13:50:29 EDT 2008
Author: pete.muir at jboss.org
Date: 2008-03-26 13:50:29 -0400 (Wed, 26 Mar 2008)
New Revision: 7710
Added:
trunk/src/main/org/jboss/seam/persistence/AbstractPersistenceProvider.java
trunk/src/main/org/jboss/seam/persistence/JpaPersistenceProvider.java
Modified:
trunk/src/main/org/jboss/seam/persistence/EntityManagerProxy.java
trunk/src/main/org/jboss/seam/persistence/HibernatePersistenceProvider.java
trunk/src/main/org/jboss/seam/persistence/PersistenceProvider.java
trunk/src/main/org/jboss/seam/util/Reflections.java
Log:
First pass at runtime persistence provider detection
Added: trunk/src/main/org/jboss/seam/persistence/AbstractPersistenceProvider.java
===================================================================
--- trunk/src/main/org/jboss/seam/persistence/AbstractPersistenceProvider.java (rev 0)
+++ trunk/src/main/org/jboss/seam/persistence/AbstractPersistenceProvider.java 2008-03-26 17:50:29 UTC (rev 7710)
@@ -0,0 +1,147 @@
+package org.jboss.seam.persistence;
+
+import java.lang.reflect.Method;
+import java.util.Date;
+
+import javax.persistence.EntityManager;
+import javax.persistence.OptimisticLockException;
+import javax.transaction.Synchronization;
+
+import org.jboss.seam.Entity;
+
+/**
+ * Provides a default implementation of PersistenceProvider methods where possible
+ *
+ * Other methods must be implemented
+ *
+ * @author Pete Muir
+ *
+ */
+public abstract class AbstractPersistenceProvider
+{
+
+ /**
+ * Set the flush mode to manual-only flushing. Called when
+ * an atomic persistence context is required.
+ */
+ public abstract void setFlushModeManual(EntityManager entityManager);
+
+ /**
+ * Does the persistence context have unflushed changes? If
+ * it does not, persistence context replication can be
+ * optimized.
+ *
+ * @return true to indicate that there are unflushed changes
+ */
+ public abstract boolean isDirty(EntityManager entityManager);
+
+ /**
+ * Get the value of the entity identifier attribute.
+ *
+ * @param bean a managed entity instance
+ */
+ public Object getId(Object bean, EntityManager entityManager)
+ {
+ return Entity.forClass( bean.getClass() ).getIdentifier(bean);
+ }
+
+ /**
+ * Get the name of the entity
+ *
+ * @param bean
+ * @param entityManager
+ *
+ * @throws IllegalArgumentException if the passed object is not an entity
+ */
+ public String getName(Object bean, EntityManager entityManager) throws IllegalArgumentException
+ {
+ return Entity.forClass(bean.getClass()).getName();
+ }
+
+ /**
+ * Get the value of the entity version attribute.
+ *
+ * @param bean a managed entity instance
+ */
+ public Object getVersion(Object bean, EntityManager entityManager)
+ {
+ return Entity.forClass( bean.getClass() ).getVersion(bean);
+ }
+
+ public void checkVersion(Object bean, EntityManager entityManager, Object oldVersion, Object version)
+ {
+ boolean equal;
+ if (oldVersion instanceof Date)
+ {
+ equal = ( (Date) oldVersion ).getTime() == ( (Date) version ).getTime();
+ }
+ else
+ {
+ equal = oldVersion.equals(version);
+ }
+ if ( !equal )
+ {
+ throw new OptimisticLockException("current database version number does not match passivated version number");
+ }
+ }
+
+ /**
+ * Enable a Filter. This is here just especially for Hibernate,
+ * since we well know that other products don't have such cool
+ * features.
+ */
+ public abstract void enableFilter(Filter filter, EntityManager entityManager);
+
+ /**
+ * Register a Synchronization with the current transaction.
+ */
+ public abstract boolean registerSynchronization(Synchronization sync, EntityManager entityManager);
+
+ /**
+ * Wrap the delegate before returning it to the application
+ */
+ public Object proxyDelegate(Object delegate)
+ {
+ return delegate;
+ }
+
+ /**
+ * Wrap the entityManager before returning it to the application
+ */
+ public EntityManager proxyEntityManager(EntityManager entityManager)
+ {
+ return new EntityManagerProxy(entityManager);
+ }
+
+ /**
+ * Returns the class of an entity bean instance
+ *
+ * @param bean The entity bean instance
+ * @return The class of the entity bean
+ */
+ public Class getBeanClass(Object bean)
+ {
+ return Entity.forClass(bean.getClass()).getBeanClass();
+ }
+
+ public Method getPostLoadMethod(Class beanClass, EntityManager entityManager)
+ {
+ return Entity.forClass(beanClass).getPostLoadMethod();
+ }
+
+ public Method getPrePersistMethod(Class beanClass, EntityManager entityManager)
+ {
+ return Entity.forClass(beanClass).getPrePersistMethod();
+ }
+
+ public Method getPreUpdateMethod(Class beanClass, EntityManager entityManager)
+ {
+ return Entity.forClass(beanClass).getPreUpdateMethod();
+ }
+
+ public Method getPreRemoveMethod(Class beanClass, EntityManager entityManager)
+ {
+ return Entity.forClass(beanClass).getPreRemoveMethod();
+ }
+
+}
\ No newline at end of file
Property changes on: trunk/src/main/org/jboss/seam/persistence/AbstractPersistenceProvider.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/src/main/org/jboss/seam/persistence/EntityManagerProxy.java
===================================================================
--- trunk/src/main/org/jboss/seam/persistence/EntityManagerProxy.java 2008-03-26 15:27:37 UTC (rev 7709)
+++ trunk/src/main/org/jboss/seam/persistence/EntityManagerProxy.java 2008-03-26 17:50:29 UTC (rev 7710)
@@ -92,7 +92,7 @@
public Object getDelegate()
{
- return PersistenceProvider.instance().proxyDelegate( delegate.getDelegate() );
+ return PersistenceProvider.instance().proxyDelegate( delegate, delegate.getDelegate() );
}
public FlushModeType getFlushMode()
Modified: trunk/src/main/org/jboss/seam/persistence/HibernatePersistenceProvider.java
===================================================================
--- trunk/src/main/org/jboss/seam/persistence/HibernatePersistenceProvider.java 2008-03-26 15:27:37 UTC (rev 7709)
+++ trunk/src/main/org/jboss/seam/persistence/HibernatePersistenceProvider.java 2008-03-26 17:50:29 UTC (rev 7710)
@@ -1,4 +1,5 @@
package org.jboss.seam.persistence;
+import static org.jboss.seam.ScopeType.STATELESS;
import static org.jboss.seam.annotations.Install.FRAMEWORK;
import java.lang.reflect.Constructor;
@@ -23,6 +24,7 @@
import org.hibernate.event.PostLoadEventListener;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.type.VersionType;
+import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.Seam;
import org.jboss.seam.annotations.Install;
@@ -40,11 +42,11 @@
* @author Pete Muir
*
*/
- at Name("org.jboss.seam.persistence.persistenceProvider")
+ at Name("org.jboss.seam.persistence.hibernatePersistenceProvider")
@Scope(ScopeType.STATELESS)
@BypassInterceptors
@Install(precedence=FRAMEWORK, classDependencies={"org.hibernate.Session", "javax.persistence.EntityManager"})
-public class HibernatePersistenceProvider extends PersistenceProvider
+public class HibernatePersistenceProvider extends AbstractPersistenceProvider
{
private static Log log = Logging.getLog(HibernatePersistenceProvider.class);
@@ -121,10 +123,6 @@
{
return proxySession( (Session) delegate );
}
- catch (NotHibernateException nhe)
- {
- return super.proxyDelegate(delegate);
- }
catch (Exception e)
{
throw new RuntimeException("could not proxy delegate", e);
@@ -134,27 +132,13 @@
@Override
public void setFlushModeManual(EntityManager entityManager)
{
- try
- {
- getSession(entityManager).setFlushMode(FlushMode.MANUAL);
- }
- catch (NotHibernateException nhe)
- {
- super.setFlushModeManual(entityManager);
- }
+ getSession(entityManager).setFlushMode(FlushMode.MANUAL);
}
@Override
public boolean isDirty(EntityManager entityManager)
{
- try
- {
- return getSession(entityManager).isDirty();
- }
- catch (NotHibernateException nhe)
- {
- return super.isDirty(entityManager);
- }
+ return getSession(entityManager).isDirty();
}
@Override
@@ -164,10 +148,6 @@
{
return getSession(entityManager).getIdentifier(bean);
}
- catch (NotHibernateException nhe)
- {
- return super.getId(bean, entityManager);
- }
catch (TransientObjectException e)
{
return super.getId(bean, entityManager);
@@ -177,63 +157,32 @@
@Override
public Object getVersion(Object bean, EntityManager entityManager)
{
- try
- {
- return getVersion( bean, getSession(entityManager) );
- }
- catch (NotHibernateException nhe)
- {
- return super.getVersion(bean, entityManager);
- }
+ return getVersion( bean, getSession(entityManager) );
}
@Override
public void checkVersion(Object bean, EntityManager entityManager, Object oldVersion, Object version)
{
- try
- {
- checkVersion(bean, getSession(entityManager), oldVersion, version);
- }
- catch (NotHibernateException nhe)
- {
- super.checkVersion(bean, entityManager, oldVersion, version);
- }
+ checkVersion(bean, getSession(entityManager), oldVersion, version);
}
@Override
public void enableFilter(Filter f, EntityManager entityManager)
{
- try
+ org.hibernate.Filter filter = getSession(entityManager).enableFilter( f.getName() );
+ for ( Map.Entry<String, ValueExpression> me: f.getParameters().entrySet() )
{
- org.hibernate.Filter filter = getSession(entityManager).enableFilter( f.getName() );
- for ( Map.Entry<String, ValueExpression> me: f.getParameters().entrySet() )
- {
- filter.setParameter( me.getKey(), me.getValue().getValue() );
- }
- filter.validate();
+ filter.setParameter( me.getKey(), me.getValue().getValue() );
}
- catch (NotHibernateException nhe)
- {
- super.enableFilter(f, entityManager);
- }
-
}
@Override
public boolean registerSynchronization(Synchronization sync, EntityManager entityManager)
{
- try
- {
- //TODO: just make sure that a Hibernate JPA EntityTransaction
- // delegates to the Hibernate Session transaction
- getSession(entityManager).getTransaction().registerSynchronization(sync);
- return true;
- }
- catch (NotHibernateException nhe)
- {
- return super.registerSynchronization(sync, entityManager);
- }
-
+ //TODO: just make sure that a Hibernate JPA EntityTransaction
+ // delegates to the Hibernate Session transaction
+ getSession(entityManager).getTransaction().registerSynchronization(sync);
+ return true;
}
@Override
@@ -243,10 +192,6 @@
{
return getSession(entityManager).getEntityName(bean);
}
- catch (NotHibernateException nhe)
- {
- return super.getName(bean, entityManager);
- }
catch (TransientObjectException e)
{
return super.getName(bean, entityManager);
@@ -424,23 +369,12 @@
private Session getSession(EntityManager entityManager)
{
- Object delegate = entityManager.getDelegate();
- if ( delegate instanceof Session )
- {
- return (Session) delegate;
- }
- else
- {
- throw new NotHibernateException();
- }
+ return (Session) entityManager.getDelegate();
}
- /**
- * Occurs when Hibernate is in the classpath, but this particular
- * EntityManager is not from Hibernate
- *
- * @author Gavin King
- *
- */
- static class NotHibernateException extends IllegalArgumentException {}
+ public static HibernatePersistenceProvider instance()
+ {
+ return (HibernatePersistenceProvider) Component.getInstance(HibernatePersistenceProvider.class, STATELESS);
+ }
+
}
Added: trunk/src/main/org/jboss/seam/persistence/JpaPersistenceProvider.java
===================================================================
--- trunk/src/main/org/jboss/seam/persistence/JpaPersistenceProvider.java (rev 0)
+++ trunk/src/main/org/jboss/seam/persistence/JpaPersistenceProvider.java 2008-03-26 17:50:29 UTC (rev 7710)
@@ -0,0 +1,59 @@
+package org.jboss.seam.persistence;
+
+import static org.jboss.seam.ScopeType.STATELESS;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import javax.persistence.EntityManager;
+import javax.transaction.Synchronization;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+
+/**
+ * PersistenceProvider for any JPA implementation. Many methods are unusable
+ * or use naive implementations
+ *
+ * @author Gavin King
+ * @author Pete Muir
+ *
+ */
+ at Name("org.jboss.seam.persistence.jpaPersistenceProvider")
+ at Scope(STATELESS)
+ at BypassInterceptors
+ at Install(precedence=BUILT_IN, classDependencies="javax.persistence.EntityManager")
+public class JpaPersistenceProvider extends AbstractPersistenceProvider
+{
+
+ @Override
+ public void enableFilter(Filter filter, EntityManager entityManager)
+ {
+ throw new UnsupportedOperationException("You must use Hibernate to use Filters");
+ }
+
+ @Override
+ public boolean isDirty(EntityManager entityManager)
+ {
+ return true;
+ }
+
+ @Override
+ public boolean registerSynchronization(Synchronization sync, EntityManager entityManager)
+ {
+ return false;
+ }
+
+ @Override
+ public void setFlushModeManual(EntityManager entityManager)
+ {
+ throw new UnsupportedOperationException("You must use Hibernate to use Manual Flush Mode");
+ }
+
+ public static JpaPersistenceProvider instance()
+ {
+ return (JpaPersistenceProvider) Component.getInstance(JpaPersistenceProvider.class, STATELESS);
+ }
+
+}
Property changes on: trunk/src/main/org/jboss/seam/persistence/JpaPersistenceProvider.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/src/main/org/jboss/seam/persistence/PersistenceProvider.java
===================================================================
--- trunk/src/main/org/jboss/seam/persistence/PersistenceProvider.java 2008-03-26 15:27:37 UTC (rev 7709)
+++ trunk/src/main/org/jboss/seam/persistence/PersistenceProvider.java 2008-03-26 17:50:29 UTC (rev 7710)
@@ -1,11 +1,10 @@
package org.jboss.seam.persistence;
import static org.jboss.seam.annotations.Install.BUILT_IN;
+import static org.jboss.seam.util.Reflections.isInstanceOf;
import java.lang.reflect.Method;
-import java.util.Date;
import javax.persistence.EntityManager;
-import javax.persistence.OptimisticLockException;
import javax.transaction.Synchronization;
import org.jboss.seam.Component;
@@ -17,9 +16,8 @@
import org.jboss.seam.annotations.intercept.BypassInterceptors;
/**
* Abstraction layer for persistence providers (JPA implementations).
- * This class provides a working base implementation that can be
- * optimized for performance and non-standardized features by extending
- * and overriding the methods.
+ * This class delegates to either the generic JpaPersistenceProvider or a more
+ * specific one if available.
*
* The methods on this class are a great todo list for the next rev
* of the JPA spec ;-)
@@ -40,7 +38,7 @@
*/
public void setFlushModeManual(EntityManager entityManager)
{
- throw new UnsupportedOperationException("For use of FlushMode.MANUAL, please use Hibernate as the persistence provider or use a custom PersistenceProvider");
+ getPersistenceProvider(entityManager).setFlushModeManual(entityManager);
}
/**
* Does the persistence context have unflushed changes? If
@@ -51,7 +49,7 @@
*/
public boolean isDirty(EntityManager entityManager)
{
- return true; //best we can do!
+ return getPersistenceProvider(entityManager).isDirty(entityManager);
}
/**
@@ -61,7 +59,7 @@
*/
public Object getId(Object bean, EntityManager entityManager)
{
- return Entity.forClass( bean.getClass() ).getIdentifier(bean);
+ return getPersistenceProvider(entityManager).getId(bean, entityManager);
}
/**
@@ -74,7 +72,7 @@
*/
public String getName(Object bean, EntityManager entityManager) throws IllegalArgumentException
{
- return Entity.forClass(bean.getClass()).getName();
+ return getPersistenceProvider(entityManager).getName(bean, entityManager);
}
/**
@@ -84,24 +82,12 @@
*/
public Object getVersion(Object bean, EntityManager entityManager)
{
- return Entity.forClass( bean.getClass() ).getVersion(bean);
+ return getPersistenceProvider(entityManager).getVersion(bean, entityManager);
}
public void checkVersion(Object bean, EntityManager entityManager, Object oldVersion, Object version)
{
- boolean equal;
- if (oldVersion instanceof Date)
- {
- equal = ( (Date) oldVersion ).getTime() == ( (Date) version ).getTime();
- }
- else
- {
- equal = oldVersion.equals(version);
- }
- if ( !equal )
- {
- throw new OptimisticLockException("current database version number does not match passivated version number");
- }
+ getPersistenceProvider(entityManager).checkVersion(bean, entityManager, oldVersion, version);
}
/**
* Enable a Filter. This is here just especially for Hibernate,
@@ -110,7 +96,7 @@
*/
public void enableFilter(Filter filter, EntityManager entityManager)
{
- throw new UnsupportedOperationException("For filters, please use Hibernate as the persistence provider");
+ getPersistenceProvider(entityManager).enableFilter(filter, entityManager);
}
/**
@@ -118,7 +104,7 @@
*/
public boolean registerSynchronization(Synchronization sync, EntityManager entityManager)
{
- return false; //best we can do!
+ return getPersistenceProvider(entityManager).registerSynchronization(sync, entityManager);
}
public static PersistenceProvider instance()
@@ -129,15 +115,22 @@
/**
* Wrap the delegate before returning it to the application
*/
+ @Deprecated
public Object proxyDelegate(Object delegate)
{
- return delegate;
+ return getPersistenceProvider(delegate).proxyDelegate(delegate);
}
+
+ public Object proxyDelegate(EntityManager entityManager, Object delegate)
+ {
+ return getPersistenceProvider(entityManager).proxyDelegate(delegate);
+ }
+
/**
* Wrap the entityManager before returning it to the application
*/
public EntityManager proxyEntityManager(EntityManager entityManager) {
- return new EntityManagerProxy(entityManager);
+ return getPersistenceProvider(entityManager).proxyEntityManager(entityManager);
}
/**
@@ -146,29 +139,71 @@
* @param bean The entity bean instance
* @return The class of the entity bean
*/
+ @Deprecated
public Class getBeanClass(Object bean)
{
return Entity.forClass(bean.getClass()).getBeanClass();
}
+ public Class getBeanClass(EntityManager entityManager, Object bean)
+ {
+ return getPersistenceProvider(entityManager).getBeanClass(bean);
+ }
+
public Method getPostLoadMethod(Class beanClass, EntityManager entityManager)
{
- return Entity.forClass(beanClass).getPostLoadMethod();
+ return getPersistenceProvider(entityManager).getPostLoadMethod(beanClass, entityManager);
}
public Method getPrePersistMethod(Class beanClass, EntityManager entityManager)
{
- return Entity.forClass(beanClass).getPrePersistMethod();
+ return getPersistenceProvider(entityManager).getPrePersistMethod(beanClass, entityManager);
}
public Method getPreUpdateMethod(Class beanClass, EntityManager entityManager)
{
- return Entity.forClass(beanClass).getPreUpdateMethod();
+ return getPersistenceProvider(entityManager).getPreUpdateMethod(beanClass, entityManager);
}
public Method getPreRemoveMethod(Class beanClass, EntityManager entityManager)
{
- return Entity.forClass(beanClass).getPreRemoveMethod();
+ return getPersistenceProvider(entityManager).getPreRemoveMethod(beanClass, entityManager);
}
+ /**
+ * Do runtime detection of PersistenceProvider
+ */
+ private AbstractPersistenceProvider getPersistenceProvider(EntityManager entityManager)
+ {
+ // Work around EJBTHREE-912 (don't you just love random NPEs!)
+ if (isInstanceOf(entityManager.getClass(), "org.jboss.ejb3.entity.HibernateSession"))
+ {
+ return HibernatePersistenceProvider.instance();
+ }
+ else if(isInstanceOf(entityManager.getDelegate().getClass(), "org.hibernate.Session"))
+ {
+ return HibernatePersistenceProvider.instance();
+ }
+ else
+ {
+ return JpaPersistenceProvider.instance();
+ }
+ }
+
+ /**
+ * Do runtime detection of PersistenceProvider
+ */
+ @Deprecated
+ private AbstractPersistenceProvider getPersistenceProvider(Object delegate)
+ {
+ if (isInstanceOf(delegate.getClass(), "org.hibernate.Session"))
+ {
+ return HibernatePersistenceProvider.instance();
+ }
+ else
+ {
+ return JpaPersistenceProvider.instance();
+ }
+ }
+
}
Modified: trunk/src/main/org/jboss/seam/util/Reflections.java
===================================================================
--- trunk/src/main/org/jboss/seam/util/Reflections.java 2008-03-26 15:27:37 UTC (rev 7709)
+++ trunk/src/main/org/jboss/seam/util/Reflections.java 2008-03-26 17:50:29 UTC (rev 7710)
@@ -326,19 +326,31 @@
}
for (Class c = clazz; c != Object.class; c = c.getSuperclass())
{
- if (name.equals(c.getName()))
+ if (instanceOf(c, name))
{
return true;
}
}
- for (Class c : clazz.getInterfaces())
+ return false;
+ }
+
+ private static boolean instanceOf(Class clazz, String name)
+ {
+ if (name.equals(clazz.getName()))
{
- if (name.equals(c.getName()))
+ return true;
+ }
+ else
+ {
+ boolean found = false;
+ Class[] interfaces = clazz.getInterfaces();
+ for (int i = 0; i < interfaces.length && !found; i++)
{
- return true;
+ found = instanceOf(interfaces[i], name);
}
+ return found;
}
- return false;
+
}
}
More information about the seam-commits
mailing list