Refactored region factories

This commit is contained in:
David Turanski
2012-07-04 10:37:44 -04:00
parent e9d1173b05
commit 8e6e43b96e
20 changed files with 226 additions and 126 deletions

View File

@@ -0,0 +1,46 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.gemfire;
import com.gemstone.gemfire.cache.DataPolicy;
import com.gemstone.gemfire.cache.RegionFactory;
/**
* @author David Turanski
*
*/
public class LocalRegionFactoryBean<K, V> extends RegionFactoryBean<K, V> {
@Override
protected void resolveDataPolicy(RegionFactory<K, V> regionFactory, boolean persistent, String dataPolicyName) {
if (dataPolicyName != null) {
if ("NORMAL".equals(dataPolicyName) || dataPolicyName == null) {
regionFactory.setDataPolicy(DataPolicy.NORMAL);
}
else if ("PRELOADED".equals(dataPolicyName)) {
regionFactory.setDataPolicy(DataPolicy.PRELOADED);
}
else if ("EMPTY".equals(dataPolicyName)) {
regionFactory.setDataPolicy(DataPolicy.EMPTY);
}
else {
throw new IllegalArgumentException("Data policy '" + dataPolicyName
+ "' is unsupported or invalid for local regions.");
}
}
}
}

View File

@@ -0,0 +1,49 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.gemfire;
import java.util.concurrent.ConcurrentMap;
import com.gemstone.gemfire.cache.CacheFactory;
import com.gemstone.gemfire.cache.DataPolicy;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.RegionFactory;
/**
* @author David Turanski
*
*/
public class PartitionedRegionFactoryBean<K, V> extends RegionFactoryBean<K, V> {
@Override
protected void resolveDataPolicy(RegionFactory<K, V> regionFactory, boolean persistent, String dataPolicyName) {
if (persistent) {
// check first for GemFire 6.5
if (ConcurrentMap.class.isAssignableFrom(Region.class)) {
regionFactory.setDataPolicy(DataPolicy.PERSISTENT_PARTITION);
}
else {
throw new IllegalArgumentException(
"Can define persistent partitions only from GemFire 6.5 onwards - current version is ["
+ CacheFactory.getVersion() + "]");
}
}
else {
regionFactory.setDataPolicy(DataPolicy.PARTITION);
}
}
}

View File

@@ -34,7 +34,6 @@ import com.gemstone.gemfire.cache.CacheClosedException;
import com.gemstone.gemfire.cache.CacheListener;
import com.gemstone.gemfire.cache.CacheLoader;
import com.gemstone.gemfire.cache.CacheWriter;
import com.gemstone.gemfire.cache.DataPolicy;
import com.gemstone.gemfire.cache.GemFireCache;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.RegionAttributes;
@@ -54,7 +53,7 @@ import com.gemstone.gemfire.cache.Scope;
* @author Costin Leau
* @author David Turanski
*/
public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> implements DisposableBean {
public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> implements DisposableBean {
protected final Log log = LogFactory.getLog(getClass());
@@ -74,9 +73,9 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
private Scope scope;
private String diskStoreName;
private boolean persistent;
private DataPolicy dataPolicy;
private String diskStoreName;
private String dataPolicyName;
@@ -117,23 +116,7 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
regionFactory.setCacheWriter(cacheWriter);
}
if (dataPolicy != null) {
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.");
}
}
resolveDataPolicy(regionFactory, persistent, dataPolicyName);
if (scope != null) {
regionFactory.setScope(scope);
@@ -163,6 +146,9 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
return reg;
}
protected abstract void resolveDataPolicy(RegionFactory<K, V> regionFactory, boolean persistent,
String dataPolicyName);
@SuppressWarnings("unchecked")
private AttributesFactory<K, V> findAttrFactory(RegionFactory<K, V> regionFactory) {
Field attrField = ReflectionUtils.findField(RegionFactory.class, "attrsFactory", AttributesFactory.class);
@@ -297,16 +283,6 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
this.cacheWriter = cacheWriter;
}
/**
* Sets the data policy. Used only when a new region is created. Overrides
* the settings specified through {@link #setAttributes(RegionAttributes)}.
*
* @param dataPolicy the region data policy
*/
public void setDataPolicy(DataPolicy dataPolicy) {
this.dataPolicy = dataPolicy;
}
/**
* Sets the region scope. Used only when a new region is created. Overrides
* the settings specified through {@link #setAttributes(RegionAttributes)}.
@@ -318,6 +294,10 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
this.scope = scope;
}
public void setPersistent(boolean persistent) {
this.persistent = persistent;
}
/**
* Sets the dataPolicy as a String. Required to support property
* placeholders

View File

@@ -0,0 +1,47 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.gemfire;
import org.springframework.util.Assert;
import com.gemstone.gemfire.cache.DataPolicy;
import com.gemstone.gemfire.cache.RegionFactory;
/**
* @author David Turanski
*
*/
public class ReplicatedRegionFactoryBean<K, V> extends RegionFactoryBean<K, V> {
@Override
protected void resolveDataPolicy(RegionFactory<K, V> regionFactory, boolean persistent, String dataPolicyName) {
DataPolicy dataPolicy = null;
if (dataPolicyName != null) {
if ("EMPTY".equals(dataPolicyName)) {
Assert.isTrue(!persistent, "Cannot have persistence on an empty region");
dataPolicy = DataPolicy.EMPTY;
}
else {
throw new IllegalArgumentException("Data policy '" + dataPolicyName
+ "' is unsupported or invalid for replicated regions.");
}
}
else {
dataPolicy = persistent ? DataPolicy.PERSISTENT_REPLICATE : DataPolicy.REPLICATE;
}
regionFactory.setDataPolicy(dataPolicy);
}
}

