[seam-commits] Seam SVN: r7745 - in branches/Seam_2_0: src/main/org/jboss/seam and 5 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Sun Mar 30 19:37:16 EDT 2008


Author: pete.muir at jboss.org
Date: 2008-03-30 19:37:16 -0400 (Sun, 30 Mar 2008)
New Revision: 7745

Added:
   branches/Seam_2_0/src/main/org/jboss/seam/init/EjbEntityDescriptor.java
   branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateEntityPermissionChecker.java
Modified:
   branches/Seam_2_0/doc/Seam_Reference_Guide/en/Security.xml
   branches/Seam_2_0/src/main/org/jboss/seam/Entity.java
   branches/Seam_2_0/src/main/org/jboss/seam/Seam.java
   branches/Seam_2_0/src/main/org/jboss/seam/contexts/PassivatedEntity.java
   branches/Seam_2_0/src/main/org/jboss/seam/contexts/ServerConversationContext.java
   branches/Seam_2_0/src/main/org/jboss/seam/contexts/SessionContext.java
   branches/Seam_2_0/src/main/org/jboss/seam/init/DeploymentDescriptor.java
   branches/Seam_2_0/src/main/org/jboss/seam/persistence/HibernatePersistenceProvider.java
   branches/Seam_2_0/src/main/org/jboss/seam/persistence/ManagedEntityIdentityInterceptor.java
   branches/Seam_2_0/src/main/org/jboss/seam/persistence/PersistenceProvider.java
   branches/Seam_2_0/src/main/org/jboss/seam/security/EntityPermissionChecker.java
   branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateSecurityInterceptor.java
   branches/Seam_2_0/src/main/org/jboss/seam/security/Identity.java
   branches/Seam_2_0/src/main/org/jboss/seam/util/Reflections.java
Log:
JBSEAM-2029, reworked Entity meta model

Modified: branches/Seam_2_0/doc/Seam_Reference_Guide/en/Security.xml
===================================================================
--- branches/Seam_2_0/doc/Seam_Reference_Guide/en/Security.xml	2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/doc/Seam_Reference_Guide/en/Security.xml	2008-03-30 23:37:16 UTC (rev 7745)
@@ -1,3 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
 <chapter id="security">
   <title>Security</title>
 
@@ -931,6 +933,32 @@
   public void prePersist() {}
    ]]></programlisting>
 
+      <note>
+         <title>Using <literal>/META-INF/orm.xml</literal></title>
+         
+
+         <para>
+            You can also specify the call back method in <literal>/META-INF/orm.xml</literal>:
+         </para>
+
+         <programlisting role="XML"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
+                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
+                 version="1.0">
+
+   <entity class="Customer">
+      <pre-persist method-name="prePersist" />
+   </entity>
+
+</entity-mappings>]]></programlisting>
+
+         <para>
+            Of course, you still need to annotate the <literal>prePersist()</literal>
+            method on <literal>Customer</literal> with <literal>@Restrict</literal>
+         </para>
+      </note>
+
       <para>
         And here's an example of an entity permission rule that checks if the authenticated user is allowed to insert
         a new <literal>MemberBlog</literal> record (from the seamspace example).  The entity for which the security
@@ -990,10 +1018,11 @@
       </sect3>
 
       <sect3>
-        <title>Entity security with Hibernate</title>
+        <title>Entity security with a Managed Hibernate Session</title>
 
         <para>
-          If you are using a Hibernate <literal>SessionFactory</literal> configured via Seam, you don't
+          If you are using a Hibernate <literal>SessionFactory</literal> configured via Seam,
+          and are using annotations, or <literal>orm.xml</literal>, then you don't
           need to do anything special to use entity security.
         </para>
 

Modified: branches/Seam_2_0/src/main/org/jboss/seam/Entity.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/Entity.java	2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/Entity.java	2008-03-30 23:37:16 UTC (rev 7745)
@@ -1,5 +1,6 @@
 package org.jboss.seam;
 
+import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 
@@ -12,20 +13,24 @@
 import javax.persistence.Version;
 
 import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.init.EjbDescriptor;
+import org.jboss.seam.init.EjbEntityDescriptor;
+import org.jboss.seam.persistence.PersistenceProvider;
 import org.jboss.seam.util.Reflections;
 
 /**
  * Metamodel class for entity classes.
  * 
- * A class will be identified as an entity class
- * if it has an @Entity annotation.
+ * A class will be identified as an entity class if it has an
  * 
+ * @Entity annotation.
+ * 
  * @author Gavin King
- *
+ * 
  */
 public class Entity extends Model
 {
-   
+
    private Method preRemoveMethod;
    private Method prePersistMethod;
    private Method preUpdateMethod;
@@ -36,85 +41,22 @@
    private Field versionField;
    private String name;
 
+   /**
+    * 
+    * @param beanClass
+    */
    public Entity(Class<?> beanClass)
    {
       super(beanClass);
-      
-      if (beanClass.isAnnotationPresent(javax.persistence.Entity.class))
+      EjbDescriptor descriptor = Seam.getEjbDescriptor(beanClass);
+      if (descriptor instanceof EjbEntityDescriptor)
       {
-         if (!"".equals(beanClass.getAnnotation(javax.persistence.Entity.class).name()))
-         {
-            name = beanClass.getAnnotation(javax.persistence.Entity.class).name();
-         }
-         else
-         {
-            name = beanClass.getName();
-         }
+         mergeAnnotationAndOrmXml((EjbEntityDescriptor) descriptor);
       }
-      
-      for ( Class<?> clazz=beanClass; clazz!=Object.class; clazz = clazz.getSuperclass() )
+      else
       {
-
-         for ( Method method: clazz.getDeclaredMethods() )
-         {
-            //TODO: does the spec allow multiple lifecycle method
-            //      in the entity class heirarchy?
-            if ( method.isAnnotationPresent(PreRemove.class) )
-            {
-               preRemoveMethod = method;
-            }
-            if ( method.isAnnotationPresent(PrePersist.class) )
-            {
-               prePersistMethod = method;
-            }
-            if ( method.isAnnotationPresent(PreUpdate.class) )
-            {
-               preUpdateMethod = method;
-            }
-            if ( method.isAnnotationPresent(PostLoad.class) )
-            {
-               postLoadMethod = method;
-            }
-            if ( method.isAnnotationPresent(Id.class) || method.isAnnotationPresent(EmbeddedId.class))
-            {
-               identifierGetter = method;
-            }
-            if ( method.isAnnotationPresent(Version.class) )
-            {
-               versionGetter = method;
-            }
-            
-            if ( !method.isAccessible() )
-            {
-               method.setAccessible(true);
-            }
-         }
-         
-         if (identifierGetter==null)
-         {
-            for ( Field field: clazz.getDeclaredFields() )
-            {
-               if ( field.isAnnotationPresent(Id.class) || field.isAnnotationPresent(EmbeddedId.class))
-               {
-                  identifierField = field;
-                  if ( !field.isAccessible() )
-                  {
-                     field.setAccessible(true);
-                  }
-               }
-               if ( field.isAnnotationPresent(Version.class) )
-               {
-                  versionField = field;
-                  if ( !field.isAccessible() )
-                  {
-                     field.setAccessible(true);
-                  }
-               }
-            }
-         }
-         
+         mergeAnnotationAndOrmXml(null);
       }
-      
    }
 
    public Method getPostLoadMethod()
@@ -137,33 +79,37 @@
       return preUpdateMethod;
    }
 
