[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