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