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