+   @Deprecated
    public Field getIdentifierField()
    {
       return identifierField;
    }
 
+   @Deprecated
    public Method getIdentifierGetter()
    {
       return identifierGetter;
    }
-   
+
+   @Deprecated
    public Field getVersionField()
    {
       return versionField;
    }
 
+   @Deprecated
    public Method getVersionGetter()
    {
       return versionGetter;
    }
-   
+
    public Object getIdentifier(Object entity)
    {
-      if (identifierGetter!=null)
+      if (identifierGetter != null)
       {
          return Reflections.invokeAndWrap(identifierGetter, entity);
       }
-      else if (identifierField!=null)
+      else if (identifierField != null)
       {
          return Reflections.getAndWrap(identifierField, entity);
       }
@@ -175,11 +121,11 @@
 
    public Object getVersion(Object entity)
    {
-      if (versionGetter!=null)
+      if (versionGetter != null)
       {
          return Reflections.invokeAndWrap(versionGetter, entity);
       }
-      else if (versionField!=null)
+      else if (versionField != null)
       {
          return Reflections.getAndWrap(versionField, entity);
       }
@@ -188,31 +134,35 @@
          return null;
       }
    }
-   
+
    public String getName()
    {
       return name;
    }
 
-   public static Entity forClass(Class clazz)
+   public static Entity forBean(Object bean)
    {
-      if ( !Contexts.isApplicationContextActive() )
+      if (!Contexts.isApplicationContextActive())
       {
          throw new IllegalStateException("No application context active");
       }
       
-      Class entityClass = Seam.getEntityClass(clazz);
+      Class beanClass = PersistenceProvider.instance().getBeanClass(bean);
       
-      if (entityClass==null)
+      if (beanClass == null)
       {
-         throw new IllegalArgumentException("Not an entity class: " + clazz.getName());
+         throw new NotEntityException("Not an entity class: " + bean.getClass().getName());
       }
-      
-      String name = getModelName(entityClass);
+      return forBeanClass(beanClass);
+   }
+   
+   private static Entity forBeanClass(Class beanClass)
+   {
+      String name = getModelName(beanClass);
       Model model = (Model) Contexts.getApplicationContext().get(name);
-      if ( model==null || !(model instanceof Entity) )
+      if (model == null || !(model instanceof Entity))
       {
-         Entity entity = new Entity(entityClass);
+         Entity entity = new Entity(beanClass);
          Contexts.getApplicationContext().set(name, entity);
          return entity;
       }
@@ -221,5 +171,171 @@
          return (Entity) model;
       }
    }
+   
+   @Deprecated
+   public static Entity forClass(Class clazz)
+   {
+      if (!Contexts.isApplicationContextActive())
+      {
+         throw new IllegalStateException("No application context active");
+      }
 
+      Class entityClass = PersistenceProvider.getEntityClass(clazz);
+      
+      if (entityClass == null)
+      {
+         throw new NotEntityException("Not an entity class: " + clazz.getName());
+      }
+      return forBeanClass(entityClass);
+   }
+
+   private void mergeAnnotationAndOrmXml(EjbEntityDescriptor descriptor)
+   {
+      // Lookup the name of the Entity from XML, annotation or default
+      this.name = lookupName(getBeanClass(), descriptor);
+      if (this.name == null)
+      {
+         throw new NotEntityException("Unable to establish name of entity " + getBeanClass());
+      }
+      
+      if (descriptor != null)
+      {
+         // Set any methods and fields we need metadata for from the XML
+         // descriptor. These take priority over annotations
+         
+         this.preRemoveMethod = getEntityCallbackMethod(getBeanClass(), descriptor.getPreRemoveMethodName());
+         this.prePersistMethod = getEntityCallbackMethod(getBeanClass(), descriptor.getPrePersistMethodName());
+         this.preUpdateMethod = getEntityCallbackMethod(getBeanClass(), descriptor.getPreUpdateMethodName());
+         this.postLoadMethod = getEntityCallbackMethod(getBeanClass(), descriptor.getPostLoadMethodName());
+         
+         this.identifierField = descriptor.getIdentifierFieldName() != null ? Reflections.getField(getBeanClass(), descriptor.getIdentifierFieldName()) : null;
+         this.identifierGetter = descriptor.getIdentifierPropertyName() != null ? Reflections.getGetterMethod(getBeanClass(), descriptor.getIdentifierPropertyName()) : null;
+         
+         this.versionField = descriptor.getVersionFieldName() != null ? Reflections.getField(getBeanClass(), descriptor.getVersionFieldName()) : null;
+         this.versionGetter = descriptor.getVersionPropertyName() != null ? Reflections.getGetterMethod(getBeanClass(), descriptor.getVersionPropertyName()) : null;
+      }
+      
+      if (descriptor == null || !descriptor.isMetaDataComplete())
+      {
+         for ( Class<?> clazz=getBeanClass(); clazz!=Object.class; clazz = clazz.getSuperclass() )
+         {
+
+            for ( Method method: clazz.getDeclaredMethods() )
+            {
+               //TODO: does the spec allow multiple lifecycle method
+               //      in the entity class heirarchy?
+               if (this.preRemoveMethod == null && method.isAnnotationPresent(PreRemove.class))
+               {
+                  this.preRemoveMethod = method;
+               }
+               if (this.prePersistMethod == null && method.isAnnotationPresent(PrePersist.class) )
+               {
+                  this.prePersistMethod = method;
+               }
+               if (preUpdateMethod == null && method.isAnnotationPresent(PreUpdate.class) )
+               {
+                  preUpdateMethod = method;
+               }
+               if (postLoadMethod == null && method.isAnnotationPresent(PostLoad.class) )
+               {
+                  postLoadMethod = method;
+               }
+               if (identifierField == null && identifierGetter == null && method.isAnnotationPresent(Id.class) || method.isAnnotationPresent(EmbeddedId.class))
+               {
+                  identifierGetter = method;
+               }
+               if (versionField == null && versionGetter == null && method.isAnnotationPresent(Version.class) )
+               {
+                  versionGetter = method;
+               }
+            }
+            
+            if ( ( identifierGetter == null && identifierField == null ) || ( versionField == null && versionGetter == null ) )
+            {
+               for ( Field field: clazz.getDeclaredFields() )
+               {
+                  if ( identifierGetter == null && identifierField == null && (field.isAnnotationPresent(Id.class) || field.isAnnotationPresent(EmbeddedId.class)))
+                  {
+                     identifierField = field;
+                  }
+                  if ( versionGetter == null && versionField == null && field.isAnnotationPresent(Version.class) )
+                  {
+                     versionField = field;
+                  }
+               }
+            }
+         }
+      }
+      
+      setAccessible(this.preRemoveMethod);
+      setAccessible(this.prePersistMethod);
+      setAccessible(this.preUpdateMethod);
+      setAccessible(this.postLoadMethod);
+      setAccessible(this.identifierField);
+      setAccessible(this.identifierGetter);
+      setAccessible(this.versionField);
+      setAccessible(this.versionGetter);
+   }
+   
+   private void setAccessible(AccessibleObject accessibleObject)
+   {
+      if (accessibleObject != null)
+      {
+         accessibleObject.setAccessible(true);
+      }
+   }
+
+   private static String lookupName(Class<?> beanClass, EjbEntityDescriptor descriptor)
+   {
+      if (descriptor != null && descriptor.getEjbName() != null)
+      {
+         // XML overrides annotations
+         return descriptor.getEjbName();
+      }
+      else if ( (descriptor == null || !descriptor.isMetaDataComplete()) && beanClass.isAnnotationPresent(javax.persistence.Entity.class) && !"".equals(beanClass.getAnnotation(javax.persistence.Entity.class).name()))
+      {
+         // Is a name specified?
+         return beanClass.getAnnotation(javax.persistence.Entity.class).name();
+      }
+      else if (descriptor != null || beanClass.isAnnotationPresent(javax.persistence.Entity.class))
+      {
+         // Use the default name if either a descriptor is specified or the
+         // annotation is present
+         return beanClass.getName();
+      }
+      else
+      {
+         return null;
+      }
+   }
+
+   private static Method getEntityCallbackMethod(Class beanClass, String callbackMethodName)
+   {
+      try
+      {
+         if (callbackMethodName != null)
+         {
+            return Reflections.getMethod(beanClass, callbackMethodName);
+         }
+         else
+         {
+            return null;
+         }
+      }
+      catch (IllegalArgumentException e)
+      {
+         throw new IllegalArgumentException("Unable to find Entity callback method specified in orm.xml", e);
+      }
+   }
+   
+   public static class NotEntityException extends IllegalArgumentException 
+   {
+      
+      public NotEntityException(String string)
+      {
+         super(string);
+      }
+      
+   }
+
 }

