[jboss-cvs] JBossAS SVN: r108058 - in projects/jboss-jca/trunk: deployers/src/test/java/org/jboss/jca/test/deployers/spec and 4 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Sep 8 17:05:38 EDT 2010


Author: jesper.pedersen
Date: 2010-09-08 17:05:36 -0400 (Wed, 08 Sep 2010)
New Revision: 108058

Added:
   projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RAActivatorDeployment.java
   projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RaXmlDeployer.java
   projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RaXmlDeployment.java
   projects/jboss-jca/trunk/deployers/src/test/java/org/jboss/jca/test/deployers/spec/RaXmlTestCase.java
   projects/jboss-jca/trunk/deployers/src/test/resources/ra16out-ra.xml
Modified:
   projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/AbstractResourceAdapterDeployer.java
   projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RAActivator.java
   projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RADeployer.java
   projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RADeployment.java
   projects/jboss-jca/trunk/doc/userguide/en/modules/configuration.xml
   projects/jboss-jca/trunk/doc/userguide/en/modules/embedded.xml
   projects/jboss-jca/trunk/embedded/src/main/resources/jca.xml
   projects/jboss-jca/trunk/sjc/src/main/resources/bootstrap/jca.xml
Log:
[JBJCA-415] Resource adapter deployer (-ra.xml) (Part 1)

Modified: projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/AbstractResourceAdapterDeployer.java
===================================================================
--- projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/AbstractResourceAdapterDeployer.java	2010-09-08 21:03:39 UTC (rev 108057)
+++ projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/AbstractResourceAdapterDeployer.java	2010-09-08 21:05:36 UTC (rev 108058)
@@ -367,19 +367,46 @@
 
    /**
     * Bind connection factory into JNDI
+    * @param url The deployment URL
     * @param deployment The deployment name
     * @param cf The connection factory
     * @return The JNDI names bound
     * @exception Throwable Thrown if an error occurs
     */
-   protected String[] bindConnectionFactory(String deployment, Object cf) throws Throwable
+   protected String[] bindConnectionFactory(URL url, String deployment, Object cf) throws Throwable
    {
       JndiStrategy js = getConfiguration().getJndiStrategy().clone();
 
-      return js.bindConnectionFactories(deployment, new Object[] {cf});
+      String[] result = js.bindConnectionFactories(deployment, new Object[] {cf});
+
+      getConfiguration().getMetadataRepository().
+         registerJndiMapping(url, cf.getClass().getName(), result[0]);                  
+
+      return result;
    }
 
    /**
+    * Bind connection factory into JNDI
+    * @param url The deployment URL
+    * @param deployment The deployment name
+    * @param cf The connection factory
+    * @param jndi The JNDI name
+    * @return The JNDI names bound
+    * @exception Throwable Thrown if an error occurs
+    */
+   protected String[] bindConnectionFactory(URL url, String deployment, Object cf, String jndi) throws Throwable
+   {
+      JndiStrategy js = getConfiguration().getJndiStrategy().clone();
+
+      String[] result = js.bindConnectionFactories(deployment, new Object[] {cf}, new String[] {jndi});
+
+      getConfiguration().getMetadataRepository().
+         registerJndiMapping(url, cf.getClass().getName(), jndi);                  
+
+      return result;
+   }
+
+   /**
     * Start
     */
    public void start()

Modified: projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RAActivator.java
===================================================================
--- projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RAActivator.java	2010-09-08 21:03:39 UTC (rev 108057)
+++ projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RAActivator.java	2010-09-08 21:05:36 UTC (rev 108058)
@@ -23,6 +23,7 @@
 package org.jboss.jca.deployers.fungal;
 
 import org.jboss.jca.common.api.metadata.common.TransactionSupportEnum;
+import org.jboss.jca.common.api.metadata.ironjacamar.IronJacamar;
 import org.jboss.jca.common.api.metadata.ra.AdminObject;
 import org.jboss.jca.common.api.metadata.ra.ConfigProperty;
 import org.jboss.jca.common.api.metadata.ra.ConnectionDefinition;
@@ -86,6 +87,9 @@
    /** The kernel */
    private Kernel kernel;
 
+   /** Enabled */
+   private boolean enabled;
+
    /** The archives that should be excluded for activation */
    private Set<String> excludeArchives;
 
@@ -97,6 +101,10 @@
     */
    public RAActivator()
    {
+      kernel = null;
+      enabled = true;
+      excludeArchives = null;
+      deployments = null;
    }
 
    /**
@@ -136,6 +144,23 @@
    }
 
    /**
+    * Is enabled
+    * @return True if enabled; otherwise false
+    */
+   public boolean isEnabled()
+   {
+      return enabled;
+   }
+
+   /**
+    * Set the eanbled flag
+    * @param value The value
+    */
+   public void setEnabled(boolean value)
+   {
+      this.enabled = value;
+   }
+   /**
     * Pre deploy
     * @exception Throwable Thrown if an error occurs
     */
@@ -149,41 +174,45 @@
     */
    public void postDeploy() throws Throwable
    {
-      Set<URL> rarDeployments = getConfiguration().getMetadataRepository().getResourceAdapters();
-
-      for (URL deployment : rarDeployments)
+      if (enabled)
       {
-         if (trace)
-            log.trace("Processing: " + deployment.toExternalForm());
+         Set<URL> rarDeployments = getConfiguration().getMetadataRepository().getResourceAdapters();
 
-         boolean include = true;
+         for (URL deployment : rarDeployments)
+         {
+            if (trace)
+               log.trace("Processing: " + deployment.toExternalForm());
+
+            boolean include = true;
          
-         if (excludeArchives != null)
-         {
-            for (String excludedArchive : excludeArchives)
+            if (excludeArchives != null)
             {
-               if (deployment.toExternalForm().endsWith(excludedArchive))
-                  include = false;
+               for (String excludedArchive : excludeArchives)
+               {
+                  if (deployment.toExternalForm().endsWith(excludedArchive))
+                     include = false;
+               }
             }
-         }
+            
+            if (include)
+            {
+               Map<String, List<String>> jndiMappings = 
+                  getConfiguration().getMetadataRepository().getJndiMappings(deployment);
 
-         if (include)
-         {
-            Map<String, String> jndiMappings = null; // getMetadataRepository().getJndiMappings();
-
-            // If there isn't any JNDI mappings then the archive isn't active
-            // so activate it
-            if (jndiMappings == null)
-            {
-               Deployment raDeployment = deploy(deployment, kernel.getKernelClassLoader());
-               if (raDeployment != null)
+               // If there isn't any JNDI mappings then the archive isn't active
+               // so activate it
+               if (jndiMappings == null)
                {
-                  if (deployments == null)
-                     deployments = new ArrayList<Deployment>(1);
+                  Deployment raDeployment = deploy(deployment, kernel.getKernelClassLoader());
+                  if (raDeployment != null)
+                  {
+                     if (deployments == null)
+                        deployments = new ArrayList<Deployment>(1);
 
-                  deployments.add(raDeployment);
+                     deployments.add(raDeployment);
 
-                  kernel.getMainDeployer().registerDeployment(raDeployment);
+                     kernel.getMainDeployer().registerDeployment(raDeployment);
+                  }
                }
             }
          }
@@ -209,6 +238,8 @@
                log.warn("Error during undeployment of " + raDeployment.getURL());
             }
          }
+
+         deployments = null;
       }
    }
 
@@ -227,7 +258,7 @@
     * @return The deployment
     * @exception DeployException Thrown if an error occurs during deployment
     */
-   public Deployment deploy(URL url, ClassLoader parent) throws DeployException
+   private Deployment deploy(URL url, ClassLoader parent) throws DeployException
    {
       Set<Failure> failures = null;
 
@@ -270,11 +301,8 @@
 
          // Get metadata
          Connector cmd = getConfiguration().getMetadataRepository().getResourceAdapter(url);
+         IronJacamar ijmd = null; // TODO - through MDR
 
-         // Notify regarding license terms
-         if (cmd != null && cmd.getLicense() != null && cmd.getLicense().isLicenseRequired())
-            log.info("Required license terms for " + url.toExternalForm());
-
          ResourceAdapter resourceAdapter = null;
          List<Validate> archiveValidationObjects = new ArrayList<Validate>();
          List<Failure> partialFailures = null;
@@ -282,6 +310,7 @@
 
          String deploymentName = f.getName().substring(0, f.getName().indexOf(".rar"));
          Object[] cfs = null;
+         String[] jndis = null;
 
          // Create objects and inject values
          if (cmd != null)
@@ -391,8 +420,9 @@
 
                if (cf != null && cf instanceof Serializable && cf instanceof Referenceable)
                {
-                  bindConnectionFactory(deploymentName, cf);
+                  String[] jndiNames = bindConnectionFactory(url, deploymentName, cf);
                   cfs = new Object[] {cf};
+                  jndis = new String[] {jndiNames[0]};
                }
             }
             else
