01: // Copyright 2006, 2007 The Apache Software Foundation
02: //
03: // Licensed under the Apache License, Version 2.0 (the "License");
04: // you may not use this file except in compliance with the License.
05: // You may obtain a copy of the License at
06: //
07: // http://www.apache.org/licenses/LICENSE-2.0
08: //
09: // Unless required by applicable law or agreed to in writing, software
10: // distributed under the License is distributed on an "AS IS" BASIS,
11: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12: // See the License for the specific language governing permissions and
13: // limitations under the License.
14:
15: package org.apache.tapestry.ioc.internal;
16:
17: import java.util.Collections;
18: import java.util.List;
19:
20: import org.apache.tapestry.ioc.ObjectCreator;
21: import org.apache.tapestry.ioc.ServiceDecorator;
22:
23: /**
24: * Responsible for constructing the interceptor stack, on demand, by invoking an ordered series of
25: * decorators ({@link org.apache.tapestry.ioc.def.DecoratorDef} (which are converted into
26: * {@link ServiceDecorator}s).
27: */
28: public class InterceptorStackBuilder implements ObjectCreator {
29: private final String _serviceId;
30:
31: private final ObjectCreator _coreServiceCreator;
32:
33: private final Module _module;
34:
35: /**
36: * @param module
37: * the module containing the decorator method
38: * @param serviceId
39: * identifies the service to be decorated
40: * @param coreServiceCreator
41: * responsible for creating the core service which is then decorated with a stack of
42: * interceptors
43: */
44: public InterceptorStackBuilder(Module module, String serviceId,
45: ObjectCreator coreServiceCreator) {
46: _module = module;
47: _serviceId = serviceId;
48: _coreServiceCreator = coreServiceCreator;
49: }
50:
51: public Object createObject() {
52: Object current = _coreServiceCreator.createObject();
53:
54: List<ServiceDecorator> decorators = _module
55: .findDecoratorsForService(_serviceId);
56:
57: // We get the decorators ordered according to their dependencies. However, we want to
58: // process from the last interceptor to the first, so we reverse the list.
59:
60: Collections.reverse(decorators);
61:
62: for (ServiceDecorator decorator : decorators) {
63: Object interceptor = decorator.createInterceptor(current);
64:
65: // Decorator methods may return null; this indicates that the decorator chose not to
66: // decorate.
67:
68: if (interceptor != null)
69: current = interceptor;
70: }
71:
72: // The stack of interceptors (plus the core service implementation) are "represented" to the
73: // outside world
74: // as the outermost interceptor. That will still be buried inside the service proxy.
75:
76: return current;
77: }
78:
79: }
|