You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2006/11/02 08:22:13 UTC

svn commit: r470257 - in /incubator/openejb/trunk/openejb3/container: openejb-core/ openejb-core/src/main/java/org/apache/openejb/alt/config/ openejb-jee/src/main/java/org/apache/openejb/jee/

Author: dblevins
Date: Wed Nov  1 23:22:11 2006
New Revision: 470257

URL: http://svn.apache.org/viewvc?view=rev&rev=470257
Log:
Support for several EJB 3.0  annotations

OPENEJB-221: javax.annotation.PostConstruct
OPENEJB-222: javax.annotation.PreDestroy
OPENEJB-235: javax.ejb.Local
OPENEJB-236: javax.ejb.LocalHome
OPENEJB-238: javax.ejb.PostActivate
OPENEJB-239: javax.ejb.PrePassivate
OPENEJB-240: javax.ejb.Remote
OPENEJB-241: javax.ejb.RemoteHome
OPENEJB-243: javax.ejb.Stateful
OPENEJB-244: javax.ejb.Stateless
OPENEJB-246: javax.ejb.TransactionAttribute
OPENEJB-247: javax.ejb.TransactionManagement

Partial support for 

OPENEJB-237 javax.ejb.MessageDriven

Added:
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/config/AnnotationDeployer.java
    incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/MethodTransaction.java
