EMMA Coverage Report (generated Fri Aug 21 15:59:46 BST 2009)
[all classes][org.springframework.batch.core.scope.util]

COVERAGE SUMMARY FOR SOURCE FILE [PlaceholderProxyFactoryBean.java]

nameclass, %method, %block, %line, %
PlaceholderProxyFactoryBean.java100% (1/1)100% (7/7)83%  (187/225)87%  (46/53)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class PlaceholderProxyFactoryBean100% (1/1)100% (7/7)83%  (187/225)87%  (46/53)
getObjectType (): Class 100% (1/1)44%  (7/16)40%  (2/5)
getObject (): Object 100% (1/1)60%  (6/10)67%  (2/3)
setBeanFactory (BeanFactory): void 100% (1/1)75%  (76/101)85%  (17/20)
PlaceholderProxyFactoryBean (ContextFactory): void 100% (1/1)100% (11/11)100% (4/4)
createScopedProxy (BeanDefinitionHolder, BeanDefinitionRegistry, boolean): Be... 100% (1/1)100% (77/77)100% (17/17)
isSingleton (): boolean 100% (1/1)100% (2/2)100% (1/1)
setTargetBeanName (String): void 100% (1/1)100% (8/8)100% (3/3)

1/*
2 * Copyright 2006-2007 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17package org.springframework.batch.core.scope.util;
18 
19import java.lang.reflect.Modifier;
20 
21import org.springframework.aop.framework.AopInfrastructureBean;
22import org.springframework.aop.framework.ProxyConfig;
23import org.springframework.aop.framework.ProxyFactory;
24import org.springframework.aop.framework.autoproxy.AutoProxyUtils;
25import org.springframework.aop.scope.DefaultScopedObject;
26import org.springframework.aop.scope.ScopedObject;
27import org.springframework.aop.scope.ScopedProxyFactoryBean;
28import org.springframework.aop.support.DelegatingIntroductionInterceptor;
29import org.springframework.beans.factory.BeanFactory;
30import org.springframework.beans.factory.BeanFactoryAware;
31import org.springframework.beans.factory.FactoryBean;
32import org.springframework.beans.factory.FactoryBeanNotInitializedException;
33import org.springframework.beans.factory.config.BeanDefinition;
34import org.springframework.beans.factory.config.BeanDefinitionHolder;
35import org.springframework.beans.factory.config.ConfigurableBeanFactory;
36import org.springframework.beans.factory.support.BeanDefinitionRegistry;
37import org.springframework.beans.factory.support.RootBeanDefinition;
38import org.springframework.util.ClassUtils;
39 
40/**
41 * Factory bean for proxies that can replace placeholders in their target. Just
42 * a specialisation of {@link ScopedProxyFactoryBean}, with a different target
43 * source type.
44 * 
45 * @author Dave Syer
46 * 
47 */
48public class PlaceholderProxyFactoryBean extends ProxyConfig implements FactoryBean, BeanFactoryAware {
49 
50        /** The TargetSource that manages scoping */
51        private final PlaceholderTargetSource scopedTargetSource = new PlaceholderTargetSource();
52 
53        /** The name of the target bean */
54        private String targetBeanName;
55 
56        /** The cached singleton proxy */
57        private Object proxy;
58 
59        private final ContextFactory contextFactory;
60 
61        /**
62         * Create a new FactoryBean instance.
63         */
64        public PlaceholderProxyFactoryBean(ContextFactory contextFactory) {
65                this.contextFactory = contextFactory;
66                // setProxyTargetClass(false);
67        }
68 
69        /**
70         * Set the name of the bean that is to be scoped.
71         */
72        public void setTargetBeanName(String targetBeanName) {
73                this.targetBeanName = targetBeanName;
74                this.scopedTargetSource.setTargetBeanName(targetBeanName);
75        }
76 
77        public void setBeanFactory(BeanFactory beanFactory) {
78                if (!(beanFactory instanceof ConfigurableBeanFactory)) {
79                        throw new IllegalStateException("Not running in a ConfigurableBeanFactory: " + beanFactory);
80                }
81                ConfigurableBeanFactory cbf = (ConfigurableBeanFactory) beanFactory;
82 
83                this.scopedTargetSource.setBeanFactory(beanFactory);
84                this.scopedTargetSource.setContextFactory(contextFactory);
85 
86                ProxyFactory pf = new ProxyFactory();
87                pf.copyFrom(this);
88                pf.setTargetSource(this.scopedTargetSource);
89 
90                Class<?> beanType = beanFactory.getType(this.targetBeanName);
91                if (beanType == null) {
92                        throw new IllegalStateException("Cannot create scoped proxy for bean '" + this.targetBeanName
93                                        + "': Target type could not be determined at the time of proxy creation.");
94                }
95                if (!isProxyTargetClass() || beanType.isInterface() || Modifier.isPrivate(beanType.getModifiers())) {
96                        pf.setInterfaces(ClassUtils.getAllInterfacesForClass(beanType, cbf.getBeanClassLoader()));
97                }
98 
99                // Add an introduction that implements only the methods on ScopedObject.
100                ScopedObject scopedObject = new DefaultScopedObject(cbf, this.scopedTargetSource.getTargetBeanName());
101                pf.addAdvice(new DelegatingIntroductionInterceptor(scopedObject));
102 
103                // Add the AopInfrastructureBean marker to indicate that the scoped
104                // proxy itself is not subject to auto-proxying! Only its target bean
105                // is.
106                pf.addInterface(AopInfrastructureBean.class);
107                
108                this.scopedTargetSource.afterPropertiesSet();
109 
110                this.proxy = pf.getProxy(cbf.getBeanClassLoader());
111        }
112 
113        public Object getObject() {
114                if (this.proxy == null) {
115                        throw new FactoryBeanNotInitializedException();
116                }
117                return this.proxy;
118        }
119 
120        public Class<?> getObjectType() {
121                if (this.proxy != null) {
122                        return this.proxy.getClass();
123                }
124                if (this.scopedTargetSource != null) {
125                        return this.scopedTargetSource.getTargetClass();
126                }
127                return null;
128        }
129 
130        public boolean isSingleton() {
131                return true;
132        }
133 
134        /**
135         * Convenience method to create a {@link BeanDefinition} for a target
136         * wrapped in a placeholder tarrget source, able to defer binding of
137         * placeholders until the bean is used.
138         * 
139         * @param definition a target bean definition
140         * @param registry a {@link BeanDefinitionRegistry}
141         * @param proxyTargetClass true if we need to use CGlib to create the
142         * proxies
143         * @return a {@link BeanDefinitionHolder} for a
144         * {@link PlaceholderProxyFactoryBean}
145         */
146        public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder definition,
147                        BeanDefinitionRegistry registry, boolean proxyTargetClass) {
148 
149                String originalBeanName = definition.getBeanName();
150                BeanDefinition targetDefinition = definition.getBeanDefinition();
151 
152                // Create a proxy definition for the original bean name,
153                // "hiding" the target bean in an internal target definition.
154                RootBeanDefinition proxyDefinition = new RootBeanDefinition(PlaceholderProxyFactoryBean.class);
155                proxyDefinition.getConstructorArgumentValues().addGenericArgumentValue(new StepContextFactory());
156                proxyDefinition.setOriginatingBeanDefinition(definition.getBeanDefinition());
157                proxyDefinition.setSource(definition.getSource());
158                proxyDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
159 
160                String targetBeanName = "lazyBindingProxy." + originalBeanName;
161                proxyDefinition.getPropertyValues().addPropertyValue("targetBeanName", targetBeanName);
162 
163                if (proxyTargetClass) {
164                        targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
165                        // ProxyFactoryBean's "proxyTargetClass" default is FALSE, so we
166                        // need to set it explicitly here.
167                        proxyDefinition.getPropertyValues().addPropertyValue("proxyTargetClass", Boolean.TRUE);
168                }
169                else {
170                        proxyDefinition.getPropertyValues().addPropertyValue("proxyTargetClass", Boolean.FALSE);
171                }
172 
173                proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
174                // The target bean should be ignored in favor of the proxy.
175                targetDefinition.setAutowireCandidate(false);
176 
177                // Register the target bean as separate bean in the factory.
178                registry.registerBeanDefinition(targetBeanName, targetDefinition);
179 
180                // Return the scoped proxy definition as primary bean definition
181                // (potentially an inner bean).
182                return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases());
183        }
184 
185}

[all classes][org.springframework.batch.core.scope.util]
EMMA 2.0.5312 (C) Vladimir Roubtsov