001// Licensed under the Apache License, Version 2.0 (the "License");
002// you may not use this file except in compliance with the License.
003// You may obtain a copy of the License at
004//
005// http://www.apache.org/licenses/LICENSE-2.0
006//
007// Unless required by applicable law or agreed to in writing, software
008// distributed under the License is distributed on an "AS IS" BASIS,
009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
010// See the License for the specific language governing permissions and
011// limitations under the License.
012
013package org.apache.tapestry5.modules;
014
015import java.util.List;
016
017import org.apache.tapestry5.SymbolConstants;
018import org.apache.tapestry5.commons.MappedConfiguration;
019import org.apache.tapestry5.commons.OrderedConfiguration;
020import org.apache.tapestry5.http.TapestryHttpSymbolConstants;
021import org.apache.tapestry5.internal.pageload.DefaultComponentRequestSelectorAnalyzer;
022import org.apache.tapestry5.internal.pageload.DefaultComponentResourceLocator;
023import org.apache.tapestry5.internal.pageload.PagePreloaderImpl;
024import org.apache.tapestry5.internal.services.ComponentDependencyRegistry;
025import org.apache.tapestry5.internal.services.ComponentTemplateSource;
026import org.apache.tapestry5.internal.services.ComponentTemplateSourceImpl;
027import org.apache.tapestry5.ioc.ServiceBinder;
028import org.apache.tapestry5.ioc.annotations.Marker;
029import org.apache.tapestry5.ioc.annotations.Startup;
030import org.apache.tapestry5.ioc.annotations.Symbol;
031import org.apache.tapestry5.ioc.services.ChainBuilder;
032import org.apache.tapestry5.services.ComponentLibraryInfoSource;
033import org.apache.tapestry5.services.Core;
034import org.apache.tapestry5.services.pageload.ComponentRequestSelectorAnalyzer;
035import org.apache.tapestry5.services.pageload.ComponentResourceLocator;
036import org.apache.tapestry5.services.pageload.PageCachingReferenceTypeService;
037import org.apache.tapestry5.services.pageload.PageClassLoaderContextManager;
038import org.apache.tapestry5.services.pageload.PageClassLoaderContextManagerImpl;
039import org.apache.tapestry5.services.pageload.PagePreloader;
040import org.apache.tapestry5.services.pageload.PreloaderMode;
041import org.apache.tapestry5.services.pageload.ReferenceType;
042
043/**
044 * @since 5.3
045 */
046@Marker(Core.class)
047public class PageLoadModule
048{
049    
050    /**
051     * Contributes factory defaults that may be overridden.
052     */
053    public static void contributeFactoryDefaults(MappedConfiguration<String, Object> configuration)
054    {
055        configuration.add(SymbolConstants.MULTIPLE_CLASSLOADERS, false);
056    }
057    
058    public static void bind(ServiceBinder binder)
059    {
060        binder.bind(ComponentRequestSelectorAnalyzer.class, DefaultComponentRequestSelectorAnalyzer.class);
061        binder.bind(ComponentResourceLocator.class, DefaultComponentResourceLocator.class);
062        binder.bind(ComponentTemplateSource.class, ComponentTemplateSourceImpl.class);
063        binder.bind(PagePreloader.class, PagePreloaderImpl.class);
064        binder.bind(PageClassLoaderContextManager.class, PageClassLoaderContextManagerImpl.class);
065    }
066
067    @Startup
068    public static void preloadPages(PagePreloader preloader,
069                                    @Symbol(SymbolConstants.PRELOADER_MODE)
070                                    PreloaderMode mode,
071                                    @Symbol(TapestryHttpSymbolConstants.PRODUCTION_MODE)
072                                    boolean productionMode)
073    {
074        if (mode.isEnabledFor(productionMode))
075        {
076            preloader.preloadPages();
077        }
078    }
079    
080    @Startup
081    public void preloadPageClassLoaderContexts(
082            PageClassLoaderContextManager pageClassLoaderContextManager,
083            ComponentDependencyRegistry componentDependencyRegistry,
084            @Symbol(SymbolConstants.PRODUCTION_MODE) boolean productionMode,
085            @Symbol(SymbolConstants.MULTIPLE_CLASSLOADERS) boolean multipleClassLoaders)
086    {
087        if (!productionMode && multipleClassLoaders)
088        {
089            // Preload the page activation context tree for the already known classes
090            for (int i = 0; i < 5; i++)
091            {
092                for (String className : componentDependencyRegistry.getClassNames()) 
093                {
094                    pageClassLoaderContextManager.get(className);
095                }
096            }
097        }
098    }
099    
100    public static PageCachingReferenceTypeService buildPageCachingReferenceTypeService(
101            List<PageCachingReferenceTypeService> configuration,
102            ChainBuilder chainBuilder) 
103    {
104        return chainBuilder.build(PageCachingReferenceTypeService.class, configuration);
105    }
106    
107    public static void contributePageCachingReferenceTypeService(
108            OrderedConfiguration<PageCachingReferenceTypeService> configuration)
109    {
110        configuration.add("Fallback", p -> ReferenceType.SOFT, "after:*");
111    }
112
113}