001: /*
002: * Copyright 2008 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.directwebremoting.spring;
017:
018: import java.lang.reflect.Method;
019: import java.util.ArrayList;
020: import java.util.List;
021:
022: import org.apache.commons.logging.Log;
023: import org.apache.commons.logging.LogFactory;
024: import org.directwebremoting.annotations.RemoteMethod;
025: import org.directwebremoting.annotations.RemoteProxy;
026: import org.springframework.beans.BeansException;
027: import org.springframework.beans.FatalBeanException;
028: import org.springframework.beans.factory.config.BeanDefinitionHolder;
029: import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
030: import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
031: import org.springframework.beans.factory.config.RuntimeBeanReference;
032: import org.springframework.beans.factory.support.BeanDefinitionBuilder;
033: import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
034: import org.springframework.beans.factory.support.BeanDefinitionRegistry;
035: import org.springframework.util.ClassUtils;
036:
037: /**
038: * @author Jose Noheda [jose.noheda@gmail.com]
039: */
040: public class DwrAnnotationPostProcessor implements
041: BeanFactoryPostProcessor {
042:
043: public void postProcessBeanFactory(
044: ConfigurableListableBeanFactory beanFactory)
045: throws BeansException {
046: BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) beanFactory;
047: for (String beanName : beanDefinitionRegistry
048: .getBeanDefinitionNames()) {
049: BeanDefinitionHolder beanDefinitionHolder = new BeanDefinitionHolder(
050: beanDefinitionRegistry.getBeanDefinition(beanName),
051: beanName);
052: Class<?> beanDefinitionClass = getBeanDefinitionClass(
053: beanDefinitionHolder, beanDefinitionRegistry);
054: if (beanDefinitionClass != null) {
055: RemoteProxy annotation = beanDefinitionClass
056: .getAnnotation(RemoteProxy.class);
057: if (annotation != null) {
058: String javascript = annotation.name();
059: if (log.isInfoEnabled()) {
060: log.info("Detected candidate bean [" + beanName
061: + "]. Remoting using " + javascript);
062: }
063: registerCreator(beanDefinitionHolder,
064: beanDefinitionRegistry,
065: beanDefinitionClass, javascript);
066: }
067: }
068: }
069: }
070:
071: protected Class<?> getBeanDefinitionClass(
072: BeanDefinitionHolder beanDefinitionHolder,
073: BeanDefinitionRegistry beanDefinitionRegistry) {
074: try {
075: String beanClassName = DwrNamespaceHandler
076: .resolveBeanClassname(beanDefinitionHolder
077: .getBeanDefinition(),
078: beanDefinitionRegistry);
079: return ClassUtils.forName(beanClassName);
080: } catch (Exception cne) {
081: if (log.isInfoEnabled()) {
082: log
083: .info("Could not infer class for ["
084: + beanDefinitionHolder.getBeanName()
085: + "]. Is it a factory bean? Omitting bean from annotation processing");
086: }
087: return null;
088: }
089: }
090:
091: protected void registerCreator(
092: BeanDefinitionHolder beanDefinitionHolder,
093: BeanDefinitionRegistry beanDefinitionRegistry,
094: Class<?> beanDefinitionClass, String javascript) {
095: BeanDefinitionBuilder beanCreator = BeanDefinitionBuilder
096: .rootBeanDefinition(BeanCreator.class);
097: try {
098: beanCreator.addPropertyValue("beanClass",
099: beanDefinitionClass);
100: String name = beanDefinitionHolder.getBeanName();
101: if (name.startsWith("scopedTarget.")) {
102: name = name.substring(name.indexOf(".") + 1);
103: }
104: beanCreator.addPropertyValue("beanId", name);
105: beanCreator.addDependsOn(name);
106: String creatorConfigName = "__" + javascript;
107: beanCreator.addPropertyValue("javascript", javascript);
108: BeanDefinitionBuilder creatorConfig = BeanDefinitionBuilder
109: .rootBeanDefinition(CreatorConfig.class);
110: creatorConfig.addPropertyValue("creator", beanCreator
111: .getBeanDefinition());
112: List<String> includes = new ArrayList<String>();
113: for (Method method : beanDefinitionClass.getMethods()) {
114: if (method.getAnnotation(RemoteMethod.class) != null) {
115: includes.add(method.getName());
116: }
117: }
118: creatorConfig.addPropertyValue("includes", includes);
119: BeanDefinitionHolder aux = new BeanDefinitionHolder(
120: creatorConfig.getBeanDefinition(),
121: creatorConfigName);
122: BeanDefinitionReaderUtils.registerBeanDefinition(aux,
123: beanDefinitionRegistry);
124: DwrNamespaceHandler
125: .lookupCreators(beanDefinitionRegistry)
126: .put(javascript,
127: new RuntimeBeanReference(creatorConfigName));
128: } catch (Exception ex) {
129: throw new FatalBeanException(
130: "Unable to create DWR bean creator for '"
131: + beanDefinitionHolder.getBeanName()
132: + "'. ", ex);
133: }
134: }
135:
136: /**
137: * The log stream
138: */
139: protected static final Log log = LogFactory
140: .getLog(DwrAnnotationPostProcessor.class);
141:
142: }
|