Complete disk store refactoring and added region attributes

This commit is contained in:
David Turanski
2012-06-27 07:18:47 -04:00
parent 400fed1662
commit 7efa90800f
23 changed files with 1968 additions and 1802 deletions

View File

@@ -109,7 +109,6 @@ public class DiskStoreFactoryBean implements FactoryBean<DiskStore>, Initializin
}
diskStoreFactory.setDiskDirsAndSizes(diskDirFiles, diskDirSizes);
}
}
public void setCache(GemFireCache cache) {
@@ -168,5 +167,4 @@ public class DiskStoreFactoryBean implements FactoryBean<DiskStore>, Initializin
this.maxSize = null;
}
}
}

View File

@@ -16,67 +16,40 @@
package org.springframework.data.gemfire;
import java.io.File;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.ObjectUtils;
import com.gemstone.gemfire.cache.AttributesFactory;
import com.gemstone.gemfire.cache.RegionAttributes;
/**
* Spring-friendly bean for creating {@link RegionAttributes}. Eliminates the need of using
* a XML 'factory-method' tag.
* Spring-friendly bean for creating {@link RegionAttributes}. Eliminates the
* need of using a XML 'factory-method' tag.
*
* @author Costin Leau
*/
public class RegionAttributesFactoryBean extends AttributesFactory implements FactoryBean<RegionAttributes>,
InitializingBean {
private int[] diskSizes;
private File[] diskDirs;
private RegionAttributes attributes;
@Override
public void afterPropertiesSet() throws Exception {
if (diskSizes!= null){
super.setDiskDirsAndSizes(diskDirs, diskSizes);
}
else{
if (!ObjectUtils.isEmpty(diskDirs)) {
super.setDiskDirs(diskDirs);
}
}
attributes = super.create();
}
@Override
public RegionAttributes getObject() throws Exception {
return attributes;
}
@Override
public Class<?> getObjectType() {
return (attributes != null ? attributes.getClass() : RegionAttributes.class);
}
@Override
public boolean isSingleton() {
return true;
}
@Override
public void setDiskDirs(File[] diskDirs) {
this.diskDirs = diskDirs;
}
/**
* Sets the sizes (in megabytes) for each disk directory.
* Used only disk directories are specified.
*
* @param sizes
*/
public void setDiskSizes(int[] sizes) {
this.diskSizes = sizes;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2010-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -52,6 +52,7 @@ import com.gemstone.gemfire.cache.Scope;
* defaults.
*
* @author Costin Leau
* @author David Turanski
*/
public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> implements DisposableBean {
@@ -73,8 +74,12 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
private Scope scope;
private String diskStoreName;
private DataPolicy dataPolicy;
private String dataPolicyName;
private Region<K, V> region;
private List<Region<?, ?>> subRegions;
@@ -116,10 +121,31 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
regionFactory.setDataPolicy(dataPolicy);
}
if (dataPolicyName != null) {
Assert.isNull(dataPolicy, "'dataPolicy' and 'dataPolicyName' are mutually exclusive.");
if ("NORMAL".equals(dataPolicyName)) {
regionFactory.setDataPolicy(DataPolicy.NORMAL);
}
else if ("PRELOADED".equals(dataPolicyName)) {
regionFactory.setDataPolicy(DataPolicy.PRELOADED);
}
else {
throw new IllegalArgumentException("Data policy '" + dataPolicyName + "' is unsupported or invalid.");
}
}
if (scope != null) {
regionFactory.setScope(scope);
}
if (diskStoreName != null) {
regionFactory.setDiskStoreName(diskStoreName);
}
Assert.state(!attributes.isLockGrantor() || scope.isGlobal(),
"Lock grantor only applies to a global scoped region");
// get underlying AttributesFactory
postProcess(findAttrFactory(regionFactory));
@@ -129,8 +155,8 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
reg.loadSnapshot(snapshot.getInputStream());
}
if (subRegions != null) {
System.out.println("**********************************************" + subRegions.get(0));
if (attributes.isLockGrantor()) {
reg.becomeLockGrantor();
}
return reg;
@@ -291,6 +317,23 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
this.scope = scope;
}
/**
* Sets the dataPolicy as a String. Required to support property
* placeholders
* @param dataPolicyName the dataPolicy name (NORMAL, PRELOADED, etc)
*/
public void setDataPolicyName(String dataPolicyName) {
this.dataPolicyName = dataPolicyName;
}
/**
* Sets the name of disk store to use for overflow and persistence
* @param diskStoreName
*/
public void setDiskStoreName(String diskStoreName) {
this.diskStoreName = diskStoreName;
}
/**
* Sets the region attributes used for the region used by this factory.
* Allows maximum control in specifying the region settings. Used only when

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2010-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,6 +44,7 @@ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
* Client extension for GemFire regions.
*
* @author Costin Leau
* @author David Turanski
*/
public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> implements BeanFactoryAware,
DisposableBean {
@@ -51,19 +52,28 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
private static final Log log = LogFactory.getLog(ClientRegionFactoryBean.class);
private boolean destroy = false;
private boolean close = true;
private Resource snapshot;
private CacheListener<K, V> cacheListeners[];
private Interest<K>[] interests;
private String poolName;
private BeanFactory beanFactory;
private ClientRegionShortcut shortcut = null;
private DataPolicy dataPolicy;
private RegionAttributes<K, V> attributes;
private Region<K, V> region;
private String diskStoreName;
@Override
public void afterPropertiesSet() throws Exception {
@@ -76,12 +86,11 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
protected Region<K, V> lookupFallback(GemFireCache cache, String regionName) throws Exception {
Assert.isTrue(cache instanceof ClientCache, "Unable to create regions from " + cache);
ClientCache c = (ClientCache) cache;
if (cache instanceof GemFireCacheImpl) {
Assert.isTrue(((GemFireCacheImpl) cache).isClient(), "A client-cache instance is required");
}
// first look at shortcut
ClientRegionShortcut s = null;
@@ -103,7 +112,8 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
else {
s = ClientRegionShortcut.LOCAL;
}
} else {
}
else {
s = shortcut;
}
@@ -154,6 +164,10 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
factory.setPoolName(poolName);
}
if (diskStoreName != null) {
factory.setDiskStoreName(diskStoreName);
}
Region<K, V> reg = factory.create(regionName);
log.info("Created new cache region [" + regionName + "]");
if (snapshot != null) {
@@ -179,6 +193,7 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
}
}
@Override
public void destroy() throws Exception {
Region<K, V> region = getObject();
// unregister interests
@@ -193,8 +208,10 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
}
}
}
// should not really happen since interests are validated at start/registration
} catch (UnsupportedOperationException ex) {
// should not really happen since interests are validated at
// start/registration
}
catch (UnsupportedOperationException ex) {
log.warn("Cannot unregister cache interests", ex);
}
@@ -203,7 +220,8 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
if (!region.getCache().isClosed()) {
try {
region.close();
} catch (CacheClosedException cce) {
}
catch (CacheClosedException cce) {
// nothing to see folks, move on.
}
}
@@ -215,13 +233,14 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
region = null;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
/**
* Set the interests for this client region. Both key and regex interest are supported.
* Set the interests for this client region. Both key and regex interest are
* supported.
*
* @param interests the interests to set
*/
@@ -257,9 +276,9 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
}
/**
* Initializes the client using a GemFire {@link ClientRegionShortcut}.
* The recommended way for creating clients since it covers all the major scenarios with minimal
* configuration.
* Initializes the client using a GemFire {@link ClientRegionShortcut}. The
* recommended way for creating clients since it covers all the major
* scenarios with minimal configuration.
*
* @param shortcut
*/
@@ -268,9 +287,9 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
}
/**
* Indicates whether the region referred by this factory bean,
* will be destroyed on shutdown (default false).
* Note: destroy and close are mutually exclusive. Enabling one will automatically disable the other.
* Indicates whether the region referred by this factory bean, will be
* destroyed on shutdown (default false). Note: destroy and close are
* mutually exclusive. Enabling one will automatically disable the other.
*
* @param destroy whether or not to destroy the region
*
@@ -285,9 +304,9 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
}
/**
* Indicates whether the region referred by this factory bean,
* will be closed on shutdown (default true).
* Note: destroy and close are mutually exclusive. Enabling one will automatically disable the other.
* Indicates whether the region referred by this factory bean, will be
* closed on shutdown (default true). Note: destroy and close are mutually
* exclusive. Enabling one will automatically disable the other.
*
* @param close whether to close or not the region
* @see #setDestroy(boolean)
@@ -300,9 +319,9 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
}
/**
* Sets the snapshots used for loading a newly <i>created</i> region.
* That is, the snapshot will be used <i>only</i> when a new region is created - if the region
* already exists, no loading will be performed.
* Sets the snapshots used for loading a newly <i>created</i> region. That
* is, the snapshot will be used <i>only</i> when a new region is created -
* if the region already exists, no loading will be performed.
*
* @see #setName(String)
* @param snapshot the snapshot to set
@@ -312,9 +331,9 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
}
/**
* Sets the cache listeners used for the region used by this factory.
* Used only when a new region is created.Overrides the settings
* specified through {@link #setAttributes(RegionAttributes)}.
* Sets the cache listeners used for the region used by this factory. Used
* only when a new region is created.Overrides the settings specified
* through {@link #setAttributes(RegionAttributes)}.
*
* @param cacheListeners the cacheListeners to set on a newly created region
*/
@@ -331,12 +350,21 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
this.dataPolicy = dataPolicy;
}
/**
* Sets the name of disk store to use for overflow and persistence
* @param diskStoreName
*/
public void setDiskStoreName(String diskStoreName) {
this.diskStoreName = diskStoreName;
}
/**
* Sets the region attributes used for the region used by this factory.
* Allows maximum control in specifying the region settings.
* Used only when a new region is created.
* Note that using this method allows for advanced customization of the region - while it provides a lot of flexibility,
* note that it's quite easy to create misconfigured regions (especially in a client/server scenario).
* Allows maximum control in specifying the region settings. Used only when
* a new region is created. Note that using this method allows for advanced
* customization of the region - while it provides a lot of flexibility,
* note that it's quite easy to create misconfigured regions (especially in
* a client/server scenario).
*
* @param attributes the attributes to set on a newly created region
*/