Modified: branches/Seam_2_0/src/main/org/jboss/seam/Seam.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/Seam.java	2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/Seam.java	2008-03-30 23:37:16 UTC (rev 7745)
@@ -24,6 +24,7 @@
 import org.jboss.seam.contexts.Lifecycle;
 import org.jboss.seam.init.EjbDescriptor;
 import org.jboss.seam.init.DeploymentDescriptor;
+import org.jboss.seam.persistence.PersistenceProvider;
 import org.jboss.seam.util.Strings;
 import org.jboss.seam.web.Session;
 
@@ -37,22 +38,28 @@
 {
     
    private static final Map<Class, String> COMPONENT_NAME_CACHE = new ConcurrentHashMap<Class, String>();
-   private static final Map<Class, EjbDescriptor> EJB_DESCRIPTOR_CACHE = new ConcurrentHashMap<Class, EjbDescriptor>();
+   private static final Map<String, EjbDescriptor> EJB_DESCRIPTOR_CACHE = new ConcurrentHashMap<String, EjbDescriptor>();
 
-   private static EjbDescriptor getEjbDescriptor(Class clazz)
+   public static EjbDescriptor getEjbDescriptor(String className)
    {
-      EjbDescriptor info = EJB_DESCRIPTOR_CACHE.get(clazz);
+      EjbDescriptor info = EJB_DESCRIPTOR_CACHE.get(className);
       if (info != null) 
       {
           return info;
       }
       else
       {
-         Map<Class, EjbDescriptor> ejbDescriptors = new DeploymentDescriptor(clazz).getEjbDescriptors();
+         Map<String, EjbDescriptor> ejbDescriptors = new DeploymentDescriptor().getEjbDescriptors();
          EJB_DESCRIPTOR_CACHE.putAll(ejbDescriptors);
-         return ejbDescriptors.get(clazz);
+         return ejbDescriptors.get(className);
       }
    }
+   
+   // TODO Better impl
+   static EjbDescriptor getEjbDescriptor(Class clazz)
+   {
+      return getEjbDescriptor(clazz.getName());
+   }
   
    /**
     * Get the default scope
@@ -143,36 +150,20 @@
    /**
     * Get the bean class from a container-generated proxy
     * class
+    * 
+    * Use PersistenceProvider.instance().getBeanClass(bean) instead
     */
+   @Deprecated
    public static Class getEntityClass(Class<?> clazz)
    {
-      while ( clazz!=null && !Object.class.equals(clazz) )
-      {
-         if ( clazz.isAnnotationPresent(Entity.class) )
-         {
-            return clazz;
-         }
-         else 
-         {
-            EjbDescriptor ejbDescriptor = EJB_DESCRIPTOR_CACHE.get(clazz);
-            if ( ejbDescriptor!=null ) 
-            {
-               return ejbDescriptor.getBeanType()==ComponentType.ENTITY_BEAN ?
-                        clazz : null;
-            }
-            else
-            {
-               clazz = clazz.getSuperclass();
-            }
-         }
-      }
-      return null;
-   }
+      return PersistenceProvider.getEntityClass(clazz);
+   } 
    
    /**
     * Is the class a container-generated proxy class for an 
     * entity bean?
     */
