com.googlecode.ehcache.annotations.config.EhCacheConfigBeanDefinitionParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache-spring-annotations Show documentation
Show all versions of ehcache-spring-annotations Show documentation
Provides a simple model for integrating Ehcache in a Spring project via annotations.
/**
* Copyright 2010 Nicholas Blair, Eric Dalquist
*
* 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 com.googlecode.ehcache.annotations.config;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.googlecode.ehcache.annotations.impl.ExpiredElementEvictor;
/**
* {@link BeanDefinitionParser} implementation to process the
* "config" element.
*
* @author Nicholas Blair, [email protected]
* @version $Id: EhCacheConfigBeanDefinitionParser.java 390 2010-05-18 03:07:02Z [email protected] $
*/
public final class EhCacheConfigBeanDefinitionParser implements
BeanDefinitionParser {
private static final long MSEC_PER_MINUTE = 60000L;
public static final String XSD_ELEMENT__EVICT_EXPIRED_ELEMENTS = "evict-expired-elements";
public static final String XSD_ATTRIBUTE__INTERVAL = "interval";
public static final String XSD_ELEMENT__INCLUDE = "include";
public static final String XSD_ELEMENT__EXCLUDE = "exclude";
public static final String XSD_ATTRIBUTE__NAME = "name";
public static final String XSD_ATTRIBUTE__PATTERN = "pattern";
public static final String EHCACHE_CONFIG_EVICTION_TASK_BEAN_NAME = EhCacheConfigBeanDefinitionParser.class.getPackage().getName() + ".internalEhCacheEvictionTask";
public static final CacheNameMatcher INCLUDE_ALL_CACHE_NAME_MATCHER = new PatternCacheNameMatcherImpl(".*");
/* (non-Javadoc)
* @see org.springframework.beans.factory.xml.BeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
*/
public BeanDefinition parse(final Element element, final ParserContext parserContext) {
final Object elementSource = parserContext.extractSource(element);
final NodeList evictExpiredElements = element.getElementsByTagNameNS(element.getNamespaceURI(),XSD_ELEMENT__EVICT_EXPIRED_ELEMENTS);
if (evictExpiredElements.getLength() > 1) {
throw new BeanCreationException("Only one '" + XSD_ELEMENT__EVICT_EXPIRED_ELEMENTS + "' is allowed");
}
final int evictExpiredElementsLength = evictExpiredElements.getLength();
if (evictExpiredElementsLength == 1) {
final Element evictExpiredElement = (Element)evictExpiredElements.item(0);
final int interval = Integer.parseInt(evictExpiredElement.getAttribute(XSD_ATTRIBUTE__INTERVAL));
final long longInterval = MSEC_PER_MINUTE * interval;
List cacheNameMatchers = parseEvictExpiredElement(evictExpiredElement);
// get RuntimeBeanReference for cacheManager
final RuntimeBeanReference cacheManagerReference = new RuntimeBeanReference(element.getAttribute(AnnotationDrivenEhCacheBeanDefinitionParser.XSD_ATTR__CACHE_MANAGER));
// make RootBeanDefinition, RuntimeBeanReference for ExpiredElementEvictor instance, wire cacheNameMatchers reference and
final RootBeanDefinition expiredElementEvictor = new RootBeanDefinition(ExpiredElementEvictor.class);
expiredElementEvictor.setSource(elementSource);
expiredElementEvictor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
final MutablePropertyValues propertyValues = expiredElementEvictor.getPropertyValues();
propertyValues.addPropertyValue("cacheManager", cacheManagerReference);
propertyValues.addPropertyValue("cacheNameMatchers", cacheNameMatchers);
propertyValues.addPropertyValue("interval", longInterval);
// register expiredElementEvictor
final BeanDefinitionRegistry registry = parserContext.getRegistry();
registry.registerBeanDefinition(EHCACHE_CONFIG_EVICTION_TASK_BEAN_NAME, expiredElementEvictor);
}
return null;
}
/**
*
* @param evictExpiredElement
* @return
*/
protected List parseEvictExpiredElement(final Element evictExpiredElement) {
List cacheNameMatchers = new ArrayList();
final NodeList childNodes = evictExpiredElement.getChildNodes();
final int childNodesLength = childNodes.getLength();
boolean configContainsExcludes = false;
boolean configContainsIncludes = false;
if(0 != childNodesLength) {
for (int index = 0; index < childNodesLength; index++) {
final Node childNode = childNodes.item(index);
if(Node.ELEMENT_NODE == childNode.getNodeType()) {
final String childName = childNode.getLocalName();
NamedNodeMap childAttributes = childNode.getAttributes();
Node nameAttr = childAttributes.getNamedItem(XSD_ATTRIBUTE__NAME);
CacheNameMatcher matcher = null;
if(null != nameAttr) {
String matcherValue = nameAttr.getTextContent();
matcher = new ExactCacheNameMatcherImpl(matcherValue);
} else {
Node patternAttr = childAttributes.getNamedItem(XSD_ATTRIBUTE__PATTERN);
if(null != patternAttr) {
String matcherValue = patternAttr.getTextContent();
matcher = new PatternCacheNameMatcherImpl(matcherValue);
}
}
if(null != matcher) {
if(XSD_ELEMENT__INCLUDE.equals(childName)) {
cacheNameMatchers.add(matcher);
configContainsIncludes = true;
} else if(XSD_ELEMENT__EXCLUDE.equals(childName)) {
cacheNameMatchers.add(new NotCacheNameMatcherImpl(matcher));
configContainsExcludes = true;
}
}
}
}
}
if(0 == cacheNameMatchers.size()) {
// no include/exclude elements found
cacheNameMatchers = Collections.singletonList(INCLUDE_ALL_CACHE_NAME_MATCHER);
} else if(!configContainsIncludes && configContainsExcludes) {
//config contains excludes only
// create a new list with a Include all matcher at the front
List newList = new ArrayList();
newList.add(INCLUDE_ALL_CACHE_NAME_MATCHER);
newList.addAll(cacheNameMatchers);
cacheNameMatchers = newList;
}
return Collections.unmodifiableList(cacheNameMatchers);
}
}