Skip to content

Commit ab252f8

Browse files
committed
DATACOUCH-6 - Add simple support for XML config
1 parent 2ed710c commit ab252f8

File tree

10 files changed

+274
-23
lines changed

10 files changed

+274
-23
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.data.couchbase.config;
18+
19+
/**
20+
* @author Michael Nitschinger
21+
*/
22+
public class BeanNames {
23+
static final String MAPPING_CONTEXT = "mappingContext";
24+
static final String COUCHBASE = "couchbase";
25+
static final String DB_FACTORY = "couchbaseDbFactory";
26+
static final String DEFAULT_CONVERTER_BEAN_NAME = "mappingConverter";
27+
static final String COUCHBASE_TEMPLATE = "couchbaseTemplate";
28+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.data.couchbase.config;
18+
19+
import org.springframework.beans.factory.config.BeanDefinition;
20+
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
21+
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
22+
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
23+
import org.springframework.beans.factory.xml.BeanDefinitionParser;
24+
import org.springframework.beans.factory.xml.ParserContext;
25+
import org.springframework.data.couchbase.monitor.ClientInfo;
26+
import org.springframework.data.couchbase.monitor.ClusterInfo;
27+
import org.springframework.util.StringUtils;
28+
import org.w3c.dom.Element;
29+
30+
/**
31+
* Enables Parsing of "<couchbase:jmx />" configurations.
32+
*
33+
* @author Michael Nitschinger
34+
*/
35+
public class CouchbaseJmxParser implements BeanDefinitionParser {
36+
37+
public BeanDefinition parse(final Element element, final ParserContext parserContext) {
38+
String name = element.getAttribute("couchbase-ref");
39+
if (!StringUtils.hasText(name)) {
40+
name = BeanNames.COUCHBASE;
41+
}
42+
registerJmxComponents(name, element, parserContext);
43+
return null;
44+
}
45+
46+
protected void registerJmxComponents(String refName, Element element, ParserContext parserContext) {
47+
Object eleSource = parserContext.extractSource(element);
48+
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
49+
50+
createBeanDefEntry(ClientInfo.class, compositeDef, refName, eleSource, parserContext);
51+
createBeanDefEntry(ClusterInfo.class, compositeDef, refName, eleSource, parserContext);
52+
53+
parserContext.registerComponent(compositeDef);
54+
}
55+
56+
protected void createBeanDefEntry(Class<?> clazz, CompositeComponentDefinition compositeDef,
57+
String refName, Object eleSource, ParserContext parserContext) {
58+
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
59+
builder.getRawBeanDefinition().setSource(eleSource);
60+
builder.addConstructorArgReference(refName);
61+
BeanDefinition assertDef = builder.getBeanDefinition();
62+
String assertName = parserContext.getReaderContext().registerWithGeneratedName(assertDef);
63+
compositeDef.addNestedComponent(new BeanComponentDefinition(assertDef, assertName));
64+
}
65+
66+
}

src/main/java/org/springframework/data/couchbase/config/CouchbaseNamespaceHandler.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,9 @@ public class CouchbaseNamespaceHandler extends NamespaceHandlerSupport {
3030

3131
public void init() {
3232
RepositoryConfigurationExtension extension = new CouchbaseRepositoryConfigurationExtension();
33-
RepositoryBeanDefinitionParser repositoryBeanDefinitionParser = new RepositoryBeanDefinitionParser(extension);
3433

35-
registerBeanDefinitionParser("repositories", repositoryBeanDefinitionParser);
36-
registerBeanDefinitionParser("mongo", new CouchbaseParser());
34+
registerBeanDefinitionParser("repositories", new RepositoryBeanDefinitionParser(extension));
35+
registerBeanDefinitionParser("couchbase", new CouchbaseParser());
3736
registerBeanDefinitionParser("jmx", new CouchbaseJmxParser());
3837
registerBeanDefinitionParser("template", new CouchbaseTemplateParser());
3938
}

src/main/java/org/springframework/data/couchbase/config/CouchbaseParser.java

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,65 @@
1717
package org.springframework.data.couchbase.config;
1818

1919
import com.couchbase.client.CouchbaseClient;
20-
import org.springframework.beans.factory.config.BeanDefinition;
20+
import org.springframework.beans.factory.BeanCreationException;
21+
import org.springframework.beans.factory.support.AbstractBeanDefinition;
2122
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
22-
import org.springframework.beans.factory.xml.BeanDefinitionParser;
23+
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
2324
import org.springframework.beans.factory.xml.ParserContext;
24-
import org.springframework.data.config.BeanComponentDefinitionBuilder;
25-
import org.springframework.data.config.ParsingUtils;
25+
import org.springframework.data.couchbase.core.CouchbaseFactoryBean;
26+
import org.springframework.util.StringUtils;
2627
import org.w3c.dom.Element;
2728

29+
import java.net.URI;
30+
import java.net.URISyntaxException;
31+
import java.util.ArrayList;
32+
import java.util.List;
33+
34+
2835
/**
29-
* Parser for "<couchbase>" definitions.
36+
* Parser for "<couchbase:couchbase />" definitions.
3037
*
3138
* @author Michael Nitschinger
3239
*/
33-
public class CouchbaseParser implements BeanDefinitionParser {
40+
public class CouchbaseParser extends AbstractSingleBeanDefinitionParser {
3441

3542
@Override
36-
public BeanDefinition parse(final Element element, final ParserContext parserContext) {
37-
Object source = parserContext.extractSource(element);
38-
String id = element.getAttribute("id");
43+
protected Class getBeanClass(final Element element) {
44+
return CouchbaseClient.class;
45+
}
3946

40-
BeanComponentDefinitionBuilder helper = new BeanComponentDefinitionBuilder(element, parserContext);
47+
@Override
48+
protected void doParse(final Element element, final BeanDefinitionBuilder bean) {
49+
String host = element.getAttribute("host");
50+
bean.addConstructorArgValue(
51+
convertHosts(StringUtils.hasText(host) ? host : CouchbaseFactoryBean.DEFAULT_NODE));
52+
String bucket = element.getAttribute("bucket");
53+
bean.addConstructorArgValue(
54+
StringUtils.hasText(bucket) ? bucket : CouchbaseFactoryBean.DEFAULT_BUCKET);
55+
String password = element.getAttribute("password");
56+
bean.addConstructorArgValue(
57+
StringUtils.hasText(password) ? password : CouchbaseFactoryBean.DEFAULT_PASSWORD);
58+
}
4159

42-
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CouchbaseClient.class);
43-
builder.s
44-
ParsingUtils.setPropertyValue(builder, element, "port", "port");
45-
ParsingUtils.setPropertyValue(builder, element, "host", "host");
60+
protected String resolveId(final Element element, final AbstractBeanDefinition definition,
61+
final ParserContext parserContext) {
62+
String id = super.resolveId(element, definition, parserContext);
63+
return StringUtils.hasText(id) ? id : BeanNames.COUCHBASE;
64+
}
65+
66+
private List<URI> convertHosts(final String hosts) {
67+
String[] split = hosts.split(",");
68+
List<URI> nodes = new ArrayList<URI>();
4669

70+
try {
71+
for (int i = 0; i < split.length; i++) {
72+
nodes.add(new URI("http://" + split[i] + ":8091/pools"));
73+
}
74+
} catch (URISyntaxException ex) {
75+
throw new BeanCreationException("Could not convert host list." + ex);
76+
}
77+
78+
return nodes;
4779
}
80+
4881
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright 2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.data.couchbase.config;
18+
19+
import org.springframework.beans.factory.support.AbstractBeanDefinition;
20+
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
21+
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
22+
import org.springframework.beans.factory.xml.ParserContext;
23+
import org.springframework.data.couchbase.core.CouchbaseTemplate;
24+
import org.springframework.util.StringUtils;
25+
import org.w3c.dom.Element;
26+
27+
/**
28+
* @author Michael Nitschinger
29+
*/
30+
public class CouchbaseTemplateParser extends AbstractSingleBeanDefinitionParser {
31+
32+
protected String resolveId(final Element element, final AbstractBeanDefinition definition,
33+
final ParserContext parserContext) {
34+
String id = super.resolveId(element, definition, parserContext);
35+
return StringUtils.hasText(id) ? id : BeanNames.COUCHBASE_TEMPLATE;
36+
}
37+
38+
@Override
39+
protected Class getBeanClass(final Element element) {
40+
return CouchbaseTemplate.class;
41+
}
42+
43+
@Override
44+
protected void doParse(final Element element, final BeanDefinitionBuilder bean) {
45+
String converterRef = element.getAttribute("converter-ref");
46+
String dbRef = element.getAttribute("db-ref");
47+
48+
bean.addConstructorArgReference(StringUtils.hasText(dbRef) ? dbRef : BeanNames.COUCHBASE);
49+
50+
if (StringUtils.hasText(converterRef)) {
51+
bean.addConstructorArgReference(converterRef);
52+
}
53+
}
54+
55+
}

src/main/java/org/springframework/data/couchbase/core/CouchbaseFactoryBean.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
* @author Michael Nitschinger
4040
*/
4141
public class CouchbaseFactoryBean implements FactoryBean<CouchbaseClient>, InitializingBean,
42-
DisposableBean, PersistenceExceptionTranslator{
42+
DisposableBean, PersistenceExceptionTranslator {
4343

4444
public static final String DEFAULT_NODE = "127.0.0.1";
4545
public static final String DEFAULT_BUCKET = "default";

src/test/java/org/springframework/data/couchbase/config/CouchbaseParserIntegrationTest.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import org.junit.Test;
2020
import org.junit.Before;
21-
import org.springframework.beans.PropertyValue;
2221
import org.springframework.beans.factory.config.BeanDefinition;
2322
import org.springframework.beans.factory.support.BeanDefinitionReader;
2423
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
@@ -27,6 +26,8 @@
2726

2827
import java.util.List;
2928

29+
import static org.junit.Assert.assertEquals;
30+
3031
/**
3132
* @author Michael Nitschinger
3233
*/
@@ -44,11 +45,15 @@ public void setUp() {
4445
@Test
4546
public void readsCouchbaseAttributesCorrectly() {
4647
reader.loadBeanDefinitions(new ClassPathResource("namespace/couchbase-bean.xml"));
48+
4749
BeanDefinition definition = factory.getBeanDefinition("couchbase");
50+
assertEquals(3, definition.getConstructorArgumentValues().getArgumentCount());
4851

49-
List<PropertyValue> values = definition.getPropertyValues().getPropertyValueList();
52+
definition = factory.getBeanDefinition("couchbase2");
53+
assertEquals(3, definition.getConstructorArgumentValues().getArgumentCount());
5054

51-
System.out.println(values);
55+
factory.getBean("couchbase");
56+
factory.getBean("couchbase2");
5257
}
5358

5459
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.data.couchbase.config;
18+
19+
import org.junit.Before;
20+
import org.junit.Test;
21+
import org.springframework.beans.factory.config.BeanDefinition;
22+
import org.springframework.beans.factory.support.BeanDefinitionReader;
23+
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
24+
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
25+
import org.springframework.core.io.ClassPathResource;
26+
27+
import static org.junit.Assert.assertEquals;
28+
29+
/**
30+
* @author Michael Nitschinger
31+
*/
32+
public class CouchbaseTemplateParserIntegrationTest {
33+
34+
DefaultListableBeanFactory factory;
35+
BeanDefinitionReader reader;
36+
37+
@Before
38+
public void setUp() {
39+
factory = new DefaultListableBeanFactory();
40+
reader = new XmlBeanDefinitionReader(factory);
41+
}
42+
43+
@Test
44+
public void readsCouchbaseTemplateAttributesCorrectly() {
45+
reader.loadBeanDefinitions(new ClassPathResource("namespace/couchbase-template-bean.xml"));
46+
47+
BeanDefinition definition = factory.getBeanDefinition("couchbaseTemplate");
48+
assertEquals(1, definition.getConstructorArgumentValues().getArgumentCount());
49+
50+
factory.getBean("couchbaseTemplate");
51+
}
52+
53+
}

src/test/resources/namespace/couchbase-bean.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
xsi:schemaLocation="http://www.springframework.org/schema/data/couchbase http://www.springframework.org/schema/data/couchbase/spring-couchbase.xsd
66
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
77

8-
<couchbase:couchbase id="couchbase" host="localhost" bucket="bucketname" password="secure" />
8+
<couchbase:couchbase/>
99

10-
<couchbase:couchbase id="couchbase2" />
10+
<couchbase:couchbase id="couchbase2" host="localhost" bucket="default" password="" />
1111

1212
</beans>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<beans xmlns="http://www.springframework.org/schema/beans"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:couchbase="http://www.springframework.org/schema/data/couchbase"
5+
xsi:schemaLocation="http://www.springframework.org/schema/data/couchbase http://www.springframework.org/schema/data/couchbase/spring-couchbase.xsd
6+
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
7+
8+
<couchbase:couchbase/>
9+
10+
<couchbase:template/>
11+
12+
</beans>

0 commit comments

Comments
 (0)