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.internal.services;
016
017 import org.apache.tapestry5.SymbolConstants;
018 import org.apache.tapestry5.internal.pageload.PageLoaderImpl;
019 import org.apache.tapestry5.internal.services.ajax.AjaxFormUpdateController;
020 import org.apache.tapestry5.internal.services.javascript.JavaScriptStackPathConstructor;
021 import org.apache.tapestry5.internal.structure.ComponentPageElementResourcesSource;
022 import org.apache.tapestry5.internal.structure.ComponentPageElementResourcesSourceImpl;
023 import org.apache.tapestry5.ioc.MappedConfiguration;
024 import org.apache.tapestry5.ioc.ObjectLocator;
025 import org.apache.tapestry5.ioc.OrderedConfiguration;
026 import org.apache.tapestry5.ioc.ServiceBinder;
027 import org.apache.tapestry5.ioc.annotations.Autobuild;
028 import org.apache.tapestry5.ioc.annotations.Contribute;
029 import org.apache.tapestry5.ioc.annotations.Marker;
030 import org.apache.tapestry5.ioc.annotations.Symbol;
031 import org.apache.tapestry5.services.*;
032 import org.apache.tapestry5.services.transform.ControlledPackageType;
033
034 import javax.servlet.http.Cookie;
035 import java.util.Map;
036
037 /**
038 * {@link org.apache.tapestry5.services.TapestryModule} has gotten too complicated and it is nice to demarkate public
039 * (and stable) from internal (and volatile).
040 */
041 @Marker(Core.class)
042 public class InternalModule
043 {
044
045 private final RequestGlobals requestGlobals;
046
047 private final InvalidationEventHub classesInvalidationEventHub;
048
049 public InternalModule(RequestGlobals requestGlobals,
050
051 @ComponentClasses
052 InvalidationEventHub classesInvalidationEventHub)
053 {
054 this.requestGlobals = requestGlobals;
055 this.classesInvalidationEventHub = classesInvalidationEventHub;
056 }
057
058 /**
059 * Bind all the private/internal services of Tapestry.
060 */
061 public static void bind(ServiceBinder binder)
062 {
063 binder.bind(PersistentFieldManager.class, PersistentFieldManagerImpl.class);
064 binder.bind(TemplateParser.class, TemplateParserImpl.class);
065 binder.bind(PageResponseRenderer.class, PageResponseRendererImpl.class);
066 binder.bind(PageMarkupRenderer.class, PageMarkupRendererImpl.class);
067 binder.bind(LinkSource.class, LinkSourceImpl.class);
068 binder.bind(LocalizationSetter.class, LocalizationSetterImpl.class);
069 binder.bind(PageElementFactory.class, PageElementFactoryImpl.class);
070 binder.bind(ResourceStreamer.class, ResourceStreamerImpl.class);
071 binder.bind(ClientPersistentFieldStorage.class, ClientPersistentFieldStorageImpl.class);
072 binder.bind(PageRenderQueue.class, PageRenderQueueImpl.class);
073 binder.bind(AjaxPartialResponseRenderer.class, AjaxPartialResponseRendererImpl.class);
074 binder.bind(PageContentTypeAnalyzer.class, PageContentTypeAnalyzerImpl.class);
075 binder.bind(ComponentPageElementResourcesSource.class, ComponentPageElementResourcesSourceImpl.class);
076 binder.bind(RequestSecurityManager.class, RequestSecurityManagerImpl.class);
077 binder.bind(InternalRequestGlobals.class, InternalRequestGlobalsImpl.class);
078 binder.bind(EndOfRequestEventHub.class);
079 binder.bind(ResponseCompressionAnalyzer.class, ResponseCompressionAnalyzerImpl.class);
080 binder.bind(ComponentModelSource.class);
081 binder.bind(AssetResourceLocator.class);
082 binder.bind(JavaScriptStackPathConstructor.class);
083 binder.bind(AjaxFormUpdateController.class);
084 binder.bind(ResourceDigestManager.class, ResourceDigestManagerImpl.class);
085 binder.bind(RequestPageCache.class, NonPoolingRequestPageCacheImpl.class);
086 binder.bind(ComponentInstantiatorSource.class);
087 binder.bind(InternalComponentInvalidationEventHub.class);
088 }
089
090 /**
091 * Chooses one of two implementations, based on the configured mode.
092 */
093 public static ActionRenderResponseGenerator buildActionRenderResponseGenerator(
094
095 @Symbol(SymbolConstants.SUPPRESS_REDIRECT_FROM_ACTION_REQUESTS)
096 boolean immediateMode,
097
098 ObjectLocator locator)
099 {
100 if (immediateMode)
101 return locator.autobuild(ImmediateActionRenderResponseGenerator.class);
102
103 return locator.autobuild(ActionRenderResponseGeneratorImpl.class);
104 }
105
106 public PageLoader buildPageLoader(@Autobuild
107 PageLoaderImpl service,
108
109 @ComponentTemplates
110 InvalidationEventHub templatesHub,
111
112 @ComponentMessages
113 InvalidationEventHub messagesHub)
114 {
115 // TODO: We could combine these three using chain-of-command.
116
117 classesInvalidationEventHub.addInvalidationListener(service);
118 templatesHub.addInvalidationListener(service);
119 messagesHub.addInvalidationListener(service);
120
121 return service;
122 }
123
124 public PageSource buildPageSource(@Autobuild
125 PageSourceImpl service,
126
127 @ComponentTemplates
128 InvalidationEventHub templatesHub,
129
130 @ComponentMessages
131 InvalidationEventHub messagesHub)
132 {
133 // This covers invalidations due to changes to classes
134
135 classesInvalidationEventHub.addInvalidationListener(service);
136
137 // This covers invalidation due to changes to message catalogs (properties files)
138
139 messagesHub.addInvalidationListener(service);
140
141 // ... and this covers invalidations due to changes to templates
142
143 templatesHub.addInvalidationListener(service);
144
145 return service;
146 }
147
148 public ComponentClassCache buildComponentClassCache(@Autobuild
149 ComponentClassCacheImpl service)
150 {
151 classesInvalidationEventHub.addInvalidationListener(service);
152
153 return service;
154 }
155
156 public CookieSource buildCookieSource()
157 {
158 return new CookieSource()
159 {
160
161 public Cookie[] getCookies()
162 {
163 return requestGlobals.getHTTPServletRequest().getCookies();
164 }
165 };
166 }
167
168 public CookieSink buildCookieSink()
169 {
170 return new CookieSink()
171 {
172
173 public void addCookie(Cookie cookie)
174 {
175 requestGlobals.getHTTPServletResponse().addCookie(cookie);
176 }
177 };
178 }
179
180 public PageActivationContextCollector buildPageActivationContextCollector(@Autobuild
181 PageActivationContextCollectorImpl service)
182 {
183 classesInvalidationEventHub.addInvalidationListener(service);
184
185 return service;
186 }
187
188 /**
189 * @since 5.1.0.0
190 */
191 public StringInterner buildStringInterner(@Autobuild
192 StringInternerImpl service)
193 {
194 classesInvalidationEventHub.addInvalidationListener(service);
195
196 return service;
197 }
198
199 /**
200 * Contributes:
201 * <dl>
202 * <dt>LinkDecoration (instance of {@link LinkDecorationListener})</dt>
203 * <dd>Triggers events for notifications about links</dd>
204 * <dl>
205 *
206 * @since 5.2.0
207 */
208 public static void contributeLinkSource(OrderedConfiguration<LinkCreationListener2> configuration)
209 {
210 configuration.addInstance("LinkDecoration", LinkDecorationListener.class);
211 }
212
213 /**
214 * Contributes packages identified by {@link ComponentClassResolver#getControlledPackageMapping()}.
215 *
216 * @since 5.3
217 */
218 @Contribute(ComponentInstantiatorSource.class)
219 public static void configureControlledPackagesFromComponentClassResolver(
220 MappedConfiguration<String, ControlledPackageType> configuration, ComponentClassResolver resolver)
221 {
222 for (Map.Entry<String, ControlledPackageType> entry : resolver.getControlledPackageMapping().entrySet())
223 {
224 configuration.add(entry.getKey(), entry.getValue());
225 }
226 }
227 }