/*
* Copyright 2008 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.directwebremoting.spring;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.directwebremoting.annotations.DataTransferObject;
import org.directwebremoting.annotations.RemoteProxy;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.RegexPatternTypeFilter;
import org.w3c.dom.Element;
import static org.springframework.util.StringUtils.*;
/**
* Adds the missing elements to the DWR namespace handling. Namely <dwr:annotation-config />
*
* @author Jose Noheda [jose.noheda@gmail.com]
*/
public class DwrAnnotationNamespaceHandler extends DwrNamespaceHandler
{
/**
* Add a new Parser to register <dwr:annotation-config />
*
* @see org.directwebremoting.spring.DwrNamespaceHandler#init()
*/
@Override
public void init()
{
super.init();
registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
registerBeanDefinitionParser("annotation-scan", new AnnotationScannerDefinitionParser());
}
/**
* Register a new creator proxy for each Spring bean that is annotated with
* {@link org.directwebremoting.annotations.RemoteProxy}.
*
* @author Jose Noheda [jose.noheda@gmail.com]
*/
protected class AnnotationConfigBeanDefinitionParser implements BeanDefinitionParser
{
/**
* Creates a post-processor that will scan the context for candidate beans.
*
* @param element <dwr:annotation-config />
* @param parserContext a reference to the bean registry
*/
public BeanDefinition parse(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(DwrAnnotationPostProcessor.class);
parserContext.getRegistry().registerBeanDefinition("dwrAnnotationPostProcessor", builder.getBeanDefinition());
return parserContext.getRegistry().getBeanDefinition("dwrAnnotationPostProcessor");
}
}
/**
* Register a new bean definition and a proxy for each class that is annotated with
* {@link org.directwebremoting.annotations.RemoteProxy} and is detected scanning the
* base-package directory.
*
* @author Jose Noheda [jose.noheda@gmail.com]
*/
protected class AnnotationScannerDefinitionParser implements BeanDefinitionParser
{
private boolean scanProxies = true;
private boolean scanConverters = true;
public BeanDefinition parse(Element element, ParserContext parserContext)
{
ClassPathBeanDefinitionScanner scanner = new DwrClassPathBeanDefinitionScanner(parserContext.getRegistry());
String basePackage = element.getAttribute("base-package");
if (!hasText(basePackage))
{
if (log.isInfoEnabled())
{
log.info("No base package defined for classpath scanning. Traversing the whole JVM classpath");
}
}
String regex = element.getAttribute("regex");
if (hasText(regex))
{
scanner.addIncludeFilter(new RegexPatternTypeFilter(Pattern.compile(regex)));
}
String proxies = element.getAttribute("scanRemoteProxy");
if (hasText(proxies) && ("TRUE".equals(proxies.toUpperCase()) || "FALSE".equals(proxies.toUpperCase())))
{
scanProxies = Boolean.parseBoolean(proxies);
}
if (scanProxies)
{
scanner.addIncludeFilter(new AnnotationTypeFilter(RemoteProxy.class));
}
String conv = element.getAttribute("scanDataTransferObject");
if (hasText(conv) && ("TRUE".equals(conv.toUpperCase()) || "FALSE".equals(conv.toUpperCase())))
{
scanConverters = Boolean.parseBoolean(conv);
}
if (scanConverters)
{
scanner.addIncludeFilter(new AnnotationTypeFilter(DataTransferObject.class));
}
if (scanProxies | scanConverters)
{
scanner.scan(basePackage == null ? "" : basePackage);
}
else
{
log.warn("Scan is not required if both @RemoteProxy and @DataTransferObject are disabled. Skipping detection");
}
return null;
}
}
/**
* The log stream
*/
private static final Log log = LogFactory.getLog(DwrAnnotationNamespaceHandler.class);
}