[jboss-svn-commits] JBoss Common SVN: r4337 - in arquillian/trunk/containers/openejb: src/main/java/org/jboss/arquillian and 11 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Apr 28 14:47:13 EDT 2010


Author: ALRubinger
Date: 2010-04-28 14:47:10 -0400 (Wed, 28 Apr 2010)
New Revision: 4337

Added:
   arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/
   arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/
   arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/api/
   arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/api/ArquillianContext.java
   arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/api/openejb/
   arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/api/openejb/OpenEJBArquillianContext.java
   arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/
   arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/ArquillianContextResolver.java
   arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/BaseContext.java
   arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/BaseContextualResolver.java
   arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/openejb/
   arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/openejb/OpenEJBArquillianContextImpl.java
   arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/openejb/OpenEJBJndiContextResolver.java
   arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/spi/
   arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/spi/ContextualResolver.java
   arquillian/trunk/containers/openejb/src/test/java/org/jboss/arquillian/prototyping/
   arquillian/trunk/containers/openejb/src/test/java/org/jboss/arquillian/prototyping/context/
   arquillian/trunk/containers/openejb/src/test/java/org/jboss/arquillian/prototyping/context/OpenEJBArquillianContextTestCase.java
Modified:
   arquillian/trunk/containers/openejb/pom.xml
   arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/openejb/OpenEJBContainer.java
   arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/openejb/OpenEJBTestEnricher.java
Log:
[ARQ-125] Prototype an ArquillianContext communications channel between the test and ARQ

Modified: arquillian/trunk/containers/openejb/pom.xml
===================================================================
--- arquillian/trunk/containers/openejb/pom.xml	2010-04-27 15:26:21 UTC (rev 4336)
+++ arquillian/trunk/containers/openejb/pom.xml	2010-04-28 18:47:10 UTC (rev 4337)
@@ -25,6 +25,7 @@
 
     <!-- Versioning -->
     <version.org.apache.openejb_openejb.core>3.1.2</version.org.apache.openejb_openejb.core>
+    <version.javax.inject_javax.inject>1</version.javax.inject_javax.inject>
 
   </properties>
 
@@ -72,6 +73,14 @@
       <version>${version.org.apache.openejb_openejb.core}</version>
     </dependency>
 
+
+   <!-- Part of prototyping, extract when ready -->
+   <dependency>
+    <groupId>javax.inject</groupId>
+    <artifactId>javax.inject</artifactId>
+    <version>${version.javax.inject_javax.inject}</version>
+   </dependency>
+
   </dependencies>
 </project>
 

Modified: arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/openejb/OpenEJBContainer.java
===================================================================
--- arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/openejb/OpenEJBContainer.java	2010-04-27 15:26:21 UTC (rev 4336)
+++ arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/openejb/OpenEJBContainer.java	2010-04-28 18:47:10 UTC (rev 4337)
@@ -92,6 +92,7 @@
       try
       {
          appInfo = config.configureApplication(archive);
+         context.add(AppInfo.class, appInfo);
          this.deployment = appInfo;
       }
       catch (final OpenEJBException e)

Modified: arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/openejb/OpenEJBTestEnricher.java
===================================================================
--- arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/openejb/OpenEJBTestEnricher.java	2010-04-27 15:26:21 UTC (rev 4336)
+++ arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/openejb/OpenEJBTestEnricher.java	2010-04-28 18:47:10 UTC (rev 4337)
@@ -16,13 +16,20 @@
  */
 package org.jboss.arquillian.openejb;
 
-import java.util.Properties;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.List;
 
-
+import javax.inject.Inject;
 import javax.naming.Binding;
 import javax.naming.InitialContext;
 import javax.naming.NamingEnumeration;
 
+import org.apache.openejb.assembler.classic.AppInfo;
+import org.jboss.arquillian.prototyping.context.api.ArquillianContext;
+import org.jboss.arquillian.prototyping.context.impl.openejb.OpenEJBArquillianContextImpl;
 import org.jboss.arquillian.spi.Context;
 import org.jboss.arquillian.spi.TestEnricher;
 import org.jboss.arquillian.testenricher.ejb.EJBInjectionEnricher;
