SGF-18
+ added basic lookup factory bean + refactored existing schema + added namespace parsers + added integration tests
This commit is contained in:
@@ -18,14 +18,9 @@ package org.springframework.data.gemfire;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.gemstone.gemfire.cache.AttributesFactory;
|
||||
import com.gemstone.gemfire.cache.Cache;
|
||||
@@ -38,19 +33,15 @@ import com.gemstone.gemfire.cache.RegionAttributes;
|
||||
import com.gemstone.gemfire.cache.Scope;
|
||||
|
||||
/**
|
||||
* FactoryBean for creating generic Gemfire {@link Region}s. Will try to first locate the region (by name)
|
||||
* FactoryBean for creating generic GemFire {@link Region}s. Will try to first locate the region (by name)
|
||||
* and, in case none if found, proceed to creating one using the given settings.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class RegionFactoryBean<K, V> implements DisposableBean, FactoryBean<Region<K, V>>, InitializingBean,
|
||||
BeanNameAware {
|
||||
public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> implements DisposableBean {
|
||||
|
||||
protected final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
private String beanName;
|
||||
private Cache cache;
|
||||
private String name;
|
||||
private boolean destroy = false;
|
||||
private Resource snapshot;
|
||||
|
||||
@@ -61,60 +52,55 @@ public class RegionFactoryBean<K, V> implements DisposableBean, FactoryBean<Regi
|
||||
private Scope scope;
|
||||
private DataPolicy dataPolicy;
|
||||
|
||||
private Region<K, V> region;
|
||||
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(cache, "Cache property must be set");
|
||||
name = (!StringUtils.hasText(name) ? beanName : name);
|
||||
Assert.hasText(name, "Name (or beanName) property must be set");
|
||||
|
||||
// first get cache
|
||||
region = cache.getRegion(name);
|
||||
if (region != null) {
|
||||
log.info("Retrieved region [" + name + "] from cache");
|
||||
}
|
||||
// fall back to cache creation if one is not found
|
||||
else {
|
||||
if (attributes != null)
|
||||
AttributesFactory.validateAttributes(attributes);
|
||||
|
||||
AttributesFactory<K, V> attrFactory = (attributes != null ? new AttributesFactory<K, V>(attributes)
|
||||
: new AttributesFactory<K, V>());
|
||||
if (!ObjectUtils.isEmpty(cacheListeners)) {
|
||||
for (CacheListener<K, V> listener : cacheListeners) {
|
||||
attrFactory.addCacheListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
if (cacheLoader != null) {
|
||||
attrFactory.setCacheLoader(cacheLoader);
|
||||
}
|
||||
|
||||
if (cacheWriter != null) {
|
||||
attrFactory.setCacheWriter(cacheWriter);
|
||||
}
|
||||
|
||||
if (dataPolicy != null) {
|
||||
attrFactory.setDataPolicy(dataPolicy);
|
||||
}
|
||||
|
||||
if (scope != null) {
|
||||
attrFactory.setScope(scope);
|
||||
}
|
||||
|
||||
postProcess(attrFactory);
|
||||
|
||||
region = cache.createRegion(name, attrFactory.create());
|
||||
log.info("Created new cache region [" + name + "]");
|
||||
if (snapshot != null) {
|
||||
region.loadSnapshot(snapshot.getInputStream());
|
||||
}
|
||||
}
|
||||
|
||||
super.afterPropertiesSet();
|
||||
|
||||
postProcess(region);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Region<K, V> lookupFallback(Cache cache, String regionName) throws Exception {
|
||||
if (attributes != null)
|
||||
AttributesFactory.validateAttributes(attributes);
|
||||
|
||||
AttributesFactory<K, V> attrFactory = (attributes != null ? new AttributesFactory<K, V>(attributes)
|
||||
: new AttributesFactory<K, V>());
|
||||
if (!ObjectUtils.isEmpty(cacheListeners)) {
|
||||
for (CacheListener<K, V> listener : cacheListeners) {
|
||||
attrFactory.addCacheListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
if (cacheLoader != null) {
|
||||
attrFactory.setCacheLoader(cacheLoader);
|
||||
}
|
||||
|
||||
if (cacheWriter != null) {
|
||||
attrFactory.setCacheWriter(cacheWriter);
|
||||
}
|
||||
|
||||
if (dataPolicy != null) {
|
||||
attrFactory.setDataPolicy(dataPolicy);
|
||||
}
|
||||
|
||||
if (scope != null) {
|
||||
attrFactory.setScope(scope);
|
||||
}
|
||||
|
||||
postProcess(attrFactory);
|
||||
|
||||
Region<K, V> reg = cache.createRegion(regionName, attrFactory.create());
|
||||
log.info("Created new cache region [" + regionName + "]");
|
||||
if (snapshot != null) {
|
||||
reg.loadSnapshot(snapshot.getInputStream());
|
||||
}
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post-process the attribute factory object used for configuring the region of this factory bean during the initialization process.
|
||||
* The object is already initialized and configured by the factory bean before this method
|
||||
@@ -144,46 +130,6 @@ public class RegionFactoryBean<K, V> implements DisposableBean, FactoryBean<Regi
|
||||
region = null;
|
||||
}
|
||||
|
||||
public Region<K, V> getObject() throws Exception {
|
||||
return region;
|
||||
}
|
||||
|
||||
public Class<?> getObjectType() {
|
||||
return (region != null ? region.getClass() : Region.class);
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setBeanName(String beanName) {
|
||||
this.beanName = beanName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cache used for creating the region.
|
||||
*
|
||||
* @see org.springframework.data.gemfire.CacheFactoryBean
|
||||
* @param cache the cache to set
|
||||
*/
|
||||
public void setCache(Cache cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the cache region. If no cache is found under
|
||||
* the given name, a new one will be created.
|
||||
* If no name is given, the beanName will be used.
|
||||
*
|
||||
* @see com.gemstone.gemfire.cache.Region#getFullPath()
|
||||
* @see #setBeanName(String)
|
||||
*
|
||||
* @param name the region name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the region referred by this factory bean,
|
||||
* will be destroyed on shutdown (default false).
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2010 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.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.gemstone.gemfire.cache.Cache;
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
* Simple FactoryBean for retrieving generic GemFire {@link Region}s. If the region doesn't exist, an exception is thrown.
|
||||
*
|
||||
* For declaring and configuring new regions, see {@link RegionFactoryBean}.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class RegionLookupFactoryBean<K, V> implements FactoryBean<Region<K, V>>, InitializingBean, BeanNameAware {
|
||||
|
||||
protected final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
private String beanName;
|
||||
private Cache cache;
|
||||
private String name;
|
||||
|
||||
Region<K, V> region;
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(cache, "Cache property must be set");
|
||||
name = (!StringUtils.hasText(name) ? beanName : name);
|
||||
Assert.hasText(name, "Name (or beanName) property must be set");
|
||||
|
||||
region = cache.getRegion(name);
|
||||
if (region != null) {
|
||||
log.info("Retrieved region [" + name + "] from cache");
|
||||
}
|
||||
|
||||
else {
|
||||
region = lookupFallback(cache, name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fall back method in case the named region does not exist.
|
||||
* By default, this implementation throws an exception.
|
||||
*
|
||||
* @param cache GemFire cache
|
||||
* @param regionName region name
|
||||
* @throws Exception
|
||||
*/
|
||||
protected Region<K, V> lookupFallback(Cache cache, String regionName) throws Exception {
|
||||
throw new BeanInitializationException("Cannot find region named " + name + " in cache " + cache);
|
||||
}
|
||||
|
||||
public Region<K, V> getObject() throws Exception {
|
||||
return region;
|
||||
}
|
||||
|
||||
public Class<?> getObjectType() {
|
||||
return (region != null ? region.getClass() : Region.class);
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setBeanName(String name) {
|
||||
this.beanName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cache used for creating the region.
|
||||
*
|
||||
* @see org.springframework.data.gemfire.CacheFactoryBean
|
||||
* @param cache the cache to set
|
||||
*/
|
||||
public void setCache(Cache cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the cache region. If no cache is found under
|
||||
* the given name, a new one will be created.
|
||||
* If no name is given, the beanName will be used.
|
||||
*
|
||||
* @see com.gemstone.gemfire.cache.Region#getFullPath()
|
||||
* @see #setBeanName(String)
|
||||
*
|
||||
* @param name the region name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ import com.gemstone.gemfire.cache.Region;
|
||||
import com.gemstone.gemfire.cache.client.Pool;
|
||||
|
||||
/**
|
||||
* Client extension for Gemfire regions.
|
||||
* Client extension for GemFire regions.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
|
||||
@@ -27,6 +27,7 @@ class GemfireNamespaceHandler extends NamespaceHandlerSupport {
|
||||
|
||||
public void init() {
|
||||
registerBeanDefinitionParser("cache", new CacheParser());
|
||||
registerBeanDefinitionParser("lookup-region", new LookupRegionParser());
|
||||
registerBeanDefinitionParser("replicated-region", new ReplicatedRegionParser());
|
||||
registerBeanDefinitionParser("partitioned-region", new PartitionedRegionParser());
|
||||
registerBeanDefinitionParser("client-region", new ClientRegionParser());
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2010 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.config;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.data.gemfire.RegionFactoryBean;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Parser for <lookup-region;gt; definitions.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
class LookupRegionParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return RegionFactoryBean.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
super.doParse(element, builder);
|
||||
|
||||
ParsingUtils.setPropertyValue(element, builder, "name", "name");
|
||||
|
||||
String attr = element.getAttribute("cache-ref");
|
||||
// add cache reference (fallback to default if nothing is specified)
|
||||
builder.addPropertyReference("cache", (StringUtils.hasText(attr) ? attr : "gemfire-cache"));
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user