+   @Deprecated
    public static boolean isEntityClass(Class<?> clazz)
    {
       return getEntityClass(clazz)!=null;

Modified: branches/Seam_2_0/src/main/org/jboss/seam/contexts/PassivatedEntity.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/contexts/PassivatedEntity.java	2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/contexts/PassivatedEntity.java	2008-03-30 23:37:16 UTC (rev 7745)
@@ -6,7 +6,6 @@
 
 import org.hibernate.Session;
 import org.jboss.seam.Component;
-import org.jboss.seam.Seam;
 import org.jboss.seam.persistence.HibernatePersistenceProvider;
 import org.jboss.seam.persistence.PersistenceContexts;
 import org.jboss.seam.persistence.PersistenceProvider;
@@ -152,7 +151,7 @@
 
    public static PassivatedEntity passivateEntity(Object value)
    {
-      Class entityClass = Seam.getEntityClass( value.getClass() );
+      Class entityClass = PersistenceProvider.getEntityClass(value.getClass());
       if (entityClass!=null)
       {
          for ( String persistenceContextName: PersistenceContexts.instance().getTouchedContexts() )

Modified: branches/Seam_2_0/src/main/org/jboss/seam/contexts/ServerConversationContext.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/contexts/ServerConversationContext.java	2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/contexts/ServerConversationContext.java	2008-03-30 23:37:16 UTC (rev 7745)
@@ -15,9 +15,9 @@
 
 import org.jboss.seam.Component;
 import org.jboss.seam.ScopeType;
-import org.jboss.seam.Seam;
 import org.jboss.seam.core.Events;
 import org.jboss.seam.core.Manager;
+import org.jboss.seam.persistence.PersistenceProvider;
 
 /**
  * A conversation context is a logical context that lasts longer than 
@@ -155,7 +155,7 @@
       else
       {
          removals.remove(name);
-         if ( Seam.isEntityClass( value.getClass() ) )
+         if ( PersistenceProvider.getEntityClass(value.getClass()) != null )
          {
             value = new EntityBean(value);
          }

Modified: branches/Seam_2_0/src/main/org/jboss/seam/contexts/SessionContext.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/contexts/SessionContext.java	2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/contexts/SessionContext.java	2008-03-30 23:37:16 UTC (rev 7745)
@@ -10,7 +10,7 @@
 import java.util.Map;
 
 import org.jboss.seam.ScopeType;
-import org.jboss.seam.Seam;
+import org.jboss.seam.persistence.PersistenceProvider;
 
 /**
  * Session context - state associated with a user session.
@@ -48,7 +48,7 @@
       {
          Object attribute = get(name);
          boolean dirty = attribute!=null && 
-               ( Contexts.isAttributeDirty(attribute) || Seam.isEntityClass( attribute.getClass() ) );
+               ( Contexts.isAttributeDirty(attribute) || PersistenceProvider.getEntityClass(attribute.getClass()) != null );
          if ( dirty )
          {
             set(name, attribute);

Modified: branches/Seam_2_0/src/main/org/jboss/seam/init/DeploymentDescriptor.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/init/DeploymentDescriptor.java	2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/init/DeploymentDescriptor.java	2008-03-30 23:37:16 UTC (rev 7745)
@@ -10,6 +10,7 @@
 import org.jboss.seam.ComponentType;
 import org.jboss.seam.log.LogProvider;
 import org.jboss.seam.log.Logging;
+import org.jboss.seam.util.Resources;
 import org.jboss.seam.util.XML;
 
 /**
@@ -22,19 +23,13 @@
 { 
     private static final LogProvider log = Logging.getLogProvider(Initialization.class);
     
-    private Map<Class, EjbDescriptor> ejbDescriptors = new HashMap<Class, EjbDescriptor>();
-    private Class componentClass;
+    private Map<String, EjbDescriptor> ejbDescriptors = new HashMap<String, EjbDescriptor>();
 
-    public DeploymentDescriptor(Class clazz) 
+    public DeploymentDescriptor() 
     {
-        componentClass = clazz;
-        if (clazz.getClassLoader() == null) {
-            return;
-        }
-
         try 
         {
-            InputStream ejbJarXml = clazz.getClassLoader().getResourceAsStream("META-INF/ejb-jar.xml");
+            InputStream ejbJarXml = Resources.getResourceAsStream("META-INF/ejb-jar.xml", null);
             if (ejbJarXml!=null)
             {
                parseEjbJarXml( XML.getRootElementSafely(ejbJarXml) );
@@ -47,7 +42,7 @@
 
         try 
         {
-            InputStream ormXml = clazz.getClassLoader().getResourceAsStream("META-INF/orm.xml");
+            InputStream ormXml = Resources.getResourceAsStream("META-INF/orm.xml", null);
             if (ormXml!=null)
             {
                parseOrmXml( XML.getRootElementSafely(ormXml) );
@@ -59,7 +54,7 @@
         }
     }
     
-    public Map<Class, EjbDescriptor> getEjbDescriptors()
+    public Map<String, EjbDescriptor> getEjbDescriptors()
     {
        return ejbDescriptors;
     }
@@ -113,27 +108,95 @@
         {
             packagePrefix = pkg.getTextTrim() + ".";
         }
+        
+        String defaultAccessType = getDefaultAccessType(root);
+        
+        boolean defaultMetadataComplete = isDefaultMetadataComplete(root);
                 
         for (Element entity: (List<Element>) root.elements("entity")) 
         {
             String className = packagePrefix + entity.attribute("class").getText();
-            EjbDescriptor info = new EjbDescriptor();
+            EjbEntityDescriptor info = new EjbEntityDescriptor();
             info.setBeanType(ComponentType.ENTITY_BEAN);
             info.setEjbClassName(className);
+            info.setEjbName(entity.attribute("name") != null ? entity.attribute("name").getText() : null);
+            if (defaultMetadataComplete || entity.attribute("metadata-complete") != null)
+            {
+               info.setMetaDataComplete(defaultMetadataComplete || "true".equals(entity.attribute("metadata-complete").getText()));
+            }
+            info.setPreRemoveMethodName(getEntityCallback(entity, "pre-remove"));
+            info.setPrePersistMethodName(getEntityCallback(entity, "pre-persist"));
+            info.setPreUpdateMethodName(getEntityCallback(entity, "pre-update"));
+            info.setPostLoadMethodName(getEntityCallback(entity, "post-load"));
+            info.setIdentifierAttribute(getEntityAttributeName(entity, "id"), getAccessType(getEntityAttributeAccessType(entity, "id"), defaultAccessType));
+            info.setVersionAttribute(getEntityAttributeName(entity, "version"), getAccessType(getEntityAttributeAccessType(entity, "version"), defaultAccessType));
             add(info);
         }
     }
-
-    protected void add(EjbDescriptor descriptor) 
+    
+    private static String getEntityCallback(Element parent, String callbackName)
     {
-       try
+       Element callbackElement = parent.element(callbackName);
+       if (callbackElement != null)
        {
-          Class ejbClass = componentClass.getClassLoader().loadClass( descriptor.getEjbClassName() );
-          ejbDescriptors.put(ejbClass, descriptor);
+          return callbackElement.attribute("method-name").getText();
        }
-       catch (ClassNotFoundException cnfe)
+       return null;
+    }
+    
+    private static String getEntityAttributeName(Element entity, String attributeName)
+    {
+       if (entity.element("attributes") != null && entity.element("attributes").element(attributeName) != null)
        {
-          log.warn("Could not load EJB class: " + descriptor.getEjbClassName());
+          return entity.element("attributes").element(attributeName).attribute("name").getText(); 
        }
+       
+       return null;
+       
     }
+    
+    private static String getEntityAttributeAccessType(Element entity, String attributeName)
+    {
+       if (entity.element("attributes") != null && entity.element("attributes").element(attributeName) != null)
+       {
+          if (entity.element("attributes").element(attributeName).attribute("access") != null)
+          {
+             return entity.element("attributes").element(attributeName).attribute("access").getText();
+          }
+       }
+       
+       return null;
+    }
+    
+    private static String getDefaultAccessType(Element root)
+    {
+       if (root.element("access") != null)
+       {
+          return root.element("access").getText();
+       }
+       else
+       {
+          if (root.element("persistence-unit-metadata") != null && root.element("persistence-unit-metadata").element("persistence-unit-defaults") != null && root.element("persistence-unit-metadata").element("persistence-unit-defaults").element("access") != null )
+          {
+             return root.element("persistence-unit-metadata").element("persistence-unit-defaults").element("access").getText();
+          }
+       }
+       return null;
+    }
+    
+    private static boolean isDefaultMetadataComplete(Element root)
+    {
+       return root.element("persistence-unit-metadata") != null && root.element("persistence-unit-metadata").element("xml-mapping-metadata-complete") != null;
+    }
+    
+    
+    private static String getAccessType(String accessType, String defaultAccessType)
+    {
+       return accessType != null ? accessType : (defaultAccessType != null ? defaultAccessType : "FIELD");
+    }
+
+    protected void add(EjbDescriptor descriptor) 
+    {
+       ejbDescriptors.put(descriptor.getEjbClassName(), descriptor);
+    }
 }

Added: branches/Seam_2_0/src/main/org/jboss/seam/init/EjbEntityDescriptor.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/init/EjbEntityDescriptor.java	                        (rev 0)
+++ branches/Seam_2_0/src/main/org/jboss/seam/init/EjbEntityDescriptor.java	2008-03-30 23:37:16 UTC (rev 7745)
@@ -0,0 +1,138 @@
+package org.jboss.seam.init;
+
+public class EjbEntityDescriptor extends EjbDescriptor
+{
+   
+   private boolean metaDataComplete;
+
+   private String preRemoveMethodName;
+   private String prePersistMethodName;
+   private String preUpdateMethodName;
+   private String postLoadMethodName;
+   private String identifierPropertyName;
+   private String identifierFieldName;
+   private String versionPropertyName;
+   private String versionFieldName;
+   
+
+   public String getPreRemoveMethodName()
+   {
+      return preRemoveMethodName;
+   }
+
+   public void setPreRemoveMethodName(String preRemoveMethodName)
+   {
+      this.preRemoveMethodName = preRemoveMethodName;
+   }
+
+   public String getPrePersistMethodName()
+   {
+      return prePersistMethodName;
+   }
+
+   public void setPrePersistMethodName(String prePersistMethodName)
+   {
+      this.prePersistMethodName = prePersistMethodName;
+   }
+
+   public String getPreUpdateMethodName()
+   {
+      return preUpdateMethodName;
+   }
+
+   public void setPreUpdateMethodName(String preUpdateMethodName)
+   {
+      this.preUpdateMethodName = preUpdateMethodName;
+   }
+
+   public String getPostLoadMethodName()
+   {
+      return postLoadMethodName;
+   }
+
+   public void setPostLoadMethodName(String postLoadMethodName)
+   {
+      this.postLoadMethodName = postLoadMethodName;
+   }
+
+   public String getIdentifierPropertyName()
+   {
+      return identifierPropertyName;
+   }
+
+   public void setIdentifierPropertyName(String identifierProperty)
+   {
+      this.identifierPropertyName = identifierProperty;
+   }
+
+   public String getVersionPropertyName()
+   {
+      return versionPropertyName;
+   }
+
+   public void setVersionPropertyName(String versionProperty)
+   {
+      this.versionPropertyName = versionProperty;
+   }
+
+   public String getIdentifierFieldName()
+   {
+      return identifierFieldName;
+   }
+
+   public void setIdentifierFieldName(String identifierField)
+   {
+      this.identifierFieldName = identifierField;
+   }
+
+   public String getVersionFieldName()
+   {
+      return versionFieldName;
+   }
+
+   public void setVersionFieldName(String versionField)
+   {
+      this.versionFieldName = versionField;
+   }
+   
+   public void setVersionAttribute(String versionAttributeName, String accessType)
+   {
+      if (accessType != null)
+      {
+         if (accessType == "PROPERTY")
+         {
+            this.versionPropertyName = versionAttributeName;
+         }
+         else if (accessType == "FIELD")
+         {
+            this.versionFieldName = versionAttributeName;
+         }
+      }
+   }
+   
+   public void setIdentifierAttribute(String identifierAttributeName, String accessType)
+   {
+      if (accessType != null)
+      {
+         if (accessType == "PROPERTY")
+         {
+            this.identifierPropertyName = identifierAttributeName;
+         }
+         else if (accessType == "FIELD")
+         {
+            this.identifierFieldName = identifierAttributeName;
+         }
+      }
+   }
+   
+   public boolean isMetaDataComplete()
+   {
+      return metaDataComplete;
+   }
+   
+   public void setMetaDataComplete(boolean metaDataComplete)
+   {
+      this.metaDataComplete = metaDataComplete;
+   }
+
+}


Property changes on: branches/Seam_2_0/src/main/org/jboss/seam/init/EjbEntityDescriptor.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: branches/Seam_2_0/src/main/org/jboss/seam/persistence/HibernatePersistenceProvider.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/persistence/HibernatePersistenceProvider.java	2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/persistence/HibernatePersistenceProvider.java	2008-03-30 23:37:16 UTC (rev 7745)
@@ -4,7 +4,6 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
-import java.util.HashMap;
 import java.util.Map;
 
 import javax.persistence.EntityManager;
@@ -16,15 +15,10 @@
 import org.hibernate.Session;
 import org.hibernate.StaleStateException;
 import org.hibernate.TransientObjectException;
-import org.hibernate.ejb.event.Callback;
-import org.hibernate.ejb.event.EJB3PostLoadEventListener;
-import org.hibernate.ejb.event.EntityCallbackHandler;
-import org.hibernate.engine.SessionImplementor;
-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;
 import org.jboss.seam.annotations.Name;
 import org.jboss.seam.annotations.Scope;
@@ -296,7 +290,7 @@
    
    private static ClassMetadata getClassMetadata(Object value, Session session)
    {
-      Class entityClass = Seam.getEntityClass( value.getClass() );
+      Class entityClass = getEntityClass(value);
       ClassMetadata classMetadata = null;
       if (entityClass!=null)
       {
@@ -318,135 +312,19 @@
    @Override
    public Class getBeanClass(Object bean)
    {
-      try
-      {
-         return super.getBeanClass(bean);
-      }
-      catch (IllegalArgumentException iae)
-      {
-         return Hibernate.getClass(bean);
-      }
+      return getEntityClass(bean);
    }
    
-   /**
-    * A nasty hack until we get a nicer method in Hibernate to use instead
-    * 
-    * TODO fix this once Hibernate exposes an API method to return the callback method/s for a
-    * given bean class
-    * 
-    * @param entityManager
-    * @return
-    */
-   private EntityCallbackHandler getCallbackHandler(Session session)
+   public static Class getEntityClass(Object bean)
    {
-      PostLoadEventListener[] listeners = ((SessionImplementor) session)
-      .getListeners().getPostLoadEventListeners();
-   
-      for (PostLoadEventListener listener : listeners)
+      Class clazz = PersistenceProvider.getEntityClass(bean.getClass());
+      if (clazz == null)
       {
-         if (listener instanceof EJB3PostLoadEventListener)
-         {
-            try
-            {
-               Field callbackHandlerField = EJB3PostLoadEventListener.class.getField("callbackHandler");
-               return (EntityCallbackHandler) callbackHandlerField.get(listener);
-            }
-            catch (Exception ex)
-            {
-               throw new RuntimeException(ex);
-            }
-         }
-      }   
-      return null;
-   }
-   
-   /**
-    * More nastiness
-    * 
-    * @param handler
-    * @param fieldName
-    * @return
-    */
-   private Callback[] getCallbacks(EntityCallbackHandler handler, String fieldName, Class beanClass)
-   {
-      try
-      {
-         Field f = EntityCallbackHandler.class.getDeclaredField(fieldName);
-         boolean isAccessible = f.isAccessible();
-         try
-         {
-            f.setAccessible(true);
-            HashMap<Class,Callback[]> callbacks = (HashMap<Class,Callback[]>) f.get(handler);
-            return callbacks.get(beanClass);
-         }
-         finally
-         {
-            f.setAccessible(isAccessible);
-         }
+         clazz = Hibernate.getClass(bean);
       }
-      catch (Exception ex)
-      {
-         throw new RuntimeException(ex);
-      }
+      return clazz;
    }
    
-   private Method getCallbackMethod(Object persistenceContext, Class beanClass, String callbackFieldName)
-   {
-      EntityCallbackHandler callbackHandler = null;
-      
-      if (persistenceContext instanceof EntityManager)
-      {
-         callbackHandler = getCallbackHandler(getSession((EntityManager) persistenceContext));
-      }
-      else if (persistenceContext instanceof Session)
-      {
-         callbackHandler = getCallbackHandler((Session) persistenceContext);
-      }
-      
-      if (callbackHandler == null)
-      {
-         throw new RuntimeException("Could not determine callback handler for persistence context " +
-               persistenceContext);         
-      }
-      
-      Callback[] callbacks = getCallbacks(callbackHandler, callbackFieldName, beanClass);
-      
-      if (callbacks != null)
-      {
-         for (Callback cb : callbacks)
-         {
-            return cb.getCallbackMethod();
-         }
-      }
-         
-      return null;      
-   }
-   
-   /*@Override
-   public Method getPostLoadMethod(Class beanClass, Object persistenceContext)
-   {
-      return getCallbackMethod(persistenceContext, beanClass, "postLoads");
-   }
-   
-   
-   @Override
-   public Method getPrePersistMethod(Class beanClass, Object persistenceContext)
-   {
-      return getCallbackMethod(persistenceContext, beanClass, "preCreates");
-   }
-   
-   @Override
-   public Method getPreUpdateMethod(Class beanClass, Object persistenceContext)
-   {
-      return getCallbackMethod(persistenceContext, beanClass, "preUpdates");
-   }
-   
-   @Override
-   public Method getPreRemoveMethod(Class beanClass, Object persistenceContext)
-   {
-      return getCallbackMethod(persistenceContext, beanClass, "preRemoves");
-   }*/
-   
    private Session getSession(EntityManager entityManager)
    {
       Object delegate = entityManager.getDelegate();
@@ -468,4 +346,9 @@
     *
     */
    static class NotHibernateException extends IllegalArgumentException {}
+   
+   public static HibernatePersistenceProvider instance()
+   {
+       return (HibernatePersistenceProvider) Component.getInstance(HibernatePersistenceProvider.class, ScopeType.STATELESS);
+   }
 }

Modified: branches/Seam_2_0/src/main/org/jboss/seam/persistence/ManagedEntityIdentityInterceptor.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/persistence/ManagedEntityIdentityInterceptor.java	2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/persistence/ManagedEntityIdentityInterceptor.java	2008-03-30 23:37:16 UTC (rev 7745)
@@ -10,7 +10,6 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.jboss.seam.Seam;
 import org.jboss.seam.annotations.In;
 import org.jboss.seam.annotations.intercept.AroundInvoke;
 import org.jboss.seam.annotations.intercept.Interceptor;
@@ -140,7 +139,7 @@
       return value instanceof List || 
             value instanceof Map || 
             value instanceof Set || 
-            Seam.isEntityClass( value.getClass() );
+            PersistenceProvider.getEntityClass(value.getClass()) != null;
    }
 
    private Object getFieldValue(Object bean, Field field) throws Exception

Modified: branches/Seam_2_0/src/main/org/jboss/seam/persistence/PersistenceProvider.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/persistence/PersistenceProvider.java	2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/persistence/PersistenceProvider.java	2008-03-30 23:37:16 UTC (rev 7745)
@@ -9,12 +9,15 @@
 import javax.transaction.Synchronization;
 
 import org.jboss.seam.Component;
+import org.jboss.seam.ComponentType;
 import org.jboss.seam.Entity;
 import org.jboss.seam.ScopeType;
+import org.jboss.seam.Seam;
 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;
+import org.jboss.seam.init.EjbDescriptor;
 /**
  * Abstraction layer for persistence providers (JPA implementations).
  * This class provides a working base implementation that can be
@@ -61,7 +64,7 @@
     */
    public Object getId(Object bean, EntityManager entityManager)
    {
-      return Entity.forClass( bean.getClass() ).getIdentifier(bean);
+      return Entity.forBean( bean ).getIdentifier(bean);
    }
    
    /**
@@ -74,7 +77,7 @@
     */
    public String getName(Object bean, EntityManager entityManager) throws IllegalArgumentException
    {
-      return Entity.forClass(bean.getClass()).getName();
+      return Entity.forBean( bean ).getName();
    }
    
    /**
@@ -84,7 +87,7 @@
     */
    public Object getVersion(Object bean, EntityManager entityManager)
    {
-      return Entity.forClass( bean.getClass() ).getVersion(bean);
+      return Entity.forBean( bean ).getVersion(bean);
    }
    
    public void checkVersion(Object bean, EntityManager entityManager, Object oldVersion, Object version)
@@ -148,29 +151,53 @@
     */
    public Class getBeanClass(Object bean)
    {
-      return Entity.forClass(bean.getClass()).getBeanClass();
+      return getEntityClass(bean.getClass());
    }
    
-   public Method getPostLoadMethod(Class beanClass, EntityManager entityManager)
+   public static Class getEntityClass(Class clazz)
    {
-      return Entity.forClass(beanClass).getPostLoadMethod();      
+      while (clazz != null && !Object.class.equals(clazz))
+      {
+         if (clazz.isAnnotationPresent(Entity.class))
+         {
+            return clazz;
+         }
+         else
+         {
+            EjbDescriptor ejbDescriptor = Seam.getEjbDescriptor(clazz.getName());
+            if (ejbDescriptor != null)
+            {
+               return ejbDescriptor.getBeanType() == ComponentType.ENTITY_BEAN ? clazz : null;
+            }
+            else
+            {
+               clazz = clazz.getSuperclass();
+            }
+         }
+      }
+      return null;
    }
    
-   public Method getPrePersistMethod(Class beanClass, EntityManager entityManager)
+   public Method getPostLoadMethod(Object bean, EntityManager entityManager)
    {
-      return Entity.forClass(beanClass).getPrePersistMethod();
+      return Entity.forBean(bean).getPostLoadMethod();
    }
    
-   public Method getPreUpdateMethod(Class beanClass, EntityManager entityManager)
+   public Method getPrePersistMethod(Object bean, EntityManager entityManager)
    {
-      return Entity.forClass(beanClass).getPreUpdateMethod();
+      return Entity.forBean(bean).getPrePersistMethod();
    }
    
-   public Method getPreRemoveMethod(Class beanClass, EntityManager entityManager)
+   public Method getPreUpdateMethod(Object bean, EntityManager entityManager)
    {
-      return Entity.forClass(beanClass).getPreRemoveMethod();
+      return Entity.forBean(bean).getPreUpdateMethod();
    }
    
+   public Method getPreRemoveMethod(Object bean, EntityManager entityManager)
+   {
+      return Entity.forBean(bean).getPreRemoveMethod();
+   }
+   
    @Deprecated
    public Method getPreRemoveMethod(Class beanClass)
    {

Modified: branches/Seam_2_0/src/main/org/jboss/seam/security/EntityPermissionChecker.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/security/EntityPermissionChecker.java	2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/security/EntityPermissionChecker.java	2008-03-30 23:37:16 UTC (rev 7745)
@@ -1,6 +1,6 @@
 package org.jboss.seam.security;
 
-import static org.jboss.seam.ScopeType.APPLICATION;
+import static org.jboss.seam.ScopeType.STATELESS;
 import static org.jboss.seam.annotations.Install.BUILT_IN;
 
 import java.lang.reflect.Method;
@@ -8,15 +8,12 @@
 import javax.persistence.EntityManager;
 
 import org.jboss.seam.Component;
-import org.jboss.seam.ScopeType;
 import org.jboss.seam.Seam;
 import org.jboss.seam.annotations.Install;
 import org.jboss.seam.annotations.Name;
 import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.Startup;
 import org.jboss.seam.annotations.intercept.BypassInterceptors;
 import org.jboss.seam.annotations.security.Restrict;
-import org.jboss.seam.contexts.Contexts;
 import org.jboss.seam.persistence.PersistenceProvider;
 import org.jboss.seam.util.Strings;
 
@@ -24,83 +21,68 @@
  * Entity permission checks
  * 
  * @author Shane Bryzak
+ * @author Pete Muir
  */
 @Name("org.jboss.seam.security.entityPermissionChecker")
- at Scope(APPLICATION)
- at Install(precedence = BUILT_IN)
+ at Scope(STATELESS)
+ at Install(precedence = BUILT_IN, classDependencies={"javax.persistence.EntityManager"})
 @BypassInterceptors
- at Startup
 public class EntityPermissionChecker
 {
-   private String entityManagerName = "entityManager";
-   
-   private EntityManager getEntityManager()
+
+   public static EntityPermissionChecker instance()
    {
-      return (EntityManager) Component.getInstance(entityManagerName);
+      return (EntityPermissionChecker) Component.getInstance(EntityPermissionChecker.class, STATELESS);
    }
    
-   public String getEntityManagerName()
+   protected Method getProtectedMethod(EntityAction action, Object bean, EntityManager entityManager)
    {
-      return entityManagerName;
+      if (bean != null)
+      {
+         switch (action)
+         {
+         case READ:
+            return PersistenceProvider.instance().getPostLoadMethod(bean, entityManager);
+            
+         case INSERT:
+            return PersistenceProvider.instance().getPrePersistMethod(bean, entityManager);
+            
+         case UPDATE:
+            return PersistenceProvider.instance().getPreUpdateMethod(bean, entityManager);
+            
+         case DELETE:
+            return PersistenceProvider.instance().getPreRemoveMethod(bean, entityManager);
+         }
+
+      }
+      return null;
    }
    
-   public void setEntityManagerName(String name)
+   public void checkEntityPermission(Object entity, EntityAction action)
    {
-      this.entityManagerName = name;
-   } 
+      checkEntityPermission(entity, action, getProtectedMethod(action, entity, null));
+   }
    
-   public static EntityPermissionChecker instance()
+   public void checkEntityPermission(Object entity, EntityAction action, EntityManager entityManager)
    {
-      if ( !Contexts.isApplicationContextActive() )
-      {
-         throw new IllegalStateException("No active application context");
-      }
-
-      EntityPermissionChecker instance = (EntityPermissionChecker) Component.getInstance(
-            EntityPermissionChecker.class, ScopeType.APPLICATION);
-
-      if (instance == null)
-      {
-         throw new IllegalStateException("No EntityPermissionChecker could be created");
-      }
-
-      return instance;      
+      checkEntityPermission(entity, action, getProtectedMethod(action, entity, entityManager));
    }
    
-   public void checkEntityPermission(Object entity, EntityAction action)
-   {      
-      if (!Identity.isSecurityEnabled()) return;
-      
-      Identity identity = Identity.instance();
-      
-      identity.isLoggedIn(true);
-      
-      PersistenceProvider provider = PersistenceProvider.instance(); 
-      Class beanClass = provider.getBeanClass(entity);
-      
-      if (beanClass != null)
+   protected void checkEntityPermission(Object entity, EntityAction action, Method m)
+   {
+      if (entity != null)
       {
-         String name = Seam.getComponentName(entity.getClass());
-         if (name == null) name = beanClass.getName();  
+         if (!Identity.isSecurityEnabled())
+            return;
+   
+         Identity identity = Identity.instance();
+   
+         identity.isLoggedIn(true);
          
-         Method m = null;
-         switch (action)
-         {
-            case READ:
-               m = provider.getPostLoadMethod(beanClass, getEntityManager());
-               break;
-            case INSERT:
-               m = provider.getPrePersistMethod(beanClass, getEntityManager());
-               break;
-            case UPDATE:
-               m = provider.getPreUpdateMethod(beanClass, getEntityManager());
-               break;
-            case DELETE:
-               m = provider.getPreRemoveMethod(beanClass, getEntityManager());
-         }
+         Class beanClass = PersistenceProvider.instance().getBeanClass(entity);
          
          Restrict restrict = null;
-         
+   
          if (m != null && m.isAnnotationPresent(Restrict.class))
          {
             restrict = m.getAnnotation(Restrict.class);
@@ -109,18 +91,24 @@
          {
             restrict = entity.getClass().getAnnotation(Restrict.class);
          }
-
+   
          if (restrict != null)
          {
             if (Strings.isEmpty(restrict.value()))
             {
-               identity.checkPermission(name, action.toString(), entity);
+               String name = Seam.getComponentName(beanClass);
+               if (name == null)
+               {
+                  name = beanClass.getName();
+               }
+               Identity.instance().checkPermission(name, action.toString(), entity);
             }
             else
             {
-               identity.checkRestriction(restrict.value());
+               Identity.instance().checkRestriction(restrict.value());
             }
          }
       }
-   }  
-}
\ No newline at end of file
+   }
+   
+}

Added: branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateEntityPermissionChecker.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateEntityPermissionChecker.java	                        (rev 0)
+++ branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateEntityPermissionChecker.java	2008-03-30 23:37:16 UTC (rev 7745)
@@ -0,0 +1,23 @@
+package org.jboss.seam.security;
+
+import static org.jboss.seam.ScopeType.STATELESS;
+import static org.jboss.seam.annotations.Install.FRAMEWORK;
+
+import java.lang.reflect.Method;
+
+import javax.persistence.EntityManager;
+
+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;
+
+
+ at Name("org.jboss.seam.security.entityPermissionChecker")
+ at Scope(STATELESS)
+ at Install(precedence = FRAMEWORK, classDependencies={"org.hibernate.Session", "javax.persistence.EntityManager"})
+ at BypassInterceptors
+public class HibernateEntityPermissionChecker extends EntityPermissionChecker
+{
+   
+}


Property changes on: branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateEntityPermissionChecker.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateSecurityInterceptor.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateSecurityInterceptor.java	2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateSecurityInterceptor.java	2008-03-30 23:37:16 UTC (rev 7745)
@@ -10,6 +10,7 @@
 import org.hibernate.EmptyInterceptor;
 import org.hibernate.Interceptor;
 import org.hibernate.type.Type;
+import org.jboss.seam.Entity.NotEntityException;
 
 /**
  * Facilitates security checks for Hibernate entities
@@ -30,7 +31,14 @@
    public boolean onLoad(Object entity, Serializable id, Object[] state,
                       String[] propertyNames, Type[] types)
    {
-      EntityPermissionChecker.instance().checkEntityPermission(entity, READ);
+      try
+      {
+         EntityPermissionChecker.instance().checkEntityPermission(entity, READ);
+      }
+      catch (NotEntityException e) 
+      {
+         // Not a JPA entity
+      }
       
       return wrappedInterceptor != null ? 
                wrappedInterceptor.onLoad(entity, id, state, propertyNames, types) : 
@@ -41,7 +49,14 @@
    public void onDelete(Object entity, Serializable id, Object[] state, 
                         String[] propertyNames, Type[] types)
    {
-      EntityPermissionChecker.instance().checkEntityPermission(entity, DELETE);
+      try
+      {
+         EntityPermissionChecker.instance().checkEntityPermission(entity, DELETE);
+      }
+      catch (NotEntityException e) 
+      {
+         // Not a JPA entity
+      }
       
       if (wrappedInterceptor != null)
          wrappedInterceptor.onDelete(entity, id, state, propertyNames, types);
@@ -51,7 +66,14 @@
    public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState,
                    Object[] previousState, String[] propertyNames, Type[] types)
    {
-      EntityPermissionChecker.instance().checkEntityPermission(entity, UPDATE);
+      try
+      {
+         EntityPermissionChecker.instance().checkEntityPermission(entity, UPDATE);
+      }
+      catch (NotEntityException e) 
+      {
+         // Not a JPA entity
+      }
       
       return wrappedInterceptor != null ? 
                wrappedInterceptor.onFlushDirty(entity, id, currentState, 
@@ -62,7 +84,14 @@
    public boolean onSave(Object entity, Serializable id, Object[] state,
                       String[] propertyNames, Type[] types)
    {
-      EntityPermissionChecker.instance().checkEntityPermission(entity, INSERT);
+      try
+      {
+         EntityPermissionChecker.instance().checkEntityPermission(entity, INSERT);
+      }
+      catch (NotEntityException e) 
+      {
+         // Not a JPA entity
+      }
       
       return wrappedInterceptor != null ? 
                wrappedInterceptor.onSave(entity, id, state, propertyNames, types) : 

Modified: branches/Seam_2_0/src/main/org/jboss/seam/security/Identity.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/security/Identity.java	2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/security/Identity.java	2008-03-30 23:37:16 UTC (rev 7745)
@@ -622,4 +622,9 @@
          subject = savedSubject;
       }
    } 
+   
+   public void checkEntityPermission(Object entity, EntityAction action)
+   {
+      EntityPermissionChecker.instance().checkEntityPermission(entity, action);
+   }
 }

Modified: branches/Seam_2_0/src/main/org/jboss/seam/util/Reflections.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/util/Reflections.java	2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/util/Reflections.java	2008-03-30 23:37:16 UTC (rev 7745)
@@ -283,9 +283,24 @@
       throw new IllegalArgumentException("no such field: " + clazz.getName() + '.' + name);
    }
    
+   public static Method getMethod(Class clazz, String name)
+   {
+      for ( Class superClass = clazz; superClass!=Object.class; superClass=superClass.getSuperclass() )
+      {
+         try
+         {
+            return superClass.getDeclaredMethod(name);
+         }
+         catch (NoSuchMethodException nsme) {}
+      }
+      throw new IllegalArgumentException("no such method: " + clazz.getName() + '.' + name);
+   }
+   
    /**
     * Get all the fields which are annotated with the given annotation. Returns an empty list
     * if none are found
+    * 
+    * This method is slow
     */
    public static List<Field> getFields(Class clazz, Class annotation)
    {
@@ -302,7 +317,7 @@
       }
       return fields;
    }
-
+   
    public static Method getMethod(Annotation annotation, String name)
    {
       try




More information about the seam-commits mailing list