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.Order; 035import org.apache.tapestry5.ioc.annotations.Startup; 036import org.apache.tapestry5.ioc.annotations.Symbol; 037import org.apache.tapestry5.ioc.services.ChainBuilder; 038import org.apache.tapestry5.ioc.services.PerthreadManager; 039import org.apache.tapestry5.services.ComponentClassResolver; 040import org.apache.tapestry5.services.Core; 041import org.apache.tapestry5.services.pageload.ComponentRequestSelectorAnalyzer; 042import org.apache.tapestry5.services.pageload.ComponentResourceLocator; 043import org.apache.tapestry5.services.pageload.PageCachingReferenceTypeService; 044import org.apache.tapestry5.services.pageload.PageClassLoaderContextManager; 045import org.apache.tapestry5.services.pageload.PageClassLoaderContextManagerImpl; 046import org.apache.tapestry5.services.pageload.PagePreloader; 047import org.apache.tapestry5.services.pageload.PreloaderMode; 048import org.apache.tapestry5.services.pageload.ReferenceType; 049import org.apache.tapestry5.services.templates.ComponentTemplateLocator; 050import org.slf4j.LoggerFactory; 051 052/** 053 * @since 5.3 054 */ 055@SuppressWarnings("deprecation") 056@Marker(Core.class) 057public class PageLoadModule 058{ 059 060 /** 061 * Contributes factory defaults that may be overridden. 062 */ 063 public static void contributeFactoryDefaults(MappedConfiguration<String, Object> configuration) 064 { 065 configuration.add(SymbolConstants.MULTIPLE_CLASSLOADERS, false); 066 configuration.add(SymbolConstants.COMPONENT_DEPENDENCY_FILE, ComponentDependencyRegistry.FILENAME); 067 } 068 069 public static void bind(ServiceBinder binder) 070 { 071 binder.bind(ComponentRequestSelectorAnalyzer.class, DefaultComponentRequestSelectorAnalyzer.class); 072 binder.bind(ComponentResourceLocator.class, DefaultComponentResourceLocator.class); 073 binder.bind(ComponentTemplateSource.class, ComponentTemplateSourceImpl.class); 074 binder.bind(PagePreloader.class, PagePreloaderImpl.class); 075 binder.bind(PageClassLoaderContextManager.class, PageClassLoaderContextManagerImpl.class); 076 } 077 078 @Startup 079 public static void preloadPages(PagePreloader preloader, 080 @Symbol(SymbolConstants.PRELOADER_MODE) 081 PreloaderMode mode, 082 @Symbol(TapestryHttpSymbolConstants.PRODUCTION_MODE) 083 boolean productionMode) 084 { 085 if (mode.isEnabledFor(productionMode)) 086 { 087 preloader.preloadPages(); 088 } 089 } 090 091 @Startup 092 @Order("before:*") 093 public void preloadPageClassLoaderContexts( 094 PageClassLoaderContextManager pageClassLoaderContextManager, 095 ComponentDependencyRegistry componentDependencyRegistry, 096 @Symbol(SymbolConstants.PRODUCTION_MODE) boolean productionMode, 097 @Symbol(SymbolConstants.MULTIPLE_CLASSLOADERS) boolean multipleClassLoaders) 098 { 099 if (!productionMode && multipleClassLoaders) 100 { 101 // If we have component dependency information previously stored in 102 // a file, then we just preload the page classloader contexts. 103 // Otherwise, we gather component dependency information then 104 // preload the page classloader contexts. 105 if (componentDependencyRegistry.isStoredDependencyInformationPresent()) 106 { 107 pageClassLoaderContextManager.preloadContexts(); 108 } 109 else 110 { 111 LoggerFactory.getLogger(PageClassLoaderContextManager.class) 112 .warn("If the component dependency process is taking too long, " 113 + "consider writing its results to a file using the " 114 + " 'Store dependency information' button " 115 + "in the /t5dashboard/pages page."); 116 pageClassLoaderContextManager.preload(); 117 } 118 } 119 } 120 121 public static PageCachingReferenceTypeService buildPageCachingReferenceTypeService( 122 List<PageCachingReferenceTypeService> configuration, 123 ChainBuilder chainBuilder) 124 { 125 return chainBuilder.build(PageCachingReferenceTypeService.class, configuration); 126 } 127 128 public static void contributePageCachingReferenceTypeService( 129 OrderedConfiguration<PageCachingReferenceTypeService> configuration) 130 { 131 configuration.add("Fallback", p -> ReferenceType.SOFT, "after:*"); 132 } 133 134 public static ComponentDependencyRegistry buildComponentDependencyRegistry( 135 InternalComponentInvalidationEventHub internalComponentInvalidationEventHub, 136 ResourceChangeTracker resourceChangeTracker, 137 ComponentTemplateSource componentTemplateSource, 138 PageClassLoaderContextManager pageClassLoaderContextManager, 139 ComponentInstantiatorSource componentInstantiatorSource, 140 ComponentClassResolver componentClassResolver, 141 TemplateParser templateParser, 142 ComponentTemplateLocator componentTemplateLocator, 143 PerthreadManager perthreadManager, 144 @Symbol(SymbolConstants.COMPONENT_DEPENDENCY_FILE) String componentDependencyFile, 145 @Symbol(SymbolConstants.PRODUCTION_MODE) boolean productionMode) 146 { 147 ComponentDependencyRegistryImpl componentDependencyRegistry = 148 new ComponentDependencyRegistryImpl( 149 pageClassLoaderContextManager, 150 componentInstantiatorSource.getProxyFactory().getPlasticManager(), 151 componentClassResolver, 152 templateParser, 153 componentTemplateLocator, 154 componentDependencyFile, 155 productionMode); 156 componentDependencyRegistry.listen(internalComponentInvalidationEventHub); 157 componentDependencyRegistry.listen(resourceChangeTracker); 158 componentDependencyRegistry.listen(componentTemplateSource.getInvalidationEventHub()); 159 // TODO: remove 160 componentDependencyRegistry.setupThreadCleanup(perthreadManager); 161 return componentDependencyRegistry; 162 } 163 164}