Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.springframework.data.gemfire.config.AbstractRegionParser Maven / Gradle / Ivy
/*
* 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.
* 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 java.util.HashMap;
import java.util.List;
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;
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;
import org.w3c.dom.Element;
import com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueue;
import com.gemstone.gemfire.cache.wan.GatewaySender;
/**
* Abstract base class encapsulating functionality common to all Region Parsers.
*
* @author David Turanski
* @author John Blum
*/
abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser {
protected final Log log = LogFactory.getLog(getClass());
@Override
protected Class getBeanClass(Element element) {
return getRegionFactoryClass();
}
protected abstract Class getRegionFactoryClass();
@Override
protected String getParentName(final Element element) {
String regionTemplate = element.getAttribute("template");
return (StringUtils.hasText(regionTemplate) ? regionTemplate : super.getParentName(element));
}
protected boolean isRegionTemplate(final Element element) {
String localName = element.getLocalName();
return (localName != null && localName.endsWith("-template"));
}
protected boolean isSubRegion(final Element element) {
String localName = element.getParentNode().getLocalName();
return (localName != null && localName.endsWith("region"));
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
super.doParse(element, builder);
builder.setAbstract(isRegionTemplate(element));
doParseRegion(element, parserContext, builder, isSubRegion(element));
}
protected abstract void doParseRegion(Element element, ParserContext parserContext, BeanDefinitionBuilder builder,
boolean subRegion);
protected void doParseCommonRegionConfiguration(Element element, ParserContext parserContext,
BeanDefinitionBuilder regionBuilder, BeanDefinitionBuilder regionAttributesBuilder, boolean subRegion) {
mergeTemplateRegionAttributes(element, parserContext, regionBuilder, regionAttributesBuilder);
String resolvedCacheRef = ParsingUtils.resolveCacheReference(element.getAttribute("cache-ref"));
if (!subRegion) {
regionBuilder.addPropertyReference("cache", resolvedCacheRef);
ParsingUtils.setPropertyValue(element, regionBuilder, "close");
ParsingUtils.setPropertyValue(element, regionBuilder, "destroy");
}
ParsingUtils.setPropertyValue(element, regionBuilder, "name");
ParsingUtils.setPropertyValue(element, regionBuilder, "ignore-if-exists", "lookupEnabled");
ParsingUtils.setPropertyValue(element, regionBuilder, "data-policy");
ParsingUtils.setPropertyValue(element, regionBuilder, "persistent");
ParsingUtils.setPropertyValue(element, regionBuilder, "shortcut");
if (StringUtils.hasText(element.getAttribute("disk-store-ref"))) {
ParsingUtils.setPropertyValue(element, regionBuilder, "disk-store-ref", "diskStoreName");
regionBuilder.addDependsOn(element.getAttribute("disk-store-ref"));
}
ParsingUtils.parseOptionalRegionAttributes(parserContext, element, regionAttributesBuilder);
ParsingUtils.parseSubscription(parserContext, element, regionAttributesBuilder);
ParsingUtils.parseStatistics(element, regionAttributesBuilder);
ParsingUtils.parseMembershipAttributes(parserContext, element, regionAttributesBuilder);
ParsingUtils.parseExpiration(parserContext, element, regionAttributesBuilder);
ParsingUtils.parseEviction(parserContext, element, regionAttributesBuilder);
ParsingUtils.parseCompressor(parserContext, element, regionAttributesBuilder);
String enableGateway = element.getAttribute("enable-gateway");
String hubId = element.getAttribute("hub-id");
// Factory will enable gateway if it is not set and hub-id is set.
if (StringUtils.hasText(enableGateway)) {
if (GemfireUtils.isGemfireVersion7OrAbove()) {
log.warn("'enable-gateway' has been deprecated since Gemfire 7.0");
}
}
ParsingUtils.setPropertyValue(element, regionBuilder, "enable-gateway");
if (StringUtils.hasText(hubId)) {
if (GemfireUtils.isGemfireVersion7OrAbove()) {
log.warn("'hub-id' has been deprecated since Gemfire 7.0");
}
if (!CollectionUtils.isEmpty(DomUtils.getChildElementsByTagName(element, "gateway-sender"))) {
parserContext.getReaderContext().error("specifying both 'hub-id' and 'gateway-sender' is invalid",
element);
}
}
ParsingUtils.setPropertyValue(element, regionBuilder, "hub-id");
parseCollectionOfCustomSubElements(element, parserContext, regionBuilder, AsyncEventQueue.class.getName(),
"async-event-queue", "asyncEventQueues");
parseCollectionOfCustomSubElements(element, parserContext, regionBuilder, GatewaySender.class.getName(),
"gateway-sender", "gatewaySenders");
List subElements = DomUtils.getChildElements(element);
for (Element subElement : subElements) {
if (subElement.getLocalName().equals("cache-listener")) {
regionBuilder.addPropertyValue("cacheListeners", ParsingUtils.parseRefOrNestedBeanDeclaration(
parserContext, subElement, regionBuilder));
}
else if (subElement.getLocalName().equals("cache-loader")) {
regionBuilder.addPropertyValue("cacheLoader", ParsingUtils.parseRefOrSingleNestedBeanDeclaration(
parserContext, subElement, regionBuilder));
}
else if (subElement.getLocalName().equals("cache-writer")) {
regionBuilder.addPropertyValue("cacheWriter", ParsingUtils.parseRefOrSingleNestedBeanDeclaration(
parserContext, subElement, regionBuilder));
}
}
if (!subRegion) {
parseSubRegions(element, parserContext, resolvedCacheRef);
}
}
void mergeTemplateRegionAttributes(Element element, ParserContext parserContext,
BeanDefinitionBuilder regionBuilder, BeanDefinitionBuilder regionAttributesBuilder) {
String regionTemplateName = getParentName(element);
if (StringUtils.hasText(regionTemplateName)) {
if (parserContext.getRegistry().containsBeanDefinition(regionTemplateName)) {
BeanDefinition templateRegion = parserContext.getRegistry().getBeanDefinition(regionTemplateName);
BeanDefinition templateRegionAttributes = getRegionAttributesBeanDefinition(templateRegion);
if (templateRegionAttributes != 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(templateRegionAttributes);
}
}
else {
parserContext.getReaderContext().error(String.format(
"The Region template [%1$s] must be 'defined before' the Region [%2$s] referring to the template!",
regionTemplateName, resolveId(element, regionBuilder.getRawBeanDefinition(), parserContext)), element);
}
}
}
BeanDefinition getRegionAttributesBeanDefinition(final BeanDefinition region) {
Assert.notNull(region, "The 'Region' BeanDefinition must not be null!");
Object regionAttributes = null;
if (region.getPropertyValues().contains("attributes")) {
PropertyValue attributesProperty = region.getPropertyValues().getPropertyValue("attributes");
regionAttributes = attributesProperty.getValue();
}
return (regionAttributes instanceof BeanDefinition ? (BeanDefinition) regionAttributes : null);
}
protected void parseCollectionOfCustomSubElements(Element element, ParserContext parserContext,
BeanDefinitionBuilder builder, String className, String subElementName, String propertyName) {
List subElements = DomUtils.getChildElementsByTagName(element, subElementName,
subElementName + "-ref");
if (!CollectionUtils.isEmpty(subElements)) {
ManagedArray array = new ManagedArray(className, subElements.size());
for (Element subElement : subElements) {
array.add(ParsingUtils.parseRefOrNestedCustomElement(parserContext, subElement, builder));
}
builder.addPropertyValue(propertyName, array);
}
}
protected void parseSubRegions(Element element, ParserContext parserContext, String resolvedCacheRef) {
Map allSubRegionElements = new HashMap();
findSubRegionElements(element, getRegionNameFromElement(element), allSubRegionElements);
if (!CollectionUtils.isEmpty(allSubRegionElements)) {
for (Map.Entry entry : allSubRegionElements.entrySet()) {
parseSubRegion(entry.getValue(), parserContext, entry.getKey(), resolvedCacheRef);
}
}
}
private void findSubRegionElements(Element parent, String parentPath, Map allSubRegionElements) {
for (Element element : DomUtils.getChildElements(parent)) {
if (element.getLocalName().endsWith("region")) {
String subRegionName = getRegionNameFromElement(element);
String subRegionPath = buildSubRegionPath(parentPath, subRegionName);
allSubRegionElements.put(subRegionPath, element);
findSubRegionElements(element, subRegionPath, allSubRegionElements);
}
}
}
private String getRegionNameFromElement(Element element) {
String name = element.getAttribute(NAME_ATTRIBUTE);
return (StringUtils.hasText(name) ? name : element.getAttribute(ID_ATTRIBUTE));
}
private String buildSubRegionPath(String parentName, String regionName) {
String regionPath = StringUtils.arrayToDelimitedString(new String[] { parentName, regionName }, "/");
if (!regionPath.startsWith("/")) {
regionPath = "/" + regionPath;
}
return regionPath;
}
private BeanDefinition parseSubRegion(Element element, ParserContext parserContext, String subRegionPath,
String cacheRef) {
String parentBeanName = getParentRegionPathFrom(subRegionPath);
String regionName = getRegionNameFromElement(element); // do before 'renaming' the element below
element.setAttribute("id", subRegionPath);
element.setAttribute("name", subRegionPath);
BeanDefinition beanDefinition = parserContext.getDelegate().parseCustomElement(element);
beanDefinition.getPropertyValues().add("cache", new RuntimeBeanReference(cacheRef));
beanDefinition.getPropertyValues().add("parent", new RuntimeBeanReference(parentBeanName));
beanDefinition.getPropertyValues().add("regionName", regionName);
return beanDefinition;
}
private String getParentRegionPathFrom(String regionPath) {
int index = regionPath.lastIndexOf("/");
String parentPath = regionPath.substring(0, index);
if (parentPath.lastIndexOf("/") == 0) {
parentPath = parentPath.substring(1);
}
return parentPath;
}
protected void validateDataPolicyShortcutAttributesMutualExclusion(final Element element,
final ParserContext parserContext) {
if (element.hasAttribute("data-policy") && element.hasAttribute("shortcut")) {
parserContext.getReaderContext().error(String.format(
"Only one of [data-policy, shortcut] may be specified with element '%1$s'.", element.getTagName()),
element);
}
}
}