From eebc822dff5dadc675fb955cc400fd268d10b939 Mon Sep 17 00:00:00 2001 From: Dirk Mahler Date: Fri, 9 Dec 2011 13:09:50 +0100 Subject: [PATCH] DATACMNS-110 - Added support for CDI integration for repositories. Added custom CDI extension to use repositories in a CDI environment. Base class picks up all Spring Data repository interfaces and allows working with qualifiers to bind beans to be created to qualifiers. --- spring-data-commons-core/pom.xml | 25 +++ .../repository/cdi/CdiRepositoryBean.java | 208 ++++++++++++++++++ .../cdi/CdiRepositoryExtensionSupport.java | 127 +++++++++++ .../support/RepositoryFactorySupport.java | 2 +- .../cdi/CdiRepositoryBeanUnitTests.java | 123 +++++++++++ ...itoryExtensionSupportIntegrationTests.java | 40 ++++ .../repository/cdi/DummyCdiExtension.java | 68 ++++++ .../data/repository/cdi/RepositoryClient.java | 28 +++ .../data/repository/cdi/SampleRepository.java | 28 +++ .../repository/cdi/StereotypeAnnotation.java | 27 +++ ...itoryExtensionSupportIntegrationTests.java | 48 ++++ .../src/test/resources/META-INF/beans.xml | 6 + .../javax.enterprise.inject.spi.Extension | 1 + spring-data-commons-core/template.mf | 2 + 14 files changed, 732 insertions(+), 1 deletion(-) create mode 100644 spring-data-commons-core/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryBean.java create mode 100644 spring-data-commons-core/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryExtensionSupport.java create mode 100644 spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/CdiRepositoryBeanUnitTests.java create mode 100644 spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/CdiRepositoryExtensionSupportIntegrationTests.java create mode 100644 spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/DummyCdiExtension.java create mode 100644 spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/RepositoryClient.java create mode 100644 spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/SampleRepository.java create mode 100644 spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/StereotypeAnnotation.java create mode 100644 spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/WebbeansCdiRepositoryExtensionSupportIntegrationTests.java create mode 100644 spring-data-commons-core/src/test/resources/META-INF/beans.xml create mode 100644 spring-data-commons-core/src/test/resources/META-INF/services/javax.enterprise.inject.spi.Extension diff --git a/spring-data-commons-core/pom.xml b/spring-data-commons-core/pom.xml index 83adecb62..f2ae174b1 100644 --- a/spring-data-commons-core/pom.xml +++ b/spring-data-commons-core/pom.xml @@ -13,6 +13,8 @@ 2.2.0 + 1.0 + 1.1.3 @@ -96,6 +98,29 @@ 3.0 true + + + + javax.enterprise + cdi-api + ${cdi.version} + provided + true + + + + javax.el + el-api + ${cdi.version} + test + + + + org.apache.openwebbeans.test + cditest-owb + ${webbeans.version} + test + diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryBean.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryBean.java new file mode 100644 index 000000000..9e2885a04 --- /dev/null +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryBean.java @@ -0,0 +1,208 @@ +/* + * Copyright 2011 the original author or authors. + * + * 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.springframework.data.repository.cdi; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import javax.enterprise.context.spi.CreationalContext; +import javax.enterprise.inject.Alternative; +import javax.enterprise.inject.Stereotype; +import javax.enterprise.inject.spi.Bean; +import javax.enterprise.inject.spi.BeanManager; +import javax.enterprise.inject.spi.InjectionPoint; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.util.Assert; + +/** + * Base class for {@link Bean} wrappers. + * + * @author Dirk Mahler + * @author Oliver Gierke + */ +public abstract class CdiRepositoryBean implements Bean { + + private static final Log LOG = LogFactory.getLog(CdiRepositoryBean.class); + + private final Set qualifiers; + private final Class repositoryType; + private final BeanManager beanManager; + + /** + * Creates a new {@link CdiRepositoryBean}. + * + * @param qualifiers must not be {@literal null}. + * @param repositoryType has to be an interface must not be {@literal null}. + */ + public CdiRepositoryBean(Set qualifiers, Class repositoryType, BeanManager beanManager) { + + Assert.notNull(qualifiers); + Assert.notNull(beanManager); + Assert.notNull(repositoryType); + Assert.isTrue(repositoryType.isInterface()); + + this.qualifiers = qualifiers; + this.repositoryType = repositoryType; + this.beanManager = beanManager; + } + + /* + * (non-Javadoc) + * @see javax.enterprise.inject.spi.Bean#getTypes() + */ + @SuppressWarnings("rawtypes") + public Set getTypes() { + + Set interfaces = new HashSet(); + interfaces.add(repositoryType); + interfaces.addAll(Arrays.asList(repositoryType.getInterfaces())); + + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Declaring types '%s' for repository '%s'.", interfaces.toString(), + repositoryType.getName())); + } + + return new HashSet(interfaces); + } + + /** + * Returns an instance of an {@link EntityManager}. + * + * @param beanManager The BeanManager. + * @param bean The bean representing an EntityManager. + * @return The EntityManager instance. + */ + @SuppressWarnings("unchecked") + protected S getDependencyInstance(Bean bean, Class type) { + CreationalContext creationalContext = beanManager.createCreationalContext(bean); + return (S) beanManager.getReference(bean, type, creationalContext); + } + + /* + * (non-Javadoc) + * @see javax.enterprise.context.spi.Contextual#create(javax.enterprise.context.spi.CreationalContext) + */ + public final T create(CreationalContext creationalContext) { + + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Creating bean instance for repository type '%s'.", repositoryType.getName())); + } + return create(creationalContext, repositoryType); + } + + /* + * (non-Javadoc) + * @see javax.enterprise.context.spi.Contextual#destroy(java.lang.Object, javax.enterprise.context.spi.CreationalContext) + */ + public void destroy(T instance, CreationalContext creationalContext) { + + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Destroying bean instance %s for repository type '%s'.", instance.toString(), + repositoryType.getName())); + } + + creationalContext.release(); + } + + /* + * (non-Javadoc) + * @see javax.enterprise.inject.spi.Bean#getQualifiers() + */ + public Set getQualifiers() { + return qualifiers; + } + + /* + * (non-Javadoc) + * @see javax.enterprise.inject.spi.Bean#getName() + */ + public String getName() { + return repositoryType.getName(); + } + + /* + * (non-Javadoc) + * @see javax.enterprise.inject.spi.Bean#getStereotypes() + */ + public Set> getStereotypes() { + + Set> stereotypes = new HashSet>(); + + for (Annotation annotation : repositoryType.getAnnotations()) { + Class annotationType = annotation.annotationType(); + if (annotationType.isAnnotationPresent(Stereotype.class)) { + stereotypes.add(annotationType); + } + } + + return stereotypes; + } + + /* + * (non-Javadoc) + * @see javax.enterprise.inject.spi.Bean#getBeanClass() + */ + public Class getBeanClass() { + return repositoryType; + } + + /* + * (non-Javadoc) + * @see javax.enterprise.inject.spi.Bean#isAlternative() + */ + public boolean isAlternative() { + return repositoryType.isAnnotationPresent(Alternative.class); + } + + /* + * (non-Javadoc) + * @see javax.enterprise.inject.spi.Bean#isNullable() + */ + public boolean isNullable() { + return false; + } + + /* + * (non-Javadoc) + * @see javax.enterprise.inject.spi.Bean#getInjectionPoints() + */ + public Set getInjectionPoints() { + return Collections.emptySet(); + } + + /** + * @param creationalContext + * @param repositoryType + * @return + */ + protected abstract T create(CreationalContext creationalContext, Class repositoryType); + + /* + * (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return String + .format("JpaRepositoryBean: type='%s', qualifiers=%s", repositoryType.getName(), qualifiers.toString()); + } +} diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryExtensionSupport.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryExtensionSupport.java new file mode 100644 index 000000000..bfa89698f --- /dev/null +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/cdi/CdiRepositoryExtensionSupport.java @@ -0,0 +1,127 @@ +/* + * Copyright 2011 the original author or authors. + * + * 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.springframework.data.repository.cdi; + +import java.lang.annotation.Annotation; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import javax.enterprise.event.Observes; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Default; +import javax.enterprise.inject.spi.AnnotatedType; +import javax.enterprise.inject.spi.Extension; +import javax.enterprise.inject.spi.ProcessAnnotatedType; +import javax.enterprise.util.AnnotationLiteral; +import javax.inject.Qualifier; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.data.repository.NoRepositoryBean; +import org.springframework.data.repository.Repository; +import org.springframework.data.repository.RepositoryDefinition; + +/** + * Base class for {@link Extension} implementations that create instances for Spring Data repositories. + * + * @author Dirk Mahler + * @author Oliver Gierke + */ +public abstract class CdiRepositoryExtensionSupport implements Extension { + + private static final Log LOGGER = LogFactory.getLog(CdiRepositoryExtensionSupport.class); + + private final Map, Set> repositoryTypes = new HashMap, Set>(); + + /** + * Implementation of a an observer which checks for Spring Data repository types and stores them in + * {@link #repositoryTypes} for later registration as bean type. + * + * @param The type. + * @param processAnnotatedType The annotated type as defined by CDI. + */ + protected void processAnnotatedType(@Observes ProcessAnnotatedType processAnnotatedType) { + + AnnotatedType annotatedType = processAnnotatedType.getAnnotatedType(); + Class repositoryType = annotatedType.getJavaClass(); + + if (isRepository(repositoryType)) { + + // Determine the qualifiers of the repository type. + Set qualifiers = getQualifiers(repositoryType); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(String.format("Discovered repository type '%s' with qualifiers %s.", repositoryType.getName(), + qualifiers)); + } + // Store the repository type using its qualifiers. + repositoryTypes.put(repositoryType, qualifiers); + } + } + + /** + * Returns whether the given type is a repository type. + * + * @param type must not be {@literal null}. + * @return + */ + private boolean isRepository(Class type) { + + boolean isInterface = type.isInterface(); + boolean extendsRepository = Repository.class.isAssignableFrom(type); + boolean isAnnotated = type.isAnnotationPresent(RepositoryDefinition.class); + boolean excludedByAnnotation = type.isAnnotationPresent(NoRepositoryBean.class); + + return isInterface && (extendsRepository || isAnnotated) && !excludedByAnnotation; + } + + /** + * Determines the qualifiers of the given type. + */ + @SuppressWarnings("serial") + private Set getQualifiers(final Class type) { + + Set qualifiers = new HashSet(); + Annotation[] annotations = type.getAnnotations(); + for (Annotation annotation : annotations) { + Class annotationType = annotation.annotationType(); + if (annotationType.isAnnotationPresent(Qualifier.class)) { + qualifiers.add(annotation); + } + } + // Add @Default qualifier if no qualifier is specified. + if (qualifiers.isEmpty()) { + qualifiers.add(new AnnotationLiteral() { + }); + } + // Add @Any qualifier. + qualifiers.add(new AnnotationLiteral() { + }); + return qualifiers; + } + + /** + * Provides access to all repository types as well as their qualifiers. + * + * @return + */ + protected Iterable, Set>> getRepositoryTypes() { + return repositoryTypes.entrySet(); + } +} diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java index 31722b581..8e8ef5c39 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java @@ -105,7 +105,7 @@ public abstract class RepositoryFactorySupport { * @param repositoryInterface * @return */ - public > T getRepository(Class repositoryInterface) { + public T getRepository(Class repositoryInterface) { return getRepository(repositoryInterface, null); } diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/CdiRepositoryBeanUnitTests.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/CdiRepositoryBeanUnitTests.java new file mode 100644 index 000000000..61709b55f --- /dev/null +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/CdiRepositoryBeanUnitTests.java @@ -0,0 +1,123 @@ +/* + * Copyright 2011 the original author or authors. + * + * 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.springframework.data.repository.cdi; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +import java.io.Serializable; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; + +import javax.enterprise.context.spi.CreationalContext; +import javax.enterprise.inject.spi.BeanManager; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.data.repository.Repository; + +/** + * Unit tests for {@link CdiRepositoryBean}. + * + * @author Oliver Gierke + */ +@RunWith(MockitoJUnitRunner.class) +public class CdiRepositoryBeanUnitTests { + + static final Set NO_ANNOTATIONS = Collections.emptySet(); + + @Mock + BeanManager beanManager; + + @Test(expected = IllegalArgumentException.class) + public void voidRejectsNullQualifiers() { + new DummyCdiRepositoryBean(null, SampleRepository.class, beanManager); + } + + @Test(expected = IllegalArgumentException.class) + public void voidRejectsNullRepositoryType() { + new DummyCdiRepositoryBean(NO_ANNOTATIONS, null, beanManager); + } + + @Test(expected = IllegalArgumentException.class) + public void voidRejectsNullBeanManager() { + new DummyCdiRepositoryBean(NO_ANNOTATIONS, SampleRepository.class, null); + } + + @Test + public void returnsBasicMetadata() { + + DummyCdiRepositoryBean bean = new DummyCdiRepositoryBean( + NO_ANNOTATIONS, SampleRepository.class, beanManager); + + assertThat(bean.getBeanClass(), is(typeCompatibleWith(SampleRepository.class))); + assertThat(bean.getName(), is(SampleRepository.class.getName())); + assertThat(bean.isNullable(), is(false)); + } + + @Test + @SuppressWarnings("unchecked") + public void returnsAllImplementedTypes() { + + DummyCdiRepositoryBean bean = new DummyCdiRepositoryBean( + NO_ANNOTATIONS, SampleRepository.class, beanManager); + + Set types = bean.getTypes(); + assertThat(types.size(), is(2)); + assertThat(types.containsAll(Arrays.asList(SampleRepository.class, Repository.class)), is(true)); + } + + @Test + public void detectsStereotypes() { + + DummyCdiRepositoryBean bean = new DummyCdiRepositoryBean( + NO_ANNOTATIONS, StereotypedSampleRepository.class, beanManager); + + Set> stereotypes = bean.getStereotypes(); + assertThat(stereotypes.size(), is(1)); + assertThat(stereotypes, hasItem(StereotypeAnnotation.class)); + } + + static class DummyCdiRepositoryBean extends CdiRepositoryBean { + + public DummyCdiRepositoryBean(Set qualifiers, Class repositoryType, BeanManager beanManager) { + super(qualifiers, repositoryType, beanManager); + } + + public Class getScope() { + return null; + } + + @Override + protected T create(CreationalContext creationalContext, Class repositoryType) { + return null; + } + } + + static interface SampleRepository extends Repository { + + } + + @StereotypeAnnotation + static interface StereotypedSampleRepository { + + } +} diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/CdiRepositoryExtensionSupportIntegrationTests.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/CdiRepositoryExtensionSupportIntegrationTests.java new file mode 100644 index 000000000..37ea8f616 --- /dev/null +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/CdiRepositoryExtensionSupportIntegrationTests.java @@ -0,0 +1,40 @@ +/* + * Copyright 2011 the original author or authors. + * + * 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.springframework.data.repository.cdi; + +import static org.junit.Assert.*; +import static org.hamcrest.CoreMatchers.*; + +import org.junit.Test; + +/** + * Common integration tests for Spring Data repository CDI extension. + * + * @author Oliver Gierke + */ +public abstract class CdiRepositoryExtensionSupportIntegrationTests { + + @Test + public void createsSpringDataRepositoryBean() { + + assertThat(getBean(SampleRepository.class), is(notNullValue())); + + RepositoryClient client = getBean(RepositoryClient.class); + assertThat(client.repository, is(notNullValue())); + } + + protected abstract T getBean(Class type); +} diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/DummyCdiExtension.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/DummyCdiExtension.java new file mode 100644 index 000000000..389589b91 --- /dev/null +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/DummyCdiExtension.java @@ -0,0 +1,68 @@ +/* + * Copyright 2011 the original author or authors. + * + * 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.springframework.data.repository.cdi; + +import java.lang.annotation.Annotation; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Map.Entry; +import java.util.Set; + +import javax.enterprise.context.NormalScope; +import javax.enterprise.context.spi.CreationalContext; +import javax.enterprise.event.Observes; +import javax.enterprise.inject.spi.AfterBeanDiscovery; +import javax.enterprise.inject.spi.BeanManager; + +import org.mockito.Mockito; + +/** + * Dummy extension of {@link CdiRepositoryExtensionSupport} to allow integration tests. Will create mocks for repository + * interfaces being found. + * + * @author Oliver Gierke + */ +public class DummyCdiExtension extends CdiRepositoryExtensionSupport { + + @SuppressWarnings({ "rawtypes", "unchecked" }) + void afterBeanDiscovery(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) { + for (Entry, Set> type : getRepositoryTypes()) { + afterBeanDiscovery.addBean(new DummyCdiRepositoryBean(type.getValue(), type.getKey(), beanManager)); + } + } + + static class DummyCdiRepositoryBean extends CdiRepositoryBean { + + public DummyCdiRepositoryBean(Set qualifiers, Class repositoryType, BeanManager beanManager) { + super(qualifiers, repositoryType, beanManager); + } + + public Class getScope() { + return MyScope.class; + } + + @Override + protected T create(CreationalContext creationalContext, Class repositoryType) { + return Mockito.mock(repositoryType); + } + } + + @NormalScope + @Retention(RetentionPolicy.RUNTIME) + @interface MyScope { + + } +} diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/RepositoryClient.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/RepositoryClient.java new file mode 100644 index 000000000..a43c75d7b --- /dev/null +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/RepositoryClient.java @@ -0,0 +1,28 @@ +/* + * Copyright 2011 the original author or authors. + * + * 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.springframework.data.repository.cdi; + +import javax.inject.Inject; + +/** + * + * @author Oliver Gierke + */ +class RepositoryClient { + + @Inject + SampleRepository repository; +} diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/SampleRepository.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/SampleRepository.java new file mode 100644 index 000000000..1b3a9fd15 --- /dev/null +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/SampleRepository.java @@ -0,0 +1,28 @@ +/* + * Copyright 2011 the original author or authors. + * + * 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.springframework.data.repository.cdi; + +import java.io.Serializable; + +import org.springframework.data.repository.Repository; + +/** + * + * @author Oliver Gierke + */ +public interface SampleRepository extends Repository { + +} diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/StereotypeAnnotation.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/StereotypeAnnotation.java new file mode 100644 index 000000000..10d448aff --- /dev/null +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/StereotypeAnnotation.java @@ -0,0 +1,27 @@ +/* + * Copyright 2011 the original author or authors. + * + * 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.springframework.data.repository.cdi; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.enterprise.inject.Stereotype; + +@Stereotype +@Retention(RetentionPolicy.RUNTIME) +@interface StereotypeAnnotation { + +} diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/WebbeansCdiRepositoryExtensionSupportIntegrationTests.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/WebbeansCdiRepositoryExtensionSupportIntegrationTests.java new file mode 100644 index 000000000..e61c8858d --- /dev/null +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/cdi/WebbeansCdiRepositoryExtensionSupportIntegrationTests.java @@ -0,0 +1,48 @@ +/* + * Copyright 2011 the original author or authors. + * + * 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.springframework.data.repository.cdi; + +import org.apache.webbeans.cditest.CdiTestContainer; +import org.apache.webbeans.cditest.CdiTestContainerLoader; +import org.junit.AfterClass; +import org.junit.BeforeClass; + +/** + * CDI extension integration test using OpenWebbeans. + * + * @author Oliver Gierke + */ +public class WebbeansCdiRepositoryExtensionSupportIntegrationTests extends CdiRepositoryExtensionSupportIntegrationTests { + + static CdiTestContainer container; + + @BeforeClass + public static void setUp() throws Exception { + + container = CdiTestContainerLoader.getCdiContainer(); + container.bootContainer(); + } + + @Override + protected T getBean(Class type) { + return container.getInstance(type); + } + + @AfterClass + public static void tearDown() throws Exception { + container.shutdownContainer(); + } +} diff --git a/spring-data-commons-core/src/test/resources/META-INF/beans.xml b/spring-data-commons-core/src/test/resources/META-INF/beans.xml new file mode 100644 index 000000000..73ae3a251 --- /dev/null +++ b/spring-data-commons-core/src/test/resources/META-INF/beans.xml @@ -0,0 +1,6 @@ + + + + diff --git a/spring-data-commons-core/src/test/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/spring-data-commons-core/src/test/resources/META-INF/services/javax.enterprise.inject.spi.Extension new file mode 100644 index 000000000..8282234ee --- /dev/null +++ b/spring-data-commons-core/src/test/resources/META-INF/services/javax.enterprise.inject.spi.Extension @@ -0,0 +1 @@ +org.springframework.data.repository.cdi.DummyCdiExtension \ No newline at end of file diff --git a/spring-data-commons-core/template.mf b/spring-data-commons-core/template.mf index 332e69927..4b4acc13d 100644 --- a/spring-data-commons-core/template.mf +++ b/spring-data-commons-core/template.mf @@ -6,6 +6,8 @@ Import-Package: sun.reflect;version="0";resolution:=optional Import-Template: com.mysema.query.*;version="[2.2.0,3.0.0)";resolution:=optional, + javax.enterprise.*;version="${cdi.version:[=.=.=,+1.0.0)}";resolution:=optional, + javax.inject.*;version="[1.0.0,2.0.0)";resolution:=optional, org.springframework.aop.*;version="${org.springframework.version.30:[=.=.=,+1.0.0)}", org.springframework.beans.*;version="${org.springframework.version.30:[=.=.=,+1.0.0)}", org.springframework.core.*;version="${org.springframework.version.30:[=.=.=,+1.0.0)}",