| // Copyright 2008, 2009, 2010 The Apache Software Foundation |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package org.apache.tapestry5.internal.services; |
| |
| import javax.servlet.http.Cookie; |
| |
| import org.apache.tapestry5.SymbolConstants; |
| import org.apache.tapestry5.internal.pageload.PageLoaderImpl; |
| import org.apache.tapestry5.internal.services.ajax.AjaxFormUpdateController; |
| import org.apache.tapestry5.internal.services.javascript.JavaScriptStackPathConstructor; |
| import org.apache.tapestry5.internal.structure.ComponentPageElementResourcesSource; |
| import org.apache.tapestry5.internal.structure.ComponentPageElementResourcesSourceImpl; |
| import org.apache.tapestry5.ioc.ObjectLocator; |
| import org.apache.tapestry5.ioc.OrderedConfiguration; |
| import org.apache.tapestry5.ioc.ScopeConstants; |
| import org.apache.tapestry5.ioc.ServiceBinder; |
| import org.apache.tapestry5.ioc.ServiceResources; |
| import org.apache.tapestry5.ioc.annotations.Autobuild; |
| import org.apache.tapestry5.ioc.annotations.Marker; |
| import org.apache.tapestry5.ioc.annotations.Primary; |
| import org.apache.tapestry5.ioc.annotations.Scope; |
| import org.apache.tapestry5.ioc.annotations.Symbol; |
| import org.apache.tapestry5.ioc.internal.services.CtClassSource; |
| import org.apache.tapestry5.ioc.services.Builtin; |
| import org.apache.tapestry5.ioc.services.ClassFactory; |
| import org.apache.tapestry5.ioc.services.ClasspathURLConverter; |
| import org.apache.tapestry5.ioc.services.PerthreadManager; |
| import org.apache.tapestry5.ioc.services.PropertyShadowBuilder; |
| import org.apache.tapestry5.services.*; |
| import org.apache.tapestry5.services.templates.ComponentTemplateLocator; |
| import org.slf4j.Logger; |
| |
| /** |
| * {@link org.apache.tapestry5.services.TapestryModule} has gotten too complicated and it is nice to demarkate public |
| * (and stable) from internal (and volatile). |
| */ |
| @Marker(Core.class) |
| public class InternalModule |
| { |
| private final UpdateListenerHub updateListenerHub; |
| |
| private final RequestGlobals requestGlobals; |
| |
| private final InvalidationEventHub classesInvalidationEventHub; |
| |
| public InternalModule(UpdateListenerHub updateListenerHub, RequestGlobals requestGlobals, |
| |
| @ComponentClasses |
| InvalidationEventHub classesInvalidationEventHub) |
| { |
| this.updateListenerHub = updateListenerHub; |
| this.requestGlobals = requestGlobals; |
| this.classesInvalidationEventHub = classesInvalidationEventHub; |
| } |
| |
| /** |
| * Bind all the private/internal services of Tapestry. |
| */ |
| public static void bind(ServiceBinder binder) |
| { |
| binder.bind(PersistentFieldManager.class, PersistentFieldManagerImpl.class); |
| binder.bind(TemplateParser.class, TemplateParserImpl.class); |
| binder.bind(PageResponseRenderer.class, PageResponseRendererImpl.class); |
| binder.bind(PageMarkupRenderer.class, PageMarkupRendererImpl.class); |
| binder.bind(LinkSource.class, LinkSourceImpl.class); |
| binder.bind(LocalizationSetter.class, LocalizationSetterImpl.class); |
| binder.bind(PageElementFactory.class, PageElementFactoryImpl.class); |
| binder.bind(ResourceStreamer.class, ResourceStreamerImpl.class); |
| binder.bind(ClientPersistentFieldStorage.class, ClientPersistentFieldStorageImpl.class); |
| binder.bind(PageRenderQueue.class, PageRenderQueueImpl.class); |
| binder.bind(AjaxPartialResponseRenderer.class, AjaxPartialResponseRendererImpl.class); |
| binder.bind(PageContentTypeAnalyzer.class, PageContentTypeAnalyzerImpl.class); |
| binder.bind(ComponentPageElementResourcesSource.class, ComponentPageElementResourcesSourceImpl.class); |
| binder.bind(RequestSecurityManager.class, RequestSecurityManagerImpl.class); |
| binder.bind(InternalRequestGlobals.class, InternalRequestGlobalsImpl.class); |
| binder.bind(EndOfRequestEventHub.class); |
| binder.bind(ResponseCompressionAnalyzer.class, ResponseCompressionAnalyzerImpl.class); |
| binder.bind(ComponentModelSource.class); |
| binder.bind(AssetResourceLocator.class); |
| binder.bind(JavaScriptStackPathConstructor.class); |
| binder.bind(AjaxFormUpdateController.class); |
| } |
| |
| /** |
| * Chooses one of two implementations, based on the configured mode. |
| */ |
| public static ActionRenderResponseGenerator buildActionRenderResponseGenerator( |
| |
| @Symbol(SymbolConstants.SUPPRESS_REDIRECT_FROM_ACTION_REQUESTS) |
| boolean immediateMode, |
| |
| ObjectLocator locator) |
| { |
| if (immediateMode) |
| return locator.autobuild(ImmediateActionRenderResponseGenerator.class); |
| |
| return locator.autobuild(ActionRenderResponseGeneratorImpl.class); |
| } |
| |
| @Scope(ScopeConstants.PERTHREAD) |
| public static RequestPageCache buildRequestPageCache(ServiceResources serviceResources, |
| @Symbol(SymbolConstants.PAGE_POOL_ENABLED) |
| boolean pagePoolEnabled, PerthreadManager perthreadManager) |
| { |
| if (pagePoolEnabled) |
| { |
| |
| RequestPageCacheImpl service = serviceResources.autobuild(RequestPageCacheImpl.class); |
| |
| perthreadManager.addThreadCleanupListener(service); |
| |
| return service; |
| } |
| |
| // Modern, non-pooling |
| |
| NonPoolingRequestPageCacheImpl service = serviceResources.autobuild(NonPoolingRequestPageCacheImpl.class); |
| |
| perthreadManager.addThreadCleanupListener(service); |
| |
| return service; |
| } |
| |
| public ComponentInstantiatorSource buildComponentInstantiatorSource(@Builtin |
| ClassFactory classFactory, |
| |
| ComponentClassTransformer transformer, |
| |
| Logger logger, |
| |
| InternalRequestGlobals internalRequestGlobals, |
| |
| ClasspathURLConverter classpathURLConverter) |
| { |
| ComponentInstantiatorSourceImpl source = new ComponentInstantiatorSourceImpl(logger, |
| classFactory.getClassLoader(), transformer, internalRequestGlobals, classpathURLConverter); |
| |
| updateListenerHub.addUpdateListener(source); |
| |
| return source; |
| } |
| |
| public static ComponentClassTransformer buildComponentClassTransformer(@Autobuild |
| ComponentClassTransformerImpl transformer, @ComponentClasses |
| InvalidationEventHub hub) |
| { |
| hub.addInvalidationListener(transformer); |
| |
| return transformer; |
| } |
| |
| public PageLoader buildPageLoader(@Autobuild |
| PageLoaderImpl service, |
| |
| @ComponentTemplates |
| InvalidationEventHub templatesHub, |
| |
| @ComponentMessages |
| InvalidationEventHub messagesHub) |
| { |
| // TODO: We could combine these three using chain-of-command. |
| |
| classesInvalidationEventHub.addInvalidationListener(service); |
| templatesHub.addInvalidationListener(service); |
| messagesHub.addInvalidationListener(service); |
| |
| return service; |
| } |
| |
| public PagePool buildPagePool(@Autobuild |
| PagePoolImpl service, |
| |
| @ComponentTemplates |
| InvalidationEventHub templatesHub, |
| |
| @ComponentMessages |
| InvalidationEventHub messagesHub) |
| { |
| // This covers invalidations due to changes to classes |
| |
| classesInvalidationEventHub.addInvalidationListener(service); |
| |
| // This covers invalidation due to changes to message catalogs (properties files) |
| |
| messagesHub.addInvalidationListener(service); |
| |
| // ... and this covers invalidations due to changes to templates |
| |
| templatesHub.addInvalidationListener(service); |
| |
| // Give the service a chance to clean up its own cache periodically as well |
| |
| updateListenerHub.addUpdateListener(service); |
| |
| return service; |
| } |
| |
| public PageSource buildPageSource(@Autobuild |
| PageSourceImpl service, |
| |
| @ComponentTemplates |
| InvalidationEventHub templatesHub, |
| |
| @ComponentMessages |
| InvalidationEventHub messagesHub) |
| { |
| // This covers invalidations due to changes to classes |
| |
| classesInvalidationEventHub.addInvalidationListener(service); |
| |
| // This covers invalidation due to changes to message catalogs (properties files) |
| |
| messagesHub.addInvalidationListener(service); |
| |
| // ... and this covers invalidations due to changes to templates |
| |
| templatesHub.addInvalidationListener(service); |
| |
| return service; |
| } |
| |
| public ComponentClassCache buildComponentClassCache(@Autobuild |
| ComponentClassCacheImpl service) |
| { |
| classesInvalidationEventHub.addInvalidationListener(service); |
| |
| return service; |
| } |
| |
| public CookieSource buildCookieSource() |
| { |
| return new CookieSource() |
| { |
| |
| public Cookie[] getCookies() |
| { |
| return requestGlobals.getHTTPServletRequest().getCookies(); |
| } |
| }; |
| } |
| |
| public CookieSink buildCookieSink() |
| { |
| return new CookieSink() |
| { |
| |
| public void addCookie(Cookie cookie) |
| { |
| requestGlobals.getHTTPServletResponse().addCookie(cookie); |
| } |
| }; |
| } |
| |
| public ResourceCache buildResourceCache(@Autobuild |
| ResourceCacheImpl service) |
| { |
| updateListenerHub.addUpdateListener(service); |
| |
| return service; |
| } |
| |
| public ComponentTemplateSource buildComponentTemplateSource(TemplateParser parser, @Primary |
| ComponentTemplateLocator locator, ClasspathURLConverter classpathURLConverter) |
| { |
| ComponentTemplateSourceImpl service = new ComponentTemplateSourceImpl(parser, locator, classpathURLConverter); |
| |
| updateListenerHub.addUpdateListener(service); |
| |
| return service; |
| } |
| |
| @Marker(ComponentLayer.class) |
| public static CtClassSource buildCtClassSource(PropertyShadowBuilder builder, |
| ComponentInstantiatorSource componentInstantiatorSource) |
| { |
| return builder.build(componentInstantiatorSource, "classSource", CtClassSource.class); |
| } |
| |
| public PageActivationContextCollector buildPageActivationContextCollector(@Autobuild |
| PageActivationContextCollectorImpl service) |
| { |
| classesInvalidationEventHub.addInvalidationListener(service); |
| |
| return service; |
| } |
| |
| /** |
| * @since 5.1.0.0 |
| */ |
| public StringInterner buildStringInterner(@Autobuild |
| StringInternerImpl service) |
| { |
| classesInvalidationEventHub.addInvalidationListener(service); |
| |
| return service; |
| } |
| |
| /** |
| * Contributes: |
| * <dl> |
| * <dt>LinkDecoration (instance of {@link LinkDecorationListener})</dt> |
| * <dd>Triggers events for notifications about links</dd> |
| * <dl> |
| * |
| * @since 5.2.0 |
| */ |
| public static void contributeLinkSource(OrderedConfiguration<LinkCreationListener2> configuration) |
| { |
| configuration.addInstance("LinkDecoration", LinkDecorationListener.class); |
| } |
| } |