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
015package org.apache.tapestry5.ioc.internal;
016
017import java.lang.reflect.Constructor;
018import java.util.Collection;
019import java.util.List;
020import java.util.Map;
021
022import org.apache.tapestry5.commons.AnnotationProvider;
023import org.apache.tapestry5.commons.ObjectCreator;
024import org.apache.tapestry5.commons.services.PlasticProxyFactory;
025import org.apache.tapestry5.ioc.Invokable;
026import org.apache.tapestry5.ioc.OperationTracker;
027import org.apache.tapestry5.ioc.ServiceBuilderResources;
028import org.apache.tapestry5.ioc.def.ServiceDef;
029import org.apache.tapestry5.ioc.def.ServiceDef3;
030import org.apache.tapestry5.ioc.internal.util.InternalUtils;
031import 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")
041public 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    @Override
066    public String getServiceId()
067    {
068        return serviceDef.getServiceId();
069    }
070
071    @Override
072    public Class getServiceInterface()
073    {
074        return serviceDef.getServiceInterface();
075    }
076
077    @Override
078    public Class getServiceImplementation()
079    {
080        return serviceDef.getServiceImplementation();
081    }
082
083    @Override
084    public Logger getLogger()
085    {
086        return logger;
087    }
088
089    @Override
090    public <T> Collection<T> getUnorderedConfiguration(final Class<T> valueType)
091    {
092        Collection<T> result = registry.invoke(
093                "Collecting unordered configuration for service " + serviceDef.getServiceId(),
094                new Invokable<Collection<T>>()
095                {
096                    @Override
097                    public Collection<T> invoke()
098                    {
099                        return registry.getUnorderedConfiguration(serviceDef, valueType);
100                    }
101                });
102
103        logConfiguration(result);
104
105        return result;
106    }
107
108    private void logConfiguration(Collection configuration)
109    {
110        if (logger.isDebugEnabled())
111            logger.debug(IOCMessages.constructedConfiguration(configuration));
112    }
113
114    @Override
115    public <T> List<T> getOrderedConfiguration(final Class<T> valueType)
116    {
117        List<T> result = registry.invoke("Collecting ordered configuration for service " + serviceDef.getServiceId(),
118                new Invokable<List<T>>()
119                {
120                    @Override
121                    public List<T> invoke()
122                    {
123                        return registry.getOrderedConfiguration(serviceDef, valueType);
124                    }
125                });
126
127        logConfiguration(result);
128
129        return result;
130    }
131
132    @Override
133    public <K, V> Map<K, V> getMappedConfiguration(final Class<K> keyType, final Class<V> valueType)
134    {
135        Map<K, V> result = registry.invoke("Collecting mapped configuration for service " + serviceDef.getServiceId(),
136                new Invokable<Map<K, V>>()
137                {
138                    @Override
139                    public Map<K, V> invoke()
140                    {
141                        return registry.getMappedConfiguration(serviceDef, keyType, valueType);
142                    }
143                });
144
145        if (logger.isDebugEnabled())
146            logger.debug(IOCMessages.constructedConfiguration(result));
147
148        return result;
149    }
150
151    @Override
152    public Object getModuleBuilder()
153    {
154        return module.getModuleBuilder();
155    }
156
157    @Override
158    public <T> T autobuild(String description, final Class<T> clazz)
159    {
160        assert clazz != null;
161
162        return registry.invoke(description, new Invokable<T>()
163        {
164            @Override
165            public T invoke()
166            {
167                Constructor constructor = InternalUtils.findAutobuildConstructor(clazz);
168
169                if (constructor == null)
170                    throw new RuntimeException(IOCMessages.noAutobuildConstructor(clazz));
171
172                String description = proxyFactory.getConstructorLocation(constructor).toString();
173
174                ObjectCreator creator = new ConstructorServiceCreator(ServiceResourcesImpl.this, description,
175                        constructor);
176
177                return clazz.cast(creator.createObject());
178            }
179        });
180    }
181
182    @Override
183    public <T> T autobuild(final Class<T> clazz)
184    {
185        assert clazz != null;
186
187        return autobuild("Autobuilding instance of class " + clazz.getName(), clazz);
188    }
189
190    @Override
191    public OperationTracker getTracker()
192    {
193        return registry;
194    }
195
196    public Class getImplementationClass()
197    {
198        return null;
199    }
200
201    @Override
202    public AnnotationProvider getClassAnnotationProvider()
203    {
204        return serviceDef.getClassAnnotationProvider();
205    }
206
207    @Override
208    public AnnotationProvider getMethodAnnotationProvider(String methodName, Class... parameterTypes)
209    {
210        return serviceDef.getMethodAnnotationProvider(methodName, parameterTypes);
211    }
212}