@@ -405,8 +435,10 @@
                   List<ConnectionDefinition> cdMetas = ra.getOutboundResourceadapter().getConnectionDefinitions();
                   if (cdMetas.size() > 0)
                   {
-                     for (ConnectionDefinition cdMeta : cdMetas)
+                     if (cdMetas.size() == 1)
                      {
+                        ConnectionDefinition cdMeta = cdMetas.get(0);
+
                         ManagedConnectionFactory mcf =
                            (ManagedConnectionFactory) initAndInject(cdMeta.getManagedConnectionFactoryClass()
                                                                     .getValue(), cdMeta
@@ -482,18 +514,17 @@
                         
                         if (cf != null && cf instanceof Serializable && cf instanceof Referenceable)
                         {
-                           if (cdMetas.size() == 1)
-                           {
-                              deploymentName = f.getName().substring(0, f.getName().indexOf(".rar"));
-                              bindConnectionFactory(deploymentName, cf);
-                              cfs = new Object[] {cf};
-                           }
-                           else
-                           {
-                              log.warn("NYI: There are multiple connection factories for: " + f.getName());
-                           }
+                           deploymentName = f.getName().substring(0, f.getName().indexOf(".rar"));
+                           String[] jndiNames = bindConnectionFactory(url, deploymentName, cf);
+                           cfs = new Object[] {cf};
+                           jndis = new String[] {jndiNames[0]};
                         }
                      }
+                     else
+                     {
+                        log.warn("There are multiple connection factories for: " + f.getName());
+                        log.warn("Use an ironjacamar.xml or a -ra.xml to activate the deployment");
+                     }
                   }
                }
             }
