Source Code Cross Referenced for CommonAnnotationBeanPostProcessor.java in  » J2EE » spring-framework-2.5 » org » springframework » context » annotation » 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.context.annotation 
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.context.annotation;
018:
019:        import java.beans.Introspector;
020:        import java.beans.PropertyDescriptor;
021:        import java.io.Serializable;
022:        import java.lang.annotation.Annotation;
023:        import java.lang.reflect.AnnotatedElement;
024:        import java.lang.reflect.Constructor;
025:        import java.lang.reflect.Field;
026:        import java.lang.reflect.Member;
027:        import java.lang.reflect.Method;
028:        import java.lang.reflect.Modifier;
029:        import java.net.MalformedURLException;
030:        import java.net.URL;
031:        import java.util.Collections;
032:        import java.util.HashSet;
033:        import java.util.Iterator;
034:        import java.util.Map;
035:        import java.util.Set;
036:        import java.util.concurrent.ConcurrentHashMap;
037:
038:        import javax.annotation.PostConstruct;
039:        import javax.annotation.PreDestroy;
040:        import javax.annotation.Resource;
041:        import javax.ejb.EJB;
042:        import javax.xml.namespace.QName;
043:        import javax.xml.ws.Service;
044:        import javax.xml.ws.WebServiceClient;
045:        import javax.xml.ws.WebServiceRef;
046:
047:        import org.springframework.beans.BeanUtils;
048:        import org.springframework.beans.BeansException;
049:        import org.springframework.beans.PropertyValues;
050:        import org.springframework.beans.factory.BeanCreationException;
051:        import org.springframework.beans.factory.BeanFactory;
052:        import org.springframework.beans.factory.BeanFactoryAware;
053:        import org.springframework.beans.factory.NoSuchBeanDefinitionException;
054:        import org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor;
055:        import org.springframework.beans.factory.annotation.InjectionMetadata;
056:        import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
057:        import org.springframework.beans.factory.config.ConfigurableBeanFactory;
058:        import org.springframework.beans.factory.config.DependencyDescriptor;
059:        import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
060:        import org.springframework.core.MethodParameter;
061:        import org.springframework.jndi.support.SimpleJndiBeanFactory;
062:        import org.springframework.util.Assert;
063:        import org.springframework.util.ClassUtils;
064:        import org.springframework.util.ReflectionUtils;
065:        import org.springframework.util.StringUtils;
066:
067:        /**
068:         * {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation
069:         * that supports common JSR-250 annotations out of the box.
070:         *
071:         * <p>This includes support for the {@link javax.annotation.PostConstruct} and
072:         * {@link javax.annotation.PreDestroy} annotations (as init annotation and destroy
073:         * annotation, respectively).
074:         *
075:         * <p>The central element is the {@link javax.annotation.Resource} annotation
076:         * for annotation-driven injection of named beans, by default from the containing
077:         * Spring BeanFactory, with only <code>mappedName</code> references resolved in JNDI.
078:         * The {@link #setAlwaysUseJndiLookup "alwaysUseJndiLookup" flag} enforces JNDI lookups
079:         * equivalent to standard Java EE 5 resource injection for <code>name</code> references
080:         * and default names as well. The target beans can be simple POJOs, with no special
081:         * requirements other than the type having to match.
082:         *
083:         * <p>The JAX-WS {@link javax.xml.ws.WebServiceRef} annotation is supported too,
084:         * analogous to {@link javax.annotation.Resource} but with the capability of creating
085:         * specific JAX-WS service endpoints. This may either point to an explicitly defined
086:         * resource by name or operate on a locally specified JAX-WS service class. Finally,
087:         * this post-processor also supports the EJB 3 {@link javax.ejb.EJB} annotation,
088:         * analogous to {@link javax.annotation.Resource} as well, with the capability to
089:         * specify both a local bean name and a global JNDI name for fallback retrieval.
090:         * The target beans can be plain POJOs as well as EJB 3 Session Beans in this case.
091:         *
092:         * <p>The common annotations supported by this post-processor are available
093:         * in Java 6 (JDK 1.6) as well as in Java EE 5 (which provides a standalone jar for
094:         * its common annotations as well, allowing for use in any Java 5 based application).
095:         * Hence, this post-processor works out of the box on JDK 1.6, and requires the
096:         * JSR-250 API jar (and optionally the JAX-WS API jar and/or the EJB 3 API jar)
097:         * to be added to the classpath on JDK 1.5 (when running outside of Java EE 5).
098:         *
099:         * <p>For default usage, resolving resource names as Spring bean names,
100:         * simply define the following in your application context:
101:         *
102:         * <pre class="code">
103:         * &lt;bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/&gt;</pre>
104:         *
105:         * For direct JNDI access, resolving resource names as JNDI resource references
106:         * within the Java EE application's "java:comp/env/" namespace, use the following:
107:         *
108:         * <pre class="code">
109:         * &lt;bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"&gt;
110:         *   &lt;property name="alwaysUseJndiLookup" value="true"/&gt;
111:         * &lt;/bean&gt;</pre>
112:         *
113:         * Note: <code>mappedName</code> references will always be resolved in JNDI,
114:         * allowing for global JNDI names (including "java:" prefix) as well. The
115:         * "alwaysUseJndiLookup" flag just affects <code>name</code> references and
116:         * default names (inferred from the field name / property name).
117:         *
118:         * <p>A default CommonAnnotationBeanPostProcessor will be registered
119:         * by the "context:annotation-config" and "context:component-scan" XML tags.
120:         * Remove or turn off the default annotation configuration there if you intend
121:         * to specify a custom CommonAnnotationBeanPostProcessor bean definition.
122:         *
123:         * @author Juergen Hoeller
124:         * @since 2.5
125:         * @see #setAlwaysUseJndiLookup
126:         * @see #setResourceFactory
127:         * @see org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor
128:         * @see org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
129:         */
130:        public class CommonAnnotationBeanPostProcessor extends
131:                InitDestroyAnnotationBeanPostProcessor implements 
132:                InstantiationAwareBeanPostProcessor, BeanFactoryAware,
133:                Serializable {
134:
135:            private static Class<? extends Annotation> webServiceRefClass = null;
136:
137:            private static Class<? extends Annotation> ejbRefClass = null;
138:
139:            static {
140:                try {
141:                    webServiceRefClass = ClassUtils.forName(
142:                            "javax.xml.ws.WebServiceRef",
143:                            CommonAnnotationBeanPostProcessor.class
144:                                    .getClassLoader());
145:                } catch (ClassNotFoundException ex) {
146:                    webServiceRefClass = null;
147:                }
148:                try {
149:                    ejbRefClass = ClassUtils.forName("javax.ejb.EJB",
150:                            CommonAnnotationBeanPostProcessor.class
151:                                    .getClassLoader());
152:                } catch (ClassNotFoundException ex) {
153:                    ejbRefClass = null;
154:                }
155:            }
156:
157:            private boolean fallbackToDefaultTypeMatch = true;
158:
159:            private boolean alwaysUseJndiLookup = false;
160:
161:            private transient BeanFactory jndiFactory = new SimpleJndiBeanFactory();
162:
163:            private transient BeanFactory resourceFactory;
164:
165:            private transient BeanFactory beanFactory;
166:
167:            private transient final Map<Class<?>, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<Class<?>, InjectionMetadata>();
168:
169:            /**
170:             * Create a new CommonAnnotationBeanPostProcessor,
171:             * with the init and destroy annotation types set to
172:             * {@link javax.annotation.PostConstruct} and {@link javax.annotation.PreDestroy},
173:             * respectively.
174:             */
175:            public CommonAnnotationBeanPostProcessor() {
176:                setInitAnnotationType(PostConstruct.class);
177:                setDestroyAnnotationType(PreDestroy.class);
178:            }
179:
180:            /**
181:             * Set whether to allow a fallback to a type match if no explicit name has been
182:             * specified. The default name (i.e. the field name or bean property name) will
183:             * still be checked first; if a bean of that name exists, it will be taken.
184:             * However, if no bean of that name exists, a by-type resolution of the
185:             * dependency will be attempted if this flag is "true".
186:             * <p>Default is "true". Switch this flag to "false" in order to enforce a
187:             * by-name lookup in all cases, throwing an exception in case of no name match.
188:             * @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#resolveDependency
189:             */
190:            public void setFallbackToDefaultTypeMatch(
191:                    boolean fallbackToDefaultTypeMatch) {
192:                this .fallbackToDefaultTypeMatch = fallbackToDefaultTypeMatch;
193:            }
194:
195:            /**
196:             * Set whether to always use JNDI lookups equivalent to standard Java EE 5 resource
197:             * injection, <b>even for <code>name</code> attributes and default names</b>.
198:             * <p>Default is "false": Resource names are used for Spring bean lookups in the
199:             * containing BeanFactory; only <code>mappedName</code> attributes point directly
200:             * into JNDI. Switch this flag to "true" for enforcing Java EE style JNDI lookups
201:             * in any case, even for <code>name</code> attributes and default names.
202:             * @see #setJndiFactory
203:             * @see #setResourceFactory
204:             */
205:            public void setAlwaysUseJndiLookup(boolean alwaysUseJndiLookup) {
206:                this .alwaysUseJndiLookup = alwaysUseJndiLookup;
207:            }
208:
209:            /**
210:             * Specify the factory for objects to be injected into <code>@Resource</code> /
211:             * <code>@WebServiceRef</code> / <code>@EJB</code> annotated fields and setter methods,
212:             * <b>for <code>mappedName</code> attributes that point directly into JNDI</b>.
213:             * This factory will also be used if "alwaysUseJndiLookup" is set to "true" in order
214:             * to enforce JNDI lookups even for <code>name</code> attributes and default names.
215:             * <p>The default is a {@link org.springframework.jndi.support.SimpleJndiBeanFactory}
216:             * for JNDI lookup behavior equivalent to standard Java EE 5 resource injection.
217:             * @see #setResourceFactory
218:             * @see #setAlwaysUseJndiLookup
219:             */
220:            public void setJndiFactory(BeanFactory jndiFactory) {
221:                Assert.notNull(jndiFactory, "BeanFactory must not be null");
222:                this .jndiFactory = jndiFactory;
223:            }
224:
225:            /**
226:             * Specify the factory for objects to be injected into <code>@Resource</code> /
227:             * <code>@WebServiceRef</code> / <code>@EJB</code> annotated fields and setter methods,
228:             * <b>for <code>name</code> attributes and default names</b>.
229:             * <p>The default is the BeanFactory that this post-processor is defined in,
230:             * if any, looking up resource names as Spring bean names. Specify the resource
231:             * factory explicitly for programmatic usage of this post-processor.
232:             * <p>Specifying Spring's {@link org.springframework.jndi.support.SimpleJndiBeanFactory}
233:             * leads to JNDI lookup behavior equivalent to standard Java EE 5 resource injection,
234:             * even for <code>name</code> attributes and default names. This is the same behavior
235:             * that the "alwaysUseJndiLookup" flag enables.
236:             * @see #setAlwaysUseJndiLookup
237:             */
238:            public void setResourceFactory(BeanFactory resourceFactory) {
239:                Assert.notNull(resourceFactory, "BeanFactory must not be null");
240:                this .resourceFactory = resourceFactory;
241:            }
242:
243:            public void setBeanFactory(BeanFactory beanFactory)
244:                    throws BeansException {
245:                Assert.notNull(beanFactory, "BeanFactory must not be null");
246:                this .beanFactory = beanFactory;
247:                if (this .resourceFactory == null) {
248:                    this .resourceFactory = beanFactory;
249:                }
250:            }
251:
252:            public Object postProcessBeforeInstantiation(Class beanClass,
253:                    String beanName) throws BeansException {
254:                return null;
255:            }
256:
257:            public boolean postProcessAfterInstantiation(Object bean,
258:                    String beanName) throws BeansException {
259:                InjectionMetadata metadata = findResourceMetadata(bean
260:                        .getClass());
261:                try {
262:                    metadata.injectFields(bean, beanName);
263:                } catch (Throwable ex) {
264:                    throw new BeanCreationException(beanName,
265:                            "Injection of resource fields failed", ex);
266:                }
267:                return true;
268:            }
269:
270:            public PropertyValues postProcessPropertyValues(PropertyValues pvs,
271:                    PropertyDescriptor[] pds, Object bean, String beanName)
272:                    throws BeansException {
273:
274:                InjectionMetadata metadata = findResourceMetadata(bean
275:                        .getClass());
276:                try {
277:                    metadata.injectMethods(bean, beanName, pvs);
278:                } catch (Throwable ex) {
279:                    throw new BeanCreationException(beanName,
280:                            "Injection of resource methods failed", ex);
281:                }
282:                return pvs;
283:            }
284:
285:            private InjectionMetadata findResourceMetadata(final Class clazz) {
286:                // Quick check on the concurrent map first, with minimal locking.
287:                InjectionMetadata metadata = this .injectionMetadataCache
288:                        .get(clazz);
289:                if (metadata == null) {
290:                    synchronized (this .injectionMetadataCache) {
291:                        metadata = this .injectionMetadataCache.get(clazz);
292:                        if (metadata == null) {
293:                            final InjectionMetadata newMetadata = new InjectionMetadata();
294:                            ReflectionUtils.doWithFields(clazz,
295:                                    new ReflectionUtils.FieldCallback() {
296:                                        public void doWith(Field field) {
297:                                            if (webServiceRefClass != null
298:                                                    && field
299:                                                            .isAnnotationPresent(webServiceRefClass)) {
300:                                                if (Modifier.isStatic(field
301:                                                        .getModifiers())) {
302:                                                    throw new IllegalStateException(
303:                                                            "@WebServiceRef annotation is not supported on static fields");
304:                                                }
305:                                                newMetadata
306:                                                        .addInjectedField(new WebServiceRefElement(
307:                                                                field, null));
308:                                            } else if (ejbRefClass != null
309:                                                    && field
310:                                                            .isAnnotationPresent(ejbRefClass)) {
311:                                                if (Modifier.isStatic(field
312:                                                        .getModifiers())) {
313:                                                    throw new IllegalStateException(
314:                                                            "@EJB annotation is not supported on static fields");
315:                                                }
316:                                                newMetadata
317:                                                        .addInjectedField(new EjbRefElement(
318:                                                                field, null));
319:                                            } else if (field
320:                                                    .isAnnotationPresent(Resource.class)) {
321:                                                if (Modifier.isStatic(field
322:                                                        .getModifiers())) {
323:                                                    throw new IllegalStateException(
324:                                                            "@Resource annotation is not supported on static fields");
325:                                                }
326:                                                newMetadata
327:                                                        .addInjectedField(new ResourceElement(
328:                                                                field, null));
329:                                            }
330:                                        }
331:                                    });
332:                            ReflectionUtils.doWithMethods(clazz,
333:                                    new ReflectionUtils.MethodCallback() {
334:                                        public void doWith(Method method) {
335:                                            if (webServiceRefClass != null
336:                                                    && method
337:                                                            .isAnnotationPresent(webServiceRefClass)) {
338:                                                if (Modifier.isStatic(method
339:                                                        .getModifiers())) {
340:                                                    throw new IllegalStateException(
341:                                                            "@WebServiceRef annotation is not supported on static methods");
342:                                                }
343:                                                if (method.getParameterTypes().length != 1) {
344:                                                    throw new IllegalStateException(
345:                                                            "@WebServiceRef annotation requires a single-arg method: "
346:                                                                    + method);
347:                                                }
348:                                                PropertyDescriptor pd = BeanUtils
349:                                                        .findPropertyForMethod(method);
350:                                                newMetadata
351:                                                        .addInjectedMethod(new WebServiceRefElement(
352:                                                                method, pd));
353:                                            } else if (ejbRefClass != null
354:                                                    && method
355:                                                            .isAnnotationPresent(ejbRefClass)) {
356:                                                if (Modifier.isStatic(method
357:                                                        .getModifiers())) {
358:                                                    throw new IllegalStateException(
359:                                                            "@EJB annotation is not supported on static methods");
360:                                                }
361:                                                if (method.getParameterTypes().length != 1) {
362:                                                    throw new IllegalStateException(
363:                                                            "@EJB annotation requires a single-arg method: "
364:                                                                    + method);
365:                                                }
366:                                                PropertyDescriptor pd = BeanUtils
367:                                                        .findPropertyForMethod(method);
368:                                                newMetadata
369:                                                        .addInjectedMethod(new EjbRefElement(
370:                                                                method, pd));
371:                                            } else if (method
372:                                                    .isAnnotationPresent(Resource.class)) {
373:                                                if (Modifier.isStatic(method
374:                                                        .getModifiers())) {
375:                                                    throw new IllegalStateException(
376:                                                            "@Resource annotation is not supported on static methods");
377:                                                }
378:                                                if (method.getParameterTypes().length != 1) {
379:                                                    throw new IllegalStateException(
380:                                                            "@Resource annotation requires a single-arg method: "
381:                                                                    + method);
382:                                                }
383:                                                PropertyDescriptor pd = BeanUtils
384:                                                        .findPropertyForMethod(method);
385:                                                newMetadata
386:                                                        .addInjectedMethod(new ResourceElement(
387:                                                                method, pd));
388:                                            }
389:                                        }
390:                                    });
391:                            metadata = newMetadata;
392:                            this .injectionMetadataCache.put(clazz, metadata);
393:                        }
394:                    }
395:                }
396:                return metadata;
397:            }
398:
399:            /**
400:             * Obtain the resource object for the given name and type.
401:             * @param resourceElement the descriptor for the annotated field/method
402:             * @param requestingBeanName the name of the requesting bean
403:             * @return the resource object (never <code>null</code>)
404:             * @throws BeansException if we failed to obtain the target resource
405:             */
406:            protected Object getResource(ResourceElement resourceElement,
407:                    String requestingBeanName) throws BeansException {
408:
409:                Object resource = null;
410:                Set autowiredBeanNames = null;
411:                String name = resourceElement.name;
412:                Class type = resourceElement.lookupType;
413:                String mappedName = resourceElement.mappedName;
414:
415:                if (StringUtils.hasLength(mappedName)) {
416:                    return this .jndiFactory.getBean(mappedName, type);
417:                }
418:                if (this .alwaysUseJndiLookup) {
419:                    return this .jndiFactory.getBean(name, type);
420:                }
421:
422:                if (this .resourceFactory == null) {
423:                    throw new NoSuchBeanDefinitionException(
424:                            type,
425:                            "No resource factory configured - "
426:                                    + "override the getResource method or specify the 'resourceFactory' property");
427:                }
428:
429:                if (this .fallbackToDefaultTypeMatch
430:                        && resourceElement.isDefaultName
431:                        && this .resourceFactory instanceof  AutowireCapableBeanFactory
432:                        && !this .resourceFactory.containsBean(name)) {
433:                    autowiredBeanNames = new HashSet();
434:                    resource = ((AutowireCapableBeanFactory) this .resourceFactory)
435:                            .resolveDependency(resourceElement
436:                                    .getDependencyDescriptor(),
437:                                    requestingBeanName, autowiredBeanNames,
438:                                    null);
439:                } else {
440:                    resource = this .resourceFactory.getBean(name, type);
441:                    autowiredBeanNames = Collections.singleton(name);
442:                }
443:
444:                if (this .resourceFactory instanceof  ConfigurableBeanFactory) {
445:                    ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) this .resourceFactory;
446:                    for (Iterator it = autowiredBeanNames.iterator(); it
447:                            .hasNext();) {
448:                        String autowiredBeanName = (String) it.next();
449:                        beanFactory.registerDependentBean(autowiredBeanName,
450:                                requestingBeanName);
451:                    }
452:                }
453:
454:                return resource;
455:            }
456:
457:            /**
458:             * Class representing injection information about an annotated field
459:             * or setter method, supporting the @Resource annotation.
460:             */
461:            private class ResourceElement extends
462:                    InjectionMetadata.InjectedElement {
463:
464:                protected String name;
465:
466:                protected boolean isDefaultName = false;
467:
468:                protected Class<?> lookupType;
469:
470:                protected String mappedName;
471:
472:                protected boolean shareable = true;
473:
474:                public ResourceElement(Member member, PropertyDescriptor pd) {
475:                    super (member, pd);
476:                    initAnnotation((AnnotatedElement) member);
477:                }
478:
479:                protected void initAnnotation(AnnotatedElement ae) {
480:                    Resource resource = ae.getAnnotation(Resource.class);
481:                    String resourceName = resource.name();
482:                    Class resourceType = resource.type();
483:                    this .isDefaultName = !StringUtils.hasLength(resourceName);
484:                    if (this .isDefaultName) {
485:                        resourceName = this .member.getName();
486:                        if (this .member instanceof  Method
487:                                && resourceName.startsWith("set")
488:                                && resourceName.length() > 3) {
489:                            resourceName = Introspector
490:                                    .decapitalize(resourceName.substring(3));
491:                        }
492:                    }
493:                    if (resourceType != null
494:                            && !Object.class.equals(resourceType)) {
495:                        checkResourceType(resourceType);
496:                    } else {
497:                        // No resource type specified... check field/method.
498:                        resourceType = getResourceType();
499:                    }
500:                    this .name = resourceName;
501:                    this .lookupType = resourceType;
502:                    this .mappedName = resource.mappedName();
503:                    this .shareable = resource.shareable();
504:                }
505:
506:                /**
507:                 * Build a DependencyDescriptor for the underlying field/method.
508:                 */
509:                public DependencyDescriptor getDependencyDescriptor() {
510:                    if (this .isField) {
511:                        return new ResourceDependencyDescriptor(
512:                                (Field) this .member, this .lookupType);
513:                    } else {
514:                        return new ResourceDependencyDescriptor(
515:                                (Method) this .member, this .lookupType);
516:                    }
517:                }
518:
519:                @Override
520:                protected Object getResourceToInject(Object target,
521:                        String requestingBeanName) {
522:                    return getResource(this , requestingBeanName);
523:                }
524:            }
525:
526:            /**
527:             * Class representing injection information about an annotated field
528:             * or setter method, supporting the @WebServiceRef annotation.
529:             */
530:            private class WebServiceRefElement extends ResourceElement {
531:
532:                private Class elementType;
533:
534:                private String wsdlLocation;
535:
536:                public WebServiceRefElement(Member member, PropertyDescriptor pd) {
537:                    super (member, pd);
538:                }
539:
540:                protected void initAnnotation(AnnotatedElement ae) {
541:                    WebServiceRef resource = ae
542:                            .getAnnotation(WebServiceRef.class);
543:                    String resourceName = resource.name();
544:                    Class resourceType = resource.type();
545:                    this .isDefaultName = !StringUtils.hasLength(resourceName);
546:                    if (this .isDefaultName) {
547:                        resourceName = this .member.getName();
548:                        if (this .member instanceof  Method
549:                                && resourceName.startsWith("set")
550:                                && resourceName.length() > 3) {
551:                            resourceName = Introspector
552:                                    .decapitalize(resourceName.substring(3));
553:                        }
554:                    }
555:                    if (resourceType != null
556:                            && !Object.class.equals(resourceType)) {
557:                        checkResourceType(resourceType);
558:                    } else {
559:                        // No resource type specified... check field/method.
560:                        resourceType = getResourceType();
561:                    }
562:                    this .name = resourceName;
563:                    this .elementType = resourceType;
564:                    if (Service.class.isAssignableFrom(resourceType)) {
565:                        this .lookupType = resourceType;
566:                    } else {
567:                        this .lookupType = (!Object.class.equals(resource
568:                                .value()) ? resource.value() : Service.class);
569:                    }
570:                    this .mappedName = resource.mappedName();
571:                    this .wsdlLocation = resource.wsdlLocation();
572:                }
573:
574:                @Override
575:                protected Object getResourceToInject(Object target,
576:                        String requestingBeanName) {
577:                    Service service = null;
578:                    try {
579:                        service = (Service) getResource(this ,
580:                                requestingBeanName);
581:                    } catch (NoSuchBeanDefinitionException notFound) {
582:                        // Service to be created through generated class.
583:                        if (Service.class.equals(this .lookupType)) {
584:                            throw new IllegalStateException(
585:                                    "No resource with name '"
586:                                            + this .name
587:                                            + "' found in context, "
588:                                            + "and no specific JAX-WS Service subclass specified. The typical solution is to either specify "
589:                                            + "a LocalJaxWsServiceFactoryBean with the given name or to specify the (generated) Service "
590:                                            + "subclass as @WebServiceRef(...) value.");
591:                        }
592:                        if (StringUtils.hasLength(this .wsdlLocation)) {
593:                            try {
594:                                Constructor ctor = this .lookupType
595:                                        .getConstructor(new Class[] {
596:                                                URL.class, QName.class });
597:                                WebServiceClient clientAnn = this .lookupType
598:                                        .getAnnotation(WebServiceClient.class);
599:                                if (clientAnn == null) {
600:                                    throw new IllegalStateException(
601:                                            "JAX-WS Service class ["
602:                                                    + this .lookupType.getName()
603:                                                    + "] does not carry a WebServiceClient annotation");
604:                                }
605:                                service = (Service) BeanUtils.instantiateClass(
606:                                        ctor, new Object[] {
607:                                                new URL(this .wsdlLocation),
608:                                                new QName(clientAnn
609:                                                        .targetNamespace(),
610:                                                        clientAnn.name()) });
611:                            } catch (NoSuchMethodException ex) {
612:                                throw new IllegalStateException(
613:                                        "JAX-WS Service class ["
614:                                                + this .lookupType.getName()
615:                                                + "] does not have a (URL, QName) constructor. Cannot apply specified WSDL location ["
616:                                                + this .wsdlLocation + "].");
617:                            } catch (MalformedURLException ex) {
618:                                throw new IllegalArgumentException(
619:                                        "Specified WSDL location ["
620:                                                + this .wsdlLocation
621:                                                + "] isn't a valid URL");
622:                            }
623:                        } else {
624:                            service = (Service) BeanUtils
625:                                    .instantiateClass(this .lookupType);
626:                        }
627:                    }
628:                    return service.getPort(this .elementType);
629:                }
630:            }
631:
632:            /**
633:             * Class representing injection information about an annotated field
634:             * or setter method, supporting the @EJB annotation.
635:             */
636:            private class EjbRefElement extends ResourceElement {
637:
638:                private String beanName;
639:
640:                public EjbRefElement(Member member, PropertyDescriptor pd) {
641:                    super (member, pd);
642:                }
643:
644:                protected void initAnnotation(AnnotatedElement ae) {
645:                    EJB resource = ae.getAnnotation(EJB.class);
646:                    String resourceBeanName = resource.beanName();
647:                    String resourceName = resource.name();
648:                    this .isDefaultName = !StringUtils.hasLength(resourceName);
649:                    if (this .isDefaultName) {
650:                        resourceName = this .member.getName();
651:                        if (this .member instanceof  Method
652:                                && resourceName.startsWith("set")
653:                                && resourceName.length() > 3) {
654:                            resourceName = Introspector
655:                                    .decapitalize(resourceName.substring(3));
656:                        }
657:                    }
658:                    Class resourceType = resource.beanInterface();
659:                    if (resourceType != null
660:                            && !Object.class.equals(resourceType)) {
661:                        checkResourceType(resourceType);
662:                    } else {
663:                        // No resource type specified... check field/method.
664:                        resourceType = getResourceType();
665:                    }
666:                    this .beanName = resourceBeanName;
667:                    this .name = resourceName;
668:                    this .lookupType = resourceType;
669:                    this .mappedName = resource.mappedName();
670:                }
671:
672:                @Override
673:                protected Object getResourceToInject(Object target,
674:                        String requestingBeanName) {
675:                    if (StringUtils.hasLength(this .beanName)) {
676:                        if (beanFactory != null
677:                                && beanFactory.containsBean(this .beanName)) {
678:                            // Local match found for explicitly specified local bean name.
679:                            Object bean = beanFactory.getBean(this .beanName,
680:                                    this .lookupType);
681:                            if (beanFactory instanceof  ConfigurableBeanFactory) {
682:                                ((ConfigurableBeanFactory) beanFactory)
683:                                        .registerDependentBean(this .beanName,
684:                                                requestingBeanName);
685:                            }
686:                            return bean;
687:                        } else if (this .isDefaultName
688:                                && !StringUtils.hasLength(this .mappedName)) {
689:                            throw new NoSuchBeanDefinitionException(
690:                                    this .beanName,
691:                                    "Cannot resolve 'beanName' in local BeanFactory. Consider specifying a general 'name' value instead.");
692:                        }
693:                    }
694:                    // JNDI name lookup - may still go to a local BeanFactory.
695:                    return getResource(this , requestingBeanName);
696:                }
697:            }
698:
699:            /**
700:             * Extension of the DependencyDescriptor class,
701:             * overriding the dependency type with the specified resource type.
702:             */
703:            private static class ResourceDependencyDescriptor extends
704:                    DependencyDescriptor {
705:
706:                private final Class resourceType;
707:
708:                public ResourceDependencyDescriptor(Field field,
709:                        Class resourceType) {
710:                    super (field, true);
711:                    this .resourceType = resourceType;
712:                }
713:
714:                public ResourceDependencyDescriptor(Method method,
715:                        Class resourceType) {
716:                    super (new MethodParameter(method, 0), true);
717:                    this .resourceType = resourceType;
718:                }
719:
720:                public Class getDependencyType() {
721:                    return this.resourceType;
722:                }
723:            }
724:
725:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.