001    // Copyright 2008, 2009, 2010 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry5.internal.spring;
016    
017    import org.apache.tapestry5.ioc.AnnotationProvider;
018    import org.apache.tapestry5.ioc.Registry;
019    import org.apache.tapestry5.ioc.annotations.Inject;
020    import org.apache.tapestry5.ioc.annotations.InjectService;
021    import org.springframework.beans.BeansException;
022    import org.springframework.beans.TypeConverter;
023    import org.springframework.beans.factory.BeanFactory;
024    import org.springframework.beans.factory.config.DependencyDescriptor;
025    import org.springframework.beans.factory.support.DefaultListableBeanFactory;
026    
027    import java.lang.annotation.Annotation;
028    import java.util.Set;
029    
030    /**
031     * Identifies dependencies whose field or method parameter contains the {@link org.apache.tapestry5.ioc.annotations.Inject}
032     * or {@link org.apache.tapestry5.ioc.annotations.InjectService} annotations and, if so, invokes {@link
033     * org.apache.tapestry5.ioc.Registry#getObject(Class, org.apache.tapestry5.ioc.AnnotationProvider)} to provide the
034     * value.
035     */
036    public class TapestryBeanFactory extends DefaultListableBeanFactory
037    {
038        private final Registry registry;
039    
040        public TapestryBeanFactory(BeanFactory parentBeanFactory, Registry registry)
041        {
042            super(parentBeanFactory);
043    
044            this.registry = registry;
045        }
046    
047        @Override
048        public Object resolveDependency(final DependencyDescriptor descriptor, String beanName, Set autowiredBeanNames,
049                                        TypeConverter typeConverter) throws BeansException
050        {
051    
052            Class objectType = descriptor.getDependencyType();
053    
054            final Annotation[] annotations = descriptor.getAnnotations();
055    
056            if (annotations != null)
057            {
058                AnnotationProvider provider = new AnnotationProvider()
059                {
060                    public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
061                    {
062                        for (Object a : annotations)
063                        {
064                            if (annotationClass.isInstance(a)) return annotationClass.cast(a);
065                        }
066    
067                        return null;
068                    }
069                };
070    
071                if (provider.getAnnotation(Inject.class) != null || provider.getAnnotation(InjectService.class) != null)
072                    return registry.getObject(objectType, provider);
073            }
074    
075            return super.resolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter);
076        }
077    }