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
015package org.apache.tapestry5.internal.spring;
016
017import org.apache.tapestry5.commons.AnnotationProvider;
018import org.apache.tapestry5.ioc.Registry;
019import org.apache.tapestry5.ioc.annotations.Inject;
020import org.apache.tapestry5.ioc.annotations.InjectService;
021import org.springframework.beans.BeansException;
022import org.springframework.beans.TypeConverter;
023import org.springframework.beans.factory.BeanFactory;
024import org.springframework.beans.factory.config.DependencyDescriptor;
025import org.springframework.beans.factory.support.DefaultListableBeanFactory;
026
027import java.lang.annotation.Annotation;
028import 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.commons.AnnotationProvider)} to provide the
034 * value.
035 */
036public 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                @Override
061                public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
062                {
063                    for (Object a : annotations)
064                    {
065                        if (annotationClass.isInstance(a)) return annotationClass.cast(a);
066                    }
067
068                    return null;
069                }
070            };
071
072            if (provider.getAnnotation(Inject.class) != null || provider.getAnnotation(InjectService.class) != null)
073                return registry.getObject(objectType, provider);
074        }
075
076        return super.resolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter);
077    }
078}