Skip to content

Commit

Permalink
DATACOUCH-6 - Add simple support for XML config
Browse files Browse the repository at this point in the history
  • Loading branch information
daschl committed Jul 17, 2013
1 parent 2ed710c commit ab252f8
Show file tree
Hide file tree
Showing 10 changed files with 274 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* 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;

/**
* @author Michael Nitschinger
*/
public class BeanNames {
static final String MAPPING_CONTEXT = "mappingContext";
static final String COUCHBASE = "couchbase";
static final String DB_FACTORY = "couchbaseDbFactory";
static final String DEFAULT_CONVERTER_BEAN_NAME = "mappingConverter";
static final String COUCHBASE_TEMPLATE = "couchbaseTemplate";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* 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.config.BeanDefinition;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
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.couchbase.monitor.ClientInfo;
import org.springframework.data.couchbase.monitor.ClusterInfo;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;

/**
* Enables Parsing of "<couchbase:jmx />" configurations.
*
* @author Michael Nitschinger
*/
public class CouchbaseJmxParser implements BeanDefinitionParser {

public BeanDefinition parse(final Element element, final ParserContext parserContext) {
String name = element.getAttribute("couchbase-ref");
if (!StringUtils.hasText(name)) {
name = BeanNames.COUCHBASE;
}
registerJmxComponents(name, element, parserContext);
return null;
}

protected void registerJmxComponents(String refName, Element element, ParserContext parserContext) {
Object eleSource = parserContext.extractSource(element);
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);

createBeanDefEntry(ClientInfo.class, compositeDef, refName, eleSource, parserContext);
createBeanDefEntry(ClusterInfo.class, compositeDef, refName, eleSource, parserContext);

parserContext.registerComponent(compositeDef);
}

protected void createBeanDefEntry(Class<?> clazz, CompositeComponentDefinition compositeDef,
String refName, Object eleSource, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
builder.getRawBeanDefinition().setSource(eleSource);
builder.addConstructorArgReference(refName);
BeanDefinition assertDef = builder.getBeanDefinition();
String assertName = parserContext.getReaderContext().registerWithGeneratedName(assertDef);
compositeDef.addNestedComponent(new BeanComponentDefinition(assertDef, assertName));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@ 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("repositories", new RepositoryBeanDefinitionParser(extension));
registerBeanDefinitionParser("couchbase", new CouchbaseParser());
registerBeanDefinitionParser("jmx", new CouchbaseJmxParser());
registerBeanDefinitionParser("template", new CouchbaseTemplateParser());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,65 @@
package org.springframework.data.couchbase.config;

import com.couchbase.client.CouchbaseClient;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.config.BeanComponentDefinitionBuilder;
import org.springframework.data.config.ParsingUtils;
import org.springframework.data.couchbase.core.CouchbaseFactoryBean;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;


/**
* Parser for "<couchbase>" definitions.
* Parser for "<couchbase:couchbase />" definitions.
*
* @author Michael Nitschinger
*/
public class CouchbaseParser implements BeanDefinitionParser {
public class CouchbaseParser extends AbstractSingleBeanDefinitionParser {

@Override
public BeanDefinition parse(final Element element, final ParserContext parserContext) {
Object source = parserContext.extractSource(element);
String id = element.getAttribute("id");
protected Class getBeanClass(final Element element) {
return CouchbaseClient.class;
}

BeanComponentDefinitionBuilder helper = new BeanComponentDefinitionBuilder(element, parserContext);
@Override
protected void doParse(final Element element, final BeanDefinitionBuilder bean) {
String host = element.getAttribute("host");
bean.addConstructorArgValue(
convertHosts(StringUtils.hasText(host) ? host : CouchbaseFactoryBean.DEFAULT_NODE));
String bucket = element.getAttribute("bucket");
bean.addConstructorArgValue(
StringUtils.hasText(bucket) ? bucket : CouchbaseFactoryBean.DEFAULT_BUCKET);
String password = element.getAttribute("password");
bean.addConstructorArgValue(
StringUtils.hasText(password) ? password : CouchbaseFactoryBean.DEFAULT_PASSWORD);
}

BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CouchbaseClient.class);
builder.s
ParsingUtils.setPropertyValue(builder, element, "port", "port");
ParsingUtils.setPropertyValue(builder, element, "host", "host");
protected String resolveId(final Element element, final AbstractBeanDefinition definition,
final ParserContext parserContext) {
String id = super.resolveId(element, definition, parserContext);
return StringUtils.hasText(id) ? id : BeanNames.COUCHBASE;
}

private List<URI> convertHosts(final String hosts) {
String[] split = hosts.split(",");
List<URI> nodes = new ArrayList<URI>();

try {
for (int i = 0; i < split.length; i++) {
nodes.add(new URI("http://" + split[i] + ":8091/pools"));
}
} catch (URISyntaxException ex) {
throw new BeanCreationException("Could not convert host list." + ex);
}

return nodes;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* 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.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.couchbase.core.CouchbaseTemplate;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;

/**
* @author Michael Nitschinger
*/
public class CouchbaseTemplateParser extends AbstractSingleBeanDefinitionParser {

protected String resolveId(final Element element, final AbstractBeanDefinition definition,
final ParserContext parserContext) {
String id = super.resolveId(element, definition, parserContext);
return StringUtils.hasText(id) ? id : BeanNames.COUCHBASE_TEMPLATE;
}

@Override
protected Class getBeanClass(final Element element) {
return CouchbaseTemplate.class;
}

@Override
protected void doParse(final Element element, final BeanDefinitionBuilder bean) {
String converterRef = element.getAttribute("converter-ref");
String dbRef = element.getAttribute("db-ref");

bean.addConstructorArgReference(StringUtils.hasText(dbRef) ? dbRef : BeanNames.COUCHBASE);

if (StringUtils.hasText(converterRef)) {
bean.addConstructorArgReference(converterRef);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
* @author Michael Nitschinger
*/
public class CouchbaseFactoryBean implements FactoryBean<CouchbaseClient>, InitializingBean,
DisposableBean, PersistenceExceptionTranslator{
DisposableBean, PersistenceExceptionTranslator {

public static final String DEFAULT_NODE = "127.0.0.1";
public static final String DEFAULT_BUCKET = "default";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

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;
Expand All @@ -27,6 +26,8 @@

import java.util.List;

import static org.junit.Assert.assertEquals;

/**
* @author Michael Nitschinger
*/
Expand All @@ -44,11 +45,15 @@ public void setUp() {
@Test
public void readsCouchbaseAttributesCorrectly() {
reader.loadBeanDefinitions(new ClassPathResource("namespace/couchbase-bean.xml"));

BeanDefinition definition = factory.getBeanDefinition("couchbase");
assertEquals(3, definition.getConstructorArgumentValues().getArgumentCount());

List<PropertyValue> values = definition.getPropertyValues().getPropertyValueList();
definition = factory.getBeanDefinition("couchbase2");
assertEquals(3, definition.getConstructorArgumentValues().getArgumentCount());

System.out.println(values);
factory.getBean("couchbase");
factory.getBean("couchbase2");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* 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.Before;
import org.junit.Test;
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 static org.junit.Assert.assertEquals;

/**
* @author Michael Nitschinger
*/
public class CouchbaseTemplateParserIntegrationTest {

DefaultListableBeanFactory factory;
BeanDefinitionReader reader;

@Before
public void setUp() {
factory = new DefaultListableBeanFactory();
reader = new XmlBeanDefinitionReader(factory);
}

@Test
public void readsCouchbaseTemplateAttributesCorrectly() {
reader.loadBeanDefinitions(new ClassPathResource("namespace/couchbase-template-bean.xml"));

BeanDefinition definition = factory.getBeanDefinition("couchbaseTemplate");
assertEquals(1, definition.getConstructorArgumentValues().getArgumentCount());

factory.getBean("couchbaseTemplate");
}

}
4 changes: 2 additions & 2 deletions src/test/resources/namespace/couchbase-bean.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
xsi:schemaLocation="http://www.springframework.org/schema/data/couchbase http://www.springframework.org/schema/data/couchbase/spring-couchbase.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<couchbase:couchbase id="couchbase" host="localhost" bucket="bucketname" password="secure" />
<couchbase:couchbase/>

<couchbase:couchbase id="couchbase2" />
<couchbase:couchbase id="couchbase2" host="localhost" bucket="default" password="" />

</beans>
12 changes: 12 additions & 0 deletions src/test/resources/namespace/couchbase-template-bean.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:couchbase="http://www.springframework.org/schema/data/couchbase"
xsi:schemaLocation="http://www.springframework.org/schema/data/couchbase http://www.springframework.org/schema/data/couchbase/spring-couchbase.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<couchbase:couchbase/>

<couchbase:template/>

</beans>

0 comments on commit ab252f8

Please sign in to comment.