diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseNamespaceHandler.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseNamespaceHandler.java new file mode 100644 index 00000000..10060d62 --- /dev/null +++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseNamespaceHandler.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013 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.config; + +import org.springframework.beans.factory.xml.NamespaceHandlerSupport; +import org.springframework.data.couchbase.repository.config.CouchbaseRepositoryConfigurationExtension; +import org.springframework.data.repository.config.RepositoryBeanDefinitionParser; +import org.springframework.data.repository.config.RepositoryConfigurationExtension; + +/** + * {@link org.springframework.beans.factory.xml.NamespaceHandler} for Couchbase configuration. + * + * @author Michael Nitschinger + */ +public class CouchbaseNamespaceHandler extends NamespaceHandlerSupport { + + public void init() { + RepositoryConfigurationExtension extension = new CouchbaseRepositoryConfigurationExtension(); + RepositoryBeanDefinitionParser repositoryBeanDefinitionParser = new RepositoryBeanDefinitionParser(extension); + + registerBeanDefinitionParser("repositories", repositoryBeanDefinitionParser); + registerBeanDefinitionParser("mongo", new CouchbaseParser()); + registerBeanDefinitionParser("jmx", new CouchbaseJmxParser()); + registerBeanDefinitionParser("template", new CouchbaseTemplateParser()); + } + +} diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseParser.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseParser.java new file mode 100644 index 00000000..981806ac --- /dev/null +++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseParser.java @@ -0,0 +1,48 @@ +/* + * Copyright 2013 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.config; + +import com.couchbase.client.CouchbaseClient; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.data.config.BeanComponentDefinitionBuilder; +import org.springframework.data.config.ParsingUtils; +import org.w3c.dom.Element; + +/** + * Parser for "" definitions. + * + * @author Michael Nitschinger + */ +public class CouchbaseParser implements BeanDefinitionParser { + + @Override + public BeanDefinition parse(final Element element, final ParserContext parserContext) { + Object source = parserContext.extractSource(element); + String id = element.getAttribute("id"); + + BeanComponentDefinitionBuilder helper = new BeanComponentDefinitionBuilder(element, parserContext); + + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CouchbaseClient.class); + builder.s + ParsingUtils.setPropertyValue(builder, element, "port", "port"); + ParsingUtils.setPropertyValue(builder, element, "host", "host"); + + } +} diff --git a/src/main/java/org/springframework/data/couchbase/core/CouchbaseFactoryBean.java b/src/main/java/org/springframework/data/couchbase/core/CouchbaseFactoryBean.java new file mode 100644 index 00000000..e47871ee --- /dev/null +++ b/src/main/java/org/springframework/data/couchbase/core/CouchbaseFactoryBean.java @@ -0,0 +1,136 @@ +/* + * Copyright 2013 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.core; + +import com.couchbase.client.CouchbaseClient; +import com.couchbase.client.CouchbaseConnectionFactory; +import com.couchbase.client.CouchbaseConnectionFactoryBuilder; +import net.spy.memcached.FailureMode; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.support.PersistenceExceptionTranslator; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * Convenient Factory for configuring Couchbase. + * + * @author Michael Nitschinger + */ +public class CouchbaseFactoryBean implements FactoryBean, InitializingBean, + DisposableBean, PersistenceExceptionTranslator{ + + public static final String DEFAULT_NODE = "127.0.0.1"; + public static final String DEFAULT_BUCKET = "default"; + public static final String DEFAULT_PASSWORD = ""; + + private CouchbaseClient couchbaseClient; + private PersistenceExceptionTranslator exceptionTranslator = new CouchbaseExceptionTranslator(); + private String bucket; + private String password; + private List nodes; + private CouchbaseConnectionFactoryBuilder builder = new CouchbaseConnectionFactoryBuilder(); + + public void setObservePollInterval(final int interval) { + builder.setObsPollInterval(interval); + } + + public void setObservePollMax(final int max) { + builder.setObsPollMax(max); + } + + public void setReconnectThresholdTime(final int time) { + builder.setReconnectThresholdTime(time, TimeUnit.SECONDS); + } + + public void setViewTimeout(final int timeout) { + builder.setViewTimeout(timeout); + } + + public void setFailureMode(final String mode) { + builder.setFailureMode(FailureMode.valueOf(mode)); + } + + public void setOpTimeout(final int timeout) { + builder.setOpTimeout(timeout); + } + + public void setOpQueueMaxBlockTime(final int time) { + builder.setOpQueueMaxBlockTime(time); + } + + @Override + public void destroy() throws Exception { + couchbaseClient.shutdown(); + } + + @Override + public CouchbaseClient getObject() throws Exception { + return couchbaseClient; + } + + @Override + public Class getObjectType() { + return CouchbaseClient.class; + } + + @Override + public boolean isSingleton() { + return true; + } + + public void setNodes(final URI[] nodes) { + this.nodes = filterNonNullElementsAsList(nodes); + } + + private List filterNonNullElementsAsList(T[] elements) { + if (elements == null) { + return Collections.emptyList(); + } + + List candidateElements = new ArrayList(); + for (T element : elements) { + if (element != null) { + candidateElements.add(element); + } + } + + return Collections.unmodifiableList(candidateElements); + } + + @Override + public void afterPropertiesSet() throws Exception { + nodes = nodes != null ? nodes : Arrays.asList(new URI("http://" + DEFAULT_NODE + ":8091/pools")); + bucket = bucket != null ? bucket : DEFAULT_BUCKET; + password = password != null ? password : DEFAULT_PASSWORD; + + CouchbaseConnectionFactory factory = builder.buildCouchbaseConnection(nodes, bucket, password); + couchbaseClient = new CouchbaseClient(factory); + } + + @Override + public DataAccessException translateExceptionIfPossible(final RuntimeException ex) { + return exceptionTranslator.translateExceptionIfPossible(ex); + } +} diff --git a/src/main/resources/org/springframework/data/couchbase/config/spring-couchbase-1.0.xsd b/src/main/resources/org/springframework/data/couchbase/config/spring-couchbase-1.0.xsd index 399d96e0..f3a6236f 100644 --- a/src/main/resources/org/springframework/data/couchbase/config/spring-couchbase-1.0.xsd +++ b/src/main/resources/org/springframework/data/couchbase/config/spring-couchbase-1.0.xsd @@ -28,9 +28,122 @@ Defines a CouchbaseClient instance used for accessing a Couchbase Cluster. - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The reference to a CouchbaseClient object. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The reference to a CouchbaseTemplate. Will default to 'couchbaseTemplate'. + + + + + + + + + + + + + + diff --git a/src/test/java/org/springframework/data/couchbase/config/CouchbaseParserIntegrationTest.java b/src/test/java/org/springframework/data/couchbase/config/CouchbaseParserIntegrationTest.java new file mode 100644 index 00000000..2f8c7ad3 --- /dev/null +++ b/src/test/java/org/springframework/data/couchbase/config/CouchbaseParserIntegrationTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2013 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.config; + +import org.junit.Test; +import org.junit.Before; +import org.springframework.beans.PropertyValue; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionReader; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; +import org.springframework.core.io.ClassPathResource; + +import java.util.List; + +/** + * @author Michael Nitschinger + */ +public class CouchbaseParserIntegrationTest { + + DefaultListableBeanFactory factory; + BeanDefinitionReader reader; + + @Before + public void setUp() { + factory = new DefaultListableBeanFactory(); + reader = new XmlBeanDefinitionReader(factory); + } + + @Test + public void readsCouchbaseAttributesCorrectly() { + reader.loadBeanDefinitions(new ClassPathResource("namespace/couchbase-bean.xml")); + BeanDefinition definition = factory.getBeanDefinition("couchbase"); + + List values = definition.getPropertyValues().getPropertyValueList(); + + System.out.println(values); + } + +} diff --git a/src/test/resources/namespace/couchbase-bean.xml b/src/test/resources/namespace/couchbase-bean.xml new file mode 100644 index 00000000..357c0e24 --- /dev/null +++ b/src/test/resources/namespace/couchbase-bean.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file