) bean));
+ }
+ }
+ }
+
+ /**
+ * Implementation of a an observer which registers beans to the CDI container for the detected Spring Data
+ * repositories.
+ *
+ * The repository beans are associated to the CouchbaseOperations using their qualifiers.
+ *
+ * @param beanManager The BeanManager instance.
+ */
+ void afterBeanDiscovery(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) {
+ for (Map.Entry, Set> entry : getRepositoryTypes()) {
+
+ Class> repositoryType = entry.getKey();
+ Set qualifiers = entry.getValue();
+
+ CdiRepositoryBean> repositoryBean = createRepositoryBean(repositoryType, qualifiers, beanManager);
+ afterBeanDiscovery.addBean(repositoryBean);
+ registerBean(repositoryBean);
+ }
+ }
+
+ /**
+ * Creates a {@link Bean}.
+ *
+ * @param The type of the repository.
+ * @param repositoryType The class representing the repository.
+ * @param beanManager The BeanManager instance.
+ * @return The bean.
+ */
+ private CdiRepositoryBean createRepositoryBean(Class repositoryType, Set qualifiers, BeanManager beanManager) {
+
+ Bean couchbaseOperationsBean = this.couchbaseOperationsMap.get(qualifiers
+ .toString());
+
+ if (couchbaseOperationsBean == null) {
+ throw new UnsatisfiedResolutionException(String.format("Unable to resolve a bean for '%s' with qualifiers %s.",
+ CouchbaseOperations.class.getName(), qualifiers));
+ }
+
+ return new CouchbaseRepositoryBean(couchbaseOperationsBean, qualifiers, repositoryType, beanManager, getCustomImplementationDetector());
+ }
+}
diff --git a/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
new file mode 100644
index 00000000..6645e6b1
--- /dev/null
+++ b/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -0,0 +1 @@
+org.springframework.data.couchbase.repository.cdi.CouchbaseRepositoryExtension
\ No newline at end of file
diff --git a/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepository.java b/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepository.java
new file mode 100644
index 00000000..4e29e7d0
--- /dev/null
+++ b/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepository.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2014 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.couchbase.repository.cdi;
+
+import org.springframework.data.couchbase.repository.CouchbaseRepository;
+import org.springframework.data.couchbase.repository.User;
+
+/**
+ * @author Mark Paluch
+ */
+public interface CdiPersonRepository extends CouchbaseRepository, CdiPersonRepositoryCustom {
+
+}
diff --git a/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepositoryCustom.java b/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepositoryCustom.java
new file mode 100644
index 00000000..ddf5d76b
--- /dev/null
+++ b/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepositoryCustom.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2014 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.couchbase.repository.cdi;
+
+/**
+ * @author Mark Paluch
+ */
+public interface CdiPersonRepositoryCustom {
+
+ int returnTwo();
+
+}
diff --git a/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepositoryImpl.java b/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepositoryImpl.java
new file mode 100644
index 00000000..d963bc71
--- /dev/null
+++ b/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiPersonRepositoryImpl.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2014 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.couchbase.repository.cdi;
+
+/**
+ * @author Mark Paluch
+ */
+public class CdiPersonRepositoryImpl implements CdiPersonRepositoryCustom {
+
+ @Override
+ public int returnTwo() {
+ return 2;
+ }
+}
diff --git a/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryClient.java b/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryClient.java
new file mode 100644
index 00000000..9fab73d0
--- /dev/null
+++ b/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryClient.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2014 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.couchbase.repository.cdi;
+
+import javax.inject.Inject;
+
+import com.couchbase.client.CouchbaseClient;
+import org.springframework.data.couchbase.repository.UserRepository;
+
+/**
+ * @author Mark Paluch
+ */
+class CdiRepositoryClient {
+
+ @Inject
+ private CdiPersonRepository cdiPersonRepository;
+
+ @Inject
+ private CouchbaseClient couchbaseClient;
+
+ public CdiPersonRepository getCdiPersonRepository() {
+ return cdiPersonRepository;
+ }
+
+ public CouchbaseClient getCouchbaseClient() {
+ return couchbaseClient;
+ }
+}
diff --git a/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryTests.java b/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryTests.java
new file mode 100644
index 00000000..b4c91043
--- /dev/null
+++ b/src/test/java/org/springframework/data/couchbase/repository/cdi/CdiRepositoryTests.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2014 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.couchbase.repository.cdi;
+
+import static org.junit.Assert.*;
+
+import org.apache.webbeans.cditest.CdiTestContainer;
+import org.apache.webbeans.cditest.CdiTestContainerLoader;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.couchbase.client.CouchbaseClient;
+import com.couchbase.client.protocol.views.DesignDocument;
+import com.couchbase.client.protocol.views.ViewDesign;
+
+/**
+ * @author Mark Paluch
+ */
+public class CdiRepositoryTests {
+
+ private static CdiTestContainer cdiContainer;
+ private CdiPersonRepository repository;
+ private CouchbaseClient couchbaseClient;
+
+ @BeforeClass
+ public static void init() throws Exception {
+ cdiContainer = CdiTestContainerLoader.getCdiContainer();
+ cdiContainer.startApplicationScope();
+ cdiContainer.bootContainer();
+ }
+
+ @AfterClass
+ public static void shutdown() throws Exception {
+ cdiContainer.stopContexts();
+ cdiContainer.shutdownContainer();
+ }
+
+ @Before
+ public void setUp() {
+ CdiRepositoryClient repositoryClient = cdiContainer.getInstance(CdiRepositoryClient.class);
+ repository = repositoryClient.getCdiPersonRepository();
+
+ couchbaseClient = repositoryClient.getCouchbaseClient();
+ createAndWaitForDesignDocs(couchbaseClient);
+
+ }
+
+ private void createAndWaitForDesignDocs(CouchbaseClient client) {
+ DesignDocument designDoc = new DesignDocument("person");
+ String mapFunction = "function (doc, meta) { if(doc._class == \"" + Person.class.getName()
+ + "\") { emit(null, null); } }";
+ designDoc.setView(new ViewDesign("all", mapFunction, "_count"));
+ client.createDesignDoc(designDoc);
+ }
+
+ /**
+ * @see DATACOUCH-109
+ */
+ @Test
+ public void testCdiRepository() {
+ assertNotNull(repository);
+ repository.deleteAll();
+
+ Person bean = new Person("key", "username");
+
+ repository.save(bean);
+
+ assertTrue(repository.exists(bean.getId()));
+
+ Person retrieved = repository.findOne(bean.getId());
+ assertNotNull(retrieved);
+ assertEquals(bean.getName(), retrieved.getName());
+ assertEquals(bean.getId(), retrieved.getId());
+
+ }
+
+ /**
+ * @see DATACOUCH-109
+ */
+ @Test
+ public void testCustomRepository() {
+
+ assertEquals(2, repository.returnTwo());
+ }
+
+}
diff --git a/src/test/java/org/springframework/data/couchbase/repository/cdi/CouchbaseClientProducer.java b/src/test/java/org/springframework/data/couchbase/repository/cdi/CouchbaseClientProducer.java
new file mode 100644
index 00000000..1c1f2c9a
--- /dev/null
+++ b/src/test/java/org/springframework/data/couchbase/repository/cdi/CouchbaseClientProducer.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2014 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.couchbase.repository.cdi;
+
+import javax.enterprise.inject.Disposes;
+import javax.enterprise.inject.Produces;
+
+import org.springframework.data.couchbase.core.CouchbaseFactoryBean;
+
+import com.couchbase.client.CouchbaseClient;
+
+/**
+ * Producer for {@link CouchbaseClient}. Defaults from {@link CouchbaseFactoryBean} are sufficient for our test.
+ *
+ * @author Mark Paluch
+ */
+class CouchbaseClientProducer {
+
+ @Produces
+ public CouchbaseClient createCouchbaseClient() throws Exception {
+
+ CouchbaseFactoryBean couchbaseFactoryBean = new CouchbaseFactoryBean();
+ couchbaseFactoryBean.setBucket("default");
+ couchbaseFactoryBean.afterPropertiesSet();
+ return couchbaseFactoryBean.getObject();
+ }
+
+ public void close(@Disposes CouchbaseClient couchbaseClient) {
+ couchbaseClient.shutdown();
+ }
+}
diff --git a/src/test/java/org/springframework/data/couchbase/repository/cdi/CouchbaseOperationsProducer.java b/src/test/java/org/springframework/data/couchbase/repository/cdi/CouchbaseOperationsProducer.java
new file mode 100644
index 00000000..bf3f1d84
--- /dev/null
+++ b/src/test/java/org/springframework/data/couchbase/repository/cdi/CouchbaseOperationsProducer.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2014 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.couchbase.repository.cdi;
+
+import javax.enterprise.inject.Produces;
+
+import org.springframework.data.couchbase.core.CouchbaseOperations;
+import org.springframework.data.couchbase.core.CouchbaseTemplate;
+
+import com.couchbase.client.CouchbaseClient;
+
+/**
+ * Produces a {@link CouchbaseOperations} instance for test usage.
+ * @author Mark Paluch
+ */
+class CouchbaseOperationsProducer {
+
+ @Produces
+ public CouchbaseOperations createCouchbaseOperations(CouchbaseClient couchbaseClient) throws Exception {
+
+ CouchbaseTemplate couchbaseTemplate = new CouchbaseTemplate(couchbaseClient);
+
+ return couchbaseTemplate;
+ }
+
+}
diff --git a/src/test/java/org/springframework/data/couchbase/repository/cdi/Person.java b/src/test/java/org/springframework/data/couchbase/repository/cdi/Person.java
new file mode 100644
index 00000000..a726d414
--- /dev/null
+++ b/src/test/java/org/springframework/data/couchbase/repository/cdi/Person.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2014 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.couchbase.repository.cdi;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.couchbase.core.mapping.Field;
+
+/**
+ * @author Mark Paluch
+ */
+public class Person {
+
+ @Id private String id;
+
+ @Field private String name;
+
+ public Person() {}
+
+ public Person(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/src/test/resources/META-INF/beans.xml b/src/test/resources/META-INF/beans.xml
new file mode 100644
index 00000000..71dc6db1
--- /dev/null
+++ b/src/test/resources/META-INF/beans.xml
@@ -0,0 +1,6 @@
+
+
+
+
diff --git a/template.mf b/template.mf
index f200af5c..2111ab1d 100644
--- a/template.mf
+++ b/template.mf
@@ -7,6 +7,7 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Export-Template:
org.springframework.data.couchbase.*;version="${project.version}"
Import-Template:
+ javax.enterprise.*;version="${cdi:[=.=.=,+1.0.0)}";resolution:=optional,
com.couchbase.client.*;version="${couchbase:[=.=.=,+1.0.0)}",
net.spy.memcached.*;version="[2.8.0,3.0.0)",
com.fasterxml.jackson.*;version="${jackson:[=.=.=,+1.0.0)}",