    001    // Copyright 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.services;
    016
    017    import java.lang.reflect.Method;
    018    import java.util.Arrays;
    019    import java.util.Set;
    020
    021    import org.apache.tapestry5.ioc.AnnotationAccess;
    022    import org.apache.tapestry5.ioc.AnnotationProvider;
    023    import org.apache.tapestry5.ioc.MethodAdvice;
    024    import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
    025    import org.apache.tapestry5.ioc.internal.util.InternalUtils;
    026    import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
    027    import org.apache.tapestry5.plastic.PlasticClass;
    028    import org.apache.tapestry5.plastic.PlasticClassTransformation;
    029    import org.apache.tapestry5.plastic.PlasticField;
    030
    031    @SuppressWarnings("all")
    032    public class AspectInterceptorBuilderImpl<T> extends AbtractAspectInterceptorBuilder<T>
    033    {
    034        private final Class<T> serviceInterface;
    035
    036        private final Set<Method> allMethods = CollectionFactory.newSet();
    037
    038        private final PlasticClassTransformation transformation;
    039
    040        private final PlasticClass plasticClass;
    041
    042        public AspectInterceptorBuilderImpl(AnnotationAccess annotationAccess, PlasticProxyFactory plasticProxyFactory,
    043                Class<T> serviceInterface, T delegate, String description)
    044        {
    045            super(annotationAccess);
    046
    047            this.serviceInterface = serviceInterface;
    048
    049            transformation = plasticProxyFactory.createProxyTransformation(serviceInterface);
    050            plasticClass = transformation.getPlasticClass();
    051
    052            plasticClass.addToString(description);
    053
    054            allMethods.addAll(Arrays.asList(serviceInterface.getMethods()));
    055
    056            PlasticField delegateField = plasticClass.introduceField(serviceInterface, "delegate").inject(delegate);
    057
    058            for (Method method : allMethods)
    059            {
    060                plasticClass.introduceMethod(method).delegateTo(delegateField);
    061            }
    062        }
    063
    064        public void adviseMethod(Method method, MethodAdvice advice)
    065        {
    066            assert method != null;
    067            assert advice != null;
    068
    069            AnnotationProvider methodAnnotationProvider = getMethodAnnotationProvider(method.getName(),
    070                    method.getParameterTypes());
    071
    072            adviseMethod(method, InternalUtils.toPlasticMethodAdvice(advice, methodAnnotationProvider));
    073        }
    074
    075        public void adviseAllMethods(MethodAdvice advice)
    076        {
    077            for (Method m : serviceInterface.getMethods())
    078                adviseMethod(m, advice);
    079        }
    080
    081        public void adviseMethod(Method method, org.apache.tapestry5.plastic.MethodAdvice advice)
    082        {
    083            assert method != null;
    084            assert advice != null;
    085
    086            if (!allMethods.contains(method))
    087                throw new IllegalArgumentException(String.format("Method %s is not defined for interface %s.", method,
    088                        serviceInterface));
    089
    090            plasticClass.introduceMethod(method).addAdvice(advice);
    091        }
    092
    093        public void adviseAllMethods(org.apache.tapestry5.plastic.MethodAdvice advice)
    094        {
    095            for (Method m : serviceInterface.getMethods())
    096            {
    097                adviseMethod(m, advice);
    098            }
    099        }
    100
    101        public Class getInterface()
    102        {
    103            return serviceInterface;
    104        }
    105
    106        public T build()
    107        {
    108            return (T) transformation.createInstantiator().newInstance();
    109        }
    110    }