    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}