@@ -35,39 +42,95 @@
  * @author <a href="mailto:aslak at conduct.no">Aslak Knutsen</a>
  * @version $Revision: $
  */
-public class OpenEJBTestEnricher extends EJBInjectionEnricher 
+public class OpenEJBTestEnricher extends EJBInjectionEnricher
 {
 
+   private ArquillianContext arquillianContext = null;
+   
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.arquillian.testenricher.ejb.EJBInjectionEnricher#enrich(org.jboss.arquillian.spi.Context, java.lang.Object)
+    */
    @Override
-   protected InitialContext createContext(Context context) throws Exception
+   public void enrich(Context context, Object testCase)
    {
-      final Properties properties = new Properties();
-      properties.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.LocalInitialContextFactory");
-      return new InitialContext(properties);
+      // Call the super implementation to handle @EJB
+      super.enrich(context, testCase);
+      
+      
+
+      // Handle Typesafe @Inject (ie. ask Arquillian for a an instance of the field type with no additional context properties)
+      final Class<? extends Annotation> inject = (Class<? extends Annotation>) Inject.class;
+      List<Field> fieldsWithInject = this.getFieldsWithAnnotation(testCase.getClass(), inject);
+      for (final Field field : fieldsWithInject)
+      {
+         // Set accessible if it's not
+         if (!field.isAccessible())
+         {
+            AccessController.doPrivileged(new PrivilegedAction<Void>()
+            {
+
+               @Override
+               public Void run()
+               {
+                  field.setAccessible(true);
+
+                  // Return
+                  return null;
+               }
+            });
+         }
+         try
+         {
+            field.set(testCase, this.getArquillianContext(context).get(field.getType()));
+         }
+         catch (final IllegalAccessException e)
+         {
+            throw new RuntimeException("Could not inject into " + field.getName() + " of test case: " + testCase, e);
+         }
+      }
+
    }
 
+   protected ArquillianContext getArquillianContext(final Context context){
+      if(arquillianContext==null)
+      {
+      // Make a context
+         final AppInfo deployment = context.get(AppInfo.class);
+         arquillianContext = new OpenEJBArquillianContextImpl(deployment);  
+      }return arquillianContext;
+   }
+   
    @Override
+   protected InitialContext createContext(final Context context) throws Exception
+   {
+      return this.getArquillianContext(context).get(InitialContext.class);
+   }
+
+   @Override
    protected Object lookupEJB(Context context, Class<?> fieldType) throws Exception
    {
       InitialContext initcontext = createContext(context);
       return lookupRecursive(fieldType, initcontext, initcontext.listBindings("/"));
    }
-   
-   protected Object lookupRecursive(Class<?> fieldType, javax.naming.Context context, NamingEnumeration<Binding> contextNames) throws Exception 
+
+   //TODO No, no no: we must look up a known location from metadata, not search for a matching type in the whole JNDI tree
+   protected Object lookupRecursive(Class<?> fieldType, javax.naming.Context context,
+         NamingEnumeration<Binding> contextNames) throws Exception
    {
-      while(contextNames.hasMore())
+      while (contextNames.hasMore())
       {
          Binding contextName = contextNames.nextElement();
          Object value = contextName.getObject();
-         if(javax.naming.Context.class.isInstance(value)) 
+         if (javax.naming.Context.class.isInstance(value))
          {
-            javax.naming.Context subContext = (javax.naming.Context)value;
+            javax.naming.Context subContext = (javax.naming.Context) value;
             return lookupRecursive(fieldType, subContext, subContext.listBindings("/"));
          }
-         else 
+         else
          {
             value = context.lookup(contextName.getName());
-            if(fieldType.isInstance(value))
+            if (fieldType.isInstance(value))
             {
                return value;
             }

Added: arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/api/ArquillianContext.java
===================================================================
--- arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/api/ArquillianContext.java	                        (rev 0)
+++ arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/api/ArquillianContext.java	2010-04-28 18:47:10 UTC (rev 4337)
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed 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.jboss.arquillian.prototyping.context.api;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+
+/**
+ * Represents a hook from the user test into the backing
+ * Arquillian subsystem.  From here we may request resources
+ * programatically.  Containers are to support
+ * injection of this context via {@link Inject} during the test
+ * enrichment process.
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public interface ArquillianContext
+{
+   //-------------------------------------------------------------------------------------||
+   // Contracts --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Obtains an instance of the requested type from Arquillian
+    * or the underlying target container.  To provide additional 
+    * context, see {@link ArquillianContext#get(Class, Map)}.
+    * 
+    * @return An instance of the type requested, or null if none is supported
+    *   by the container for the given arguments
+    * @param type The type of object to be returned from the container
+    * @throws IllegalArgumentException If the type if not specified
+    */
+   <T> T get(Class<T> type) throws IllegalArgumentException;
+
+   /**
+    * Obtains an instance of the requested type from Arquillian
+    * or the underlying target container.  The supplied properties
+    * may be used to define additional context used to resolve
+    * the correct instance to be returned: for instance @EJB injection
+    * by type may also require a beanName to be deterministic. 
+    * 
+    * @return An instance of the type requested, or null if none is supported
+    *   by the container for the given arguments
+    * @param type The type of object to be returned from the container
+    * @param properties Additional context used to determine object resolution.
+    *   The keys and values contained herein may be container-specific
+    * @throws IllegalArgumentException If either argument is not specified
+    */
+   <T> T get(Class<T> type, Map<String, Object> properties) throws IllegalArgumentException;
+
+}

Added: arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/api/openejb/OpenEJBArquillianContext.java
===================================================================
--- arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/api/openejb/OpenEJBArquillianContext.java	                        (rev 0)
+++ arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/api/openejb/OpenEJBArquillianContext.java	2010-04-28 18:47:10 UTC (rev 4337)
@@ -0,0 +1,42 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed 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.jboss.arquillian.prototyping.context.api.openejb;
+
+import org.apache.openejb.assembler.classic.AppInfo;
+import org.jboss.arquillian.prototyping.context.api.ArquillianContext;
+
+/**
+ * OpenEJB-specific extension to the {@link ArquillianContext} hook 
+ * provided as an available injection resource to tests.  Extends support
+ * to make available OpenEJB APIs regarding the deployment and test in question.
+ * 
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public interface OpenEJBArquillianContext extends ArquillianContext
+{
+   //-------------------------------------------------------------------------------------||
+   // Contracts --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Returns the OpenEJB object model metadata representing the
+    * deployment in play
+    */
+   AppInfo getDeploymentMetadata();
+}

Added: arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/ArquillianContextResolver.java
===================================================================
--- arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/ArquillianContextResolver.java	                        (rev 0)
+++ arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/ArquillianContextResolver.java	2010-04-28 18:47:10 UTC (rev 4337)
@@ -0,0 +1,84 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed 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.jboss.arquillian.prototyping.context.impl;
+
+import java.util.Map;
+
+import org.jboss.arquillian.prototyping.context.api.ArquillianContext;
+import org.jboss.arquillian.prototyping.context.spi.ContextualResolver;
+
+/**
+ * {@link ContextualResolver} implementation which can resolve
+ * to a supplied {@link ArquillianContext}
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class ArquillianContextResolver extends BaseContextualResolver implements ContextualResolver
+{
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * The instance to be returned if requesting an {@link ArquillianContext}
+    */
+   private final ArquillianContext delegate;
+
+   //-------------------------------------------------------------------------------------||
+   // Constructor ------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Constructs a new instance which is to resolve {@link ArquillianContext}s
+    * to the specified instance
+    * @param delegate The instance to be returned if {@link ArquillianContextResolver#get(Class, Map)}
+    * encounters a request for {@link ArquillianContext} type
+    * @throws IllegalArgumentException If the delegate is not specified
+    */
+   public ArquillianContextResolver(final ArquillianContext delegate) throws IllegalArgumentException
+   {
+      // Precondition checks
+      if (delegate == null)
+      {
+         throw new IllegalArgumentException("delegate must be specified");
+      }
+      this.delegate = delegate;
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Required Implementations -----------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.arquillian.prototyping.context.spi.ContextualResolver#resolve(java.lang.Class, java.util.Map)
+    */
+   @Override
+   public <T> T resolve(final Class<T> type, final Map<String, Object> properties) throws IllegalArgumentException
+   {
+
+      // Do we handle this?
+      if (ArquillianContext.class.isAssignableFrom(type))
+      {
+         return type.cast(delegate);
+      }
+
+      // None found
+      return null;
+   }
+}

Added: arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/BaseContext.java
===================================================================
--- arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/BaseContext.java	                        (rev 0)
+++ arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/BaseContext.java	2010-04-28 18:47:10 UTC (rev 4337)
@@ -0,0 +1,49 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed 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.jboss.arquillian.prototyping.context.impl;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.jboss.arquillian.prototyping.context.api.ArquillianContext;
+
+/**
+ * Base for implementations of {@link ArquillianContext}.
+ * Provides container non-specific support. 
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public abstract class BaseContext implements ArquillianContext
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Required Implementations -----------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.arquillian.prototyping.context.api.ArquillianContext#get(java.lang.Class)
+    */
+   @Override
+   public <T> T get(final Class<T> type) throws IllegalArgumentException
+   {
+      final Map<String, Object> properties = Collections.emptyMap();
+      return this.get(type, properties);
+   }
+
+}

Added: arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/BaseContextualResolver.java
===================================================================
--- arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/BaseContextualResolver.java	                        (rev 0)
+++ arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/BaseContextualResolver.java	2010-04-28 18:47:10 UTC (rev 4337)
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed 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.jboss.arquillian.prototyping.context.impl;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.jboss.arquillian.prototyping.context.spi.ContextualResolver;
+
+/**
+ * Base for implementations of {@link ContextualResolver}.
+ * Provides container non-specific support. 
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public abstract class BaseContextualResolver implements ContextualResolver
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Required Implementations -----------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.arquillian.prototyping.context.spi.ContextualResolver#get(java.lang.Class)
+    */
+   @Override
+   public <T> T get(final Class<T> type) throws IllegalArgumentException
+   {
+      final Map<String, Object> properties = Collections.emptyMap();
+      return this.resolve(type, properties);
+   }
+}

Added: arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/openejb/OpenEJBArquillianContextImpl.java
===================================================================
--- arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/openejb/OpenEJBArquillianContextImpl.java	                        (rev 0)
+++ arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/openejb/OpenEJBArquillianContextImpl.java	2010-04-28 18:47:10 UTC (rev 4337)
@@ -0,0 +1,153 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed 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.jboss.arquillian.prototyping.context.impl.openejb;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.openejb.assembler.classic.AppInfo;
+import org.jboss.arquillian.prototyping.context.api.ArquillianContext;
+import org.jboss.arquillian.prototyping.context.api.openejb.OpenEJBArquillianContext;
+import org.jboss.arquillian.prototyping.context.impl.ArquillianContextResolver;
+import org.jboss.arquillian.prototyping.context.impl.BaseContext;
+import org.jboss.arquillian.prototyping.context.spi.ContextualResolver;
+
+/**
+ * OpenEJB Container implementation of a {@link ArquillianContext}. 
+ * TODO Explain more.
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class OpenEJBArquillianContextImpl extends BaseContext implements OpenEJBArquillianContext
+{
+
+   /*
+    * TODO: Much of this logic is generic and should go into a base ChainedDelegatingContext
+    * which consults a resolver chain (first match should be OK).  Only the definition of 
+    * which resolvers in the chain are container-specific, and this is how we achieve composition
+    */
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Logger
+    */
+   private static final Logger log = Logger.getLogger(OpenEJBArquillianContextImpl.class.getName());
+
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Delegate resolver chain
+    */
+   private final List<ContextualResolver> resolvers;
+
+   /**
+    * OpenEJB Metadata Deployment View 
+    */
+   private final AppInfo deployment;
+
+   //-------------------------------------------------------------------------------------||
+   // Constructor ------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Creates a new instance, setting all delegate resolvers
+    * @param deployment The OpenEJB metadata representing the deployment
+    * @throws IllegalArgumentException If the deployment is not specified
+    */
+   public OpenEJBArquillianContextImpl(final AppInfo deployment) throws IllegalArgumentException
+   {
+      // Precondition checks
+      if (deployment == null)
+      {
+         throw new IllegalArgumentException("deployment must be specified");
+      }
+
+      // Create resolvers
+      final List<ContextualResolver> resolvers = new ArrayList<ContextualResolver>();
+
+      // Add resolvers
+      resolvers.add(new ArquillianContextResolver(this));
+      resolvers.add(OpenEJBJndiContextResolver.getInstance());
+
+      // Log
+      if (log.isLoggable(Level.FINE))
+      {
+         log.fine("Using resolvers: " + resolvers);
+      }
+
+      // Set
+      this.resolvers = Collections.unmodifiableList(resolvers);
+      this.deployment = deployment;
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Required Implementations -----------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.arquillian.prototyping.context.api.ArquillianContext#get(java.lang.Class, java.util.Map)
+    */
+   @Override
+   public <T> T get(final Class<T> type, final Map<String, Object> properties) throws IllegalArgumentException
+   {
+      // Precondition checks
+      if (type == null)
+      {
+         throw new IllegalArgumentException("type must be specified");
+      }
+      if (properties == null)
+      {
+         throw new IllegalArgumentException("properties must be specified");
+      }
+
+      // Delegate to the chain
+      for (final ContextualResolver resolver : resolvers)
+      {
+         // Attempt to find a match from the delegate
+         final T resolved = resolver.resolve(type, properties);
+         // If we've found one, return
+         if (resolved != null)
+         {
+            return resolved;
+         }
+      }
+
+      // No conditions met
+      return null;
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.arquillian.prototyping.context.api.openejb.OpenEJBArquillianContext#getDeploymentMetadata()
+    */
+   @Override
+   public AppInfo getDeploymentMetadata()
+   {
+      return deployment;
+   }
+}

Added: arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/openejb/OpenEJBJndiContextResolver.java
===================================================================
--- arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/openejb/OpenEJBJndiContextResolver.java	                        (rev 0)
+++ arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/impl/openejb/OpenEJBJndiContextResolver.java	2010-04-28 18:47:10 UTC (rev 4337)
@@ -0,0 +1,133 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed 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.jboss.arquillian.prototyping.context.impl.openejb;
+
+import java.util.Map;
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.jboss.arquillian.prototyping.context.impl.BaseContextualResolver;
+import org.jboss.arquillian.prototyping.context.spi.ContextualResolver;
+
+/**
+ * {@link ContextualResolver} implementation which can resolve/create 
+ * JNDI {@link Context}s for the OpenEJB Container.  This resolver will
+ * default the property {@link Context#INITIAL_CONTEXT_FACTORY}, then apply all
+ * supplied user contextual properties to create and return a new {@link InitialContext}
+ * instance.
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class OpenEJBJndiContextResolver extends BaseContextualResolver implements ContextualResolver
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Singleton instance
+    */
+   private static final OpenEJBJndiContextResolver INSTANCE = new OpenEJBJndiContextResolver();
+
+   /**
+    * Value for {@link Context#INITIAL_CONTEXT_FACTORY} for OpenEJB
+    */
+   private static final String PROP_VALUE_OPENEJB_INITIAL_CONTEXT_FACTORY = "org.apache.openejb.client.LocalInitialContextFactory";
+
+   //-------------------------------------------------------------------------------------||
+   // Constructor ------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Internal constructor; use instead {@link OpenEJBJndiContextResolver#getInstance()}
+    */
+   private OpenEJBJndiContextResolver()
+   {
+
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Factory ----------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Obtains the single instance
+    */
+   public static OpenEJBJndiContextResolver getInstance()
+   {
+      return INSTANCE;
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Required Implementations -----------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.arquillian.prototyping.context.spi.ContextualResolver#resolve(java.lang.Class, java.util.Map)
+    */
+   @Override
+   public <T> T resolve(final Class<T> type, final Map<String, Object> properties) throws IllegalArgumentException
+   {
+
+      // JNDI Context
+      if (Context.class.isAssignableFrom(type))
+      {
+         return type.cast(createJndiContext(properties));
+      }
+
+      // None found
+      return null;
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Internal Helper Methods ------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Creates a JNDI Naming context using the specified properties.  Will automatically
+    * specify {@link Context#INITIAL_CONTEXT_FACTORY} if not explicitly 
+    * supplied in properties
+    */
+   private Context createJndiContext(final Map<String, Object> properties)
+   {
+      // Create JNDI Context props
+      final Properties propsUsedInContextCreation = new Properties();
+
+      // Default the initial context property
+      propsUsedInContextCreation.put(Context.INITIAL_CONTEXT_FACTORY, PROP_VALUE_OPENEJB_INITIAL_CONTEXT_FACTORY);
+
+      // Load in the user-defined properties
+      propsUsedInContextCreation.putAll(properties);
+
+      // Create a new JNDI Context
+      try
+      {
+         return new InitialContext(propsUsedInContextCreation);
+      }
+      catch (final NamingException e)
+      {
+         throw new RuntimeException("Could not create new JNDI Context", e);
+      }
+
+   }
+}

Added: arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/spi/ContextualResolver.java
===================================================================
--- arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/spi/ContextualResolver.java	                        (rev 0)
+++ arquillian/trunk/containers/openejb/src/main/java/org/jboss/arquillian/prototyping/context/spi/ContextualResolver.java	2010-04-28 18:47:10 UTC (rev 4337)
@@ -0,0 +1,68 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed 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.jboss.arquillian.prototyping.context.spi;
+
+import java.util.Map;
+
+/**
+ * An entity capable of resolving a given type and
+ * optional contextual properties to an implementation
+ * instance.  In practice this may be used by Arquillian or
+ * backing containers to supply resources such as EJB or 
+ * JNDI Naming Context references.  The contextual properties
+ * consulted will vary per implementation, and should be used
+ * when pure type-based resolution techniques are insufficient
+ * or non-deterministic. 
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public interface ContextualResolver
+{
+   //-------------------------------------------------------------------------------------||
+   // Contracts --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Obtains an instance of the requested type from Arquillian
+    * or the underlying target container.  To provide additional 
+    * context, see {@link ContextualResolver#resolve(Class, Map)}.
+    * 
+    * @return An instance of the type requested, or null if none is supported
+    *   by the container for the given arguments
+    * @param type The type of object to be returned from the container
+    * @throws IllegalArgumentException If the type if not specified
+    */
+   <T> T get(Class<T> type) throws IllegalArgumentException;
+
+   /**
+    * Obtains an instance of the requested type from Arquillian
+    * or the underlying target container.  The supplied properties
+    * may be used to define additional context used to resolve
+    * the correct instance to be returned: for instance @EJB injection
+    * by type may also require a beanName to be deterministic. 
+    * 
+    * @return An instance of the type requested, or null if none is supported
+    *   by the container for the given arguments
+    * @param type The type of object to be returned from the container
+    * @param properties Additional context used to determine object resolution.
+    *   The keys and values contained herein may be container-specific
+    * @throws IllegalArgumentException If either argument is not specified
+    */
+   <T> T resolve(Class<T> type, Map<String, Object> properties) throws IllegalArgumentException;
+
+}

Added: arquillian/trunk/containers/openejb/src/test/java/org/jboss/arquillian/prototyping/context/OpenEJBArquillianContextTestCase.java
===================================================================
--- arquillian/trunk/containers/openejb/src/test/java/org/jboss/arquillian/prototyping/context/OpenEJBArquillianContextTestCase.java	                        (rev 0)
+++ arquillian/trunk/containers/openejb/src/test/java/org/jboss/arquillian/prototyping/context/OpenEJBArquillianContextTestCase.java	2010-04-28 18:47:10 UTC (rev 4337)
@@ -0,0 +1,149 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed 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.jboss.arquillian.prototyping.context;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import javax.inject.Inject;
+import javax.naming.AuthenticationException;
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+import junit.framework.TestCase;
+
+import org.jboss.arquillian.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.arquillian.openejb.ejb.EchoBean;
+import org.jboss.arquillian.openejb.ejb.EchoLocalBusiness;
+import org.jboss.arquillian.prototyping.context.api.ArquillianContext;
+import org.jboss.arquillian.prototyping.context.api.openejb.OpenEJBArquillianContext;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests that integration with the backing container via 
+ * {@link OpenEJBArquillianContext} is in place as contracted
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+ at RunWith(Arquillian.class)
+public class OpenEJBArquillianContextTestCase
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Logger
+    */
+   private static final Logger log = Logger.getLogger(OpenEJBArquillianContextTestCase.class.getName());
+
+   /**
+    * JNDI Name that OpenEJB will assign to our deployment
+    */
+   private static final String JNDI_NAME = "EchoBeanLocal";
+
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * TODO: We don't really need a deployment
+    */
+   @Deployment
+   public static JavaArchive createDeployment()
+   {
+      return ShrinkWrap.create("slsb.jar", JavaArchive.class).addClasses(EchoLocalBusiness.class, EchoBean.class);
+   }
+
+   /**
+    * The hook to the ARQ container, and by extension, OpenEJB
+    */
+   @Inject
+   private OpenEJBArquillianContext arquillianContext;
+
+   //-------------------------------------------------------------------------------------||
+   // Tests ------------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Ensures that we may inject an {@link ArquillianContext}
+    * into the test
+    */
+   @Test
+   public void injectArquillianContext()
+   {
+      Assert.assertNotNull("Arquillian context should have been injected", arquillianContext);
+   }
+
+   /**
+    * Ensures we can get at OpenEJB deployment metadata
+    * from the {@link OpenEJBArquillianContext} 
+    */
+   @Test
+   public void deploymentMetadata()
+   {
+      final String ejbName = arquillianContext.getDeploymentMetadata().ejbJars.get(0).enterpriseBeans.get(0).ejbName;
+      log.info("Got EJB Name: " + ejbName);
+      Assert.assertEquals("Did not obtain correct EJB name from deployment metadata", EchoBean.class.getSimpleName(),
+            ejbName);
+   }
+
+   /**
+    * Ensures we can create an OpenEJB-specific JNDI {@link Context} via the 
+    * {@link OpenEJBArquillianContext} 
+    */
+   @Test
+   public void programmaticNamingContext() throws NamingException
+   {
+      final Context context = arquillianContext.get(Context.class);
+      Assert.assertNotNull("Should be able to look up EJB via naming context obtained from Arquillian context", context
+            .lookup(JNDI_NAME));
+   }
+
+   /**
+    * Ensures we can create an OpenEJB-specific JNDI {@link Context} via the 
+    * {@link OpenEJBArquillianContext} which supports/respects context propreties
+    */
+   @Test
+   public void programmaticNamingContextWithProperties() throws NamingException
+   {
+      final Map<String, Object> props = new HashMap<String, Object>();
+      props.put(Context.SECURITY_PRINCIPAL, "testuser");
+      props.put(Context.SECURITY_CREDENTIALS, "testpassword");
+      try
+      {
+         // This should fail on construction, because we haven't a matching user/pass configured in OpenEJB
+         arquillianContext.get(Context.class, props);
+      }
+      catch (final RuntimeException re)
+      {
+         // Validates that the props we passed in were respected when making the naming context
+         Assert.assertEquals(AuthenticationException.class, re.getCause().getClass());
+         return;
+      }
+      TestCase.fail("Should have obtained exception on logging in with bad user/pass config");
+
+   }
+}



More information about the jboss-svn-commits mailing list