Source Code Cross Referenced for ScriptFactoryPostProcessor.java in  » J2EE » spring-framework-2.0.6 » org » springframework » scripting » support » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » spring framework 2.0.6 » org.springframework.scripting.support 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2002-2007 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:
017:        package org.springframework.scripting.support;
018:
019:        import java.util.HashMap;
020:        import java.util.Iterator;
021:        import java.util.Map;
022:
023:        import net.sf.cglib.asm.Type;
024:        import net.sf.cglib.core.Signature;
025:        import net.sf.cglib.proxy.InterfaceMaker;
026:        import org.apache.commons.logging.Log;
027:        import org.apache.commons.logging.LogFactory;
028:
029:        import org.springframework.aop.TargetSource;
030:        import org.springframework.aop.framework.AopInfrastructureBean;
031:        import org.springframework.aop.framework.ProxyFactory;
032:        import org.springframework.aop.support.DelegatingIntroductionInterceptor;
033:        import org.springframework.beans.BeanUtils;
034:        import org.springframework.beans.PropertyValue;
035:        import org.springframework.beans.factory.BeanClassLoaderAware;
036:        import org.springframework.beans.factory.BeanDefinitionStoreException;
037:        import org.springframework.beans.factory.BeanFactory;
038:        import org.springframework.beans.factory.BeanFactoryAware;
039:        import org.springframework.beans.factory.DisposableBean;
040:        import org.springframework.beans.factory.config.BeanDefinition;
041:        import org.springframework.beans.factory.config.BeanPostProcessor;
042:        import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
043:        import org.springframework.beans.factory.support.AbstractBeanFactory;
044:        import org.springframework.beans.factory.support.DefaultListableBeanFactory;
045:        import org.springframework.beans.factory.support.RootBeanDefinition;
046:        import org.springframework.context.ResourceLoaderAware;
047:        import org.springframework.core.Conventions;
048:        import org.springframework.core.Ordered;
049:        import org.springframework.core.io.DefaultResourceLoader;
050:        import org.springframework.core.io.ResourceLoader;
051:        import org.springframework.scripting.ScriptFactory;
052:        import org.springframework.scripting.ScriptSource;
053:        import org.springframework.util.ClassUtils;
054:        import org.springframework.util.ObjectUtils;
055:        import org.springframework.util.StringUtils;
056:
057:        /**
058:         * {@link org.springframework.beans.factory.config.BeanPostProcessor} that
059:         * handles {@link org.springframework.scripting.ScriptFactory} definitions,
060:         * replacing each factory with the actual scripted Java object generated by it.
061:         *
062:         * <p>This is similar to the
063:         * {@link org.springframework.beans.factory.FactoryBean} mechanism, but is
064:         * specifically tailored for scripts and not built into Spring's core
065:         * container itself but rather implemented as an extension.
066:         *
067:         * <p><b>NOTE:</b> The most important characteristic of this post-processor
068:         * is that constructor arguments are applied to the
069:         * {@link org.springframework.scripting.ScriptFactory} instance
070:         * while bean property values are applied to the generated scripted object.
071:         * Typically, constructor arguments include a script source locator and
072:         * potentially script interfaces, while bean property values include
073:         * references and config values to inject into the scripted object itself.
074:         *
075:         * <p>The following {@link ScriptFactoryPostProcessor} will automatically
076:         * be applied to the two
077:         * {@link org.springframework.scripting.ScriptFactory} definitions below.
078:         * At runtime, the actual scripted objects will be exposed for
079:         * "bshMessenger" and "groovyMessenger", rather than the
080:         * {@link org.springframework.scripting.ScriptFactory} instances. Both of
081:         * those are supposed to be castable to the example's <code>Messenger</code>
082:         * interfaces here.
083:         *
084:         * <pre class="code">&lt;bean class="org.springframework.scripting.support.ScriptFactoryPostProcessor"/&gt;
085:         *
086:         * &lt;bean id="bshMessenger" class="org.springframework.scripting.bsh.BshScriptFactory"&gt;
087:         *   &lt;constructor-arg value="classpath:mypackage/Messenger.bsh"/&gt;
088:         *   &lt;constructor-arg value="mypackage.Messenger"/&gt;
089:         *   &lt;property name="message" value="Hello World!"/&gt;
090:         * &lt;/bean&gt;
091:         *
092:         * &lt;bean id="groovyMessenger" class="org.springframework.scripting.bsh.GroovyScriptFactory"&gt;
093:         *   &lt;constructor-arg value="classpath:mypackage/Messenger.groovy"/&gt;
094:         *   &lt;property name="message" value="Hello World!"/&gt;
095:         * &lt;/bean&gt;</pre>
096:         *
097:         * <p><b>NOTE:</b> Please note that the above excerpt from a Spring
098:         * XML bean definition file uses just the &lt;bean/&gt;-style syntax
099:         * (in an effort to illustrate using the {@link ScriptFactoryPostProcessor} itself).
100:         * In reality, you would never create a &lt;bean/&gt; definition for a
101:         * {@link ScriptFactoryPostProcessor} explicitly; rather you would import the
102:         * tags from the <code>'lang'</code> namespace and simply create scripted
103:         * beans using the tags in that namespace... as part of doing so, a
104:         * {@link ScriptFactoryPostProcessor} will implicitly be created for you.
105:         *
106:         * <p>The Spring reference documentation contains numerous examples of using
107:         * tags in the <code>'lang'</code> namespace; by way of an example, find below
108:         * a Groovy-backed bean defined using the <code>'lang:groovy'</code> tag.
109:         *
110:         * <pre class="code">
111:         * &lt;?xml version="1.0" encoding="UTF-8"?&gt;
112:         * &lt;beans xmlns="http://www.springframework.org/schema/beans"
113:         *     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
114:         *     xmlns:lang="http://www.springframework.org/schema/lang"&gt;
115:         *
116:         *   &lt;!-- this is the bean definition for the Groovy-backed Messenger implementation --&gt;
117:         *   &lt;lang:groovy id="messenger" script-source="classpath:Messenger.groovy"&gt;
118:         *     &lt;lang:property name="message" value="I Can Do The Frug" /&gt;
119:         *   &lt;/lang:groovy&gt;
120:         *
121:         *   &lt;!-- an otherwise normal bean that will be injected by the Groovy-backed Messenger --&gt;
122:         *   &lt;bean id="bookingService" class="x.y.DefaultBookingService"&gt;
123:         *     &lt;property name="messenger" ref="messenger" /&gt;
124:         *   &lt;/bean&gt;
125:         *
126:         * &lt;/beans&gt;</pre>
127:         *
128:         * @author Juergen Hoeller
129:         * @author Rob Harrop
130:         * @author Rick Evans
131:         * @since 2.0
132:         */
133:        public class ScriptFactoryPostProcessor extends
134:                InstantiationAwareBeanPostProcessorAdapter implements 
135:                BeanClassLoaderAware, BeanFactoryAware, ResourceLoaderAware,
136:                DisposableBean, Ordered {
137:
138:            /**
139:             * The {@link org.springframework.core.io.Resource}-style prefix that denotes
140:             * an inline script.
141:             * <p>An inline script is a script that is defined right there in the (typically XML)
142:             * configuration, as opposed to being defined in an external file.
143:             */
144:            public static final String INLINE_SCRIPT_PREFIX = "inline:";
145:
146:            public static final String REFRESH_CHECK_DELAY_ATTRIBUTE = Conventions
147:                    .getQualifiedAttributeName(
148:                            ScriptFactoryPostProcessor.class,
149:                            "refreshCheckDelay");
150:
151:            private static final String SCRIPT_FACTORY_NAME_PREFIX = "scriptFactory.";
152:
153:            private static final String SCRIPTED_OBJECT_NAME_PREFIX = "scriptedObject.";
154:
155:            /** Logger available to subclasses */
156:            protected final Log logger = LogFactory.getLog(getClass());
157:
158:            private long defaultRefreshCheckDelay = -1;
159:
160:            private ClassLoader beanClassLoader = ClassUtils
161:                    .getDefaultClassLoader();
162:
163:            private AbstractBeanFactory beanFactory;
164:
165:            private ResourceLoader resourceLoader = new DefaultResourceLoader();
166:
167:            final DefaultListableBeanFactory scriptBeanFactory = new DefaultListableBeanFactory();
168:
169:            /** Map from bean name String to ScriptSource object */
170:            private final Map scriptSourceCache = new HashMap();
171:
172:            /**
173:             * Set the delay between refresh checks, in milliseconds.
174:             * Default is -1, indicating no refresh checks at all.
175:             * <p>Note that an actual refresh will only happen when
176:             * the {@link org.springframework.scripting.ScriptSource} indicates
177:             * that it has been modified.
178:             * @see org.springframework.scripting.ScriptSource#isModified()
179:             */
180:            public void setDefaultRefreshCheckDelay(
181:                    long defaultRefreshCheckDelay) {
182:                this .defaultRefreshCheckDelay = defaultRefreshCheckDelay;
183:            }
184:
185:            public void setBeanClassLoader(ClassLoader classLoader) {
186:                this .beanClassLoader = classLoader;
187:            }
188:
189:            public void setBeanFactory(BeanFactory beanFactory) {
190:                if (!(beanFactory instanceof  AbstractBeanFactory)) {
191:                    throw new IllegalStateException(
192:                            "ScriptFactoryPostProcessor must run in AbstractBeanFactory, not in "
193:                                    + beanFactory);
194:                }
195:                this .beanFactory = (AbstractBeanFactory) beanFactory;
196:
197:                // Required so that references (up container hierarchies) are correctly resolved.
198:                this .scriptBeanFactory.setParentBeanFactory(this .beanFactory);
199:
200:                // Required so that all BeanPostProcessors, Scopes, etc become available.
201:                this .scriptBeanFactory.copyConfigurationFrom(this .beanFactory);
202:
203:                // Filter out BeanPostProcessors that are part of the AOP infrastructure,
204:                // since those are only meant to apply to beans defined in the original factory.
205:                for (Iterator it = this .scriptBeanFactory
206:                        .getBeanPostProcessors().iterator(); it.hasNext();) {
207:                    BeanPostProcessor postProcessor = (BeanPostProcessor) it
208:                            .next();
209:                    if (postProcessor instanceof  AopInfrastructureBean) {
210:                        it.remove();
211:                    }
212:                }
213:            }
214:
215:            public void setResourceLoader(ResourceLoader resourceLoader) {
216:                this .resourceLoader = resourceLoader;
217:            }
218:
219:            public int getOrder() {
220:                return Integer.MIN_VALUE;
221:            }
222:
223:            public Class predictBeanType(Class beanClass, String beanName) {
224:                // We only apply special treatment to ScriptFactory implementations here.
225:                if (!ScriptFactory.class.isAssignableFrom(beanClass)) {
226:                    return null;
227:                }
228:
229:                RootBeanDefinition bd = this .beanFactory
230:                        .getMergedBeanDefinition(beanName);
231:                String scriptFactoryBeanName = SCRIPT_FACTORY_NAME_PREFIX
232:                        + beanName;
233:                String scriptedObjectBeanName = SCRIPTED_OBJECT_NAME_PREFIX
234:                        + beanName;
235:                prepareScriptBeans(bd, scriptFactoryBeanName,
236:                        scriptedObjectBeanName);
237:
238:                ScriptFactory scriptFactory = (ScriptFactory) this .scriptBeanFactory
239:                        .getBean(scriptFactoryBeanName, ScriptFactory.class);
240:                ScriptSource scriptSource = getScriptSource(
241:                        scriptFactoryBeanName, scriptFactory
242:                                .getScriptSourceLocator());
243:                Class[] interfaces = scriptFactory.getScriptInterfaces();
244:
245:                Class scriptedType = null;
246:                try {
247:                    scriptedType = scriptFactory
248:                            .getScriptedObjectType(scriptSource);
249:                } catch (Exception ex) {
250:                    if (logger.isDebugEnabled()) {
251:                        logger.debug(
252:                                "Could not determine the scripted object type for script factory ["
253:                                        + scriptFactory + "]", ex);
254:                    }
255:                }
256:
257:                if (scriptedType != null) {
258:                    return scriptedType;
259:                } else if (ObjectUtils.isEmpty(interfaces)) {
260:                    if (bd.isSingleton()) {
261:                        return this .scriptBeanFactory.getBean(
262:                                scriptedObjectBeanName).getClass();
263:                    } else {
264:                        return null;
265:                    }
266:                } else {
267:                    return (interfaces.length == 1 ? interfaces[0]
268:                            : createCompositeInterface(interfaces));
269:                }
270:            }
271:
272:            public Object postProcessBeforeInstantiation(Class beanClass,
273:                    String beanName) {
274:                // We only apply special treatment to ScriptFactory implementations here.
275:                if (!ScriptFactory.class.isAssignableFrom(beanClass)) {
276:                    return null;
277:                }
278:
279:                RootBeanDefinition bd = this .beanFactory
280:                        .getMergedBeanDefinition(beanName);
281:                String scriptFactoryBeanName = SCRIPT_FACTORY_NAME_PREFIX
282:                        + beanName;
283:                String scriptedObjectBeanName = SCRIPTED_OBJECT_NAME_PREFIX
284:                        + beanName;
285:                prepareScriptBeans(bd, scriptFactoryBeanName,
286:                        scriptedObjectBeanName);
287:
288:                long refreshCheckDelay = resolveRefreshCheckDelay(bd);
289:                if (refreshCheckDelay >= 0) {
290:                    ScriptFactory scriptFactory = (ScriptFactory) this .scriptBeanFactory
291:                            .getBean(scriptFactoryBeanName, ScriptFactory.class);
292:                    ScriptSource scriptSource = getScriptSource(
293:                            scriptFactoryBeanName, scriptFactory
294:                                    .getScriptSourceLocator());
295:                    Class[] interfaces = scriptFactory.getScriptInterfaces();
296:                    RefreshableScriptTargetSource ts = new RefreshableScriptTargetSource(
297:                            this .scriptBeanFactory, scriptedObjectBeanName,
298:                            scriptSource);
299:                    ts.setRefreshCheckDelay(refreshCheckDelay);
300:                    return createRefreshableProxy(ts, interfaces);
301:                }
302:
303:                return this .scriptBeanFactory.getBean(scriptedObjectBeanName);
304:            }
305:
306:            /**
307:             * Prepare the script beans in the internal BeanFactory that this
308:             * post-processor uses. Each original bean definition will be split
309:             * into a ScriptFactory definition and a scripted object definition.
310:             * @param bd the original bean definition in the main BeanFactory
311:             * @param scriptFactoryBeanName the name of the internal ScriptFactory bean
312:             * @param scriptedObjectBeanName the name of the internal scripted object bean
313:             */
314:            protected void prepareScriptBeans(RootBeanDefinition bd,
315:                    String scriptFactoryBeanName, String scriptedObjectBeanName) {
316:
317:                // Avoid recreation of the script bean definition in case of a prototype.
318:                synchronized (this .scriptBeanFactory) {
319:                    if (!this .scriptBeanFactory
320:                            .containsBeanDefinition(scriptedObjectBeanName)) {
321:
322:                        this .scriptBeanFactory.registerBeanDefinition(
323:                                scriptFactoryBeanName,
324:                                createScriptFactoryBeanDefinition(bd));
325:                        ScriptFactory scriptFactory = (ScriptFactory) this .scriptBeanFactory
326:                                .getBean(scriptFactoryBeanName,
327:                                        ScriptFactory.class);
328:                        ScriptSource scriptSource = getScriptSource(
329:                                scriptFactoryBeanName, scriptFactory
330:                                        .getScriptSourceLocator());
331:                        Class[] interfaces = scriptFactory
332:                                .getScriptInterfaces();
333:
334:                        Class[] scriptedInterfaces = interfaces;
335:                        if (scriptFactory.requiresConfigInterface()
336:                                && !bd.getPropertyValues().isEmpty()) {
337:                            Class configInterface = createConfigInterface(bd,
338:                                    interfaces);
339:                            scriptedInterfaces = (Class[]) ObjectUtils
340:                                    .addObjectToArray(interfaces,
341:                                            configInterface);
342:                        }
343:
344:                        RootBeanDefinition objectBd = createScriptedObjectBeanDefinition(
345:                                bd, scriptFactoryBeanName, scriptSource,
346:                                scriptedInterfaces);
347:                        long refreshCheckDelay = resolveRefreshCheckDelay(bd);
348:                        if (refreshCheckDelay >= 0) {
349:                            objectBd.setSingleton(false);
350:                        }
351:
352:                        this .scriptBeanFactory.registerBeanDefinition(
353:                                scriptedObjectBeanName, objectBd);
354:                    }
355:                }
356:            }
357:
358:            /**
359:             * Get the refresh check delay for the given {@link ScriptFactory} {@link BeanDefinition}.
360:             * If the {@link BeanDefinition} has a
361:             * {@link org.springframework.core.AttributeAccessor metadata attribute}
362:             * under the key {@link #REFRESH_CHECK_DELAY_ATTRIBUTE} which is a valid {@link Number}
363:             * type, then this value is used. Otherwise, the the {@link #defaultRefreshCheckDelay}
364:             * value is used.
365:             * @param beanDefinition the BeanDefinition to check
366:             * @return the refresh check delay
367:             */
368:            protected long resolveRefreshCheckDelay(
369:                    BeanDefinition beanDefinition) {
370:                long refreshCheckDelay = this .defaultRefreshCheckDelay;
371:                Object attributeValue = beanDefinition
372:                        .getAttribute(REFRESH_CHECK_DELAY_ATTRIBUTE);
373:                if (attributeValue instanceof  Number) {
374:                    refreshCheckDelay = ((Number) attributeValue).longValue();
375:                } else if (attributeValue instanceof  String) {
376:                    refreshCheckDelay = Long.parseLong((String) attributeValue);
377:                } else if (attributeValue != null) {
378:                    throw new BeanDefinitionStoreException(
379:                            "Invalid refresh check delay attribute ["
380:                                    + REFRESH_CHECK_DELAY_ATTRIBUTE
381:                                    + "] with value [" + attributeValue
382:                                    + "]: needs to be of type Number or String");
383:                }
384:                return refreshCheckDelay;
385:            }
386:
387:            /**
388:             * Create a ScriptFactory bean definition based on the given script definition,
389:             * extracting only the definition data that is relevant for the ScriptFactory
390:             * (that is, only bean class and constructor arguments).
391:             * @param bd the full script bean definition
392:             * @return the extracted ScriptFactory bean definition
393:             * @see org.springframework.scripting.ScriptFactory
394:             */
395:            protected RootBeanDefinition createScriptFactoryBeanDefinition(
396:                    RootBeanDefinition bd) {
397:                RootBeanDefinition scriptBd = new RootBeanDefinition();
398:                scriptBd.setBeanClassName(bd.getBeanClassName());
399:                scriptBd.getConstructorArgumentValues().addArgumentValues(
400:                        bd.getConstructorArgumentValues());
401:                return scriptBd;
402:            }
403:
404:            /**
405:             * Obtain a ScriptSource for the given bean, lazily creating it
406:             * if not cached already.
407:             * @param beanName the name of the scripted bean
408:             * @param scriptSourceLocator the script source locator associated with the bean
409:             * @return the corresponding ScriptSource instance
410:             * @see #convertToScriptSource
411:             */
412:            protected ScriptSource getScriptSource(String beanName,
413:                    String scriptSourceLocator) {
414:                synchronized (this .scriptSourceCache) {
415:                    ScriptSource scriptSource = (ScriptSource) this .scriptSourceCache
416:                            .get(beanName);
417:                    if (scriptSource == null) {
418:                        scriptSource = convertToScriptSource(
419:                                scriptSourceLocator, this .resourceLoader);
420:                        this .scriptSourceCache.put(beanName, scriptSource);
421:                    }
422:                    return scriptSource;
423:                }
424:            }
425:
426:            /**
427:             * Convert the given script source locator to a ScriptSource instance.
428:             * <p>By default, supported locators are Spring resource locations
429:             * (such as "file:C:/myScript.bsh" or "classpath:myPackage/myScript.bsh")
430:             * and inline scripts ("inline:myScriptText...").
431:             * @param scriptSourceLocator the script source locator
432:             * @param resourceLoader the ResourceLoader to use (if necessary)
433:             * @return the ScriptSource instance
434:             */
435:            protected ScriptSource convertToScriptSource(
436:                    String scriptSourceLocator, ResourceLoader resourceLoader) {
437:                if (scriptSourceLocator.startsWith(INLINE_SCRIPT_PREFIX)) {
438:                    return new StaticScriptSource(scriptSourceLocator
439:                            .substring(INLINE_SCRIPT_PREFIX.length()));
440:                } else {
441:                    return new ResourceScriptSource(resourceLoader
442:                            .getResource(scriptSourceLocator));
443:                }
444:            }
445:
446:            /**
447:             * Create a config interface for the given bean definition, defining setter
448:             * methods for the defined property values as well as an init method and
449:             * a destroy method (if defined).
450:             * <p>This implementation creates the interface via CGLIB's InterfaceMaker,
451:             * determining the property types from the given interfaces (as far as possible).
452:             * @param bd the bean definition (property values etc) to create a
453:             * config interface for
454:             * @param interfaces the interfaces to check against (might define
455:             * getters corresponding to the setters we're supposed to generate)
456:             * @return the config interface
457:             * @see net.sf.cglib.proxy.InterfaceMaker
458:             * @see org.springframework.beans.BeanUtils#findPropertyType
459:             */
460:            protected Class createConfigInterface(RootBeanDefinition bd,
461:                    Class[] interfaces) {
462:                InterfaceMaker maker = new InterfaceMaker();
463:                PropertyValue[] pvs = bd.getPropertyValues()
464:                        .getPropertyValues();
465:                for (int i = 0; i < pvs.length; i++) {
466:                    String propertyName = pvs[i].getName();
467:                    Class propertyType = BeanUtils.findPropertyType(
468:                            propertyName, interfaces);
469:                    String setterName = "set"
470:                            + StringUtils.capitalize(propertyName);
471:                    Signature signature = new Signature(setterName,
472:                            Type.VOID_TYPE, new Type[] { Type
473:                                    .getType(propertyType) });
474:                    maker.add(signature, new Type[0]);
475:                }
476:                if (bd.getInitMethodName() != null) {
477:                    Signature signature = new Signature(bd.getInitMethodName(),
478:                            Type.VOID_TYPE, new Type[0]);
479:                    maker.add(signature, new Type[0]);
480:                }
481:                if (bd.getDestroyMethodName() != null) {
482:                    Signature signature = new Signature(bd
483:                            .getDestroyMethodName(), Type.VOID_TYPE,
484:                            new Type[0]);
485:                    maker.add(signature, new Type[0]);
486:                }
487:                return maker.create();
488:            }
489:
490:            /**
491:             * Create a composite interface Class for the given interfaces,
492:             * implementing the given interfaces in one single Class.
493:             * <p>The default implementation builds a JDK proxy class
494:             * for the given interfaces.
495:             * @param interfaces the interfaces to merge
496:             * @return the merged interface as Class
497:             * @see java.lang.reflect.Proxy#getProxyClass
498:             */
499:            protected Class createCompositeInterface(Class[] interfaces) {
500:                return ClassUtils.createCompositeInterface(interfaces,
501:                        this .beanClassLoader);
502:            }
503:
504:            /**
505:             * Create a bean definition for the scripted object, based on the given script
506:             * definition, extracting the definition data that is relevant for the scripted
507:             * object (that is, everything but bean class and constructor arguments).
508:             * @param bd the full script bean definition
509:             * @param scriptFactoryBeanName the name of the internal ScriptFactory bean
510:             * @param scriptSource the ScriptSource for the scripted bean
511:             * @param interfaces the interfaces that the scripted bean is supposed to implement
512:             * @return the extracted ScriptFactory bean definition
513:             * @see org.springframework.scripting.ScriptFactory#getScriptedObject
514:             */
515:            protected RootBeanDefinition createScriptedObjectBeanDefinition(
516:                    RootBeanDefinition bd, String scriptFactoryBeanName,
517:                    ScriptSource scriptSource, Class[] interfaces) {
518:
519:                RootBeanDefinition objectBd = new RootBeanDefinition(bd);
520:                objectBd.setFactoryBeanName(scriptFactoryBeanName);
521:                objectBd.setFactoryMethodName("getScriptedObject");
522:                objectBd.getConstructorArgumentValues().clear();
523:                objectBd.getConstructorArgumentValues()
524:                        .addIndexedArgumentValue(0, scriptSource);
525:                objectBd.getConstructorArgumentValues()
526:                        .addIndexedArgumentValue(1, interfaces);
527:                return objectBd;
528:            }
529:
530:            /**
531:             * Create a refreshable proxy for the given AOP TargetSource.
532:             * @param ts the refreshable TargetSource
533:             * @param interfaces the proxy interfaces (may be <code>null</code> to
534:             * indicate proxying of all interfaces implemented by the target class)
535:             * @return the generated proxy
536:             * @see RefreshableScriptTargetSource
537:             */
538:            protected Object createRefreshableProxy(TargetSource ts,
539:                    Class[] interfaces) {
540:                ProxyFactory proxyFactory = new ProxyFactory();
541:                proxyFactory.setTargetSource(ts);
542:
543:                if (interfaces == null) {
544:                    interfaces = ClassUtils.getAllInterfacesForClass(ts
545:                            .getTargetClass());
546:                }
547:                proxyFactory.setInterfaces(interfaces);
548:
549:                DelegatingIntroductionInterceptor introduction = new DelegatingIntroductionInterceptor(
550:                        ts);
551:                introduction.suppressInterface(TargetSource.class);
552:                proxyFactory.addAdvice(introduction);
553:
554:                return proxyFactory.getProxy(this .beanClassLoader);
555:            }
556:
557:            /**
558:             * Destroy the inner bean factory (used for scripts) on shutdown.
559:             */
560:            public void destroy() {
561:                this.scriptBeanFactory.destroySingletons();
562:            }
563:
564:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.