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.ComponentDependencyRegistryImpl; 026import org.apache.tapestry5.internal.services.ComponentInstantiatorSource; 027import org.apache.tapestry5.internal.services.ComponentTemplateSource; 028import org.apache.tapestry5.internal.services.ComponentTemplateSourceImpl; 029import org.apache.tapestry5.internal.services.InternalComponentInvalidationEventHub; 030import org.apache.tapestry5.internal.services.TemplateParser; 031import org.apache.tapestry5.internal.services.assets.ResourceChangeTracker; 032import org.apache.tapestry5.ioc.ServiceBinder; 033import org.apache.tapestry5.ioc.annotations.Marker; 034import org.apache.tapestry5.ioc.annotations.Startup; 035import org.apache.tapestry5.ioc.annotations.Symbol; 036import org.apache.tapestry5.ioc.services.ChainBuilder; 037import org.apache.tapestry5.ioc.services.PerthreadManager; 038import org.apache.tapestry5.services.ComponentClassResolver; 039import org.apache.tapestry5.services.Core; 040import org.apache.tapestry5.services.pageload.ComponentRequestSelectorAnalyzer; 041import org.apache.tapestry5.services.pageload.ComponentResourceLocator; 042import org.apache.tapestry5.services.pageload.PageCachingReferenceTypeService; 043import org.apache.tapestry5.services.pageload.PageClassLoaderContextManager; 044import org.apache.tapestry5.services.pageload.PageClassLoaderContextManagerImpl; 045import org.apache.tapestry5.services.pageload.PagePreloader; 046import org.apache.tapestry5.services.pageload.PreloaderMode; 047import org.apache.tapestry5.services.pageload.ReferenceType; 048import org.apache.tapestry5.services.templates.ComponentTemplateLocator; 049 050/** 051 * @since 5.3 052 */ 053@SuppressWarnings("deprecation") 054@Marker(Core.class) 055public class PageLoadModule 056{ 057 058 /** 059 * Contributes factory defaults that may be overridden. 060 */ 061 public static void contributeFactoryDefaults(MappedConfiguration<String, Object> configuration) 062 { 063 configuration.add(SymbolConstants.MULTIPLE_CLASSLOADERS, false); 064 configuration.add(SymbolConstants.COMPONENT_DEPENDENCY_FILE, ComponentDependencyRegistry.FILENAME); 065 } 066 067 public static void bind(ServiceBinder binder) 068 { 069 binder.bind(ComponentRequestSelectorAnalyzer.class, DefaultComponentRequestSelectorAnalyzer.class); 070 binder.bind(ComponentResourceLocator.class, DefaultComponentResourceLocator.class); 071 binder.bind(ComponentTemplateSource.class, ComponentTemplateSourceImpl.class); 072 binder.bind(PagePreloader.class, PagePreloaderImpl.class); 073 binder.bind(PageClassLoaderContextManager.class, PageClassLoaderContextManagerImpl.class); 074 } 075 076 @Startup 077 public static void preloadPages(PagePreloader preloader, 078 @Symbol(SymbolConstants.PRELOADER_MODE) 079 PreloaderMode mode, 080 @Symbol(TapestryHttpSymbolConstants.PRODUCTION_MODE) 081 boolean productionMode) 082 { 083 if (mode.isEnabledFor(productionMode)) 084 { 085 preloader.preloadPages(); 086 } 087 } 088 089 @Startup 090 public void preloadPageClassLoaderContexts( 091 PageClassLoaderContextManager pageClassLoaderContextManager, 092 ComponentDependencyRegistry componentDependencyRegistry, 093 @Symbol(SymbolConstants.PRODUCTION_MODE) boolean productionMode, 094 @Symbol(SymbolConstants.MULTIPLE_CLASSLOADERS) boolean multipleClassLoaders) 095 { 096 if (!productionMode && multipleClassLoaders) 097 { 098 // Preload the page activation context tree for the already known classes 099 for (int i = 0; i < 5; i++) 100 { 101 for (String className : componentDependencyRegistry.getClassNames()) 102 { 103 pageClassLoaderContextManager.get(className); 104 } 105 } 106 } 107 } 108 109 public static PageCachingReferenceTypeService buildPageCachingReferenceTypeService( 110 List<PageCachingReferenceTypeService> configuration, 111 ChainBuilder chainBuilder) 112 { 113 return chainBuilder.build(PageCachingReferenceTypeService.class, configuration); 114 } 115 116 public static void contributePageCachingReferenceTypeService( 117 OrderedConfiguration<PageCachingReferenceTypeService> configuration) 118 { 119 configuration.add("Fallback", p -> ReferenceType.SOFT, "after:*"); 120 } 121 122 public static ComponentDependencyRegistry buildComponentDependencyRegistry( 123 InternalComponentInvalidationEventHub internalComponentInvalidationEventHub, 124 ResourceChangeTracker resourceChangeTracker, 125 ComponentTemplateSource componentTemplateSource, 126 PageClassLoaderContextManager pageClassLoaderContextManager, 127 ComponentInstantiatorSource componentInstantiatorSource, 128 ComponentClassResolver componentClassResolver, 129 TemplateParser templateParser, 130 ComponentTemplateLocator componentTemplateLocator, 131 PerthreadManager perthreadManager, 132 @Symbol(SymbolConstants.COMPONENT_DEPENDENCY_FILE) String componentDependencyFile, 133 @Symbol(SymbolConstants.PRODUCTION_MODE) boolean productionMode) 134 { 135 ComponentDependencyRegistryImpl componentDependencyRegistry = 136 new ComponentDependencyRegistryImpl( 137 pageClassLoaderContextManager, 138 componentInstantiatorSource.getProxyFactory().getPlasticManager(), 139 componentClassResolver, 140 templateParser, 141 componentTemplateLocator, 142 componentDependencyFile, 143 productionMode); 144 componentDependencyRegistry.listen(internalComponentInvalidationEventHub); 145 componentDependencyRegistry.listen(resourceChangeTracker); 146 componentDependencyRegistry.listen(componentTemplateSource.getInvalidationEventHub()); 147 // TODO: remove 148 componentDependencyRegistry.setupThreadCleanup(perthreadManager); 149 return componentDependencyRegistry; 150 } 151 152}