SGF-194 Rewrote Subregion parsing in AbstractRegionParser

This commit is contained in:
David Turanski
2013-10-01 08:45:08 -04:00
parent 283b3723eb
commit 651f89662c
6 changed files with 91 additions and 89 deletions

View File

@@ -60,7 +60,7 @@ public class SubRegionFactoryBean<K, V> extends AttributesFactory<K, V> implemen
+ parent.getRegionService());
}
else {
log.debug("creating subregion of [" + parent.getFullPath() + "] with name " + regionName);
log.debug("creating subregion of [" + ( parent.getFullPath() == null ? parent.getName() : parent.getFullPath()) + "] with name " + regionName);
this.subRegion = this.parent.createSubregion(regionName, create());
}
}
@@ -86,7 +86,7 @@ public class SubRegionFactoryBean<K, V> extends AttributesFactory<K, V> implemen
* @param name
*/
public void setName(String name) {
this.name = name;
this.name = name;
}
/**
@@ -102,7 +102,7 @@ public class SubRegionFactoryBean<K, V> extends AttributesFactory<K, V> implemen
* @param parent
*/
public void setParent(Region<?, ?> parent) {
this.parent = parent;
this.parent = parent;
}
/**

View File

@@ -16,12 +16,10 @@
package org.springframework.data.gemfire.config;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedArray;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
@@ -32,13 +30,20 @@ import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Base class for all Region Parsers
*
*
* @author David Turanski
*/
abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser {
private final Map<String,Element> subRegionElements = new HashMap<String, Element>();
protected final Log log = LogFactory.getLog(getClass());
@Override
@@ -56,55 +61,12 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser {
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
super.doParse(element, builder);
boolean subRegion = isSubRegion(element);
doParseRegion(element, parserContext, builder, subRegion);
if (subRegion) {
builder.addPropertyValue("parent", parserContext.getContainingBeanDefinition().getAttribute("parent"));
builder.addPropertyValue("regionName", element.getAttribute(NAME_ATTRIBUTE));
}
doParseRegion(element, parserContext, builder, subRegion);
}
protected abstract void doParseRegion(Element element, ParserContext parserContext, BeanDefinitionBuilder builder,
boolean subRegion);
protected void doParseSubRegion(Element element, Element subElement, ParserContext parserContext,
BeanDefinitionBuilder builder, boolean subRegion) {
String regionPath = null;
String parentBeanName = null;
if (subRegion) {
parentBeanName = parserContext.getContainingBeanDefinition().getAttribute("regionPath").toString();
}
else {
parentBeanName = getRegionNameFromElement(element);
}
regionPath = StringUtils.arrayToDelimitedString(new String[] { parentBeanName,
getRegionNameFromElement(subElement) }, "/");
if (!regionPath.startsWith("/")) {
regionPath = "/" + regionPath;
}
/*
* The Region parser needs some context to handle recursion correctly
*/
builder.getBeanDefinition().setAttribute("parent",
new BeanDefinitionHolder(builder.getBeanDefinition(), parentBeanName));
builder.getBeanDefinition().setAttribute("regionPath", regionPath);
// Make recursive call
BeanDefinition subRegionDef = this.parseSubRegion(subElement, parserContext, builder);
// TODO: Is there a better work-around?
/*
* This setting prevents the BF from generating a name for this been
*/
subRegionDef.setScope(BeanDefinition.SCOPE_PROTOTYPE);
if (log.isDebugEnabled()) {
log.debug("registering subregion as " + regionPath);
}
this.registerBeanDefinition(new BeanDefinitionHolder(subRegionDef, regionPath), parserContext.getRegistry());
}
protected void doParseCommonRegionConfiguration(Element element, ParserContext parserContext,
BeanDefinitionBuilder builder, BeanDefinitionBuilder attrBuilder, boolean subRegion) {
@@ -117,7 +79,7 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser {
}
// add attributes
ParsingUtils.setPropertyValue(element, builder, "name");
ParsingUtils.parseOptionalRegionAttributes(parserContext, element, attrBuilder);
ParsingUtils.parseStatistics(element, attrBuilder);
ParsingUtils.setPropertyValue(element, attrBuilder, "publisher");
@@ -179,11 +141,18 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser {
builder.addPropertyValue("cacheWriter",
ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, subElement, builder));
}
else if (subElement.getLocalName().endsWith("region")) {
doParseSubRegion(element, subElement, parserContext, builder, subRegion);
}
}
if (!subRegion) {
Map<String,Element> allSubRegionElements = new HashMap<String, Element>();
findSubregionElements(element,getRegionNameFromElement(element),allSubRegionElements);
if (!CollectionUtils.isEmpty(allSubRegionElements)) {
for (Map.Entry<String,Element> entry: allSubRegionElements.entrySet()) {
parseSubRegion(entry.getValue(),parserContext,entry.getKey());
}
}
}
}
private void parseCollectionOfCustomSubElements(ParserContext parserContext, Element element,
@@ -200,14 +169,48 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser {
}
}
private BeanDefinition parseSubRegion(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
BeanDefinition beanDefinition = parserContext.getDelegate().parseCustomElement(element,
builder.getBeanDefinition());
return beanDefinition;
private BeanDefinition parseSubRegion(Element element, ParserContext parserContext, String regionPath) {
element.setAttribute("id", regionPath);
String regionName = getRegionNameFromElement(element);
element.setAttribute("name", regionPath);
BeanDefinition beanDefinition = parserContext.getDelegate().parseCustomElement(element);
String parentBeanName = getParentPathForSubRegion(regionPath);
beanDefinition.getPropertyValues().add("parent",new RuntimeBeanReference(parentBeanName));
beanDefinition.getPropertyValues().add("regionName",regionName);
return beanDefinition;
}
private String getRegionNameFromElement(Element element) {
String name = element.getAttribute(NAME_ATTRIBUTE);
return StringUtils.hasText(name) ? name : element.getAttribute(ID_ATTRIBUTE);
}
private String buildPathForSubRegion(String parentName, String regionName) {
String regionPath = StringUtils.arrayToDelimitedString(new String[] { parentName,
regionName }, "/");
if (!regionPath.startsWith("/")) {
regionPath = "/" + regionPath;
}
return regionPath;
}
private String getParentPathForSubRegion(String regionPath) {
int index = regionPath.lastIndexOf("/");
String parentPath = regionPath.substring(0,index);
if (parentPath.lastIndexOf("/") == 0) {
parentPath = parentPath.substring(1);
}
return parentPath;
}
private void findSubregionElements(Element parent, String parentPath, Map<String,Element> allSubregionElements) {
for (Element element : DomUtils.getChildElements(parent)) {
if (element.getLocalName().endsWith("region")) {
String regionPath = buildPathForSubRegion(parentPath, getRegionNameFromElement(element));
allSubregionElements.put(regionPath,element);
findSubregionElements(element,regionPath,allSubregionElements);
}
}
}
}

View File

@@ -27,7 +27,7 @@ import org.w3c.dom.Element;
/**
* Parser for &lt;lookup-region;gt; definitions.
*
*
* @author Costin Leau
* @author David Turanski
*/
@@ -48,15 +48,6 @@ class LookupRegionParser extends AbstractRegionParser {
else {
builder.addPropertyValue("lookupOnly", true);
}
// parse nested elements
List<Element> subElements = DomUtils.getChildElements(element);
for (Element subElement : subElements) {
String name = subElement.getLocalName();
if (name.endsWith("region")) {
doParseSubRegion(element, subElement, parserContext, builder, subRegion);
}
}
}
@Override