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 }