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 }