@@ -597,27 +628,17 @@
          // Bean validation
          if (getConfiguration().getBeanValidation())
          {
-            //JbossRa20 jrmd20 = null;
             List<Class> groupsClasses = null;
 
-            /*
-            if (jrmd instanceof JbossRa20)
+            if (ijmd != null && ijmd.getBeanValidationGroups() != null &&
+                ijmd.getBeanValidationGroups().size() > 0)
             {
-               jrmd20 = (JbossRa20) jrmd;
-            }
-
-            if (jrmd20 != null && 
-                jrmd20.getBeanValidationGroups() != null &&
-                jrmd20.getBeanValidationGroups().size() > 0)
-            {
-               BeanValidationGroup bvGroups = jrmd20.getBeanValidationGroups().get(0);
                groupsClasses = new ArrayList<Class>();
-               for (String group : bvGroups.getBeanValidationGroup())
+               for (String group : ijmd.getBeanValidationGroups())
                {
                   groupsClasses.add(Class.forName(group, true, cl));
                }
             }
-            */
 
             if (beanValidationObjects.size() > 0)
             {
@@ -634,31 +655,25 @@
          {
             String bootstrapIdentifier = null;
 
-            /*
-            if (jrmd != null && jrmd instanceof JbossRa20)
+            if (ijmd != null)
             {
-               JbossRa20 jrmd20 = (JbossRa20) jrmd;
-               bootstrapIdentifier = jrmd20.getBootstrapContext();
+               bootstrapIdentifier = ijmd.getBootstrapContext();
             }
-            */
 
             startContext(resourceAdapter, bootstrapIdentifier);
          }
 
          log.info("Deployed: " + url.toExternalForm());
 
-         RADeployment depoyment = new RADeployment(url, 
-                                                   deploymentName, 
-                                                   true,
-                                                   resourceAdapter, 
-                                                   getConfiguration().getJndiStrategy(), 
-                                                   getConfiguration().getMetadataRepository(), 
-                                                   cfs,
-                                                   destination, 
-                                                   cl,
-                                                   log);
-
-         return depoyment;
+         return new RAActivatorDeployment(url, 
+                                          deploymentName, 
+                                          resourceAdapter, 
+                                          getConfiguration().getJndiStrategy(), 
+                                          getConfiguration().getMetadataRepository(), 
+                                          cfs,
+                                          jndis,
+                                          cl,
+                                          log);
       }
       catch (DeployException de)
       {

Added: projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RAActivatorDeployment.java
===================================================================
--- projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RAActivatorDeployment.java	                        (rev 0)
+++ projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RAActivatorDeployment.java	2010-09-08 21:05:36 UTC (rev 108058)
@@ -0,0 +1,178 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008-2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.deployers.fungal;
+
+import org.jboss.jca.core.spi.mdr.MetadataRepository;
+import org.jboss.jca.core.spi.naming.JndiStrategy;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.URL;
+
+import javax.resource.spi.ResourceAdapter;
+
+import org.jboss.logging.Logger;
+
+import com.github.fungal.spi.deployers.Deployment;
+
+/**
+ * A resource adapter activator deployment for JCA/SJC
+ * @author <a href="mailto:jesper.pedersen at jboss.org">Jesper Pedersen</a>
+ */
+public class RAActivatorDeployment implements Deployment
+{
+   /** The logger */
+   private Logger log;
+
+   /** The deployment */
+   private URL deployment;
+
+   /** The deployment name */
+   private String deploymentName;
+
+   /** The resource adapter instance */
+   private ResourceAdapter ra;
+
+   /** The JNDI strategy */
+   private JndiStrategy jndiStrategy;
+
+   /** The MDR */
+   private MetadataRepository mdr;
+
+   /** The connection factories */
+   private Object[] cfs;
+
+   /** The JNDI names for the connection factories */
+   private String[] jndis;
+
+   /** The classloader */
+   private ClassLoader cl;
+
+   /**
+    * Constructor
+    * @param deployment The deployment
+    * @param deploymentName The deployment name
+    * @param ra The resource adapter instance if present
+    * @param jndiStrategy The JNDI strategy
+    * @param metadataRepository The metadata repository
+    * @param cfs The connection factories
+    * @param jndis The JNDI names for the connection factories
+    * @param cl The classloader for the deployment
+    * @param log The logger
+    */
+   public RAActivatorDeployment(URL deployment, 
+                                String deploymentName,
+                                ResourceAdapter ra, 
+                                JndiStrategy jndiStrategy,
+                                MetadataRepository metadataRepository,
+                                Object[] cfs, 
+                                String[] jndis,
+                                ClassLoader cl,
+                                Logger log)
+   {
+      this.deployment = deployment;
+      this.deploymentName = deploymentName;
+      this.ra = ra;
+      this.jndiStrategy = jndiStrategy;
+      this.mdr = metadataRepository;
+      this.cfs = cfs;
+      this.jndis = jndis;
+      this.cl = cl;
+      this.log = log;
+   }
+
+   /**
+    * Get the unique URL for the deployment
+    * @return The URL
+    */
+   public URL getURL()
+   {
+      return deployment;
+   }
+
+   /**
+    * Get the classloader
+    * @return The classloader
+    */
+   public ClassLoader getClassLoader()
+   {
+      return cl;
+   }
+
+   /**
+    * Stop
+    */
+   public void stop()
+   {
+      log.debug("Undeploying: " + deployment.toExternalForm());
+      
+      if (mdr != null && cfs != null && jndis != null)
+      {
+         for (int i = 0; i < cfs.length; i++)
+         {
+            String cf = cfs[i].getClass().getName();
+            String jndi = jndis[i];
+
+            mdr.unregisterJndiMapping(deployment, cf, jndi);
+         }
+      }
+
+      if (cfs != null)
+      {
+         try
+         {
+            jndiStrategy.unbindConnectionFactories(deploymentName, cfs);
+         }
+         catch (Throwable t)
+         {
+            log.warn("Exception during JNDI unbinding", t);
+         }
+      }
+
+      if (ra != null)
+      {
+         ra.stop();
+         ra = null;
+      }
+   }
+
+   /**
+    * Destroy
+    */
+   public void destroy()
+   {
+      if (cl != null && cl instanceof Closeable)
+      {
+         try
+         {
+            ((Closeable)cl).close();
+         }
+         catch (IOException ioe)
+         {
+            // Swallow
+         }
+      }
+
+      log.info("Undeployed: " + deployment.toExternalForm());
+   }
+}

Modified: projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RADeployer.java
===================================================================
--- projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RADeployer.java	2010-09-08 21:03:39 UTC (rev 108057)
+++ projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RADeployer.java	2010-09-08 21:05:36 UTC (rev 108058)
@@ -318,7 +318,7 @@
 
                   if (cf != null && cf instanceof Serializable && cf instanceof Referenceable)
                   {
-                     bindConnectionFactory(deploymentName, cf);
+                     bindConnectionFactory(url, deploymentName, cf);
                      cfs = new Object[] {cf};
                   }
                }
@@ -428,7 +428,7 @@
                                  if (cdMetas.size() == 1)
                                  {
                                     deploymentName = f.getName().substring(0, f.getName().indexOf(".rar"));
-                                    bindConnectionFactory(deploymentName, cf);
+                                    bindConnectionFactory(url, deploymentName, cf);
                                     cfs = new Object[] {cf};
                                  }
                                  else
@@ -577,7 +577,7 @@
          if (cmd != null)
          {
             // Register with MDR
-            getConfiguration().getMetadataRepository().registerResourceAdapter(url, cmd);
+            getConfiguration().getMetadataRepository().registerResourceAdapter(url, root, cmd);
          }
 
          if (activateDeployment)
@@ -585,7 +585,6 @@
             // Bean validation
             if (getConfiguration().getBeanValidation())
             {
-
                List<Class> groupsClasses = null;
 
                if (ijmd != null && ijmd.getBeanValidationGroups() != null &&

Modified: projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RADeployment.java
===================================================================
--- projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RADeployment.java	2010-09-08 21:03:39 UTC (rev 108057)
+++ projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RADeployment.java	2010-09-08 21:05:36 UTC (rev 108058)
@@ -132,22 +132,22 @@
     */
    public void stop()
    {
+      if (mdr != null)
+      {
+         try
+         {
+            mdr.unregisterResourceAdapter(deployment);
+         }
+         catch (Throwable t)
+         {
+            log.warn("Exception during unregistering deployment", t);
+         }
+      }
+
       if (activator)
       {
          log.debug("Undeploying: " + deployment.toExternalForm());
 
-         if (mdr != null)
-         {
-            try
-            {
-               mdr.unregisterResourceAdapter(deployment);
-            }
-            catch (Throwable t)
-            {
-               log.warn("Exception during unregistering deployment", t);
-            }
-         }
-
          if (cfs != null)
          {
             try
@@ -185,21 +185,21 @@
          }
       }
 
-      if (activator)
+      if (tmpDirectory != null && tmpDirectory.exists())
       {
-         if (tmpDirectory != null && tmpDirectory.exists())
+         try
          {
-            try
-            {
-               FileUtil fu = new FileUtil();
-               fu.recursiveDelete(tmpDirectory);
-            }
-            catch (IOException ioe)
-            {
-               // Ignore
-            }
+            FileUtil fu = new FileUtil();
+            fu.recursiveDelete(tmpDirectory);
          }
+         catch (IOException ioe)
+         {
+            // Ignore
+         }
+      }
          
+      if (activator)
+      {
          log.info("Undeployed: " + deployment.toExternalForm());
       }
    }

Added: projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RaXmlDeployer.java
===================================================================
--- projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RaXmlDeployer.java	                        (rev 0)
+++ projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RaXmlDeployer.java	2010-09-08 21:05:36 UTC (rev 108058)
@@ -0,0 +1,761 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008-2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.deployers.fungal;
+
+import org.jboss.jca.common.api.metadata.common.TransactionSupportEnum;
+import org.jboss.jca.common.api.metadata.ra.AdminObject;
+import org.jboss.jca.common.api.metadata.ra.ConfigProperty;
+import org.jboss.jca.common.api.metadata.ra.Connector;
+import org.jboss.jca.common.api.metadata.ra.Connector.Version;
+import org.jboss.jca.common.api.metadata.ra.MessageListener;
+import org.jboss.jca.common.api.metadata.ra.ResourceAdapter1516;
+import org.jboss.jca.common.api.metadata.ra.ra10.ResourceAdapter10;
+import org.jboss.jca.common.api.metadata.resourceadapter.ResourceAdapters;
+import org.jboss.jca.common.metadata.resourceadapter.ResourceAdapterParser;
+import org.jboss.jca.core.connectionmanager.ConnectionManager;
+import org.jboss.jca.core.connectionmanager.ConnectionManagerFactory;
+import org.jboss.jca.core.connectionmanager.pool.api.Pool;
+import org.jboss.jca.core.connectionmanager.pool.api.PoolConfiguration;
+import org.jboss.jca.core.connectionmanager.pool.api.PoolFactory;
+import org.jboss.jca.core.connectionmanager.pool.api.PoolStrategy;
+import org.jboss.jca.validator.Failure;
+import org.jboss.jca.validator.Key;
+import org.jboss.jca.validator.Severity;
+import org.jboss.jca.validator.Validate;
+import org.jboss.jca.validator.ValidateObject;
+import org.jboss.jca.validator.Validator;
+import org.jboss.jca.validator.ValidatorException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.resource.Referenceable;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.resource.spi.TransactionSupport;
+import javax.resource.spi.TransactionSupport.TransactionSupportLevel;
+
+import org.jboss.logging.Logger;
+
+import com.github.fungal.api.Kernel;
+import com.github.fungal.api.classloading.ClassLoaderFactory;
+import com.github.fungal.api.classloading.KernelClassLoader;
+import com.github.fungal.spi.deployers.DeployException;
+import com.github.fungal.spi.deployers.Deployer;
+import com.github.fungal.spi.deployers.DeployerOrder;
+import com.github.fungal.spi.deployers.DeployerPhases;
+import com.github.fungal.spi.deployers.Deployment;
+import com.github.fungal.spi.deployers.MultiStageDeployer;
+
+/**
+ * The -ra.xml deployer for JCA/SJC
+ * @author <a href="mailto:jesper.pedersen at jboss.org">Jesper Pedersen</a>
+ */
+public final class RaXmlDeployer extends AbstractResourceAdapterDeployer implements Deployer,
+                                                                                    MultiStageDeployer,
+                                                                                    DeployerOrder,
+                                                                                    DeployerPhases
+{
+   private static Logger log = Logger.getLogger(RaXmlDeployer.class);
+
+   private static boolean trace = log.isTraceEnabled();
+
+   /** The kernel */
+   private Kernel kernel;
+
+   /** The list of generated deployments */
+   private List<Deployment> deployments;
+
+   /**
+    * Constructor
+    */
+   public RaXmlDeployer()
+   {
+   }
+
+   /**
+    * Deployer order
+    * @return The deployment
+    */
+   public int getOrder()
+   {
+      return 0;
+   }
+
+   /**
+    * Get the kernel
+    * @return The kernel
+    */
+   public Kernel getKernel()
+   {
+      return kernel;
+   }
+
+   /**
+    * Set the kernel
+    * @param kernel The kernel
+    */
+   public void setKernel(Kernel kernel)
+   {
+      this.kernel = kernel;
+   }
+
+   /**
+    * Pre deploy
+    * @exception Throwable Thrown if an error occurs
+    */
+   public void preDeploy() throws Throwable
+   {
+   }
+
+   /**
+    * Post deploy
+    * @exception Throwable Thrown if an error occurs
+    */
+   public void postDeploy() throws Throwable
+   {
+   }
+
+   /**
+    * Pre undeploy
+    * @exception Throwable Thrown if an error occurs
+    */
+   public void preUndeploy() throws Throwable
+   {
+      if (deployments != null)
+      {
+         for (Deployment raDeployment : deployments)
+         {
+            try
+            {
+               kernel.getMainDeployer().unregisterDeployment(raDeployment);
+            }
+            catch (Throwable t)
+            {
+               log.warn("Error during undeployment of " + raDeployment.getURL());
+            }
+         }
+
+         deployments = null;
+      }
+   }
+
+   /**
+    * Post undeploy
+    * @exception Throwable Thrown if an error occurs
+    */
+   public void postUndeploy() throws Throwable
+   {
+   }
+
+   /**
+    * Deploy
+    * @param url The url
+    * @param parent The parent classloader
+    * @return The deployment
+    * @exception DeployException Thrown if an error occurs during deployment
+    */
+   @Override
+   public synchronized Deployment deploy(URL url, ClassLoader parent) throws DeployException
+   {
+      if (url == null || !(url.toExternalForm().endsWith("-ra.xml")))
+         return null;
+
+      log.debug("Deploying: " + url.toExternalForm());
+
+      ClassLoader oldTCCL = SecurityActions.getThreadContextClassLoader();
+      InputStream is = null;
+      try
+      {
+         File f = new File(url.toURI());
+
+         if (!f.exists())
+            throw new IOException("Archive " + url.toExternalForm() + " doesnt exists");
+
+         // Parse metadata
+         is = new FileInputStream(f);
+         ResourceAdapterParser parser = new ResourceAdapterParser();
+         ResourceAdapters raXmlDeployment = parser.parse(is);
+
+         int size = raXmlDeployment.getResourceAdapters().size();
+         if (size == 1)
+         {
+            return doDeploy(url, raXmlDeployment.getResourceAdapters().get(0), parent);
+         }
+         else
+         {
+            deployments = new ArrayList<Deployment>(size);
+
+            for (org.jboss.jca.common.api.metadata.resourceadapter.ResourceAdapter raxml : 
+                    raXmlDeployment.getResourceAdapters())
+            {
+               Deployment raDeployment = doDeploy(url, raxml, parent);
+               if (raDeployment != null)
+               {
+                  deployments.add(raDeployment);
+
+                  kernel.getMainDeployer().registerDeployment(raDeployment);
+               }
+            }
+
+            return null;
+         }
+      }
+      catch (DeployException de)
+      {
+         // Just rethrow
+         throw de;
+      }
+      catch (Throwable t)
+      {
+         throw new DeployException("Exception during deployment of " + url.toExternalForm(), t);
+      }
+      finally
+      {
+         if (is != null)
+         {
+            try
+            {
+               is.close();
+            }
+            catch (IOException ioe)
+            {
+               // Ignore
+            }
+         }
+
+         SecurityActions.setThreadContextClassLoader(oldTCCL);
+      }
+   }
+
+   /**
+    * Deploy an entry in the -ra.xml deployment
+    * @param url The deployment url
+    * @param raxml The -ra.xml entry
+    * @param parent The parent classloader
+    * @return The deployment
+    * @exception DeployException Thrown if an error occurs during deployment
+    */
+   private Deployment doDeploy(URL url,
+                               org.jboss.jca.common.api.metadata.resourceadapter.ResourceAdapter raxml, 
+                               ClassLoader parent)
+      throws DeployException
+   {
+      Set<Failure> failures = null;
+
+      ClassLoader oldTCCL = SecurityActions.getThreadContextClassLoader();
+      try
+      {
+         // Find the archive in MDR
+         String archive = raxml.getArchive();
+         URL deployment = null;
+         Set<URL> deployments = getConfiguration().getMetadataRepository().getResourceAdapters();
+
+         for (URL u : deployments)
+         {
+            if (u.toExternalForm().endsWith(archive))
+               deployment = u;
+         }
+
+         if (deployment == null)
+         {
+            throw new DeployException("Archive " + archive + " couldn't be resolved in " + url.toExternalForm());
+         }
+
+         Connector cmd = getConfiguration().getMetadataRepository().getResourceAdapter(deployment);
+         File root = getConfiguration().getMetadataRepository().getRoot(deployment);
+
+         // Create classloader
+         URL[] urls = getUrls(root);
+         KernelClassLoader cl = null;
+         if (getConfiguration().getScopeDeployment())
+         {
+            cl = ClassLoaderFactory.create(ClassLoaderFactory.TYPE_PARENT_LAST, urls, parent);
+         }
+         else
+         {
+            cl = ClassLoaderFactory.create(ClassLoaderFactory.TYPE_PARENT_FIRST, urls, parent);
+         }
+         SecurityActions.setThreadContextClassLoader(cl);
+
+         javax.resource.spi.ResourceAdapter resourceAdapter = null;
+         List<Validate> archiveValidationObjects = new ArrayList<Validate>();
+         List<Failure> partialFailures = null;
+         List<Object> beanValidationObjects = new ArrayList<Object>();
+
+         String deploymentName = archive.substring(0, archive.indexOf(".rar"));
+         Object[] cfs = null;
+         String[] jndiNames = null;
+
+         // Create objects and inject values
+         if (cmd != null)
+         {
+            // ResourceAdapter
+            if (cmd.getVersion() != Version.V_10)
+            {
+               ResourceAdapter1516 ra1516 = (ResourceAdapter1516)cmd.getResourceadapter();
+               if (ra1516 != null && ra1516.getResourceadapterClass() != null)
+               {
+                  resourceAdapter =
+                     (javax.resource.spi.ResourceAdapter) initAndInject(
+                         ra1516.getResourceadapterClass(), ra1516.getConfigProperties(), cl);
+
+                  if (trace)
+                  {
+                     log.trace("ResourceAdapter: " + resourceAdapter.getClass().getName());
+                     log.trace("ResourceAdapter defined in classloader: " +
+                               resourceAdapter.getClass().getClassLoader());
+                  }
+
+                  archiveValidationObjects.add(new ValidateObject(Key.RESOURCE_ADAPTER,
+                                                                  resourceAdapter,
+                                                                  ra1516.getConfigProperties()));
+                  beanValidationObjects.add(resourceAdapter);
+               }
+            }
+
+            // ManagedConnectionFactory
+            if (cmd.getVersion() == Version.V_10)
+            {
+
+               ManagedConnectionFactory mcf =
+                     (ManagedConnectionFactory) initAndInject(((ResourceAdapter10) cmd.getResourceadapter())
+                           .getManagedConnectionFactoryClass()
+                           .getValue(), ((ResourceAdapter10) cmd.getResourceadapter())
+                           .getConfigProperties(), cl);
+
+               if (trace)
+               {
+                  log.trace("ManagedConnectionFactory: " + mcf.getClass().getName());
+                  log.trace("ManagedConnectionFactory defined in classloader: " +
+                         mcf.getClass().getClassLoader());
+               }
+
+               mcf.setLogWriter(new PrintWriter(getConfiguration().getPrintStream()));
+
+               archiveValidationObjects.add(new ValidateObject(Key.MANAGED_CONNECTION_FACTORY,
+                                                               mcf,
+                                                               ((ResourceAdapter10) cmd.getResourceadapter())
+                                                               .getConfigProperties()));
+               beanValidationObjects.add(mcf);
+               associateResourceAdapter(resourceAdapter, mcf);
+
+               // Create the pool
+               PoolConfiguration pc = new PoolConfiguration();
+               PoolFactory pf = new PoolFactory();
+
+               Pool pool = pf.create(PoolStrategy.ONE_POOL, mcf, pc, true);
+
+               // Add a connection manager
+               ConnectionManager cm = null;
+
+               TransactionSupportLevel tsl = TransactionSupportLevel.NoTransaction;
+               TransactionSupportEnum tsmd = TransactionSupportEnum.NoTransaction;
+
+               tsmd = ((ResourceAdapter10) cmd.getResourceadapter()).getTransactionSupport();
+
+               if (tsmd == TransactionSupportEnum.NoTransaction)
+               {
+                  tsl = TransactionSupportLevel.NoTransaction;
+               }
+               else if (tsmd == TransactionSupportEnum.LocalTransaction)
+               {
+                  tsl = TransactionSupportLevel.LocalTransaction;
+               }
+               else if (tsmd == TransactionSupportEnum.XATransaction)
+               {
+                  tsl = TransactionSupportLevel.XATransaction;
+               }
+               // Section 7.13 -- Read from metadata -> overwrite with specified value if present
+               if (mcf instanceof TransactionSupport)
+                  tsl = ((TransactionSupport) mcf).getTransactionSupport();
+
+               // Select the correct connection manager
+               ConnectionManagerFactory cmf = new ConnectionManagerFactory();
+               cm = cmf.create(tsl, pool, getConfiguration().getTransactionManager());
+
+               // ConnectionFactory
+               Object cf = mcf.createConnectionFactory(cm);
+
+               if (cf == null)
+               {
+                  log.error("ConnectionFactory is null");
+               }
+               else
+               {
+                  if (trace)
+                  {
+                     log.trace("ConnectionFactory: " + cf.getClass().getName());
+                     log.trace("ConnectionFactory defined in classloader: "
+                           + cf.getClass().getClassLoader());
+                  }
+               }
+
+               archiveValidationObjects.add(new ValidateObject(Key.CONNECTION_FACTORY, cf));
+
+               if (cf != null && cf instanceof Serializable && cf instanceof Referenceable)
+               {
+                  org.jboss.jca.common.api.metadata.common.ConnectionDefinition cd =
+                     findConnectionDefinition(mcf.getClass().getName(), raxml.getConnectionDefinitions());
+
+                  String jndiName = cd.getJndiName();
+
+                  bindConnectionFactory(deployment, deploymentName, cf, jndiName);
+                  cfs = new Object[] {cf};
+                  jndiNames = new String[] {jndiName};
+               }
+            }
+            else
+            {
+               ResourceAdapter1516 ra = (ResourceAdapter1516) cmd.getResourceadapter();
+               if (ra != null &&
+                   ra.getOutboundResourceadapter() != null &&
+                   ra.getOutboundResourceadapter().getConnectionDefinitions() != null)
+               {
+                  List<org.jboss.jca.common.api.metadata.ra.ConnectionDefinition> cdMetas = 
+                     ra.getOutboundResourceadapter().getConnectionDefinitions();
+
+                  if (cdMetas.size() > 0)
+                  {
+                     cfs = new Object[cdMetas.size()];
+                     jndiNames = new String[cdMetas.size()];
+
+                     for (int cdIndex = 0; cdIndex < cdMetas.size(); cdIndex++)
+                     {
+                        org.jboss.jca.common.api.metadata.ra.ConnectionDefinition cdMeta = cdMetas.get(cdIndex);
+
+                        org.jboss.jca.common.api.metadata.common.ConnectionDefinition cdRaXml =
+                           findConnectionDefinition(cdMeta.getManagedConnectionFactoryClass().getValue(), 
+                                                    raxml.getConnectionDefinitions());
+
+                        if (cdRaXml != null && cdRaXml.isEnabled())
+                        {
+                           ManagedConnectionFactory mcf =
+                              (ManagedConnectionFactory) initAndInject(cdMeta.getManagedConnectionFactoryClass()
+                                                                       .getValue(), cdMeta
+                                                                       .getConfigProperties(), cl);
+                           
+                           if (trace)
+                           {
+                              log.trace("ManagedConnectionFactory: " + mcf.getClass().getName());
+                              log.trace("ManagedConnectionFactory defined in classloader: " +
+                                        mcf.getClass().getClassLoader());
+                           }
+
+                           mcf.setLogWriter(new PrintWriter(getConfiguration().getPrintStream()));
+
+                           archiveValidationObjects.add(new ValidateObject(Key.MANAGED_CONNECTION_FACTORY,
+                                                                           mcf,
+                                                                           cdMeta.getConfigProperties()));
+                           beanValidationObjects.add(mcf);
+                           associateResourceAdapter(resourceAdapter, mcf);
+
+                           // Create the pool
+                           PoolConfiguration pc = new PoolConfiguration();
+                           PoolFactory pf = new PoolFactory();
+
+                           Pool pool = pf.create(PoolStrategy.ONE_POOL, mcf, pc, true);
+
+                           // Add a connection manager
+                           ConnectionManager cm = null;
+                           TransactionSupportLevel tsl = TransactionSupportLevel.NoTransaction;
+                           TransactionSupportEnum tsmd = TransactionSupportEnum.NoTransaction;
+
+                           tsmd = ra.getOutboundResourceadapter().getTransactionSupport();
+                        
+                           if (tsmd == TransactionSupportEnum.NoTransaction)
+                           {
+                              tsl = TransactionSupportLevel.NoTransaction;
+                           }
+                           else if (tsmd == TransactionSupportEnum.LocalTransaction)
+                           {
+                              tsl = TransactionSupportLevel.LocalTransaction;
+                           }
+                           else if (tsmd == TransactionSupportEnum.XATransaction)
+                           {
+                              tsl = TransactionSupportLevel.XATransaction;
+                           }
+
+                           // Section 7.13 -- Read from metadata -> overwrite with specified value if present
+                           if (mcf instanceof TransactionSupport)
+                              tsl = ((TransactionSupport) mcf).getTransactionSupport();
+
+                           // Select the correct connection manager
+                           ConnectionManagerFactory cmf = new ConnectionManagerFactory();
+                           cm = cmf.create(tsl, pool, getConfiguration().getTransactionManager());
+
+                           // ConnectionFactory
+                           Object cf = mcf.createConnectionFactory(cm);
+
+                           if (cf == null)
+                           {
+                              log.error("ConnectionFactory is null");
+                           }
+                           else
+                           {
+                              if (trace)
+                              {
+                                 log.trace("ConnectionFactory: " + cf.getClass().getName());
+                                 log.trace("ConnectionFactory defined in classloader: "
+                                           + cf.getClass().getClassLoader());
+                              }
+                           }
+                           
+                           archiveValidationObjects.add(new ValidateObject(Key.CONNECTION_FACTORY, cf));
+                        
+                           if (cf != null && cf instanceof Serializable && cf instanceof Referenceable)
+                           {
+                              String jndiName = cdRaXml.getJndiName();
+
+                              bindConnectionFactory(deployment, deploymentName, cf, jndiName);
+                              cfs[cdIndex] = cf;
+                              jndiNames[cdIndex] = jndiName;
+                           }
+                        }
+                     }
+                  }
+               }
+            }
+
+            // ActivationSpec
+            if (cmd.getVersion() != Version.V_10)
+            {
+               ResourceAdapter1516 ra1516 = (ResourceAdapter1516) cmd.getResourceadapter();
+               if (ra1516 != null &&
+                   ra1516.getInboundResourceadapter() != null &&
+                   ra1516.getInboundResourceadapter().getMessageadapter() != null &&
+                   ra1516.getInboundResourceadapter().getMessageadapter().getMessagelisteners() != null)
+               {
+                  List<MessageListener> mlMetas = 
+                     ra1516.getInboundResourceadapter().getMessageadapter().getMessagelisteners();
+
+                  if (mlMetas.size() > 0)
+                  {
+                     for (MessageListener mlMeta : mlMetas)
+                     {
+                        if (mlMeta.getActivationspec() != null &&
+                            mlMeta.getActivationspec().getActivationspecClass().getValue() != null)
+                        {
+                           List<? extends ConfigProperty> cpm = mlMeta
+                                 .getActivationspec().getConfigProperties();
+
+                           Object o = initAndInject(mlMeta
+                                 .getActivationspec().getActivationspecClass().getValue(), cpm, cl);
+
+                           if (trace)
+                           {
+                              log.trace("ActivationSpec: " + o.getClass().getName());
+                              log.trace("ActivationSpec defined in classloader: " + o.getClass().getClassLoader());
+                           }
+
+                           archiveValidationObjects.add(new ValidateObject(Key.ACTIVATION_SPEC, o, cpm));
+                           beanValidationObjects.add(o);
+                           associateResourceAdapter(resourceAdapter, o);
+                        }
+                     }
+                  }
+               }
+            }
+
+            // AdminObject
+            if (cmd.getVersion() != Version.V_10)
+            {
+               ResourceAdapter1516 ra1516 = (ResourceAdapter1516) cmd.getResourceadapter();
+               if (ra1516 != null && ra1516.getAdminObjects() != null)
+               {
+                  List<AdminObject> aoMetas = ((ResourceAdapter1516) cmd.getResourceadapter()).getAdminObjects();
+                  if (aoMetas.size() > 0)
+                  {
+                     for (AdminObject aoMeta : aoMetas)
+                     {
+                        if (aoMeta.getAdminobjectClass() != null &&
+                            aoMeta.getAdminobjectClass().getValue() != null)
+                        {
+                           Object o =
+                              initAndInject(aoMeta.getAdminobjectClass().getValue(), aoMeta.getConfigProperties(),
+                                            cl);
+
+                           if (trace)
+                           {
+                              log.trace("AdminObject: " + o.getClass().getName());
+                              log.trace("AdminObject defined in classloader: " + o.getClass().getClassLoader());
+                           }
+
+                           archiveValidationObjects
+                                 .add(new ValidateObject(Key.ADMIN_OBJECT, o, aoMeta.getConfigProperties()));
+                           beanValidationObjects.add(o);
+                        }
+                     }
+                  }
+               }
+            }
+         }
+
+         // Archive validation
+         partialFailures = validateArchive(url, archiveValidationObjects);
+
+         if (partialFailures != null)
+         {
+            if (failures == null)
+            {
+               failures = new HashSet<Failure>();
+            }
+            failures.addAll(partialFailures);
+         }
+
+         if ((getConfiguration().getArchiveValidationFailOnWarn() && hasFailuresLevel(failures, Severity.WARNING)) ||
+             (getConfiguration().getArchiveValidationFailOnError() && hasFailuresLevel(failures, Severity.ERROR)))
+         {
+            throw new ValidatorException(printFailuresLog(url.getPath(), new Validator(), failures, null), failures);
+         }
+         else
+         {
+            printFailuresLog(url.getPath(), new Validator(), failures, null);
+         }
+
+         // Bean validation
+         if (getConfiguration().getBeanValidation())
+         {
+            List<Class> groupsClasses = null;
+
+            if (raxml.getBeanValidationGroups() != null &&
+                raxml.getBeanValidationGroups().size() > 0)
+            {
+               List<String> groups = raxml.getBeanValidationGroups();
+
+               groupsClasses = new ArrayList<Class>(groups.size());
+               for (String group : groups)
+               {
+                  groupsClasses.add(Class.forName(group, true, cl));
+               }
+            }
+
+            if (beanValidationObjects.size() > 0)
+            {
+               BeanValidation beanValidator = new BeanValidation();
+               for (Object o : beanValidationObjects)
+               {
+                  beanValidator.validate(o, groupsClasses);
+               }
+            }
+         }
+
+         // Activate deployment
+         if (resourceAdapter != null)
+         {
+            String bootstrapIdentifier = null;
+
+            if (raxml.getBootstrapContext() != null &&
+                !raxml.getBootstrapContext().trim().equals(""))
+            {
+               bootstrapIdentifier = raxml.getBootstrapContext();
+            }
+
+            startContext(resourceAdapter, bootstrapIdentifier);
+         }
+
+         log.info("Deployed: " + url.toExternalForm());
+
+         return new RaXmlDeployment(url, 
+                                    deployment,
+                                    deploymentName, 
+                                    resourceAdapter, 
+                                    getConfiguration().getJndiStrategy(), 
+                                    getConfiguration().getMetadataRepository(), 
+                                    cfs,
+                                    jndiNames, 
+                                    cl,
+                                    log);
+      }
+      catch (DeployException de)
+      {
+         // Just rethrow
+         throw de;
+      }
+      catch (Throwable t)
+      {
+         if ((getConfiguration().getArchiveValidationFailOnWarn() && hasFailuresLevel(failures, Severity.WARNING)) ||
+             (getConfiguration().getArchiveValidationFailOnError() && hasFailuresLevel(failures, Severity.ERROR)))
+            throw new DeployException("Deployment " + url.toExternalForm() + " failed",
+                  new ValidatorException(printFailuresLog(url.getPath(), new Validator(), failures, null), failures));
+         else
+         {
+            printFailuresLog(url.getPath(), new Validator(), failures, null);
+            throw new DeployException("Deployment " + url.toExternalForm() + " failed", t);
+         }
+      }
+      finally
+      {
+         SecurityActions.setThreadContextClassLoader(oldTCCL);
+      }
+   }
+
+   /**
+    * Find the JNDI name for a connection factory
+    * @param clz The fully quilified class name for the managed connection factory
+    * @param defs The connection definitions
+    * @return The JNDI name
+    */
+   private org.jboss.jca.common.api.metadata.common.ConnectionDefinition findConnectionDefinition(String clz,
+      List<org.jboss.jca.common.api.metadata.common.ConnectionDefinition> defs)
+   {
+      if (defs != null)
+      {
+         // If there is only one we will return that
+         if (defs.size() == 1)
+            return defs.get(0);
+
+         // If there are multiple definitions the MCF class name is mandatory
+         if (clz == null)
+            throw new IllegalArgumentException("ManagedConnectionFactory must be defined in class-name");
+
+         for (org.jboss.jca.common.api.metadata.common.ConnectionDefinition cd : defs)
+         {
+            if (clz.equals(cd.getClassName()))
+               return cd;
+         }
+      }
+
+      return null;
+   }
+
+   /**
+    * Start
+    */
+   @Override
+   public void start()
+   {
+      super.start();
+
+      if (kernel == null)
+         throw new IllegalStateException("Kernel not defined");
+   }
+}

Added: projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RaXmlDeployment.java
===================================================================
--- projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RaXmlDeployment.java	                        (rev 0)
+++ projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/fungal/RaXmlDeployment.java	2010-09-08 21:05:36 UTC (rev 108058)
@@ -0,0 +1,184 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008-2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.deployers.fungal;
+
+import org.jboss.jca.core.spi.mdr.MetadataRepository;
+import org.jboss.jca.core.spi.naming.JndiStrategy;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.URL;
+
+import javax.resource.spi.ResourceAdapter;
+
+import org.jboss.logging.Logger;
+
+import com.github.fungal.spi.deployers.Deployment;
+
+/**
+ * A -ra.xml deployment for JCA/SJC
+ * @author <a href="mailto:jesper.pedersen at jboss.org">Jesper Pedersen</a>
+ */
+public class RaXmlDeployment implements Deployment
+{
+   /** The logger */
+   private Logger log;
+
+   /** The deployment */
+   private URL deployment;
+
+   /** The resource adapter deployment */
+   private URL raDeployment;
+
+   /** The deployment name */
+   private String deploymentName;
+
+   /** The resource adapter instance */
+   private ResourceAdapter ra;
+
+   /** The JNDI strategy */
+   private JndiStrategy jndiStrategy;
+
+   /** The MDR */
+   private MetadataRepository mdr;
+
+   /** The connection factories */
+   private Object[] cfs;
+
+   /** The JNDI names of the connection factories */
+   private String[] jndis;
+
+   /** The classloader */
+   private ClassLoader cl;
+
+   /**
+    * Constructor
+    * @param deployment The deployment
+    * @param raDeployment The resource adapter deployment
+    * @param deploymentName The deployment name
+    * @param ra The resource adapter instance if present
+    * @param jndiStrategy The JNDI strategy
+    * @param metadataRepository The metadata repository
+    * @param cfs The connection factories
+    * @param jndis The JNDI names of the connection factories
+    * @param cl The classloader for the deployment
+    * @param log The logger
+    */
+   public RaXmlDeployment(URL deployment, 
+                          URL raDeployment,
+                          String deploymentName,
+                          ResourceAdapter ra, 
+                          JndiStrategy jndiStrategy,
+                          MetadataRepository metadataRepository,
+                          Object[] cfs, 
+                          String[] jndis, 
+                          ClassLoader cl,
+                          Logger log)
+   {
+      this.deployment = deployment;
+      this.raDeployment = raDeployment;
+      this.deploymentName = deploymentName;
+      this.ra = ra;
+      this.jndiStrategy = jndiStrategy;
+      this.mdr = metadataRepository;
+      this.cfs = cfs;
+      this.jndis = jndis;
+      this.cl = cl;
+      this.log = log;
+   }
+
+   /**
+    * Get the unique URL for the deployment
+    * @return The URL
+    */
+   public URL getURL()
+   {
+      return deployment;
+   }
+
+   /**
+    * Get the classloader
+    * @return The classloader
+    */
+   public ClassLoader getClassLoader()
+   {
+      return cl;
+   }
+
+   /**
+    * Stop
+    */
+   public void stop()
+   {
+      log.debug("Undeploying: " + deployment.toExternalForm());
+
+      if (mdr != null && cfs != null && jndis != null)
+      {
+         for (int i = 0; i < cfs.length; i++)
+         {
+            String cf = cfs[i].getClass().getName();
+            String jndi = jndis[i];
+
+            mdr.unregisterJndiMapping(raDeployment, cf, jndi);
+         }
+      }
+
+      if (cfs != null && jndis != null)
+      {
+         try
+         {
+            jndiStrategy.unbindConnectionFactories(deploymentName, cfs, jndis);
+         }
+         catch (Throwable t)
+         {
+            log.warn("Exception during JNDI unbinding", t);
+         }
+      }
+
+      if (ra != null)
+      {
+         ra.stop();
+         ra = null;
+      }
+   }
+
+   /**
+    * Destroy
+    */
+   public void destroy()
+   {
+      if (cl != null && cl instanceof Closeable)
+      {
+         try
+         {
+            ((Closeable)cl).close();
+         }
+         catch (IOException ioe)
+         {
+            // Swallow
+         }
+      }
+
+      log.info("Undeployed: " + deployment.toExternalForm());
+   }
+}

Added: projects/jboss-jca/trunk/deployers/src/test/java/org/jboss/jca/test/deployers/spec/RaXmlTestCase.java
===================================================================
--- projects/jboss-jca/trunk/deployers/src/test/java/org/jboss/jca/test/deployers/spec/RaXmlTestCase.java	                        (rev 0)
+++ projects/jboss-jca/trunk/deployers/src/test/java/org/jboss/jca/test/deployers/spec/RaXmlTestCase.java	2010-09-08 21:05:36 UTC (rev 108058)
@@ -0,0 +1,164 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008-2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.test.deployers.spec;
+
+import org.jboss.jca.deployers.fungal.RAActivator;
+import org.jboss.jca.embedded.EmbeddedJCA;
+
+import java.io.File;
+import java.net.URL;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.jboss.logging.Logger;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ * Test cases for deploying resource adapter archives (.RAR) using -ra.xml files
+ * for activation
+ * 
+ * @author <a href="mailto:jesper.pedersen at jboss.org">Jesper Pedersen</a>
+ * @version $Revision: $
+ */
+public class RaXmlTestCase
+{
+
+   // --------------------------------------------------------------------------------||
+   // Class Members ------------------------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   private static Logger log = Logger.getLogger(RaXmlTestCase.class);
+
+   private static final String JNDI_PREFIX = "java:/eis/";
+
+   /*
+    * Embedded
+    */
+   private static EmbeddedJCA embedded;
+
+   // --------------------------------------------------------------------------------||
+   // Tests --------------------------------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   /**
+    * ra16out.rar
+    * @throws Throwable throwable exception 
+    */
+   @Test
+   public void testRa16out() throws Throwable
+   {
+      URL archive = getURL("ra16out.rar");
+      URL raXml = getURL("test" + File.separator + "ra16out-ra.xml");
+      Context context = null;
+ 
+      try
+      {
+         embedded.deploy(archive);
+         embedded.deploy(raXml);
+
+         context = new InitialContext();
+         Object o = context.lookup(JNDI_PREFIX + "ra16out-raxml");
+         assertNotNull(o);
+      }
+      catch (Throwable t)
+      {
+         log.error(t.getMessage(), t);
+         fail(t.getMessage());
+      }
+      finally
+      {
+         if (context != null)
+         {
+            try
+            {
+               context.close();
+            }
+            catch (NamingException ne)
+            {
+               // Ignore
+            }
+         }
+
+         embedded.undeploy(raXml);
+         embedded.undeploy(archive);
+      }
+   }
+
+   // --------------------------------------------------------------------------------||
+   // Lifecycle Methods --------------------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   /**
+    * Lifecycle start, before the suite is executed
+    * @throws Throwable throwable exception 
+    */
+   @BeforeClass
+   public static void beforeClass() throws Throwable
+   {
+      // Create and set an embedded JCA instance
+      embedded = new EmbeddedJCA();
+
+      // Startup
+      embedded.startup();
+
+      // Disable RAActivator
+      RAActivator raa = embedded.lookup("RAActivator", RAActivator.class);
+      
+      if (raa == null)
+         throw new IllegalStateException("RAActivator not defined");
+
+      raa.setEnabled(false);
+   }
+
+   /**
+    * Lifecycle stop, after the suite is executed
+    * @throws Throwable throwable exception 
+    */
+   @AfterClass
+   public static void afterClass() throws Throwable
+   {
+      // Shutdown embedded
+      embedded.shutdown();
+
+      // Set embedded to null
+      embedded = null;
+   }
+
+   /**
+    * Get the URL for a test archive
+    * @param archive The name of the test archive
+    * @return The URL to the archive
+    * @throws Throwable throwable exception
+    */
+   public URL getURL(String archive) throws Throwable
+   {
+      File f = new File(System.getProperty("archives.dir") + File.separator + archive);
+      return f.toURI().toURL();
+   }
+}

Added: projects/jboss-jca/trunk/deployers/src/test/resources/ra16out-ra.xml
===================================================================
--- projects/jboss-jca/trunk/deployers/src/test/resources/ra16out-ra.xml	                        (rev 0)
+++ projects/jboss-jca/trunk/deployers/src/test/resources/ra16out-ra.xml	2010-09-08 21:05:36 UTC (rev 108058)
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<resource-adapters>
+  <resource-adapter>
+    <archive>ra16out.rar</archive>
+    <connection-definitions>
+      <connection-definition jndi-name="java:/eis/ra16out-raxml"
+                             class-name="org.jboss.jca.test.deployers.spec.rars.ra16out.TestManagedConnectionFactory">
+      </connection-definition>
+    </connection-definitions>
+  </resource-adapter>
+</resource-adapters>

Modified: projects/jboss-jca/trunk/doc/userguide/en/modules/configuration.xml
===================================================================
--- projects/jboss-jca/trunk/doc/userguide/en/modules/configuration.xml	2010-09-08 21:03:39 UTC (rev 108057)
+++ projects/jboss-jca/trunk/doc/userguide/en/modules/configuration.xml	2010-09-08 21:05:36 UTC (rev 108058)
@@ -288,6 +288,13 @@
                   </entry>
                 </row>
                 <row>
+                  <entry><code>Enabled</code></entry>
+                  <entry><code>boolean</code></entry>
+                  <entry>
+                    Should the activator be enabled. Default is <code>true</code>
+                  </entry>
+                </row>
+                <row>
                   <entry><code>Kernel</code></entry>
                   <entry><code>com.github.fungal.api.Kernel</code></entry>
                   <entry>

Modified: projects/jboss-jca/trunk/doc/userguide/en/modules/embedded.xml
===================================================================
--- projects/jboss-jca/trunk/doc/userguide/en/modules/embedded.xml	2010-09-08 21:03:39 UTC (rev 108057)
+++ projects/jboss-jca/trunk/doc/userguide/en/modules/embedded.xml	2010-09-08 21:05:36 UTC (rev 108058)
@@ -161,6 +161,37 @@
 
         <para>See the IronJacamar Embedded API documentation for additional functionality.</para>
 
+        <section id="embedded_usage_automaticactivation">
+          <title>Automatic activation of archives</title>
+
+          <para>IronJacamar features a bean called <code>RAActivator</code> which will automatic
+            create a JNDI binding for connection factories and administration objects. However, 
+            sometimes it is of benefit to define these bindings in a <code>-ra.xml</code> file, and therefore
+            <code>RAActivator</code> has to be disabled during that deployment phase.</para>
+          
+          <para>This done by using the following code snippet</para>
+
+          <programlisting>
+import org.jboss.jca.deployers.fungal.RAActivator;
+
+// Disable RAActivator
+RAActivator raa = embedded.lookup("RAActivator", RAActivator.class);
+
+if (raa == null)
+   throw new IllegalStateException("RAActivator not defined");
+
+raa.setEnabled(false);
+
+embedded.deploy("myrar.rar");
+embedded.deploy("myrar-ra.xml");
+
+raa.setEnabled(true);
+          </programlisting>
+
+          <para>which disables the bean, does the deployments and then reenables the bean again.</para>
+
+        </section>
+
       </section>
 
       <section id="embedded_usage_advanced">

Modified: projects/jboss-jca/trunk/embedded/src/main/resources/jca.xml
===================================================================
--- projects/jboss-jca/trunk/embedded/src/main/resources/jca.xml	2010-09-08 21:03:39 UTC (rev 108057)
+++ projects/jboss-jca/trunk/embedded/src/main/resources/jca.xml	2010-09-08 21:05:36 UTC (rev 108058)
@@ -124,9 +124,14 @@
     <property name="XATerminator"><inject bean="TransactionManager" property="XATerminator"/></property>
   </bean>
 
-  <!-- JNDI strategy -->
-  <bean name="JndiStrategy"
+  <!-- Explicit JNDI strategy -->
+  <bean name="ExplicitJndiStrategy"
         interface="org.jboss.jca.core.spi.naming.JndiStrategy"
+        class="org.jboss.jca.core.naming.ExplicitJndiStrategy"/>
+
+  <!-- Simple JNDI strategy -->
+  <bean name="SimpleJndiStrategy"
+        interface="org.jboss.jca.core.spi.naming.JndiStrategy"
         class="org.jboss.jca.core.naming.SimpleJndiStrategy"/>
 
   <!-- MDR -->
@@ -134,8 +139,8 @@
         interface="org.jboss.jca.core.spi.mdr.MetadataRepository"
         class="org.jboss.jca.core.mdr.SimpleMetadataRepository"/>
 
-  <!-- RA configuration -->
-  <bean name="RAConfiguration"
+  <!-- Deployer configuration -->
+  <bean name="DeployerConfiguration"
         class="org.jboss.jca.deployers.fungal.RAConfiguration">
     <property name="ArchiveValidation">true</property>
     <property name="ArchiveValidationFailOnWarn">false</property>
@@ -143,24 +148,49 @@
     <property name="BeanValidation">true</property>
     <property name="PrintStream"><inject bean="JBossStdioContext" property="Out"/></property>
     <property name="DefaultBootstrapContext"><inject bean="DefaultBootstrapContext"/></property>
-    <property name="JndiStrategy"><inject bean="JndiStrategy"/></property>
+    <property name="JndiStrategy"><inject bean="ExplicitJndiStrategy"/></property>
     <property name="TransactionManager"><inject bean="RealTransactionManager"/></property>
     <property name="MetadataRepository"><inject bean="MDR"/></property>
   </bean>
 
+  <!-- Activator configuration -->
+  <bean name="ActivatorConfiguration"
+        class="org.jboss.jca.deployers.fungal.RAConfiguration">
+    <property name="ArchiveValidation">true</property>
+    <property name="ArchiveValidationFailOnWarn">false</property>
+    <property name="ArchiveValidationFailOnError">true</property>
+    <property name="BeanValidation">true</property>
+    <property name="PrintStream"><inject bean="JBossStdioContext" property="Out"/></property>
+    <property name="DefaultBootstrapContext"><inject bean="DefaultBootstrapContext"/></property>
+    <property name="JndiStrategy"><inject bean="SimpleJndiStrategy"/></property>
+    <property name="TransactionManager"><inject bean="RealTransactionManager"/></property>
+    <property name="MetadataRepository"><inject bean="MDR"/></property>
+  </bean>
+
   <!-- RA deployer -->
   <bean name="RADeployer"
         interface="com.github.fungal.spi.deployers.Deployer"
         class="org.jboss.jca.deployers.fungal.RADeployer">
-    <property name="Configuration"><inject bean="RAConfiguration"/></property>
+    <property name="Configuration"><inject bean="DeployerConfiguration"/></property>
     <depends>BeanValidation</depends>
     <depends>JBossStdioContextSelector</depends>
   </bean>
 
+  <!-- -ra.xml deployer -->
+  <bean name="RaXmlDeployer"
+        interface="com.github.fungal.spi.deployers.Deployer" 
+        class="org.jboss.jca.deployers.fungal.RaXmlDeployer">
+    <property name="Configuration"><inject bean="DeployerConfiguration"/></property>
+    <property name="Kernel"><inject bean="Kernel"/></property>
+    <depends>BeanValidation</depends>
+    <depends>JBossStdioContextSelector</depends>
+  </bean>
+
   <!-- RA activator -->
   <bean name="RAActivator" 
         class="org.jboss.jca.deployers.fungal.RAActivator">
-    <property name="Configuration"><inject bean="RAConfiguration"/></property>
+    <property name="Configuration"><inject bean="ActivatorConfiguration"/></property>
+    <property name="Enabled">true</property>
     <property name="Kernel"><inject bean="Kernel"/></property>
     <property name="ExcludeArchives">
       <set elementClass="java.lang.String">

Modified: projects/jboss-jca/trunk/sjc/src/main/resources/bootstrap/jca.xml
===================================================================
--- projects/jboss-jca/trunk/sjc/src/main/resources/bootstrap/jca.xml	2010-09-08 21:03:39 UTC (rev 108057)
+++ projects/jboss-jca/trunk/sjc/src/main/resources/bootstrap/jca.xml	2010-09-08 21:05:36 UTC (rev 108058)
@@ -127,9 +127,14 @@
     <property name="XATerminator"><inject bean="TransactionManager" property="XATerminator"/></property>
   </bean>
 
-  <!-- JNDI strategy -->
-  <bean name="JndiStrategy"
+  <!-- Explicit JNDI strategy -->
+  <bean name="ExplicitJndiStrategy"
         interface="org.jboss.jca.core.spi.naming.JndiStrategy"
+        class="org.jboss.jca.core.naming.ExplicitJndiStrategy"/>
+
+  <!-- Simple JNDI strategy -->
+  <bean name="SimpleJndiStrategy"
+        interface="org.jboss.jca.core.spi.naming.JndiStrategy"
         class="org.jboss.jca.core.naming.SimpleJndiStrategy"/>
 
   <!-- MDR -->
@@ -137,8 +142,8 @@
         interface="org.jboss.jca.core.spi.mdr.MetadataRepository"
         class="org.jboss.jca.core.mdr.SimpleMetadataRepository"/>
 
-  <!-- RA configuration -->
-  <bean name="RAConfiguration"
+  <!-- Deployer configuration -->
+  <bean name="DeployerConfiguration"
         class="org.jboss.jca.deployers.fungal.RAConfiguration">
     <property name="ArchiveValidation">true</property>
     <property name="ArchiveValidationFailOnWarn">false</property>
@@ -146,24 +151,49 @@
     <property name="BeanValidation">true</property>
     <property name="PrintStream"><inject bean="JBossStdioContext" property="Out"/></property>
     <property name="DefaultBootstrapContext"><inject bean="DefaultBootstrapContext"/></property>
-    <property name="JndiStrategy"><inject bean="JndiStrategy"/></property>
+    <property name="JndiStrategy"><inject bean="ExplicitJndiStrategy"/></property>
     <property name="TransactionManager"><inject bean="RealTransactionManager"/></property>
     <property name="MetadataRepository"><inject bean="MDR"/></property>
   </bean>
 
+  <!-- Activator configuration -->
+  <bean name="ActivatorConfiguration"
+        class="org.jboss.jca.deployers.fungal.RAConfiguration">
+    <property name="ArchiveValidation">true</property>
+    <property name="ArchiveValidationFailOnWarn">false</property>
+    <property name="ArchiveValidationFailOnError">true</property>
+    <property name="BeanValidation">true</property>
+    <property name="PrintStream"><inject bean="JBossStdioContext" property="Out"/></property>
+    <property name="DefaultBootstrapContext"><inject bean="DefaultBootstrapContext"/></property>
+    <property name="JndiStrategy"><inject bean="SimpleJndiStrategy"/></property>
+    <property name="TransactionManager"><inject bean="RealTransactionManager"/></property>
+    <property name="MetadataRepository"><inject bean="MDR"/></property>
+  </bean>
+
   <!-- RA deployer -->
   <bean name="RADeployer"
         interface="com.github.fungal.spi.deployers.Deployer" 
         class="org.jboss.jca.deployers.fungal.RADeployer">
-    <property name="Configuration"><inject bean="RAConfiguration"/></property>
+    <property name="Configuration"><inject bean="DeployerConfiguration"/></property>
     <depends>BeanValidation</depends>
     <depends>JBossStdioContextSelector</depends>
   </bean>
 
+  <!-- -ra.xml deployer -->
+  <bean name="RaXmlDeployer"
+        interface="com.github.fungal.spi.deployers.Deployer" 
+        class="org.jboss.jca.deployers.fungal.RaXmlDeployer">
+    <property name="Configuration"><inject bean="DeployerConfiguration"/></property>
+    <property name="Kernel"><inject bean="Kernel"/></property>
+    <depends>BeanValidation</depends>
+    <depends>JBossStdioContextSelector</depends>
+  </bean>
+
   <!-- RA activator -->
   <bean name="RAActivator" 
         class="org.jboss.jca.deployers.fungal.RAActivator">
-    <property name="Configuration"><inject bean="RAConfiguration"/></property>
+    <property name="Configuration"><inject bean="ActivatorConfiguration"/></property>
+    <property name="Enabled">true</property>
     <property name="Kernel"><inject bean="Kernel"/></property>
     <property name="ExcludeArchives">
       <set elementClass="java.lang.String">



More information about the jboss-cvs-commits mailing list