View File

@@ -16,6 +16,8 @@
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;
@@ -23,6 +25,7 @@ import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
/**
@@ -86,6 +89,52 @@ abstract class AbstractRegionParser extends AliasReplacingBeanDefinitionParser {
this.registerBeanDefinition(new BeanDefinitionHolder(subRegionDef, regionPath), parserContext.getRegistry());
}
protected void doParseRegionCommon(Element element, ParserContext parserContext, BeanDefinitionBuilder builder,
BeanDefinitionBuilder attrBuilder, boolean subRegion) {
if (!subRegion) {
String cacheRef = element.getAttribute("cache-ref");
// add cache reference (fallback to default if nothing is specified)
builder.addPropertyReference("cache", (StringUtils.hasText(cacheRef) ? cacheRef : "gemfire-cache"));
}
// add attributes
ParsingUtils.setPropertyValue(element, builder, "name");
ParsingUtils.parseOptionalRegionAttributes(parserContext, element, attrBuilder);
ParsingUtils.parseStatistics(element, attrBuilder);
ParsingUtils.setPropertyValue(element, attrBuilder, "publisher");
if (StringUtils.hasText(element.getAttribute("disk-store-ref"))) {
ParsingUtils.setPropertyValue(element, builder, "disk-store-ref", "diskStoreName");
builder.addDependsOn(element.getAttribute("disk-store-ref"));
}
ParsingUtils.parseExpiration(parserContext, element, attrBuilder);
ParsingUtils.parseEviction(parserContext, element, attrBuilder);
List<Element> subElements = DomUtils.getChildElements(element);
// parse nested elements
for (Element subElement : subElements) {
String name = subElement.getLocalName();
if ("cache-listener".equals(name)) {
builder.addPropertyValue("cacheListeners", parseCacheListener(parserContext, subElement, builder));
}
else if ("cache-loader".equals(name)) {
builder.addPropertyValue("cacheLoader", parseCacheLoader(parserContext, subElement, builder));
}
else if ("cache-writer".equals(name)) {
builder.addPropertyValue("cacheWriter", parseCacheWriter(parserContext, subElement, builder));
}
// subregion
else if (name.endsWith("region")) {
doParseSubRegion(element, subElement, parserContext, builder, subRegion);
}
}
}
private BeanDefinition parseSubRegion(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
BeanDefinition beanDefinition = parserContext.getDelegate().parseCustomElement(element,
builder.getBeanDefinition());
@@ -96,4 +145,16 @@ abstract class AbstractRegionParser extends AliasReplacingBeanDefinitionParser {
String name = element.getAttribute(NAME_ATTRIBUTE);
return StringUtils.hasText(name) ? name : element.getAttribute(ID_ATTRIBUTE);
}
private Object parseCacheListener(ParserContext parserContext, Element subElement, BeanDefinitionBuilder builder) {
return ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, subElement, builder);
}
private Object parseCacheLoader(ParserContext parserContext, Element subElement, BeanDefinitionBuilder builder) {
return ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, subElement, builder);
}
private Object parseCacheWriter(ParserContext parserContext, Element subElement, BeanDefinitionBuilder builder) {
return ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, subElement, builder);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011 the original author or authors.
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,6 +32,7 @@ import org.w3c.dom.Element;
* parsing method is final).
*
* @author Costin Leau
* @author David Turanski
*/
abstract class AliasReplacingBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2010-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,12 +34,15 @@ import com.gemstone.gemfire.cache.DataPolicy;
/**
* Parser for &lt;client-region;gt; definitions.
*
* To avoid eager evaluations, the region interests are declared as nested definition.
* To avoid eager evaluations, the region interests are declared as nested
* definition.
*
* @author Costin Leau
* @author David Turanski
*/
class ClientRegionParser extends AliasReplacingBeanDefinitionParser {
@Override
protected Class<?> getBeanClass(Element element) {
return ClientRegionFactoryBean.class;
}
@@ -58,7 +61,6 @@ class ClientRegionParser extends AliasReplacingBeanDefinitionParser {
ParsingUtils.setPropertyValue(element, builder, "pool-name", "poolName");
ParsingUtils.setPropertyValue(element, builder, "shortcut", "shortcut");
// set the persistent policy
String attr = element.getAttribute("persistent");
@@ -76,14 +78,19 @@ class ClientRegionParser extends AliasReplacingBeanDefinitionParser {
// eviction + overflow attributes
// client attributes
BeanDefinitionBuilder attrBuilder = BeanDefinitionBuilder.genericBeanDefinition(RegionAttributesFactoryBean.class);
BeanDefinitionBuilder attrBuilder = BeanDefinitionBuilder
.genericBeanDefinition(RegionAttributesFactoryBean.class);
ParsingUtils.parseStatistics(element, attrBuilder);
if (StringUtils.hasText(element.getAttribute("disk-store-ref"))) {
ParsingUtils.setPropertyValue(element, builder, "disk-store-ref", "diskStoreName");
builder.addDependsOn(element.getAttribute("disk-store-ref"));
}
boolean overwriteDataPolicy = false;
overwriteDataPolicy |= ParsingUtils.parseEviction(parserContext, element, attrBuilder);
overwriteDataPolicy |= ParsingUtils.parseDiskStorage(element, attrBuilder);
if (!frozenDataPolicy && overwriteDataPolicy) {
builder.addPropertyValue("dataPolicy", DataPolicy.NORMAL);

View File

@@ -16,15 +16,13 @@
package org.springframework.data.gemfire.config;
import java.util.List;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.gemfire.RegionAttributesFactoryBean;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
import com.gemstone.gemfire.cache.DataPolicy;
import com.gemstone.gemfire.cache.Scope;
/**
@@ -39,78 +37,23 @@ class LocalRegionParser extends AbstractRegionParser {
boolean subRegion) {
// set the data policy
String attr = element.getAttribute("persistent");
// if (Boolean.parseBoolean(attr)) {
// builder.addPropertyValue("dataPolicy",
// DataPolicy.PERSISTENT_REPLICATE);
// }
// else {
// builder.addPropertyValue("dataPolicy", DataPolicy.REPLICATE);
// }
String attr = element.getAttribute("data-policy");
if (StringUtils.hasText(attr)) {
builder.addPropertyValue("dataPolicyName", attr.toUpperCase());
}
else {
builder.addPropertyValue("dataPolicy", DataPolicy.NORMAL);
}
builder.addPropertyValue("scope", Scope.LOCAL);
ParsingUtils.setPropertyValue(element, builder, "name", "name");
BeanDefinitionBuilder attrBuilder = builder;
if (!subRegion) {
attr = element.getAttribute("cache-ref");
// add cache reference (fallback to default if nothing is specified)
builder.addPropertyReference("cache", (StringUtils.hasText(attr) ? attr : "gemfire-cache"));
attrBuilder = BeanDefinitionBuilder.genericBeanDefinition(RegionAttributesFactoryBean.class);
}
// add attributes
ParsingUtils.parseStatistics(element, attrBuilder);
attr = element.getAttribute("publisher");
if (StringUtils.hasText(attr)) {
attrBuilder.addPropertyValue("publisher", Boolean.valueOf(attr));
}
ParsingUtils.parseExpiration(parserContext, element, attrBuilder);
ParsingUtils.parseEviction(parserContext, element, attrBuilder);
ParsingUtils.parseDiskStorage(element, attrBuilder);
BeanDefinitionBuilder attrBuilder = subRegion ? builder : BeanDefinitionBuilder
.genericBeanDefinition(RegionAttributesFactoryBean.class);
super.doParseRegionCommon(element, parserContext, builder, attrBuilder, subRegion);
if (!subRegion) {
builder.addPropertyValue("attributes", attrBuilder.getBeanDefinition());
}
List<Element> subElements = DomUtils.getChildElements(element);
// parse nested elements
for (Element subElement : subElements) {
String name = subElement.getLocalName();
if ("cache-listener".equals(name)) {
builder.addPropertyValue("cacheListeners", parseCacheListener(parserContext, subElement, builder));
}
else if ("cache-loader".equals(name)) {
builder.addPropertyValue("cacheLoader", parseCacheLoader(parserContext, subElement, builder));
}
else if ("cache-writer".equals(name)) {
builder.addPropertyValue("cacheWriter", parseCacheWriter(parserContext, subElement, builder));
}
// subregion
else if (name.endsWith("region")) {
doParseSubRegion(element, subElement, parserContext, builder, subRegion);
}
}
}
private Object parseCacheListener(ParserContext parserContext, Element subElement, BeanDefinitionBuilder builder) {
return ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, subElement, builder);
}
private Object parseCacheLoader(ParserContext parserContext, Element subElement, BeanDefinitionBuilder builder) {
return ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, subElement, builder);
}
private Object parseCacheWriter(ParserContext parserContext, Element subElement, BeanDefinitionBuilder builder) {
return ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, subElement, builder);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2010-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,19 +28,19 @@ import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.core.Conventions;
import org.springframework.data.gemfire.DiskStoreFactoryBean;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
import com.gemstone.gemfire.cache.DiskStoreFactory;
import com.gemstone.gemfire.cache.ExpirationAction;
import com.gemstone.gemfire.cache.ExpirationAttributes;
import com.gemstone.gemfire.cache.Scope;
/**
* Various minor utility used by the parser.
*
* @author Costin Leau
* @author David Turanski
*/
abstract class ParsingUtils {
@@ -156,54 +156,6 @@ abstract class ParsingUtils {
return list;
}
/**
* Parses disk store sub-element. Populates the given attribute factory with
* the proper attributes.
*
* @param element - element enclosing the disk-store definition
* @param beanBuilder - beanbuilder for a RegionAttributesFactoryBean
* instance
* @return true if parsing actually occured, false otherwise
*/
static boolean parseDiskStorage(Element element, BeanDefinitionBuilder beanBuilder) {
Element diskStoreElement = DomUtils.getChildElementByTagName(element, "disk-store");
if (diskStoreElement == null)
return false;
if (diskStoreElement.getParentNode().getLocalName().endsWith("region")) {
System.out.println("This is a nested disk-store");
}
BeanDefinitionBuilder diskDefBuilder = BeanDefinitionBuilder.genericBeanDefinition(DiskStoreFactory.class);
setPropertyValue(diskStoreElement, diskDefBuilder, "auto-compact", "rollOplogs");
setPropertyValue(diskStoreElement, diskDefBuilder, "max-oplog-size", "maxOplogSize");
setPropertyValue(diskStoreElement, diskDefBuilder, "time-interval", "timeInterval");
setPropertyValue(diskStoreElement, diskDefBuilder, "queue-size", "bytesThreshold");
// parse nested disk-dir
List<Element> list = DomUtils.getChildElementsByTagName(diskStoreElement, "disk-dir");
ManagedList<Object> locations = new ManagedList<Object>(list.size());
ManagedList<Object> sizes = new ManagedList<Object>(list.size());
for (Element diskDirElement : list) {
locations.add(diskDirElement.getAttribute("location"));
String attr = diskDirElement.getAttribute("max-size");
sizes.add(StringUtils.hasText(attr) ? attr : "10240");
}
// wrap up the disk attributes factory to call 'create'
BeanDefinitionBuilder factoryWrapper = BeanDefinitionBuilder.genericBeanDefinition(DiskStoreFactoryBean.class);
factoryWrapper.addPropertyValue("diskAttributesFactory", diskDefBuilder.getBeanDefinition());
beanBuilder.addPropertyValue("diskWriteAttributes", factoryWrapper.getBeanDefinition());
beanBuilder.addPropertyValue("diskDirs", locations);
beanBuilder.addPropertyValue("diskSizes", sizes);
return true;
}
/**
* Parses the eviction sub-element. Populates the given attribute factory
* with the proper attributes.
@@ -228,8 +180,8 @@ abstract class ParsingUtils {
evictionDefBuilder.addPropertyValue("type", EvictionType.valueOf(attr.toUpperCase()));
}
setPropertyValue(evictionElement, evictionDefBuilder, "threshold", "threshold");
setPropertyValue(evictionElement, evictionDefBuilder, "action", "action");
setPropertyValue(evictionElement, evictionDefBuilder, "threshold");
setPropertyValue(evictionElement, evictionDefBuilder, "action");
// get object sizer (if declared)
Element objectSizerElement = DomUtils.getChildElementByTagName(evictionElement, "object-sizer");
@@ -270,16 +222,21 @@ abstract class ParsingUtils {
return result;
}
static void parseAdditionalAttributes(ParserContext parserContext, Element element,
static void parseOptionalRegionAttributes(ParserContext parserContext, Element element,
BeanDefinitionBuilder attrBuilder) {
setPropertyValue(element, attrBuilder, "persistent", "persistBackup");
if (!("partitioned-region".equals(element.getLocalName()))) {
setPropertyValue(element, attrBuilder, "persistent", "persistBackup");
}
setPropertyValue(element, attrBuilder, "ignore-jta", "ignoreJTA");
setPropertyValue(element, attrBuilder, "key-constraint", "keyConstraint");
setPropertyValue(element, attrBuilder, "value-constraint", "valueConstraint");
setPropertyValue(element, attrBuilder, "lock-grantor", "lockGrantor");
setPropertyValue(element, attrBuilder, "enable-subscription-conflation", "enableSubscriptionConflation");
setPropertyValue(element, attrBuilder, "enable-async-conflation", "enableAsyncConflation");
setPropertyValue(element, attrBuilder, "initial-capacity", "initialCapacity");
setPropertyValue(element, attrBuilder, "key-constraint");
setPropertyValue(element, attrBuilder, "value-constraint");
setPropertyValue(element, attrBuilder, "is-lock-grantor", "lockGrantor");
setPropertyValue(element, attrBuilder, "enable-subscription-conflation");
setPropertyValue(element, attrBuilder, "enable-async-conflation");
setPropertyValue(element, attrBuilder, "initial-capacity");
setPropertyValue(element, attrBuilder, "load-factor");
setPropertyValue(element, attrBuilder, "cloning-enabled");
String indexUpdateType = element.getAttribute("index-update-type");
if (StringUtils.hasText(indexUpdateType)) {
attrBuilder.addPropertyValue("indexMaintenanceSynchronous", "synchronous".equals(indexUpdateType));
@@ -287,6 +244,16 @@ abstract class ParsingUtils {
}
static void parseScope(Element element, BeanDefinitionBuilder builder) {
String scope = element.getAttribute("scope");
if (StringUtils.hasText(scope)) {
builder.addPropertyValue("scope", Scope.fromString(scope.toUpperCase().replace("-", "_")));
}
else {
builder.addPropertyValue("scope", Scope.DISTRIBUTED_ACK);
}
}
private static boolean parseExpiration(Element rootElement, String elementName, String propertyName,
BeanDefinitionBuilder attrBuilder) {
Element expirationElement = DomUtils.getChildElementByTagName(rootElement, elementName);

View File

@@ -65,21 +65,13 @@ class PartitionedRegionParser extends AbstractRegionParser {
builder.addPropertyValue("dataPolicy", DataPolicy.PARTITION);
}
BeanDefinitionBuilder attrBuilder = builder;
ParsingUtils.parseScope(element, builder);
if (!subRegion) {
attr = element.getAttribute("cache-ref");
// add cache reference (fallback to default if nothing is specified)
builder.addPropertyReference("cache", (StringUtils.hasText(attr) ? attr : "gemfire-cache"));
attrBuilder = BeanDefinitionBuilder.genericBeanDefinition(RegionAttributesFactoryBean.class);
}
ParsingUtils.setPropertyValue(element, builder, "name", "name");
ParsingUtils.parseStatistics(element, attrBuilder);
ParsingUtils.parseExpiration(parserContext, element, attrBuilder);
ParsingUtils.parseEviction(parserContext, element, attrBuilder);
ParsingUtils.parseDiskStorage(element, attrBuilder);
BeanDefinitionBuilder attrBuilder = subRegion ? builder : BeanDefinitionBuilder
.genericBeanDefinition(RegionAttributesFactoryBean.class);
super.doParseRegionCommon(element, parserContext, builder, attrBuilder, subRegion);
//
// partition attributes
BeanDefinitionBuilder parAttrBuilder = BeanDefinitionBuilder
.genericBeanDefinition(PartitionAttributesFactoryBean.class);
@@ -120,36 +112,16 @@ class PartitionedRegionParser extends AbstractRegionParser {
if (StringUtils.hasText(attr)) {
parAttrBuilder.addPropertyValue("totalNumBuckets", Integer.valueOf(attr));
}
List<Element> subElements = DomUtils.getChildElements(element);
// parse nested cache-listener elements
//
List<Element> subElements = DomUtils.getChildElementsByTagName(element, "partition-resolver");
//
// // parse nested cache-listener elements
for (Element subElement : subElements) {
String name = subElement.getLocalName();
if ("cache-listener".equals(name)) {
builder.addPropertyValue("cacheListeners", parseCacheListener(parserContext, subElement, builder));
}
else if ("cache-loader".equals(name)) {
builder.addPropertyValue("cacheLoader", parseCacheLoader(parserContext, subElement, builder));
}
else if ("cache-writer".equals(name)) {
builder.addPropertyValue("cacheWriter", parseCacheWriter(parserContext, subElement, builder));
}
else if ("partition-resolver".equals(name)) {
parAttrBuilder.addPropertyValue("partitionResolver",
parsePartitionResolver(parserContext, subElement, builder));
}
// subregion
else if (name.endsWith("region")) {
doParseSubRegion(element, subElement, parserContext, builder, subRegion);
}
parAttrBuilder.addPropertyValue("partitionResolver",
parsePartitionResolver(parserContext, subElement, builder));
}
// add partition attributes attributes
//
// // add partition attributes attributes
attrBuilder.addPropertyValue("partitionAttributes", parAttrBuilder.getBeanDefinition());
// add partition/overflow settings as attributes
if (!subRegion) {
@@ -157,18 +129,6 @@ class PartitionedRegionParser extends AbstractRegionParser {
}
}
private Object parseCacheListener(ParserContext parserContext, Element subElement, BeanDefinitionBuilder builder) {
return ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, subElement, builder);
}
private Object parseCacheLoader(ParserContext parserContext, Element subElement, BeanDefinitionBuilder builder) {
return ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, subElement, builder);
}
private Object parseCacheWriter(ParserContext parserContext, Element subElement, BeanDefinitionBuilder builder) {
return ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, subElement, builder);
}
private Object parsePartitionResolver(ParserContext parserContext, Element subElement, BeanDefinitionBuilder builder) {
return ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, subElement, builder);
}

View File

@@ -16,17 +16,12 @@
package org.springframework.data.gemfire.config;
import java.util.List;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.gemfire.RegionAttributesFactoryBean;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
import com.gemstone.gemfire.cache.DataPolicy;
import com.gemstone.gemfire.cache.Scope;
/**
* Parser for &lt;replicated-region;gt; definitions.
@@ -48,69 +43,14 @@ class ReplicatedRegionParser extends AbstractRegionParser {
builder.addPropertyValue("dataPolicy", DataPolicy.REPLICATE);
}
builder.addPropertyValue("scope", Scope.DISTRIBUTED_ACK);
ParsingUtils.parseScope(element, builder);
ParsingUtils.setPropertyValue(element, builder, "name", "name");
BeanDefinitionBuilder attrBuilder = builder;
if (!subRegion) {
attr = element.getAttribute("cache-ref");
// add cache reference (fallback to default if nothing is specified)
builder.addPropertyReference("cache", (StringUtils.hasText(attr) ? attr : "gemfire-cache"));
attrBuilder = BeanDefinitionBuilder.genericBeanDefinition(RegionAttributesFactoryBean.class);
}
// add attributes
ParsingUtils.parseAdditionalAttributes(parserContext, element, attrBuilder);
ParsingUtils.parseStatistics(element, attrBuilder);
attr = element.getAttribute("publisher");
if (StringUtils.hasText(attr)) {
attrBuilder.addPropertyValue("publisher", Boolean.valueOf(attr));
}
ParsingUtils.parseExpiration(parserContext, element, attrBuilder);
ParsingUtils.parseEviction(parserContext, element, attrBuilder);
ParsingUtils.parseDiskStorage(element, attrBuilder);
BeanDefinitionBuilder attrBuilder = subRegion ? builder : BeanDefinitionBuilder
.genericBeanDefinition(RegionAttributesFactoryBean.class);
super.doParseRegionCommon(element, parserContext, builder, attrBuilder, subRegion);
if (!subRegion) {
builder.addPropertyValue("attributes", attrBuilder.getBeanDefinition());
}
List<Element> subElements = DomUtils.getChildElements(element);
// parse nested elements
for (Element subElement : subElements) {
String name = subElement.getLocalName();
if ("cache-listener".equals(name)) {
builder.addPropertyValue("cacheListeners", parseCacheListener(parserContext, subElement, builder));
}
else if ("cache-loader".equals(name)) {
builder.addPropertyValue("cacheLoader", parseCacheLoader(parserContext, subElement, builder));
}
else if ("cache-writer".equals(name)) {
builder.addPropertyValue("cacheWriter", parseCacheWriter(parserContext, subElement, builder));
}
// subregion
else if (name.endsWith("region")) {
doParseSubRegion(element, subElement, parserContext, builder, subRegion);
}
}
}
private Object parseCacheListener(ParserContext parserContext, Element subElement, BeanDefinitionBuilder builder) {
return ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, subElement, builder);
}
private Object parseCacheLoader(ParserContext parserContext, Element subElement, BeanDefinitionBuilder builder) {
return ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, subElement, builder);
}
private Object parseCacheWriter(ParserContext parserContext, Element subElement, BeanDefinitionBuilder builder) {
return ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, subElement, builder);
}
}