001    // Copyright 2006, 2007, 2008, 2011 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.ioc.internal;
016    
017    import java.lang.reflect.Method;
018    import java.util.Set;
019    
020    import org.apache.tapestry5.func.F;
021    import org.apache.tapestry5.func.Flow;
022    import org.apache.tapestry5.func.Mapper;
023    import org.apache.tapestry5.ioc.AnnotationProvider;
024    import org.apache.tapestry5.ioc.ObjectCreator;
025    import org.apache.tapestry5.ioc.ServiceBuilderResources;
026    import org.apache.tapestry5.ioc.def.ServiceDef3;
027    import org.apache.tapestry5.ioc.internal.services.AnnotationProviderChain;
028    import org.apache.tapestry5.ioc.internal.util.InternalUtils;
029    
030    public class ServiceDefImpl implements ServiceDef3
031    {
032        private final Class serviceInterface;
033    
034        private final Class serviceImplementation;
035    
036        private final String serviceId;
037    
038        private final String scope;
039    
040        private final boolean eagerLoad;
041    
042        private final ObjectCreatorSource source;
043    
044        private final Set<Class> markers;
045    
046        private final boolean preventDecoration;
047    
048        /**
049         * @param serviceInterface
050         *            interface implemented by the service (or the service implementation class, for
051         *            non-proxied services)
052         * @param serviceImplementation
053         *            service implementation class if exists
054         * @param serviceId
055         *            unique id for the service
056         * @param markers
057         *            set of marker annotation classes (will be retained not copied)
058         * @param scope
059         *            scope of the service (i.e., {@link org.apache.tapestry5.ioc.ScopeConstants#DEFAULT}).
060         * @param eagerLoad
061         *            if true, the service is realized at startup, rather than on-demand
062         * @param preventDecoration
063         *            if true, the service may not be decorated
064         * @param source
065         *            used to create the service implementation when needed
066         */
067        ServiceDefImpl(Class serviceInterface, Class serviceImplementation, String serviceId, Set<Class> markers,
068                String scope, boolean eagerLoad, boolean preventDecoration, ObjectCreatorSource source)
069        {
070            this.serviceInterface = serviceInterface;
071            this.serviceImplementation = serviceImplementation;
072            this.serviceId = serviceId;
073            this.scope = scope;
074            this.eagerLoad = eagerLoad;
075            this.preventDecoration = preventDecoration;
076            this.source = source;
077    
078            this.markers = markers;
079        }
080    
081        @Override
082        public String toString()
083        {
084            return source.getDescription();
085        }
086    
087        public ObjectCreator createServiceCreator(ServiceBuilderResources resources)
088        {
089            return source.constructCreator(resources);
090        }
091    
092        public String getServiceId()
093        {
094            return serviceId;
095        }
096    
097        public Class getServiceInterface()
098        {
099            return serviceInterface;
100        }
101    
102        public String getServiceScope()
103        {
104            return scope;
105        }
106    
107        public boolean isEagerLoad()
108        {
109            return eagerLoad;
110        }
111    
112        public Set<Class> getMarkers()
113        {
114            return markers;
115        }
116    
117        public boolean isPreventDecoration()
118        {
119            return preventDecoration;
120        }
121    
122        private Flow<Class> searchPath()
123        {
124            return F.flow(serviceImplementation, serviceInterface).removeNulls();
125        }
126    
127        public AnnotationProvider getClassAnnotationProvider()
128        {
129            return AnnotationProviderChain.create(searchPath().map(InternalUtils.CLASS_TO_AP_MAPPER).toList());
130        }
131    
132        public AnnotationProvider getMethodAnnotationProvider(final String methodName, final Class... argumentTypes)
133        {
134            return AnnotationProviderChain.create(searchPath().map(new Mapper<Class, Method>()
135            {
136                public Method map(Class element)
137                {
138                    return InternalUtils.findMethod(element, methodName, argumentTypes);
139                }
140            }).map(InternalUtils.METHOD_TO_AP_MAPPER).toList());
141        }
142    }