001    // Copyright 2006, 2007, 2008, 2009, 2010, 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.Constructor;
018    import java.util.Collection;
019    import java.util.List;
020    import java.util.Map;
021    
022    import org.apache.tapestry5.ioc.AnnotationProvider;
023    import org.apache.tapestry5.ioc.Invokable;
024    import org.apache.tapestry5.ioc.ObjectCreator;
025    import org.apache.tapestry5.ioc.OperationTracker;
026    import org.apache.tapestry5.ioc.ServiceBuilderResources;
027    import org.apache.tapestry5.ioc.def.ServiceDef;
028    import org.apache.tapestry5.ioc.def.ServiceDef3;
029    import org.apache.tapestry5.ioc.internal.util.InternalUtils;
030    import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
031    import org.slf4j.Logger;
032    
033    /**
034     * Implementation of {@link org.apache.tapestry5.ioc.ServiceBuilderResources}. We just have one
035     * implementation that fills the purposes of methods that need a {@link org.apache.tapestry5.ioc.ServiceResources}
036     * (which includes service decorator methods) as well as methods that need a
037     * {@link org.apache.tapestry5.ioc.ServiceBuilderResources} (which is just service builder methods). Since it is most
038     * commonly used for the former, we'll just leave the name as ServiceResourcesImpl.
039     */
040    @SuppressWarnings("all")
041    public class ServiceResourcesImpl extends ObjectLocatorImpl implements ServiceBuilderResources
042    {
043        private final InternalRegistry registry;
044    
045        private final Module module;
046    
047        private final ServiceDef3 serviceDef;
048    
049        private final Logger logger;
050    
051        private final PlasticProxyFactory proxyFactory;
052    
053        public ServiceResourcesImpl(InternalRegistry registry, Module module, ServiceDef3 serviceDef,
054                PlasticProxyFactory proxyFactory, Logger logger)
055        {
056            super(registry, module);
057    
058            this.registry = registry;
059            this.module = module;
060            this.serviceDef = serviceDef;
061            this.proxyFactory = proxyFactory;
062            this.logger = logger;
063        }
064    
065        public String getServiceId()
066        {
067            return serviceDef.getServiceId();
068        }
069    
070        public Class getServiceInterface()
071        {
072            return serviceDef.getServiceInterface();
073        }
074    
075        public Logger getLogger()
076        {
077            return logger;
078        }
079    
080        public <T> Collection<T> getUnorderedConfiguration(final Class<T> valueType)
081        {
082            Collection<T> result = registry.invoke(
083                    "Collecting unordered configuration for service " + serviceDef.getServiceId(),
084                    new Invokable<Collection<T>>()
085                    {
086                        public Collection<T> invoke()
087                        {
088                            return registry.getUnorderedConfiguration(serviceDef, valueType);
089                        }
090                    });
091    
092            logConfiguration(result);
093    
094            return result;
095        }
096    
097        private void logConfiguration(Collection configuration)
098        {
099            if (logger.isDebugEnabled())
100                logger.debug(IOCMessages.constructedConfiguration(configuration));
101        }
102    
103        public <T> List<T> getOrderedConfiguration(final Class<T> valueType)
104        {
105            List<T> result = registry.invoke("Collecting ordered configuration for service " + serviceDef.getServiceId(),
106                    new Invokable<List<T>>()
107                    {
108                        public List<T> invoke()
109                        {
110                            return registry.getOrderedConfiguration(serviceDef, valueType);
111                        }
112                    });
113    
114            logConfiguration(result);
115    
116            return result;
117        }
118    
119        public <K, V> Map<K, V> getMappedConfiguration(final Class<K> keyType, final Class<V> valueType)
120        {
121            Map<K, V> result = registry.invoke("Collecting mapped configuration for service " + serviceDef.getServiceId(),
122                    new Invokable<Map<K, V>>()
123                    {
124                        public Map<K, V> invoke()
125                        {
126                            return registry.getMappedConfiguration(serviceDef, keyType, valueType);
127                        }
128                    });
129    
130            if (logger.isDebugEnabled())
131                logger.debug(IOCMessages.constructedConfiguration(result));
132    
133            return result;
134        }
135    
136        public Object getModuleBuilder()
137        {
138            return module.getModuleBuilder();
139        }
140    
141        @Override
142        public <T> T autobuild(String description, final Class<T> clazz)
143        {
144            assert clazz != null;
145    
146            return registry.invoke(description, new Invokable<T>()
147            {
148                public T invoke()
149                {
150                    Constructor constructor = InternalUtils.findAutobuildConstructor(clazz);
151    
152                    if (constructor == null)
153                        throw new RuntimeException(IOCMessages.noAutobuildConstructor(clazz));
154    
155                    String description = proxyFactory.getConstructorLocation(constructor).toString();
156    
157                    ObjectCreator creator = new ConstructorServiceCreator(ServiceResourcesImpl.this, description,
158                            constructor);
159    
160                    return clazz.cast(creator.createObject());
161                }
162            });
163        }
164    
165        @Override
166        public <T> T autobuild(final Class<T> clazz)
167        {
168            assert clazz != null;
169    
170            return autobuild("Autobuilding instance of class " + clazz.getName(), clazz);
171        }
172    
173        public OperationTracker getTracker()
174        {
175            return registry;
176        }
177    
178        public Class getImplementationClass()
179        {
180            return null;
181        }
182    
183        public AnnotationProvider getClassAnnotationProvider()
184        {
185            return serviceDef.getClassAnnotationProvider();
186        }
187    
188        public AnnotationProvider getMethodAnnotationProvider(String methodName, Class... parameterTypes)
189        {
190            return serviceDef.getMethodAnnotationProvider(methodName, parameterTypes);
191        }
192    }