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