    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    }