001    // Copyright 2009, 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 org.apache.tapestry5.ioc.*;
018    import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
019    import org.apache.tapestry5.ioc.internal.util.InjectionResources;
020    import org.apache.tapestry5.ioc.internal.util.InternalUtils;
021    import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
022    import org.slf4j.Logger;
023    
024    import java.lang.reflect.Method;
025    import java.util.Map;
026    
027    /**
028     * Base class for service decorators and service advisors that work by invoking a module method.
029     *
030     * @since 5.1.0.0
031     */
032    public class AbstractMethodInvokingInstrumenter
033    {
034        private final ModuleBuilderSource moduleSource;
035    
036        protected final Map<Class, Object> resourcesDefaults = CollectionFactory.newMap();
037    
038        private final ServiceResources resources;
039    
040        private final PlasticProxyFactory proxyFactory;
041    
042        protected final Method method;
043    
044        protected final Class serviceInterface;
045    
046        protected final String serviceId;
047    
048        private final Logger logger;
049    
050        public AbstractMethodInvokingInstrumenter(ModuleBuilderSource moduleSource, Method method,
051                                                  ServiceResources resources, PlasticProxyFactory proxyFactory)
052        {
053            this.moduleSource = moduleSource;
054            this.method = method;
055            this.resources = resources;
056            this.proxyFactory = proxyFactory;
057    
058            serviceId = resources.getServiceId();
059    
060            resourcesDefaults.put(String.class, serviceId);
061            resourcesDefaults.put(ObjectLocator.class, resources);
062            resourcesDefaults.put(ServiceResources.class, resources);
063            logger = resources.getLogger();
064            resourcesDefaults.put(Logger.class, logger);
065            serviceInterface = resources.getServiceInterface();
066            resourcesDefaults.put(Class.class, serviceInterface);
067            resourcesDefaults.put(OperationTracker.class, resources.getTracker());
068        }
069    
070        @Override
071        public String toString()
072        {
073            Location location = proxyFactory.getMethodLocation(method);
074    
075            return location.toString();
076        }
077    
078        private Object getModuleInstance()
079        {
080            return InternalUtils.isStatic(method) ? null : moduleSource.getModuleBuilder();
081        }
082    
083        protected Object invoke(final InjectionResources injectionResources)
084        {
085            String description = String.format("Invoking method %s", toString());
086    
087            ObjectCreator<Object> plan = InternalUtils.createMethodInvocationPlan(resources.getTracker(), resources, injectionResources, logger, description, getModuleInstance(), method);
088    
089            return plan.createObject();
090        }
091    }