    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 java.util.List;
    018
    019    import org.apache.tapestry5.ioc.ObjectCreator;
    020    import org.apache.tapestry5.ioc.ServiceAdvisor;
    021    import org.apache.tapestry5.ioc.def.ServiceDef3;
    022    import org.apache.tapestry5.ioc.services.AspectDecorator;
    023    import org.apache.tapestry5.ioc.services.AspectInterceptorBuilder;
    024
    025    /**
    026     * Equivalent of {@link org.apache.tapestry5.ioc.internal.InterceptorStackBuilder}, but works using an
    027     * {@link org.apache.tapestry5.ioc.services.AspectInterceptorBuilder} that receives advice from
    028     * {@link org.apache.tapestry5.ioc.ServiceAdvisor}s.
    029     *
    030     * @since 5.1.0.0
    031     */
    032    public class AdvisorStackBuilder implements ObjectCreator
    033    {
    034        private final ServiceDef3 serviceDef;
    035
    036        private final ObjectCreator delegate;
    037
    038        private final AspectDecorator aspectDecorator;
    039
    040        private final InternalRegistry registry;
    041
    042        /**
    043         * @param serviceDef
    044         *            the service that is ultimately being constructed
    045         * @param delegate
    046         *            responsible for creating the object to be decorated
    047         * @param aspectDecorator
    048         *            used to create the {@link org.apache.tapestry5.ioc.services.AspectInterceptorBuilder} passed to each
    049         *            {@link org.apache.tapestry5.ioc.ServiceAdvisor}
    050         * @param registry
    051         */
    052        public AdvisorStackBuilder(ServiceDef3 serviceDef, ObjectCreator delegate, AspectDecorator aspectDecorator,
    053                InternalRegistry registry)
    054        {
    055            this.serviceDef = serviceDef;
    056            this.delegate = delegate;
    057            this.registry = registry;
    058            this.aspectDecorator = aspectDecorator;
    059        }
    060
    061        public Object createObject()
    062        {
    063            Object service = delegate.createObject();
    064
    065            List<ServiceAdvisor> advisors = registry.findAdvisorsForService(serviceDef);
    066
    067            if (advisors.isEmpty())
    068                return service;
    069
    070            final AspectInterceptorBuilder builder = aspectDecorator.createBuilder(serviceDef.getServiceInterface(),
    071                    service, serviceDef, String.format("<AspectProxy for %s(%s)>", serviceDef.getServiceId(), serviceDef
    072                            .getServiceInterface().getName()));
    073
    074            for (final ServiceAdvisor advisor : advisors)
    075            {
    076                registry.run("Invoking " + advisor, new Runnable()
    077                {
    078                    public void run()
    079                    {
    080                        advisor.advise(builder);
    081                    }
    082                });
    083            }
    084
    085            return builder.build();
    086        }
    087    }