    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
    015package org.apache.tapestry5.ioc.internal;
    016
    017import org.apache.tapestry5.ioc.*;
    018import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
    019import org.apache.tapestry5.ioc.internal.util.InjectionResources;
    020import org.apache.tapestry5.ioc.internal.util.InternalUtils;
    021import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
    022import org.slf4j.Logger;
    023
    024import java.lang.reflect.Method;
    025import 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 */
    032public 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}