Modified:
    incubator/openejb/trunk/openejb3/container/openejb-core/pom.xml
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/config/DeploymentLoader.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/config/EjbJarInfoBuilder.java
    incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/AroundInvoke.java
    incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/AssemblyDescriptor.java
    incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/ContainerTransaction.java
    incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/EnterpriseBean.java
    incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/EntityBean.java
    incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/MessageDrivenBean.java
    incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/Method.java
    incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/SessionBean.java

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/pom.xml
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/pom.xml?view=diff&rev=470257&r1=470256&r2=470257
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/pom.xml (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/pom.xml Wed Nov  1 23:22:11 2006
@@ -17,7 +17,7 @@
 
 -->
 
-<!-- $Rev$ $Date$ -->
+        <!-- $Rev$ $Date$ -->
 
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
@@ -64,7 +64,7 @@
             <configuration>
               <tasks>
                 <tstamp>
-                  <format property="TSTAMP" pattern="hh:mm" />
+                  <format property="TSTAMP" pattern="hh:mm"/>
                 </tstamp>
                 <replace file="target/classes/openejb-version.properties"
                          token="@DATE-REPLACED-BY-MAVEN@" value="${DSTAMP}"/>
@@ -85,7 +85,8 @@
               <!--<addClasspath>true</addClasspath>-->
             </manifest>
             <manifestEntries>
-              <Class-Path>openejb-loader-${pom.version}.jar xbean-finder-${removePropertyFromCorePomXbeanVersion}.jar</Class-Path>
+              <Class-Path>openejb-loader-${pom.version}.jar
+                xbean-finder-${removePropertyFromCorePomXbeanVersion}.jar</Class-Path>
             </manifestEntries>
           </archive>
         </configuration>
@@ -103,7 +104,8 @@
         </executions>
         <configuration>
           <namespace>http://openejb.apache.org/schemas/core</namespace>
-          <excludedClasses>org.apache.openejb.alt.config.ejb,org.apache.openejb.util.io,org.apache.openejb.InterfaceType,org.apache.openejb.BeanType</excludedClasses>
+          <excludedClasses>
+            org.apache.openejb.alt.config.ejb,org.apache.openejb.util.io,org.apache.openejb.InterfaceType,org.apache.openejb.BeanType</excludedClasses>
         </configuration>
       </plugin>
     </plugins>
@@ -170,6 +172,16 @@
     <dependency>
       <groupId>org.apache.xbean</groupId>
       <artifactId>xbean-finder</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>asm</groupId>
+      <artifactId>asm</artifactId>
+      <version>2.2.3</version>
+    </dependency>
+    <dependency>
+      <groupId>asm</groupId>
+      <artifactId>asm-commons</artifactId>
+      <version>2.2.3</version>
     </dependency>
     <dependency>
       <groupId>geronimo</groupId>

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/config/AnnotationDeployer.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/config/AnnotationDeployer.java?view=auto&rev=470257
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/config/AnnotationDeployer.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/config/AnnotationDeployer.java Wed Nov  1 23:22:11 2006
@@ -0,0 +1,377 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.alt.config;
+
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.jee.AroundInvoke;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.EnterpriseBean;
+import org.apache.openejb.jee.LifecycleCallback;
+import org.apache.openejb.jee.RemoteBean;
+import org.apache.openejb.jee.SessionBean;
+import org.apache.openejb.jee.StatefulBean;
+import org.apache.openejb.jee.StatelessBean;
+import org.apache.openejb.jee.TransactionType;
+import org.apache.openejb.jee.AssemblyDescriptor;
+import org.apache.openejb.jee.TransAttribute;
+import org.apache.openejb.jee.MethodTransaction;
+import org.apache.openejb.jee.ContainerTransaction;
+import org.apache.openejb.jee.MethodParams;
+import org.apache.openejb.jee.MessageDrivenBean;
+import org.apache.openejb.util.Logger;
+import org.apache.xbean.finder.ClassFinder;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.ejb.Local;
+import javax.ejb.LocalHome;
+import javax.ejb.PostActivate;
+import javax.ejb.PrePassivate;
+import javax.ejb.Remote;
+import javax.ejb.RemoteHome;
+import javax.ejb.Stateful;
+import javax.ejb.Stateless;
+import javax.ejb.TransactionAttribute;
+import javax.ejb.TransactionManagement;
+import javax.ejb.TransactionManagementType;
+import javax.ejb.TransactionAttributeType;
+import javax.ejb.MessageDriven;
+import java.io.File;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class AnnotationDeployer implements DynamicDeployer {
+
+    public static final Logger logger = Logger.getInstance("OpenEJB.startup", AnnotationDeployer.class.getPackage().getName());
+    private final DynamicDeployer deployer;
+    private final DiscoverBeansInClassLoader discoverBeansInClassLoader;
+    private final ProcessAnnotatedBeans processAnnotatedBeans;
+
+    public AnnotationDeployer(DynamicDeployer deployer) {
+        this.deployer = deployer;
+
+        discoverBeansInClassLoader = new DiscoverBeansInClassLoader();
+        processAnnotatedBeans = new ProcessAnnotatedBeans();
+    }
+
+    public EjbModule deploy(EjbModule ejbModule) throws OpenEJBException {
+        ejbModule = discoverBeansInClassLoader.deploy(ejbModule);
+        ejbModule = deployer.deploy(ejbModule);
+        ejbModule = processAnnotatedBeans.deploy(ejbModule);
+        return ejbModule;
+    }
+
+    public static class DiscoverBeansInClassLoader implements DynamicDeployer {
+
+        public EjbModule deploy(EjbModule ejbModule) throws OpenEJBException {
+            ClassFinder finder;
+            if (ejbModule.getJarURI() != null) {
+                try {
+                    String location = ejbModule.getJarURI();
+                    File file = new File(location);
+
+                    URL url;
+                    if (file.exists()) {
+                        url = file.toURL();
+                    } else {
+                        url = new URL(location);
+                    }
+                    finder = new ClassFinder(ejbModule.getClassLoader(), url);
+                } catch (MalformedURLException e) {
+                    DeploymentLoader.logger.warning("Unable to scrape for @Stateful, @Stateless or @MessageDriven annotations.  EjbModule URL not valid: " + ejbModule.getJarURI(), e);
+                    return ejbModule;
+                }
+            } else {
+                try {
+                    finder = new ClassFinder(ejbModule.getClassLoader());
+                } catch (Exception e) {
+                    DeploymentLoader.logger.warning("Unable to scrape for @Stateful, @Stateless or @MessageDriven annotations.  ClassFinder failed.", e);
+                    return ejbModule;
+                }
+            }
+
+            EjbJar ejbJar = ejbModule.getEjbJar();
+
+            List<Class> classes = finder.findAnnotatedClasses(Stateless.class);
+            for (Class beanClass : classes) {
+                Stateless stateless = (Stateless) beanClass.getAnnotation(Stateless.class);
+                String ejbName = stateless.name().length() == 0 ? beanClass.getSimpleName() : stateless.name();
+                if (ejbJar.getEnterpriseBean(ejbName) == null) {
+                    ejbJar.addEnterpriseBean(new StatelessBean(ejbName, beanClass.getName()));
+                }
+            }
+
+            classes = finder.findAnnotatedClasses(Stateful.class);
+            for (Class beanClass : classes) {
+                Stateful stateless = (Stateful) beanClass.getAnnotation(Stateful.class);
+                String ejbName = stateless.name().length() == 0 ? beanClass.getName() : stateless.name();
+                if (ejbJar.getEnterpriseBean(ejbName) == null) {
+                    ejbJar.addEnterpriseBean(new StatefulBean(ejbName, beanClass.getName()));
+                }
+            }
+
+            classes = finder.findAnnotatedClasses(MessageDriven.class);
+            for (Class beanClass : classes) {
+                MessageDriven mdb = (MessageDriven) beanClass.getAnnotation(MessageDriven.class);
+                String ejbName = mdb.name().length() == 0 ? beanClass.getName() : mdb.name();
+                if (ejbJar.getEnterpriseBean(ejbName) == null) {
+                    MessageDrivenBean messageBean = new MessageDrivenBean(ejbName);
+                    Class interfce = mdb.messageListenerInterface();
+                    if (interfce != null){
+                        messageBean.setMessagingType(interfce.getName());
+                    }
+                    ejbJar.addEnterpriseBean(messageBean);
+                }
+            }
+
+            return ejbModule;
+        }
+    }
+
+    public static class ProcessAnnotatedBeans implements DynamicDeployer {
+        public EjbModule deploy(EjbModule ejbModule) throws OpenEJBException {
+
+            ClassLoader classLoader = ejbModule.getClassLoader();
+            EnterpriseBean[] enterpriseBeans = ejbModule.getEjbJar().getEnterpriseBeans();
+            for (EnterpriseBean bean : enterpriseBeans) {
+                final String ejbName = bean.getEjbName();
+
+                Class clazz = null;
+                try {
+                    clazz = classLoader.loadClass(bean.getEjbClass());
+                } catch (ClassNotFoundException e) {
+                    throw new OpenEJBException("Unable to load bean class: " + bean.getEjbClass());
+                }
+                ClassFinder classFinder = new ClassFinder(clazz);
+
+                if (bean.getTransactionType() == null) {
+                    TransactionManagement tx = (TransactionManagement) clazz.getAnnotation(TransactionManagement.class);
+                    TransactionManagementType transactionType = tx.value();
+                    switch(transactionType){
+                        case BEAN: bean.setTransactionType(TransactionType.BEAN); break;
+                        case CONTAINER: bean.setTransactionType(TransactionType.CONTAINER); break;
+                    }
+                }
+
+                AssemblyDescriptor assemblyDescriptor = ejbModule.getEjbJar().getAssemblyDescriptor();
+                if (assemblyDescriptor == null){
+                    assemblyDescriptor = new AssemblyDescriptor();
+                    ejbModule.getEjbJar().setAssemblyDescriptor(assemblyDescriptor);
+                }
+
+                if (bean.getTransactionType() == TransactionType.CONTAINER){
+                    Map<String, List<MethodTransaction>> methodTransactions = assemblyDescriptor.getMethodTransactions(ejbName);
+
+                    // SET THE DEFAULT
+                    if (!methodTransactions.containsKey("*")){
+                        TransactionAttribute attribute = (TransactionAttribute) clazz.getAnnotation(TransactionAttribute.class);
+                        if (attribute != null){
+                            ContainerTransaction ctx = new ContainerTransaction(cast(attribute.value()), ejbName, "*");
+                            assemblyDescriptor.getContainerTransaction().add(ctx);
+                        }
+                    }
+
+                    List<Method> methods = classFinder.findAnnotatedMethods(TransactionAttribute.class);
+                    for (Method method : methods) {
+                        TransactionAttribute attribute = method.getAnnotation(TransactionAttribute.class);
+                        if (!methodTransactions.containsKey(method.getName())){
+                            // no method with this name in descriptor
+                            addContainerTransaction(attribute, ejbName, method, assemblyDescriptor);
+                        } else {
+                            // method name already declared
+                            List<MethodTransaction> list = methodTransactions.get(method.getName());
+                            for (MethodTransaction mtx : list) {
+                                MethodParams methodParams = mtx.getMethodParams();
+                                if (methodParams == null){
+                                    // params not specified, so this is more specific
+                                    addContainerTransaction(attribute, ejbName, method, assemblyDescriptor);
+                                } else {
+                                    List<String> params1 = methodParams.getMethodParam();
+                                    String[] params2 = asStrings(method.getParameterTypes());
+                                    if (params1.size() != params2.length) {
+                                        // params not the same
+                                        addContainerTransaction(attribute, ejbName, method, assemblyDescriptor);
+                                    } else {
+                                        for (int i = 0; i < params1.size(); i++) {
+                                            String a = params1.get(i);
+                                            String b = params2[i];
+                                            if (!a.equals(b)){
+                                                // params not the same
+                                                addContainerTransaction(attribute, ejbName, method, assemblyDescriptor);
+                                                break;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                LifecycleCallback postConstruct = getFirst(bean.getPostConstruct());
+                if (postConstruct == null) {
+                    Method method = getFirst(classFinder.findAnnotatedMethods(PostConstruct.class));
+                    if (method != null) bean.addPostConstruct(method.getName());
+                }
+
+                LifecycleCallback preDestroy = getFirst(bean.getPreDestroy());
+                if (preDestroy == null) {
+                    Method method = getFirst(classFinder.findAnnotatedMethods(PreDestroy.class));
+                    if (method != null) bean.addPreDestroy(method.getName());
+                }
+
+                AroundInvoke aroundInvoke = getFirst(bean.getAroundInvoke());
+                if (aroundInvoke == null) {
+                    Method method = getFirst(classFinder.findAnnotatedMethods(javax.interceptor.AroundInvoke.class));
+                    if (method != null) bean.addAroundInvoke(method.getName());
+                }
+
+                if (bean instanceof org.apache.openejb.jee.SessionBean) {
+                    org.apache.openejb.jee.SessionBean sessionBean = (org.apache.openejb.jee.SessionBean) bean;
+
+                    LifecycleCallback postActivate = getFirst(sessionBean.getPostActivate());
+                    if (postActivate == null) {
+                        Method method = getFirst(classFinder.findAnnotatedMethods(PostActivate.class));
+                        if (method != null) sessionBean.addPostActivate(method.getName());
+                    }
+
+                    LifecycleCallback prePassivate = getFirst(sessionBean.getPrePassivate());
+                    if (prePassivate == null) {
+                        Method method = getFirst(classFinder.findAnnotatedMethods(PrePassivate.class));
+                        if (method != null) sessionBean.addPrePassivate(method.getName());
+                    }
+                }
+
+                if (bean instanceof RemoteBean) {
+                    RemoteBean remoteBean = (RemoteBean) bean;
+
+                    if (remoteBean.getHome() == null) {
+                        RemoteHome remoteHome = (RemoteHome) clazz.getAnnotation(RemoteHome.class);
+                        if (remoteHome != null) {
+                            Class homeClass = remoteHome.value();
+                            try {
+                                Method create = homeClass.getMethod("create");
+                                Class remoteClass = create.getReturnType();
+                                remoteBean.setHome(homeClass.getName());
+                                remoteBean.setRemote(remoteClass.getName());
+                            } catch (NoSuchMethodException e) {
+                                logger.error("Class annotated as a RemoteHome has no 'create()' method.  Unable to determine remote interface type.  Bean class: " + clazz.getName() + ",  Home class: " + homeClass.getName());
+                            }
+                        }
+                    }
+
+                    if (remoteBean.getLocalHome() == null) {
+                        LocalHome localHome = (LocalHome) clazz.getAnnotation(LocalHome.class);
+                        if (localHome != null) {
+                            Class homeClass = localHome.value();
+                            try {
+                                Method create = homeClass.getMethod("create");
+                                Class remoteClass = create.getReturnType();
+                                remoteBean.setHome(homeClass.getName());
+                                remoteBean.setRemote(remoteClass.getName());
+                            } catch (NoSuchMethodException e) {
+                                logger.error("Class annotated as a LocalHome has no 'create()' method.  Unable to determine remote interface type.  Bean class: " + clazz.getName() + ",  Home class: " + homeClass.getName());
+                            }
+                        }
+                    }
+
+                    if (remoteBean instanceof SessionBean) {
+                        SessionBean sessionBean = (SessionBean) remoteBean;
+
+                        List<Class> interfaces = new ArrayList();
+                        interfaces.addAll(Arrays.asList(clazz.getInterfaces()));
+
+                        // Remove anything not eligable to be a remote or local interface
+                        for (Class interfce : copy(interfaces)) {
+                            String name = interfce.getName();
+                            if (name.equals("java.io.Serializable") || name.equals("java.io.Externalizable") || name.startsWith("javax.ejb.")) {
+                                interfaces.remove(interfce);
+                            }
+                        }
+
+                        Remote remote = (Remote) clazz.getAnnotation(Remote.class);
+                        if (remote != null) {
+                            for (Class interfce : remote.value()) {
+                                sessionBean.setBusinessRemote(interfce.getName()); // TODO: This should be turned back into an array
+                            }
+                        } else {
+//                            for (Class interfce : copy(interfaces)) {
+//                                if (interfce.isAnnotationPresent(Remote.class)) {
+//                                    sessionBean.setBusinessRemote(interfce.getName()); // TODO: This should be turned back into an array
+//                                    interfaces.remove(interfce);
+//                                }
+//                            }
+                        }
+
+
+                        Local local = (Local) clazz.getAnnotation(Local.class);
+                        if (local != null) {
+                            for (Class interfce : local.value()) {
+                                sessionBean.setBusinessLocal(interfce.getName()); // TODO: This should be turned back into an array
+                            }
+                        } else {
+//                            for (Class interfce : copy(interfaces)) {
+//                                sessionBean.setBusinessLocal(interfce.getName()); // TODO: This should be turned back into an array
+//                            }
+                        }
+                    }
+                }
+
+
+            }
+            return ejbModule;
+        }
+
+        private List<Class> copy(List<Class> classes) {
+            return new ArrayList(classes);
+        }
+
+        private void addContainerTransaction(TransactionAttribute attribute, String ejbName, Method method, AssemblyDescriptor assemblyDescriptor) {
+            ContainerTransaction ctx = new ContainerTransaction(cast(attribute.value()), ejbName, method.getName(), asStrings(method.getParameterTypes()));
+            assemblyDescriptor.getContainerTransaction().add(ctx);
+        }
+
+        private String[] asStrings(Class[] types) {
+            List<String> names = new ArrayList();
+            for (Class clazz : types) {
+                names.add(clazz.getName());
+            }
+            return names.toArray(new String[]{});
+        }
+
+        private TransAttribute cast(TransactionAttributeType transactionAttributeType) {
+            return TransAttribute.valueOf(transactionAttributeType.toString());
+        }
+
+        private <T> T getFirst(List<T> list) {
+            if (list.size() > 0) {
+                return list.get(0);
+            }
+            return null;
+        }
+    }
+
+
+}

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/config/DeploymentLoader.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/config/DeploymentLoader.java?view=diff&rev=470257&r1=470256&r2=470257
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/config/DeploymentLoader.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/config/DeploymentLoader.java Wed Nov  1 23:22:11 2006
@@ -22,7 +22,10 @@
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.OpenEJB;
+import org.apache.openejb.util.Logger;
+import org.apache.xbean.finder.ClassFinder;
 
+import javax.ejb.Stateless;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Enumeration;
@@ -38,6 +41,8 @@
  */
 public class DeploymentLoader {
 
+    public static final Logger logger = Logger.getInstance("OpenEJB.startup", DeploymentLoader.class.getPackage().getName());
+
     public DeploymentLoader(){
 
     }
@@ -121,7 +126,6 @@
         return loadDeploymentsList(list, null);
     }
 
-
     public List<EjbModule> loadDeploymentsList(List<Deployments> deployments, DynamicDeployer deployer) throws OpenEJBException {
         if (deployer == null){
             deployer = new DynamicDeployer(){
@@ -131,6 +135,8 @@
             };
         }
 
+        deployer = new AnnotationDeployer(deployer);
+        
         if (!SystemInstance.get().getProperty("openejb.validation.skip", "false").equalsIgnoreCase("true")){
             deployer = new ValidateEjbModule(deployer);
         }

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/config/EjbJarInfoBuilder.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/config/EjbJarInfoBuilder.java?view=diff&rev=470257&r1=470256&r2=470257
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/config/EjbJarInfoBuilder.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/alt/config/EjbJarInfoBuilder.java Wed Nov  1 23:22:11 2006
@@ -56,6 +56,7 @@
 import org.apache.openejb.jee.SessionBean;
 import org.apache.openejb.jee.SessionType;
 import org.apache.openejb.jee.LifecycleCallback;
+import org.apache.openejb.jee.TransactionType;
 import org.apache.openejb.loader.SystemInstance;
 
 import java.io.File;
@@ -396,7 +397,8 @@
         bean.local = s.getLocal();
         bean.businessLocal = s.getBusinessLocal();
         bean.businessRemote = s.getBusinessRemote();
-        bean.transactionType = s.getTransactionType().toString();
+        TransactionType txType = s.getTransactionType();
+        bean.transactionType = (txType != null)?txType.toString(): TransactionType.CONTAINER.toString();
 
         return bean;
     }

Modified: incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/AroundInvoke.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/AroundInvoke.java?view=diff&rev=470257&r1=470256&r2=470257
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/AroundInvoke.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/AroundInvoke.java Wed Nov  1 23:22:11 2006
@@ -49,6 +49,14 @@
     @XmlElement(name = "method-name", required = true)
     protected String methodName;
 
+    public AroundInvoke() {
+    }
+
+    public AroundInvoke(String clazz, String methodName) {
+        this.clazz = clazz;
+        this.methodName = methodName;
+    }
+
     public String getClazz() {
         return clazz;
     }

Modified: incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/AssemblyDescriptor.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/AssemblyDescriptor.java?view=diff&rev=470257&r1=470256&r2=470257
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/AssemblyDescriptor.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/AssemblyDescriptor.java Wed Nov  1 23:22:11 2006
@@ -24,10 +24,13 @@
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlID;
 import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.LinkedHashMap;
 
 
 /**
@@ -99,6 +102,25 @@
             containerTransaction = new ArrayList<ContainerTransaction>();
         }
         return this.containerTransaction;
+    }
+
+    public Map<String,List<MethodTransaction>> getMethodTransactions(String ejbName) {
+        Map<String,List<MethodTransaction>> methods = new LinkedHashMap();
+        for (ContainerTransaction transaction : getContainerTransaction()) {
+
+            for (Method method : transaction.getMethod()) {
+                if (method.getEjbName().equals(ejbName)){
+                    String methodName = method.getMethodName();
+                    List<MethodTransaction> list = methods.get(methodName);
+                    if (list == null){
+                        list = new ArrayList();
+                        methods.put(methodName, list);
+                    }
+                    list.add(new MethodTransaction(transaction.getTransAttribute(), method));
+                }
+            }
+        }
+        return methods;
     }
 
     public List<InterceptorBinding> getInterceptorBinding() {

Modified: incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/ContainerTransaction.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/ContainerTransaction.java?view=diff&rev=470257&r1=470256&r2=470257
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/ContainerTransaction.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/ContainerTransaction.java Wed Nov  1 23:22:11 2006
@@ -64,6 +64,18 @@
         return description.toArray();
     }
 
+    public ContainerTransaction() {
+    }
+
+
+    public ContainerTransaction(TransAttribute transAttribute, String ejbName, String methodName, String... parameters) {
+        this(transAttribute, new Method(ejbName, methodName, parameters));
+    }
+    public ContainerTransaction(TransAttribute transAttribute, Method method) {
+        this.transAttribute = transAttribute;
+        getMethod().add(method);
+    }
+
     public void setDescriptions(Text[] text) {
         description.set(text);
     }

Modified: incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/EnterpriseBean.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/EnterpriseBean.java?view=diff&rev=470257&r1=470256&r2=470257
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/EnterpriseBean.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/EnterpriseBean.java Wed Nov  1 23:22:11 2006
@@ -43,6 +43,8 @@
 
     public List<AroundInvoke> getAroundInvoke();
 
+    public void addAroundInvoke(String method);
+
     public List<EnvEntry> getEnvEntry();
 
     public List<EjbRef> getEjbRef();
@@ -65,6 +67,10 @@
 
     public List<LifecycleCallback> getPreDestroy();
 
+    public void addPostConstruct(String method);
+
+    public void addPreDestroy(String method);
+
     public SecurityIdentity getSecurityIdentity();
 
     public void setSecurityIdentity(SecurityIdentity value);
@@ -72,5 +78,9 @@
     public String getId();
 
     public void setId(String value);
+
+    public TransactionType getTransactionType();
+
+    public void setTransactionType(TransactionType type);
 
 }

Modified: incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/EntityBean.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/EntityBean.java?view=diff&rev=470257&r1=470256&r2=470257
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/EntityBean.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/EntityBean.java Wed Nov  1 23:22:11 2006
@@ -463,6 +463,11 @@
         return this.postConstruct;
     }
 
+    public void addPostConstruct(String method){
+        assert ejbClass != null: "Set the ejbClass before calling this method";
+        getPostConstruct().add(new LifecycleCallback(ejbClass, method));
+    }
+
     public List<LifecycleCallback> getPreDestroy() {
         if (preDestroy == null) {
             preDestroy = new ArrayList<LifecycleCallback>();
@@ -470,6 +475,11 @@
         return this.preDestroy;
     }
 
+    public void addPreDestroy(String method){
+        assert ejbClass != null: "Set the ejbClass before calling this method";
+        getPreDestroy().add(new LifecycleCallback(ejbClass, method));
+    }
+
     public List<SecurityRoleRef> getSecurityRoleRef() {
         if (securityRoleRef == null) {
             securityRoleRef = new ArrayList<SecurityRoleRef>();
@@ -503,4 +513,18 @@
     public List<AroundInvoke> getAroundInvoke() {
         return Collections.EMPTY_LIST;
     }
+
+
+    public void addAroundInvoke(String method){
+    }
+
+    public TransactionType getTransactionType() {
+        return TransactionType.CONTAINER;
+    }
+
+    public void setTransactionType(TransactionType type){
+    }
+
+
+
 }

Modified: incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/MessageDrivenBean.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/MessageDrivenBean.java?view=diff&rev=470257&r1=470256&r2=470257
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/MessageDrivenBean.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/MessageDrivenBean.java Wed Nov  1 23:22:11 2006
@@ -164,6 +164,13 @@
     @XmlID
     protected String id;
 
+    public MessageDrivenBean() {
+    }
+
+    public MessageDrivenBean(String ejbName) {
+        this.ejbName = ejbName;
+    }
+
     @XmlElement(name = "description", required = true)
     public Text[] getDescriptions() {
         return description.toArray();
@@ -318,6 +325,11 @@
         return this.aroundInvoke;
     }
 
+    public void addAroundInvoke(String method){
+        assert ejbClass != null: "Set the ejbClass before calling this method";
+        getAroundInvoke().add(new AroundInvoke(ejbClass, method));
+    }
+
     public List<EnvEntry> getEnvEntry() {
         if (envEntry == null) {
             envEntry = new ArrayList<EnvEntry>();
@@ -388,12 +400,23 @@
         return this.postConstruct;
     }
 
+    public void addPostConstruct(String method){
+        assert ejbClass != null: "Set the ejbClass before calling this method";
+        getPostConstruct().add(new LifecycleCallback(ejbClass, method));
+    }
+
     public List<LifecycleCallback> getPreDestroy() {
         if (preDestroy == null) {
             preDestroy = new ArrayList<LifecycleCallback>();
         }
         return this.preDestroy;
     }
+
+    public void addPreDestroy(String method){
+        assert ejbClass != null: "Set the ejbClass before calling this method";
+        getPreDestroy().add(new LifecycleCallback(ejbClass, method));
+    }
+
 
     public SecurityIdentity getSecurityIdentity() {
         return securityIdentity;

Modified: incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/Method.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/Method.java?view=diff&rev=470257&r1=470256&r2=470257
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/Method.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/Method.java Wed Nov  1 23:22:11 2006
@@ -231,9 +231,30 @@
     @XmlTransient
     protected TextMap description = new TextMap();
 
+    public Method(String ejbName, String methodName, String... parameters) {
+        this.ejbName = ejbName;
+        this.methodName = methodName;
+
+        if (parameters.length > 0){
+            MethodParams params = new MethodParams();
+            for (String paramName : parameters) {
+                params.getMethodParam().add(paramName);
+            }
+            this.methodParams = params;
+        }
+    }
+
     @XmlElement(name = "description", required = true)
     public Text[] getDescriptions() {
         return description.toArray();
+    }
+
+    public Method() {
+    }
+
+    public Method(String ejbName, String methodName) {
+        this.ejbName = ejbName;
+        this.methodName = methodName;
     }
 
     public void setDescriptions(Text[] text) {

Added: incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/MethodTransaction.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/MethodTransaction.java?view=auto&rev=470257
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/MethodTransaction.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/MethodTransaction.java Wed Nov  1 23:22:11 2006
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.jee;
+
+import java.util.List;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class MethodTransaction {
+    private final Method method;
+    private final TransAttribute attribute;
+
+    public MethodTransaction(TransAttribute attribute, Method method) {
+        this.attribute = attribute;
+        this.method = method;
+    }
+
+    public TransAttribute getAttribute() {
+        return attribute;
+    }
+
+    public String getEjbName() {
+        return method.getEjbName();
+    }
+
+    public MethodIntf getMethodIntf() {
+        return method.getMethodIntf();
+    }
+
+    public String getMethodName() {
+        return method.getMethodName();
+    }
+
+    public MethodParams getMethodParams() {
+        return method.getMethodParams();
+    }
+
+    public Method getMethod() {
+        return method;
+    }
+}

Modified: incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/SessionBean.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/SessionBean.java?view=diff&rev=470257&r1=470256&r2=470257
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/SessionBean.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/SessionBean.java Wed Nov  1 23:22:11 2006
@@ -161,7 +161,7 @@
     @XmlElement(name = "remove-method", required = true)
     protected List<RemoveMethod> removeMethod;
     @XmlElement(name = "transaction-type")
-    protected TransactionType transactionType = TransactionType.BEAN;
+    protected TransactionType transactionType;
     @XmlElement(name = "around-invoke", required = true)
     protected List<AroundInvoke> aroundInvoke;
     @XmlElement(name = "env-entry", required = true)
@@ -391,6 +391,11 @@
         return this.aroundInvoke;
     }
 
+    public void addAroundInvoke(String method){
+        assert ejbClass != null: "Set the ejbClass before calling this method";
+        getAroundInvoke().add(new AroundInvoke(ejbClass, method));
+    }
+    
     public List<EnvEntry> getEnvEntry() {
         if (envEntry == null) {
             envEntry = new ArrayList<EnvEntry>();