DATACASS-91 - improved XML parsing & Java config
This commit is contained in:
@@ -22,7 +22,7 @@ import static org.springframework.cassandra.config.xml.ParsingUtils.addRequiredP
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.cassandra.config.CassandraSessionFactoryBean;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -37,7 +37,7 @@ import org.w3c.dom.NamedNodeMap;
|
||||
* @author David Webb
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraSessionParser extends AbstractSimpleBeanDefinitionParser {
|
||||
public class CassandraSessionParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
*/
|
||||
package org.springframework.cassandra.config.xml;
|
||||
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.*;
|
||||
import static org.springframework.cassandra.config.xml.ParsingUtils.addOptionalPropertyReference;
|
||||
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.cassandra.config.CassandraTemplateFactoryBean;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -32,7 +32,7 @@ import org.w3c.dom.Element;
|
||||
* @author David Webb
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraTemplateParser extends AbstractSimpleBeanDefinitionParser {
|
||||
public class CassandraTemplateParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.springframework.data.cassandra.config;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@@ -22,6 +23,23 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class CassandraEntityClassScanner {
|
||||
|
||||
public static Set<Class<?>> scan(String... entityBasePackages) throws ClassNotFoundException {
|
||||
return new CassandraEntityClassScanner(entityBasePackages).scanForEntityClasses();
|
||||
}
|
||||
|
||||
public static Set<Class<?>> scan(Class<?>... entityBasePackageClasses) throws ClassNotFoundException {
|
||||
return new CassandraEntityClassScanner(entityBasePackageClasses).scanForEntityClasses();
|
||||
}
|
||||
|
||||
public static Set<Class<?>> scan(Collection<String> entityBasePackages) throws ClassNotFoundException {
|
||||
return new CassandraEntityClassScanner(entityBasePackages).scanForEntityClasses();
|
||||
}
|
||||
|
||||
public static Set<Class<?>> scan(Collection<String> entityBasePackages, Collection<Class<?>> entityBasePackageClasses)
|
||||
throws ClassNotFoundException {
|
||||
return new CassandraEntityClassScanner(entityBasePackages, entityBasePackageClasses).scanForEntityClasses();
|
||||
}
|
||||
|
||||
protected Set<String> entityBasePackages = new HashSet<String>();
|
||||
protected Set<Class<?>> entityBasePackageClasses = new HashSet<Class<?>>();
|
||||
protected ClassLoader beanClassLoader;
|
||||
@@ -29,6 +47,14 @@ public class CassandraEntityClassScanner {
|
||||
public CassandraEntityClassScanner() {
|
||||
}
|
||||
|
||||
public CassandraEntityClassScanner(Class<?>... entityBasePackageClasses) {
|
||||
this(null, Arrays.asList(entityBasePackageClasses));
|
||||
}
|
||||
|
||||
public CassandraEntityClassScanner(String... entityBasePackages) {
|
||||
this(Arrays.asList(entityBasePackages));
|
||||
}
|
||||
|
||||
public CassandraEntityClassScanner(Collection<String> entityBasePackages) {
|
||||
this(entityBasePackages, null);
|
||||
}
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
package org.springframework.data.cassandra.config;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.data.cassandra.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.Mapping;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public class CassandraMappingContextFactoryBean implements FactoryBean<CassandraMappingContext>, InitializingBean {
|
||||
|
||||
protected Set<String> entityBasePackages = new HashSet<String>();
|
||||
protected Mapping mapping;
|
||||
protected ClassLoader beanClassLoader;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
mapping = mapping == null ? new Mapping() : mapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CassandraMappingContext getObject() throws Exception {
|
||||
|
||||
DefaultCassandraMappingContext mappingContext = new DefaultCassandraMappingContext();
|
||||
mappingContext.setInitialEntitySet(new CassandraEntityClassScanner(entityBasePackages).scanForEntityClasses());
|
||||
mappingContext.setMapping(mapping);
|
||||
mappingContext.setBeanClassLoader(beanClassLoader);
|
||||
|
||||
mappingContext.initialize(); // this is necessary here
|
||||
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return CassandraMappingContext.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Set<String> getEntityBasePackages() {
|
||||
return entityBasePackages;
|
||||
}
|
||||
|
||||
public void setEntityBasePackages(Set<String> basePackages) {
|
||||
this.entityBasePackages = basePackages == null ? new HashSet<String>() : new HashSet<String>(basePackages);
|
||||
}
|
||||
|
||||
public Mapping getMapping() {
|
||||
return mapping;
|
||||
}
|
||||
|
||||
public void setMapping(Mapping mapping) {
|
||||
|
||||
Assert.notNull(mapping);
|
||||
|
||||
this.mapping = mapping;
|
||||
}
|
||||
|
||||
public ClassLoader getBeanClassLoader() {
|
||||
return beanClassLoader;
|
||||
}
|
||||
|
||||
public void setBeanClassLoader(ClassLoader entityClassLoader) {
|
||||
this.beanClassLoader = entityClassLoader;
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package org.springframework.data.cassandra.config;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.data.cassandra.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.convert.MappingCassandraConverter;
|
||||
import org.springframework.data.cassandra.mapping.CassandraMappingContext;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public class CassandraMappingConverterFactoryBean implements FactoryBean<CassandraConverter>, InitializingBean {
|
||||
|
||||
protected CassandraMappingContext mappingContext;
|
||||
protected Set<String> basePackages = new HashSet<String>();
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(mappingContext);
|
||||
Assert.notNull(basePackages);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CassandraConverter getObject() throws Exception {
|
||||
return new MappingCassandraConverter(mappingContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return CassandraConverter.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public CassandraMappingContext getMappingContext() {
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
public void setMappingContext(CassandraMappingContext mappingContext) {
|
||||
|
||||
Assert.notNull(mappingContext);
|
||||
|
||||
this.mappingContext = mappingContext;
|
||||
}
|
||||
}
|
||||
@@ -15,22 +15,19 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.config.java;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.cassandra.config.java.AbstractClusterConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.cassandra.config.CassandraDataSessionFactoryBean;
|
||||
import org.springframework.data.cassandra.config.CassandraEntityClassScanner;
|
||||
import org.springframework.data.cassandra.config.CassandraMappingContextFactoryBean;
|
||||
import org.springframework.data.cassandra.config.CassandraMappingConverterFactoryBean;
|
||||
import org.springframework.data.cassandra.config.SchemaAction;
|
||||
import org.springframework.data.cassandra.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.convert.MappingCassandraConverter;
|
||||
import org.springframework.data.cassandra.core.CassandraAdminOperations;
|
||||
import org.springframework.data.cassandra.core.CassandraAdminTemplate;
|
||||
import org.springframework.data.cassandra.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.Table;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
|
||||
@@ -69,7 +66,7 @@ public abstract class AbstractSpringDataCassandraConfiguration extends AbstractC
|
||||
CassandraDataSessionFactoryBean bean = new CassandraDataSessionFactoryBean();
|
||||
|
||||
bean.setCluster(cluster().getObject());
|
||||
bean.setConverter(cassandraConverter().getObject());
|
||||
bean.setConverter(cassandraConverter());
|
||||
bean.setSchemaAction(getSchemaAction());
|
||||
bean.setKeyspaceName(getKeyspaceName());
|
||||
bean.setStartupScripts(getStartupScripts());
|
||||
@@ -85,7 +82,7 @@ public abstract class AbstractSpringDataCassandraConfiguration extends AbstractC
|
||||
*/
|
||||
@Bean
|
||||
public CassandraAdminOperations cassandraTemplate() throws Exception {
|
||||
return new CassandraAdminTemplate(session().getObject(), cassandraConverter().getObject());
|
||||
return new CassandraAdminTemplate(session().getObject(), cassandraConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,10 +91,10 @@ public abstract class AbstractSpringDataCassandraConfiguration extends AbstractC
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
@Bean
|
||||
public CassandraMappingContextFactoryBean cassandraMapping() throws ClassNotFoundException {
|
||||
public CassandraMappingContext cassandraMapping() throws ClassNotFoundException {
|
||||
|
||||
CassandraMappingContextFactoryBean bean = new CassandraMappingContextFactoryBean();
|
||||
bean.setEntityBasePackages(new HashSet<String>(Arrays.asList(getEntityBasePackages())));
|
||||
DefaultCassandraMappingContext bean = new DefaultCassandraMappingContext();
|
||||
bean.setInitialEntitySet(CassandraEntityClassScanner.scan(getEntityBasePackages()));
|
||||
bean.setBeanClassLoader(beanClassLoader);
|
||||
|
||||
return bean;
|
||||
@@ -107,32 +104,8 @@ public abstract class AbstractSpringDataCassandraConfiguration extends AbstractC
|
||||
* Return the {@link CassandraConverter} instance to convert Rows to Objects, Objects to BuiltStatements
|
||||
*/
|
||||
@Bean
|
||||
public CassandraMappingConverterFactoryBean cassandraConverter() throws Exception {
|
||||
|
||||
CassandraMappingConverterFactoryBean bean = new CassandraMappingConverterFactoryBean();
|
||||
bean.setMappingContext(cassandraMapping().getObject());
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the mapping base package for entity classes.
|
||||
*
|
||||
* @see #getEntityBasePackages()
|
||||
* @see #getEntityScanner()
|
||||
* @return <code>Set<Class<?>></code> representing the annotated entity classes found.
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||
|
||||
CassandraEntityClassScanner entityScanner = getEntityScanner();
|
||||
entityScanner.setEntityBasePackages(Arrays.asList(getEntityBasePackages()));
|
||||
|
||||
return entityScanner.scanForEntityClasses();
|
||||
}
|
||||
|
||||
public CassandraEntityClassScanner getEntityScanner() {
|
||||
return new CassandraEntityClassScanner();
|
||||
public CassandraConverter cassandraConverter() throws Exception {
|
||||
return new MappingCassandraConverter(cassandraMapping());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,10 +6,10 @@ import java.util.Set;
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.data.cassandra.config.CassandraMappingContextFactoryBean;
|
||||
import org.springframework.data.cassandra.config.DefaultDataBeanNames;
|
||||
import org.springframework.data.cassandra.mapping.DefaultCassandraMappingContext;
|
||||
import org.springframework.data.cassandra.mapping.EntityMapping;
|
||||
import org.springframework.data.cassandra.mapping.Mapping;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -21,11 +21,11 @@ import org.w3c.dom.Element;
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraMappingContextParser extends AbstractSimpleBeanDefinitionParser {
|
||||
public class CassandraMappingContextParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return CassandraMappingContextFactoryBean.class;
|
||||
return DefaultCassandraMappingContext.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -37,33 +37,17 @@ public class CassandraMappingContextParser extends AbstractSimpleBeanDefinitionP
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
super.doParse(element, parserContext, builder);
|
||||
|
||||
parseBasePackagesAttribute(element, parserContext, builder);
|
||||
parseMapping(element, parserContext, builder);
|
||||
protected void doParse(Element element, BeanDefinitionBuilder builder) {
|
||||
parseMapping(element, builder);
|
||||
}
|
||||
|
||||
protected void parseBasePackagesAttribute(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
String basePackages = element.getAttribute("entity-base-packages");
|
||||
if (!StringUtils.hasText(basePackages)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<String> basePackageSet = StringUtils.commaDelimitedListToSet(basePackages);
|
||||
builder.addPropertyValue("entityBasePackages", basePackageSet);
|
||||
}
|
||||
|
||||
protected void parseMapping(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
|
||||
// TODO: parse <mapping> **attributes** here, if there ever are any
|
||||
protected void parseMapping(Element element, BeanDefinitionBuilder builder) {
|
||||
|
||||
Set<EntityMapping> mappings = new HashSet<EntityMapping>();
|
||||
|
||||
for (Element child : DomUtils.getChildElementsByTagName(element, "entity")) {
|
||||
for (Element entity : DomUtils.getChildElementsByTagName(element, "entity")) {
|
||||
|
||||
EntityMapping entityMapping = parseEntity(child);
|
||||
EntityMapping entityMapping = parseEntity(entity);
|
||||
|
||||
if (entityMapping != null) {
|
||||
mappings.add(entityMapping);
|
||||
|
||||
@@ -3,10 +3,10 @@ package org.springframework.data.cassandra.config.xml;
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.data.cassandra.config.CassandraMappingConverterFactoryBean;
|
||||
import org.springframework.data.cassandra.config.DefaultDataBeanNames;
|
||||
import org.springframework.data.cassandra.convert.MappingCassandraConverter;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
@@ -15,11 +15,11 @@ import org.w3c.dom.Element;
|
||||
*
|
||||
* @author Matthew T. Adams
|
||||
*/
|
||||
public class CassandraMappingConverterParser extends AbstractSimpleBeanDefinitionParser {
|
||||
public class CassandraMappingConverterParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return CassandraMappingConverterFactoryBean.class;
|
||||
return MappingCassandraConverter.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -31,21 +31,13 @@ public class CassandraMappingConverterParser extends AbstractSimpleBeanDefinitio
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
protected void doParse(Element element, BeanDefinitionBuilder builder) {
|
||||
|
||||
super.doParse(element, parserContext, builder);
|
||||
|
||||
parseMappingContextAttribute(element, parserContext, builder);
|
||||
}
|
||||
|
||||
protected void parseMappingContextAttribute(Element element, ParserContext parserContext,
|
||||
BeanDefinitionBuilder builder) {
|
||||
|
||||
String mappingContextRef = element.getAttribute("mapping-ref");
|
||||
if (!StringUtils.hasText(mappingContextRef)) {
|
||||
mappingContextRef = DefaultDataBeanNames.MAPPING_CONTEXT;
|
||||
String mappingRef = element.getAttribute("mapping-ref");
|
||||
if (!StringUtils.hasText(mappingRef)) {
|
||||
mappingRef = DefaultDataBeanNames.MAPPING_CONTEXT;
|
||||
}
|
||||
|
||||
builder.addPropertyReference("mappingContext", mappingContextRef);
|
||||
builder.addConstructorArgReference(mappingRef);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,6 @@ public class DefaultCassandraMappingContext extends
|
||||
protected ApplicationContext context;
|
||||
protected Mapping mapping = new Mapping();
|
||||
protected ClassLoader beanClassLoader;
|
||||
protected boolean initialized;
|
||||
|
||||
// useful caches
|
||||
protected Map<String, Set<CassandraPersistentEntity<?>>> entitySetsByTableName = new HashMap<String, Set<CassandraPersistentEntity<?>>>();
|
||||
@@ -70,27 +69,12 @@ public class DefaultCassandraMappingContext extends
|
||||
setSimpleTypeHolder(new CassandraSimpleTypeHolder());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.initialize();
|
||||
|
||||
processMappingOverrides();
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<context:property-placeholder
|
||||
location="classpath:/spring-data-cassandra-build.properties" />
|
||||
|
||||
<cass:converter />
|
||||
<cass:converter mapping-ref="cassandraMapping"/>
|
||||
|
||||
<cass:template />
|
||||
|
||||
|
||||
Reference in New Issue
Block a user