View File

@@ -102,6 +102,11 @@ abstract class AbstractRegionParser extends AliasReplacingBeanDefinitionParser {
ParsingUtils.parseOptionalRegionAttributes(parserContext, element, attrBuilder);
ParsingUtils.parseStatistics(element, attrBuilder);
ParsingUtils.setPropertyValue(element, attrBuilder, "publisher");
if (!isSubRegion(element)) {
ParsingUtils.setPropertyValue(element, builder, "persistent");
}
// set the data policy
ParsingUtils.setPropertyValue(element, builder, "data-policy", "dataPolicyName");
if (StringUtils.hasText(element.getAttribute("disk-store-ref"))) {
ParsingUtils.setPropertyValue(element, builder, "disk-store-ref", "diskStoreName");

View File

@@ -21,7 +21,6 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.gemfire.RegionFactoryBean;
import org.springframework.data.gemfire.SubRegionFactoryBean;
import org.w3c.dom.Element;
@@ -43,10 +42,12 @@ abstract class AliasReplacingBeanDefinitionParser extends AbstractSingleBeanDefi
return SubRegionFactoryBean.class;
}
else {
return RegionFactoryBean.class;
return getRegionFactoryClass();
}
}
protected abstract Class<?> getRegionFactoryClass();
@Override
protected final void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {

View File

@@ -41,9 +41,8 @@ import com.gemstone.gemfire.cache.DataPolicy;
* @author David Turanski
*/
class ClientRegionParser extends AliasReplacingBeanDefinitionParser {
@Override
protected Class<?> getBeanClass(Element element) {
protected Class<?> getRegionFactoryClass() {
return ClientRegionFactoryBean.class;
}

View File

@@ -18,11 +18,10 @@ package org.springframework.data.gemfire.config;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.gemfire.LocalRegionFactoryBean;
import org.springframework.data.gemfire.RegionAttributesFactoryBean;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
import com.gemstone.gemfire.cache.DataPolicy;
import com.gemstone.gemfire.cache.Scope;
/**
@@ -36,15 +35,6 @@ class LocalRegionParser extends AbstractRegionParser {
protected void doParseRegion(Element element, ParserContext parserContext, BeanDefinitionBuilder builder,
boolean subRegion) {
// set the data policy
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);
BeanDefinitionBuilder attrBuilder = subRegion ? builder : BeanDefinitionBuilder
@@ -56,4 +46,9 @@ class LocalRegionParser extends AbstractRegionParser {
}
}
@Override
protected Class<?> getRegionFactoryClass() {
return LocalRegionFactoryBean.class;
}
}

View File

@@ -21,7 +21,6 @@ import java.util.List;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.gemfire.RegionLookupFactoryBean;
import org.springframework.data.gemfire.SubRegionFactoryBean;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
@@ -34,16 +33,6 @@ import org.w3c.dom.Element;
*/
class LookupRegionParser extends AbstractRegionParser {
@Override
protected Class<?> getBeanClass(Element element) {
if (isSubRegion(element)) {
return SubRegionFactoryBean.class;
}
else {
return RegionLookupFactoryBean.class;
}
}
@Override
protected void doParseRegion(Element element, ParserContext parserContext, BeanDefinitionBuilder builder,
boolean subRegion) {
@@ -69,4 +58,9 @@ class LookupRegionParser extends AbstractRegionParser {
}
}
}
@Override
protected Class<?> getRegionFactoryClass() {
return RegionLookupFactoryBean.class;
}
}

View File

@@ -17,20 +17,16 @@
package org.springframework.data.gemfire.config;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.gemfire.PartitionAttributesFactoryBean;
import org.springframework.data.gemfire.PartitionedRegionFactoryBean;
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.CacheFactory;
import com.gemstone.gemfire.cache.DataPolicy;
import com.gemstone.gemfire.cache.Region;
/**
* Parser for &lt;partitioned-region;gt; definitions.
*
@@ -41,30 +37,16 @@ import com.gemstone.gemfire.cache.Region;
* @author David Turanski
*/
class PartitionedRegionParser extends AbstractRegionParser {
@Override
protected Class<?> getRegionFactoryClass() {
return PartitionedRegionFactoryBean.class;
}
@Override
protected void doParseRegion(Element element, ParserContext parserContext, BeanDefinitionBuilder builder,
boolean subRegion) {
super.doParse(element, builder);
// set the data policy
String attr = element.getAttribute("persistent");
if (Boolean.parseBoolean(attr)) {
// check first for GemFire 6.5
if (ConcurrentMap.class.isAssignableFrom(Region.class)) {
builder.addPropertyValue("dataPolicy", "PERSISTENT_PARTITION");
}
else {
parserContext.getReaderContext().error(
"Can define persistent partitions only from GemFire 6.5 onwards - current version is ["
+ CacheFactory.getVersion() + "]", element);
}
}
else {
builder.addPropertyValue("dataPolicy", DataPolicy.PARTITION);
}
BeanDefinitionBuilder attrBuilder = subRegion ? builder : BeanDefinitionBuilder
.genericBeanDefinition(RegionAttributesFactoryBean.class);
@@ -74,7 +56,7 @@ class PartitionedRegionParser extends AbstractRegionParser {
BeanDefinitionBuilder parAttrBuilder = BeanDefinitionBuilder
.genericBeanDefinition(PartitionAttributesFactoryBean.class);
attr = element.getAttribute("colocated-with");
String attr = element.getAttribute("colocated-with");
if (StringUtils.hasText(attr)) {
parAttrBuilder.addPropertyValue("colocatedWith", attr);

View File

@@ -19,10 +19,9 @@ package org.springframework.data.gemfire.config;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.gemfire.RegionAttributesFactoryBean;
import org.springframework.data.gemfire.ReplicatedRegionFactoryBean;
import org.w3c.dom.Element;
import com.gemstone.gemfire.cache.DataPolicy;
/**
* Parser for &lt;replicated-region;gt; definitions.
*
@@ -34,15 +33,6 @@ class ReplicatedRegionParser extends AbstractRegionParser {
protected void doParseRegion(Element element, ParserContext parserContext, BeanDefinitionBuilder builder,
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);
}
ParsingUtils.parseScope(element, builder);
BeanDefinitionBuilder attrBuilder = subRegion ? builder : BeanDefinitionBuilder
@@ -53,4 +43,9 @@ class ReplicatedRegionParser extends AbstractRegionParser {
builder.addPropertyValue("attributes", attrBuilder.getBeanDefinition());
}
}
@Override
protected Class<?> getRegionFactoryClass() {
return ReplicatedRegionFactoryBean.class;
}
}