Additional work and changes for JIRA feature requests SGF-207 and SGF-254 to enable developers with the ability to create Region templates to model attributes and configuration meta-data common to multiple, strongly-typed GemFire Region types (e.g. REPLICATE, PARTITION, etc).
This commit is contained in:
@@ -22,6 +22,7 @@ import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
@@ -29,6 +30,7 @@ import org.springframework.beans.factory.support.ManagedArray;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.data.gemfire.GemfireUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
@@ -81,6 +83,8 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser {
|
||||
protected void doParseCommonRegionConfiguration(Element element, ParserContext parserContext,
|
||||
BeanDefinitionBuilder builder, BeanDefinitionBuilder regionAttributesBuilder, boolean subRegion) {
|
||||
|
||||
mergeTemplateRegionAttributes(element, parserContext, builder, regionAttributesBuilder);
|
||||
|
||||
String resolvedCacheRef = ParsingUtils.resolveCacheReference(element.getAttribute("cache-ref"));
|
||||
|
||||
if (!subRegion) {
|
||||
@@ -159,6 +163,45 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser {
|
||||
}
|
||||
}
|
||||
|
||||
void mergeTemplateRegionAttributes(Element element, ParserContext parserContext,
|
||||
BeanDefinitionBuilder regionBuilder, BeanDefinitionBuilder regionAttributesBuilder) {
|
||||
String regionTemplate = getParentName(element);
|
||||
|
||||
if (StringUtils.hasText(regionTemplate)) {
|
||||
if (parserContext.getRegistry().containsBeanDefinition(regionTemplate)) {
|
||||
BeanDefinition regionTemplateDefinition = parserContext.getRegistry()
|
||||
.getBeanDefinition(regionTemplate);
|
||||
|
||||
BeanDefinition regionTemplateAttributesDefinition = getRegionAttributesBeanDefinition(
|
||||
regionTemplateDefinition);
|
||||
|
||||
if (regionTemplateAttributesDefinition != null) {
|
||||
// NOTE we only need to merge the parent RegionAttributes with this since the parent will have
|
||||
// already merged it's parent's RegionAttributes and so on...
|
||||
regionAttributesBuilder.getRawBeanDefinition().overrideFrom(regionTemplateAttributesDefinition);
|
||||
}
|
||||
}
|
||||
else {
|
||||
parserContext.getReaderContext().error(String.format(
|
||||
"The Region template [%1$s] must be defined in the Spring context configuration meta-data 'before' the Region [%2$s] using the template!",
|
||||
regionTemplate, resolveId(element, regionBuilder.getRawBeanDefinition(), parserContext)), element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BeanDefinition getRegionAttributesBeanDefinition(final BeanDefinition region) {
|
||||
Assert.notNull(region, "The 'Region' BeanDefinition must not be null!");
|
||||
|
||||
Object regionAttributesDefinition = null;
|
||||
|
||||
if (region.getPropertyValues().contains("attributes")) {
|
||||
PropertyValue regionAttributes = region.getPropertyValues().getPropertyValue("attributes");
|
||||
regionAttributesDefinition = regionAttributes.getValue();
|
||||
}
|
||||
|
||||
return (regionAttributesDefinition instanceof BeanDefinition ? (BeanDefinition) regionAttributesDefinition : null);
|
||||
}
|
||||
|
||||
private void parseCollectionOfCustomSubElements(Element element, ParserContext parserContext,
|
||||
BeanDefinitionBuilder builder, String className, String subElementName, String propertyName) {
|
||||
List<Element> subElements = DomUtils.getChildElementsByTagName(element, subElementName,
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.springframework.data.gemfire.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.ManagedList;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
@@ -53,8 +55,6 @@ class PartitionedRegionParser extends AbstractRegionParser {
|
||||
|
||||
validateDataPolicyShortcutAttributesMutualExclusion(element, parserContext);
|
||||
|
||||
super.doParse(element, regionBuilder);
|
||||
|
||||
BeanDefinitionBuilder regionAttributesBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
RegionAttributesFactoryBean.class);
|
||||
|
||||
@@ -65,6 +65,8 @@ class PartitionedRegionParser extends AbstractRegionParser {
|
||||
BeanDefinitionBuilder partitionAttributesBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
PartitionAttributesFactoryBean.class);
|
||||
|
||||
mergeTemplateRegionPartitionAttributes(element, parserContext, regionBuilder, partitionAttributesBuilder);
|
||||
|
||||
parseColocatedWith(element, regionBuilder, partitionAttributesBuilder, "colocated-with");
|
||||
ParsingUtils.setPropertyValue(element, partitionAttributesBuilder, "copies", "redundantCopies");
|
||||
ParsingUtils.setPropertyValue(element, partitionAttributesBuilder, "local-max-memory");
|
||||
@@ -108,6 +110,40 @@ class PartitionedRegionParser extends AbstractRegionParser {
|
||||
regionAttributesBuilder.addPropertyValue("partitionAttributes", partitionAttributesBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
void mergeTemplateRegionPartitionAttributes(Element element, ParserContext parserContext,
|
||||
BeanDefinitionBuilder regionBuilder, BeanDefinitionBuilder partitionAttributesBuilder) {
|
||||
String regionTemplate = getParentName(element);
|
||||
|
||||
if (StringUtils.hasText(regionTemplate)) {
|
||||
if (parserContext.getRegistry().containsBeanDefinition(regionTemplate)) {
|
||||
BeanDefinition regionTemplateDefinition = parserContext.getRegistry()
|
||||
.getBeanDefinition(regionTemplate);
|
||||
|
||||
BeanDefinition regionTemplateAttributesDefinition = getRegionAttributesBeanDefinition(
|
||||
regionTemplateDefinition);
|
||||
|
||||
if (regionTemplateAttributesDefinition != null) {
|
||||
if (regionTemplateAttributesDefinition.getPropertyValues().contains("partitionAttributes")) {
|
||||
PropertyValue partitionAttributes = regionTemplateAttributesDefinition.getPropertyValues()
|
||||
.getPropertyValue("partitionAttributes");
|
||||
|
||||
Object partitionAttributesDefinition = partitionAttributes.getValue();
|
||||
|
||||
if (partitionAttributesDefinition instanceof BeanDefinition) {
|
||||
partitionAttributesBuilder.getRawBeanDefinition().overrideFrom(
|
||||
(BeanDefinition) partitionAttributesDefinition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
parserContext.getReaderContext().error(String.format(
|
||||
"The Region template [%1$s] must be defined in the Spring context configuration meta-data 'before' the Region [%2$s] using the template!",
|
||||
regionTemplate, resolveId(element, regionBuilder.getRawBeanDefinition(), parserContext)), element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseColocatedWith(Element element, BeanDefinitionBuilder regionBuilder,
|
||||
BeanDefinitionBuilder partitionAttributesBuilder, String attributeName) {
|
||||
// NOTE rather than using a dependency (with depends-on) we could also set the colocatedWith property of the
|
||||
|
||||
Reference in New Issue
Block a user