    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    }