From e3a131007c423b36fafe286da6bb933a8d917d9c Mon Sep 17 00:00:00 2001 From: Matthew Adams Date: Mon, 10 Feb 2014 23:14:30 -0600 Subject: [PATCH] DATACASS-91 - now scanning packages via XML & Java config --- ...ataCassandraMappingContextFactoryBean.java | 46 ------------ .../CassandraDataSessionFactoryBean.java | 56 -------------- .../CassandraMappingContextFactoryBean.java | 73 +++++++++++++++++++ ...CassandraMappingConverterFactoryBean.java} | 2 +- .../config/DefaultDataBeanNames.java | 2 +- ...tractSpringDataCassandraConfiguration.java | 36 ++++----- .../xml/CassandraDataNamespaceHandler.java | 4 +- .../xml/CassandraDataSessionParser.java | 66 +---------------- ...ava => CassandraMappingContextParser.java} | 56 +++++++++++++- ...a => CassandraMappingConverterParser.java} | 23 ++---- .../DefaultCassandraMappingContext.java | 70 ++++++++++++++++-- .../cassandra/config/spring-cassandra-1.0.xsd | 21 ++---- ...itoryXmlConfigIntegrationTests-context.xml | 30 ++++---- .../CassandraNamespaceTests-context.xml | 2 +- ...itoryXmlConfigIntegrationTests-context.xml | 30 ++++---- .../resources/spring-data-cassandra-basic.xml | 8 +- 16 files changed, 266 insertions(+), 259 deletions(-) delete mode 100644 spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraDataCassandraMappingContextFactoryBean.java create mode 100644 spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraMappingContextFactoryBean.java rename spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/{CassandraDataMappingConverterFactoryBean.java => CassandraMappingConverterFactoryBean.java} (91%) rename spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/{CassandraDataCassandraMappingContextParser.java => CassandraMappingContextParser.java} (50%) rename spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/{CassandraDataMappingCassandraConverterParser.java => CassandraMappingConverterParser.java} (68%) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraDataCassandraMappingContextFactoryBean.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraDataCassandraMappingContextFactoryBean.java deleted file mode 100644 index 3a087a06c..000000000 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraDataCassandraMappingContextFactoryBean.java +++ /dev/null @@ -1,46 +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; - -public class CassandraDataCassandraMappingContextFactoryBean implements FactoryBean, - InitializingBean { - - protected Set basePackages = new HashSet(); - - @Override - public void afterPropertiesSet() throws Exception { - } - - @Override - public CassandraMappingContext getObject() throws Exception { - - DefaultCassandraMappingContext cmc = new DefaultCassandraMappingContext(); - cmc.setInitialEntitySet(new CassandraEntityClassScanner(basePackages).scanForEntityClasses()); - - return cmc; - } - - @Override - public Class getObjectType() { - return CassandraMappingContext.class; - } - - @Override - public boolean isSingleton() { - return true; - } - - public Set getBasePackages() { - return basePackages; - } - - public void setBasePackages(Set basePackages) { - this.basePackages = basePackages; - } -} diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraDataSessionFactoryBean.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraDataSessionFactoryBean.java index 436b66b68..69bc1be26 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraDataSessionFactoryBean.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraDataSessionFactoryBean.java @@ -7,10 +7,7 @@ import org.springframework.data.cassandra.convert.CassandraConverter; import org.springframework.data.cassandra.core.CassandraAdminTemplate; import org.springframework.data.cassandra.mapping.CassandraMappingContext; import org.springframework.data.cassandra.mapping.CassandraPersistentEntity; -import org.springframework.data.cassandra.mapping.EntityMapping; -import org.springframework.data.cassandra.mapping.Mapping; import org.springframework.util.Assert; -import org.springframework.util.StringUtils; import com.datastax.driver.core.KeyspaceMetadata; import com.datastax.driver.core.Metadata; @@ -22,8 +19,6 @@ public class CassandraDataSessionFactoryBean extends CassandraSessionFactoryBean protected CassandraAdminTemplate admin; protected CassandraConverter converter; protected CassandraMappingContext mappingContext; - protected Mapping mapping; - protected ClassLoader entityClassLoader = getClass().getClassLoader(); @Override public void afterPropertiesSet() throws Exception { @@ -34,42 +29,9 @@ public class CassandraDataSessionFactoryBean extends CassandraSessionFactoryBean admin = new CassandraAdminTemplate(session, converter); - mapping = mapping == null ? new Mapping() : mapping; - - processMappingOverrides(); performSchemaAction(); } - protected void processMappingOverrides() throws ClassNotFoundException { - - if (mapping == null) { - return; - } - - for (EntityMapping entityMapping : mapping.getEntityMappings()) { - - if (entityMapping == null) { - continue; - } - - String entityClassName = entityMapping.getEntityClassName(); - Class entityClass = Class.forName(entityClassName, false, entityClassLoader); - - CassandraPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); - - if (entity == null) { - throw new IllegalStateException(String.format("unknown persistent entity class name [%s]", entityClassName)); - } - - String tableName = entityMapping.getTableName(); - if (!StringUtils.hasText(tableName)) { - continue; - } - - entity.setTableName(tableName); - } - } - protected void performSchemaAction() { boolean dropTables = false; @@ -138,22 +100,4 @@ public class CassandraDataSessionFactoryBean extends CassandraSessionFactoryBean this.converter = converter; this.mappingContext = converter.getMappingContext(); } - - public Mapping getMapping() { - return mapping; - } - - public void setMapping(Mapping mapping) { - Assert.notNull(mapping); - this.mapping = mapping; - } - - public ClassLoader getEntityClassLoader() { - return entityClassLoader; - } - - public void setEntityClassLoader(ClassLoader entityClassLoader) { - Assert.notNull(entityClassLoader); - this.entityClassLoader = entityClassLoader; - } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraMappingContextFactoryBean.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraMappingContextFactoryBean.java new file mode 100644 index 000000000..2489a7ad9 --- /dev/null +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraMappingContextFactoryBean.java @@ -0,0 +1,73 @@ +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, InitializingBean { + + protected Set basePackages = new HashSet(); + protected Mapping mapping; + protected ClassLoader entityClassLoader; + + @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(basePackages).scanForEntityClasses()); + mappingContext.setMapping(mapping); + mappingContext.setBeanClassLoader(entityClassLoader); + + mappingContext.initialize(); // this is necessary here + + return mappingContext; + } + + @Override + public Class getObjectType() { + return CassandraMappingContext.class; + } + + @Override + public boolean isSingleton() { + return true; + } + + public Set getBasePackages() { + return basePackages; + } + + public void setBasePackages(Set basePackages) { + this.basePackages = basePackages == null ? new HashSet() : new HashSet(basePackages); + } + + public Mapping getMapping() { + return mapping; + } + + public void setMapping(Mapping mapping) { + + Assert.notNull(mapping); + + this.mapping = mapping; + } + + public ClassLoader getEntityClassLoader() { + return entityClassLoader; + } + + public void setEntityClassLoader(ClassLoader entityClassLoader) { + this.entityClassLoader = entityClassLoader; + } +} diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraDataMappingConverterFactoryBean.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraMappingConverterFactoryBean.java similarity index 91% rename from spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraDataMappingConverterFactoryBean.java rename to spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraMappingConverterFactoryBean.java index 48fba014a..e6e3353f5 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraDataMappingConverterFactoryBean.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/CassandraMappingConverterFactoryBean.java @@ -10,7 +10,7 @@ import org.springframework.data.cassandra.convert.MappingCassandraConverter; import org.springframework.data.cassandra.mapping.CassandraMappingContext; import org.springframework.util.Assert; -public class CassandraDataMappingConverterFactoryBean implements FactoryBean, InitializingBean { +public class CassandraMappingConverterFactoryBean implements FactoryBean, InitializingBean { protected CassandraMappingContext mappingContext; protected Set basePackages = new HashSet(); diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/DefaultDataBeanNames.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/DefaultDataBeanNames.java index 4443e54d6..c91114d88 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/DefaultDataBeanNames.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/DefaultDataBeanNames.java @@ -6,5 +6,5 @@ public interface DefaultDataBeanNames extends DefaultBeanNames { public static final String DATA_TEMPLATE = "cassandraTemplate"; public static final String CONVERTER = "cassandraConverter"; - public static final String MAPPING_CONTEXT = "cassandra-mapping"; + public static final String MAPPING_CONTEXT = "cassandraMapping"; } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/java/AbstractSpringDataCassandraConfiguration.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/java/AbstractSpringDataCassandraConfiguration.java index a86e13b5c..992da0ac6 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/java/AbstractSpringDataCassandraConfiguration.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/java/AbstractSpringDataCassandraConfiguration.java @@ -16,6 +16,7 @@ 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; @@ -24,14 +25,12 @@ 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.Mapping; import org.springframework.data.cassandra.mapping.Table; import org.springframework.data.mapping.context.MappingContext; @@ -48,7 +47,6 @@ public abstract class AbstractSpringDataCassandraConfiguration extends AbstractC protected abstract String getKeyspaceName(); protected ClassLoader beanClassLoader; - protected Mapping mapping = new Mapping(); /** * The {@link SchemaAction} to perform. Defaults to {@link SchemaAction#NONE}. @@ -71,15 +69,12 @@ public abstract class AbstractSpringDataCassandraConfiguration extends AbstractC CassandraDataSessionFactoryBean bean = new CassandraDataSessionFactoryBean(); bean.setCluster(cluster().getObject()); - bean.setConverter(converter()); + bean.setConverter(converter().getObject()); bean.setSchemaAction(getSchemaAction()); bean.setKeyspaceName(getKeyspaceName()); bean.setStartupScripts(getStartupScripts()); bean.setShutdownScripts(getShutdownScripts()); - bean.setEntityClassLoader(beanClassLoader); - bean.setMapping(mapping); - return bean; } @@ -90,7 +85,7 @@ public abstract class AbstractSpringDataCassandraConfiguration extends AbstractC */ @Bean public CassandraAdminOperations cassandraTemplate() throws Exception { - return new CassandraAdminTemplate(session().getObject(), converter()); + return new CassandraAdminTemplate(session().getObject(), converter().getObject()); } /** @@ -99,20 +94,25 @@ public abstract class AbstractSpringDataCassandraConfiguration extends AbstractC * @throws ClassNotFoundException */ @Bean - public CassandraMappingContext cassandraMappingContext() throws ClassNotFoundException { - DefaultCassandraMappingContext context = new DefaultCassandraMappingContext(); - context.setInitialEntitySet(getInitialEntitySet()); - return context; + public CassandraMappingContextFactoryBean cassandraMapping() throws ClassNotFoundException { + + CassandraMappingContextFactoryBean bean = new CassandraMappingContextFactoryBean(); + bean.setBasePackages(new HashSet(Arrays.asList(getMappingBasePackages()))); + bean.setEntityClassLoader(beanClassLoader); + + return bean; } /** * Return the {@link CassandraConverter} instance to convert Rows to Objects, Objects to BuiltStatements - * - * @throws ClassNotFoundException */ @Bean - public CassandraConverter converter() throws ClassNotFoundException { - return new MappingCassandraConverter(cassandraMappingContext()); + public CassandraMappingConverterFactoryBean converter() throws Exception { + + CassandraMappingConverterFactoryBean bean = new CassandraMappingConverterFactoryBean(); + bean.setMappingContext(cassandraMapping().getObject()); + + return bean; } /** diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraDataNamespaceHandler.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraDataNamespaceHandler.java index 349b87ce3..8dc3ac7b2 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraDataNamespaceHandler.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraDataNamespaceHandler.java @@ -36,7 +36,7 @@ public class CassandraDataNamespaceHandler extends NamespaceHandlerSupport { registerBeanDefinitionParser("cluster", new CassandraDataClusterParser()); registerBeanDefinitionParser("session", new CassandraDataSessionParser()); registerBeanDefinitionParser("template", new CassandraDataTemplateParser()); - registerBeanDefinitionParser("mapping-converter", new CassandraDataMappingCassandraConverterParser()); - registerBeanDefinitionParser("mapping-context", new CassandraDataCassandraMappingContextParser()); + registerBeanDefinitionParser("mapping-converter", new CassandraMappingConverterParser()); + registerBeanDefinitionParser("mapping", new CassandraMappingContextParser()); } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraDataSessionParser.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraDataSessionParser.java index fef2f1842..e850bb07b 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraDataSessionParser.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraDataSessionParser.java @@ -1,20 +1,15 @@ package org.springframework.data.cassandra.config.xml; -import static org.springframework.cassandra.config.xml.ParsingUtils.*; - -import java.util.HashSet; -import java.util.Set; +import static org.springframework.cassandra.config.xml.ParsingUtils.addOptionalPropertyReference; +import static org.springframework.cassandra.config.xml.ParsingUtils.addOptionalPropertyValue; +import static org.springframework.cassandra.config.xml.ParsingUtils.addRequiredPropertyReference; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.cassandra.config.xml.CassandraSessionParser; -import org.springframework.data.cassandra.config.DefaultDataBeanNames; import org.springframework.data.cassandra.config.CassandraDataSessionFactoryBean; +import org.springframework.data.cassandra.config.DefaultDataBeanNames; import org.springframework.data.cassandra.config.SchemaAction; -import org.springframework.data.cassandra.mapping.EntityMapping; -import org.springframework.data.cassandra.mapping.Mapping; -import org.springframework.util.StringUtils; -import org.springframework.util.xml.DomUtils; import org.w3c.dom.Attr; import org.w3c.dom.Element; @@ -53,57 +48,4 @@ public class CassandraDataSessionParser extends CassandraSessionParser { addRequiredPropertyReference(builder, "converter", DefaultDataBeanNames.CONVERTER); addRequiredPropertyReference(builder, "schemaAction", SchemaAction.NONE.name()); } - - @Override - protected void parseUnhandledElement(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { - - if ("mapping".equals(element.getLocalName())) { - parseMapping(element, parserContext, builder); - } else { - super.parseUnhandledElement(element, parserContext, builder); - } - } - - protected void parseMapping(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { - - // TODO: parse attributes here, if there ever are any - - Set mappings = new HashSet(); - - for (Element child : DomUtils.getChildElementsByTagName(element, "entity")) { - - EntityMapping entityMapping = parseEntity(child); - - if (entityMapping != null) { - mappings.add(entityMapping); - } - } - - Mapping mapping = new Mapping(); - mapping.setEntityMappings(mappings); - - builder.addPropertyValue("mapping", mapping); - } - - protected EntityMapping parseEntity(Element entity) { - - String className = entity.getAttribute("class"); - if (!StringUtils.hasText(className)) { - throw new IllegalStateException("class attribute must not be empty"); - } - - Element table = DomUtils.getChildElementByTagName(entity, "table"); - if (table == null) { - return null; - } - - String tableName = table.getAttribute("name"); - if (!StringUtils.hasText(tableName)) { - tableName = null; - } - - // TODO: parse future entity mappings here, like table options - - return new EntityMapping(className, tableName); - } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraDataCassandraMappingContextParser.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraMappingContextParser.java similarity index 50% rename from spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraDataCassandraMappingContextParser.java rename to spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraMappingContextParser.java index fe696044c..ee3991c39 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraDataCassandraMappingContextParser.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraMappingContextParser.java @@ -1,5 +1,6 @@ package org.springframework.data.cassandra.config.xml; +import java.util.HashSet; import java.util.Set; import org.springframework.beans.factory.BeanDefinitionStoreException; @@ -7,21 +8,24 @@ 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.ParserContext; -import org.springframework.data.cassandra.config.CassandraDataCassandraMappingContextFactoryBean; +import org.springframework.data.cassandra.config.CassandraMappingContextFactoryBean; import org.springframework.data.cassandra.config.DefaultDataBeanNames; +import org.springframework.data.cassandra.mapping.EntityMapping; +import org.springframework.data.cassandra.mapping.Mapping; import org.springframework.util.StringUtils; +import org.springframework.util.xml.DomUtils; import org.w3c.dom.Element; /** - * Spring Data Cassandra XML namespace parser for the <mapping-context> element. + * Spring Data Cassandra XML namespace parser for the <mapping> element. * * @author Matthew T. Adams */ -public class CassandraDataCassandraMappingContextParser extends AbstractSimpleBeanDefinitionParser { +public class CassandraMappingContextParser extends AbstractSimpleBeanDefinitionParser { @Override protected Class getBeanClass(Element element) { - return CassandraDataCassandraMappingContextFactoryBean.class; + return CassandraMappingContextFactoryBean.class; } @Override @@ -37,6 +41,7 @@ public class CassandraDataCassandraMappingContextParser extends AbstractSimpleBe super.doParse(element, parserContext, builder); parseBasePackagesAttribute(element, parserContext, builder); + parseMapping(element, parserContext, builder); } protected void parseBasePackagesAttribute(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { @@ -49,4 +54,47 @@ public class CassandraDataCassandraMappingContextParser extends AbstractSimpleBe Set basePackageSet = StringUtils.commaDelimitedListToSet(basePackages); builder.addPropertyValue("basePackages", basePackageSet); } + + protected void parseMapping(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { + + // TODO: parse **attributes** here, if there ever are any + + Set mappings = new HashSet(); + + for (Element child : DomUtils.getChildElementsByTagName(element, "entity")) { + + EntityMapping entityMapping = parseEntity(child); + + if (entityMapping != null) { + mappings.add(entityMapping); + } + } + + Mapping mapping = new Mapping(); + mapping.setEntityMappings(mappings); + + builder.addPropertyValue("mapping", mapping); + } + + protected EntityMapping parseEntity(Element entity) { + + String className = entity.getAttribute("class"); + if (!StringUtils.hasText(className)) { + throw new IllegalStateException("class attribute must not be empty"); + } + + Element table = DomUtils.getChildElementByTagName(entity, "table"); + if (table == null) { + return null; + } + + String tableName = table.getAttribute("name"); + if (!StringUtils.hasText(tableName)) { + tableName = null; + } + + // TODO: parse future entity mappings here, like table options + + return new EntityMapping(className, tableName); + } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraDataMappingCassandraConverterParser.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraMappingConverterParser.java similarity index 68% rename from spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraDataMappingCassandraConverterParser.java rename to spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraMappingConverterParser.java index 18eefc9c7..6a830f119 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraDataMappingCassandraConverterParser.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/xml/CassandraMappingConverterParser.java @@ -1,13 +1,11 @@ package org.springframework.data.cassandra.config.xml; -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.ParserContext; -import org.springframework.data.cassandra.config.CassandraDataMappingConverterFactoryBean; +import org.springframework.data.cassandra.config.CassandraMappingConverterFactoryBean; import org.springframework.data.cassandra.config.DefaultDataBeanNames; import org.springframework.util.StringUtils; import org.w3c.dom.Element; @@ -17,11 +15,11 @@ import org.w3c.dom.Element; * * @author Matthew T. Adams */ -public class CassandraDataMappingCassandraConverterParser extends AbstractSimpleBeanDefinitionParser { +public class CassandraMappingConverterParser extends AbstractSimpleBeanDefinitionParser { @Override protected Class getBeanClass(Element element) { - return CassandraDataMappingConverterFactoryBean.class; + return CassandraMappingConverterFactoryBean.class; } @Override @@ -34,29 +32,20 @@ public class CassandraDataMappingCassandraConverterParser extends AbstractSimple @Override protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { + super.doParse(element, parserContext, builder); parseMappingContextAttribute(element, parserContext, builder); - parseBasePackagesAttribute(element, parserContext, builder); } protected void parseMappingContextAttribute(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { - String mappingContextRef = element.getAttribute("mapping-context-ref"); + String mappingContextRef = element.getAttribute("mapping-ref"); if (!StringUtils.hasText(mappingContextRef)) { mappingContextRef = DefaultDataBeanNames.MAPPING_CONTEXT; } + builder.addPropertyReference("mappingContext", mappingContextRef); } - - protected void parseBasePackagesAttribute(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { - - String basePackages = element.getAttribute("base-packages"); - if (!StringUtils.hasText(basePackages)) { - return; - } - - Set basePackageSet = StringUtils.commaDelimitedListToSet(basePackages); - } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/DefaultCassandraMappingContext.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/DefaultCassandraMappingContext.java index 36ac828e4..02417f1fd 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/DefaultCassandraMappingContext.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/DefaultCassandraMappingContext.java @@ -37,6 +37,7 @@ import org.springframework.data.mapping.model.MappingException; import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.TypeInformation; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; import com.datastax.driver.core.TableMetadata; @@ -52,6 +53,9 @@ public class DefaultCassandraMappingContext extends CassandraMappingContext, ApplicationContextAware { protected ApplicationContext context; + protected Mapping mapping = new Mapping(); + protected ClassLoader beanClassLoader; + protected boolean initialized; // useful caches protected Map>> entitySetsByTableName = new HashMap>>(); @@ -65,18 +69,27 @@ 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(); - } - protected void processMappingOverrides() { - - // TODO: search for external entity mapping info (xml/properties/yaml/etc) here & update this.mapping - // similar to JPA's or JDO's external metadata search algorithms + initialized = true; } @Override @@ -224,4 +237,51 @@ public class DefaultCassandraMappingContext extends return entity; } + + public void setMapping(Mapping mapping) { + + Assert.notNull(mapping); + + this.mapping = mapping; + } + + protected void processMappingOverrides() { + + if (mapping == null) { + return; + } + + for (EntityMapping entityMapping : mapping.getEntityMappings()) { + + if (entityMapping == null) { + continue; + } + + String entityClassName = entityMapping.getEntityClassName(); + Class entityClass; + try { + entityClass = Class.forName(entityClassName, false, beanClassLoader == null ? getClass().getClassLoader() + : beanClassLoader); + } catch (ClassNotFoundException e) { + throw new IllegalStateException(String.format("unknown persistent entity name [%s]", entityClassName), e); + } + + CassandraPersistentEntity entity = getPersistentEntity(entityClass); + + if (entity == null) { + throw new IllegalStateException(String.format("unknown persistent entity class name [%s]", entityClassName)); + } + + String tableName = entityMapping.getTableName(); + if (!StringUtils.hasText(tableName)) { + continue; + } + + entity.setTableName(tableName); + } + } + + public void setBeanClassLoader(ClassLoader beanClassLoader) { + this.beanClassLoader = beanClassLoader; + } } diff --git a/spring-data-cassandra/src/main/resources/org/springframework/data/cassandra/config/spring-cassandra-1.0.xsd b/spring-data-cassandra/src/main/resources/org/springframework/data/cassandra/config/spring-cassandra-1.0.xsd index 14d048be2..1f784ee6c 100644 --- a/spring-data-cassandra/src/main/resources/org/springframework/data/cassandra/config/spring-cassandra-1.0.xsd +++ b/spring-data-cassandra/src/main/resources/org/springframework/data/cassandra/config/spring-cassandra-1.0.xsd @@ -452,8 +452,6 @@ Arbitrary CQL script to be executed against the session's keyspace during bean d ]]> - @@ -629,13 +627,6 @@ The replication factor for the data center. - - - - - - - + + + + @@ -729,12 +724,12 @@ Defines a CassandraConverter for getting rich mapping functionality. - diff --git a/spring-data-cassandra/src/test/resources/org/springframework/data/cassandra/test/integration/composites/CommentRepositoryXmlConfigIntegrationTests-context.xml b/spring-data-cassandra/src/test/resources/org/springframework/data/cassandra/test/integration/composites/CommentRepositoryXmlConfigIntegrationTests-context.xml index 325c8e0c7..8f3c5e1ca 100644 --- a/spring-data-cassandra/src/test/resources/org/springframework/data/cassandra/test/integration/composites/CommentRepositoryXmlConfigIntegrationTests-context.xml +++ b/spring-data-cassandra/src/test/resources/org/springframework/data/cassandra/test/integration/composites/CommentRepositoryXmlConfigIntegrationTests-context.xml @@ -1,6 +1,6 @@ - - + + + + + + + - - + + - - - - - - - + - diff --git a/spring-data-cassandra/src/test/resources/org/springframework/data/cassandra/test/integration/config/CassandraNamespaceTests-context.xml b/spring-data-cassandra/src/test/resources/org/springframework/data/cassandra/test/integration/config/CassandraNamespaceTests-context.xml index a25253303..5b0e5d619 100644 --- a/spring-data-cassandra/src/test/resources/org/springframework/data/cassandra/test/integration/config/CassandraNamespaceTests-context.xml +++ b/spring-data-cassandra/src/test/resources/org/springframework/data/cassandra/test/integration/config/CassandraNamespaceTests-context.xml @@ -27,7 +27,7 @@ - + - - + + + + + + + - - + + - - - - - - - + - diff --git a/spring-data-cassandra/src/test/resources/spring-data-cassandra-basic.xml b/spring-data-cassandra/src/test/resources/spring-data-cassandra-basic.xml index 39c99629f..15653c53d 100644 --- a/spring-data-cassandra/src/test/resources/spring-data-cassandra-basic.xml +++ b/spring-data-cassandra/src/test/resources/spring-data-cassandra-basic.xml @@ -1,6 +1,6 @@ - + - - - +