    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    }