Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge InternalModule into TapestryModule.

Extend the Tapestry IoC Cookbook.

git-svn-id: https://svn.apache.org/repos/asf/tapestry/tapestry5/trunk@593411 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
commit 0a645346c03057ceeee340665e0abcc27e243b8d 1 parent 4ea6744
@hlship hlship authored
View
60 .classpath
@@ -1,33 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="src" output="bin" path="tapestry-annotations/src/main/java"/>
- <classpathentry kind="src" output="bin" path="tapestry-component-report/src/main/java"/>
- <classpathentry kind="src" output="bin" path="tapestry-core/src/main/java"/>
- <classpathentry kind="src" output="bin-test" path="tapestry-core/src/test/java"/>
- <classpathentry kind="lib" path="tapestry-core/src/main/resources"/>
- <classpathentry kind="lib" path="tapestry-core/src/test/resources"/>
- <classpathentry kind="src" output="bin" path="tapestry-hibernate/src/main/java"/>
- <classpathentry kind="src" output="bin-test" path="tapestry-hibernate/src/test/java"/>
- <classpathentry kind="lib" path="tapestry-hibernate/src/main/resources"/>
- <classpathentry kind="lib" path="tapestry-hibernate/src/test/resources"/>
- <classpathentry kind="src" output="bin" path="tapestry-ioc/src/main/java"/>
- <classpathentry kind="src" output="bin-test" path="tapestry-ioc/src/test/java"/>
- <classpathentry kind="lib" path="tapestry-ioc/src/main/resources"/>
- <classpathentry kind="lib" path="tapestry-ioc/src/test/resources"/>
- <classpathentry kind="src" output="bin" path="tapestry-spring/src/main/java"/>
- <classpathentry kind="src" output="bin-test" path="tapestry-spring/src/test/java"/>
- <classpathentry kind="lib" path="tapestry-spring/src/main/resources"/>
- <classpathentry kind="lib" path="tapestry-spring/src/test/resources"/>
- <classpathentry kind="src" output="bin" path="tapestry-test/src/main/java"/>
- <classpathentry kind="lib" path="tapestry-test/src/main/resources"/>
- <classpathentry kind="src" output="bin" path="tapestry-tutorial1/src/main/java"/>
- <classpathentry kind="src" output="bin-test" path="tapestry-tutorial1/src/test/java"/>
- <classpathentry kind="lib" path="tapestry-tutorial1/src/main/resources"/>
- <classpathentry kind="lib" path="tapestry-tutorial1/src/test/resources"/>
- <classpathentry kind="src" output="bin" path="tapestry-upload/src/main/java"/>
- <classpathentry kind="src" output="bin-test" path="tapestry-upload/src/test/java"/>
- <classpathentry kind="lib" path="tapestry-upload/src/main/resources"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER/noworkspace"/>
- <classpathentry kind="output" path="bin"/>
+ <classpathentry kind="src" output="bin" path="tapestry-annotations/src/main/java"/>
+ <classpathentry kind="src" output="bin" path="tapestry-component-report/src/main/java"/>
+ <classpathentry kind="src" output="bin" path="tapestry-core/src/main/java"/>
+ <classpathentry kind="src" output="bin-test" path="tapestry-core/src/test/java"/>
+ <classpathentry kind="lib" path="tapestry-core/src/main/resources"/>
+ <classpathentry kind="lib" path="tapestry-core/src/test/resources"/>
+ <classpathentry kind="src" output="bin" path="tapestry-hibernate/src/main/java"/>
+ <classpathentry kind="src" output="bin-test" path="tapestry-hibernate/src/test/java"/>
+ <classpathentry kind="lib" path="tapestry-hibernate/src/main/resources"/>
+ <classpathentry kind="lib" path="tapestry-hibernate/src/test/resources"/>
+ <classpathentry kind="src" output="bin" path="tapestry-ioc/src/main/java"/>
+ <classpathentry kind="src" output="bin-test" path="tapestry-ioc/src/test/java"/>
+ <classpathentry kind="lib" path="tapestry-ioc/src/main/resources"/>
+ <classpathentry kind="lib" path="tapestry-ioc/src/test/resources"/>
+ <classpathentry kind="src" output="bin" path="tapestry-spring/src/main/java"/>
+ <classpathentry kind="src" output="bin-test" path="tapestry-spring/src/test/java"/>
+ <classpathentry kind="lib" path="tapestry-spring/src/main/resources"/>
+ <classpathentry kind="lib" path="tapestry-spring/src/test/resources"/>
+ <classpathentry kind="src" output="bin" path="tapestry-test/src/main/java"/>
+ <classpathentry kind="lib" path="tapestry-test/src/main/resources"/>
+ <classpathentry kind="src" output="bin" path="tapestry-tutorial1/src/main/java"/>
+ <classpathentry kind="src" output="bin-test" path="tapestry-tutorial1/src/test/java"/>
+ <classpathentry kind="lib" path="tapestry-tutorial1/src/main/resources"/>
+ <classpathentry kind="lib" path="tapestry-tutorial1/src/test/resources"/>
+ <classpathentry kind="src" output="bin" path="tapestry-upload/src/main/java"/>
+ <classpathentry kind="src" output="bin-test" path="tapestry-upload/src/test/java"/>
+ <classpathentry kind="lib" path="tapestry-upload/src/main/resources"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER/modules/noworkspace"/>
+ <classpathentry kind="output" path="bin"/>
</classpath>
View
41 .project
@@ -1,22 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
- <name>datatech</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.maven.ide.eclipse.maven2Builder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.jdt.core.javanature</nature>
- <nature>org.maven.ide.eclipse.maven2Nature</nature>
- </natures>
+ <name>tapestry5</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.maven.ide.eclipse.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.maven.ide.eclipse.maven2Nature</nature>
+ </natures>
</projectDescription>
View
2  src/site/apt/index.apt
@@ -102,6 +102,8 @@ What's changed since Tapestry 4?
New and Noteworthy
+ * An {{{tapestry-ioc/overview.html}overview}} and {{{tapestry-ioc/cookbook/}cookbook}} for Tapestry IoC has been written.
+
* The nightly build on the {{{http://tapestry.formos.com/bamboo}Bamboo CI server}} now creates
{{{http://tapestry.formos.com/nightly/tapestry5/}full documentation}}.
View
3  tapestry-core/src/main/java/org/apache/tapestry/internal/services/InjectWorker.java
@@ -35,8 +35,7 @@
private final InjectionProvider _injectionProvider;
- public InjectWorker(final ObjectLocator locator,
- final InjectionProvider injectionProvider)
+ public InjectWorker(ObjectLocator locator, InjectionProvider injectionProvider)
{
_locator = locator;
_injectionProvider = injectionProvider;
View
574 tapestry-core/src/main/java/org/apache/tapestry/internal/services/InternalModule.java
@@ -1,574 +0,0 @@
-// Copyright 2006, 2007 The Apache Software Foundation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package org.apache.tapestry.internal.services;
-
-import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
-import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newCaseInsensitiveMap;
-
-import java.net.URL;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.servlet.http.Cookie;
-
-import org.apache.tapestry.Binding;
-import org.apache.tapestry.ComponentResources;
-import org.apache.tapestry.internal.bindings.LiteralBinding;
-import org.apache.tapestry.internal.bindings.PropBindingFactory;
-import org.apache.tapestry.internal.events.InvalidationListener;
-import org.apache.tapestry.internal.util.IntegerRange;
-import org.apache.tapestry.ioc.Location;
-import org.apache.tapestry.ioc.MappedConfiguration;
-import org.apache.tapestry.ioc.ObjectProvider;
-import org.apache.tapestry.ioc.OrderedConfiguration;
-import org.apache.tapestry.ioc.ServiceBinder;
-import org.apache.tapestry.ioc.ServiceResources;
-import org.apache.tapestry.ioc.annotations.Marker;
-import org.apache.tapestry.ioc.annotations.Scope;
-import org.apache.tapestry.ioc.annotations.Symbol;
-import org.apache.tapestry.ioc.services.Builtin;
-import org.apache.tapestry.ioc.services.ChainBuilder;
-import org.apache.tapestry.ioc.services.ClassFactory;
-import org.apache.tapestry.ioc.services.PropertyAccess;
-import org.apache.tapestry.ioc.services.ThreadCleanupHub;
-import org.apache.tapestry.ioc.services.ThreadLocale;
-import org.apache.tapestry.ioc.services.TypeCoercer;
-import org.apache.tapestry.services.ActionResponseGenerator;
-import org.apache.tapestry.services.ApplicationGlobals;
-import org.apache.tapestry.services.ApplicationInitializer;
-import org.apache.tapestry.services.ApplicationInitializerFilter;
-import org.apache.tapestry.services.AssetFactory;
-import org.apache.tapestry.services.BindingFactory;
-import org.apache.tapestry.services.ClasspathAssetAliasManager;
-import org.apache.tapestry.services.ClasspathProvider;
-import org.apache.tapestry.services.ComponentActionRequestFilter;
-import org.apache.tapestry.services.ComponentActionRequestHandler;
-import org.apache.tapestry.services.ComponentClassResolver;
-import org.apache.tapestry.services.ComponentMessagesSource;
-import org.apache.tapestry.services.Context;
-import org.apache.tapestry.services.ContextProvider;
-import org.apache.tapestry.services.ObjectRenderer;
-import org.apache.tapestry.services.PersistentFieldStrategy;
-import org.apache.tapestry.services.PropertyConduitSource;
-import org.apache.tapestry.services.Request;
-import org.apache.tapestry.services.RequestExceptionHandler;
-import org.apache.tapestry.services.RequestFilter;
-import org.apache.tapestry.services.RequestGlobals;
-import org.apache.tapestry.services.ResourceDigestGenerator;
-import org.apache.tapestry.services.TapestryModule;
-import org.slf4j.Logger;
-
-@Marker(Builtin.class)
-public final class InternalModule
-{
- public static void bind(ServiceBinder binder)
- {
- binder.bind(TemplateParser.class, TemplateParserImpl.class);
- binder.bind(PageResponseRenderer.class, PageResponseRendererImpl.class);
- binder.bind(PageMarkupRenderer.class, PageMarkupRendererImpl.class);
- binder.bind(ComponentInvocationMap.class, NoOpComponentInvocationMap.class);
- binder.bind(ObjectRenderer.class, LocationRenderer.class).withId("LocationRenderer");
- binder.bind(UpdateListenerHub.class, UpdateListenerHubImpl.class);
- binder.bind(ObjectProvider.class, AssetObjectProvider.class).withId("AssetObjectProvider");
- binder.bind(LinkFactory.class, LinkFactoryImpl.class);
- binder.bind(LocalizationSetter.class, LocalizationSetterImpl.class);
- binder.bind(PageElementFactory.class, PageElementFactoryImpl.class);
- binder.bind(ClassNameLocator.class, ClassNameLocatorImpl.class);
- binder.bind(RequestExceptionHandler.class, DefaultRequestExceptionHandler.class);
- binder.bind(ResourceStreamer.class, ResourceStreamerImpl.class);
- binder.bind(ClientPersistentFieldStorage.class, ClientPersistentFieldStorageImpl.class);
- binder.bind(RequestEncodingInitializer.class, RequestEncodingInitializerImpl.class);
- }
-
- public static void contributeTemplateParser(MappedConfiguration<String, URL> config)
- {
- Class c = InternalModule.class;
- config.add("-//W3C//DTD XHTML 1.0 Strict//EN", c.getResource("xhtml1-strict.dtd"));
- config.add("-//W3C//DTD XHTML 1.0 Transitional//EN", c
- .getResource("xhtml1-transitional.dtd"));
- config.add("-//W3C//DTD XHTML 1.0 Frameset//EN", c.getResource("xhtml1-frameset.dtd"));
- config.add("-//W3C//DTD HTML 4.01//EN", c.getResource("xhtml1-strict.dtd"));
- config.add("-//W3C//DTD HTML 4.01 Transitional//EN", c
- .getResource("xhtml1-transitional.dtd"));
- config.add("-//W3C//DTD HTML 4.01 Frameset//EN", c.getResource("xhtml1-frameset.dtd"));
- config.add("-//W3C//ENTITIES Latin 1 for XHTML//EN", c.getResource("xhtml-lat1.ent"));
- config.add("-//W3C//ENTITIES Symbols for XHTML//EN", c.getResource("xhtml-symbol.ent"));
- config.add("-//W3C//ENTITIES Special for XHTML//EN", c.getResource("xhtml-special.ent"));
- }
-
- /**
- * Contributes factory defaults that map be overridden.
- *
- * @see TapestryModule#contributeClasspathAssetAliasManager(MappedConfiguration, String, String)
- */
- public static void contributeFactoryDefaults(MappedConfiguration<String, String> configuration)
- {
- // Remember this is request-to-request time, presumably it'll take the developer more than
- // one second to make a change, save it, and switch back to the browser.
-
- configuration.add("tapestry.file-check-interval", "1000"); // 1 second
- configuration.add("tapestry.file-check-update-timeout", "50"); // 50 milliseconds
-
- // This should be overridden for particular applications.
- configuration.add("tapestry.supported-locales", "en");
-
- configuration.add("tapestry.default-cookie-max-age", "604800"); // One week
-
- configuration.add("tapestry.start-page-name", "start");
-
- // This is designed to make it easy to keep synchronized with script.aculo.ous. As we
- // support a new version, we create a new folder, and update the path entry. We can then
- // delete the old version folder (or keep it around). This should be more manageable than
- // overwriting the local copy with updates. There's also a ClasspathAliasManager
- // contribution based on the path.
-
- configuration.add("tapestry.scriptaculous", "classpath:${tapestry.scriptaculous.path}");
- configuration.add(
- "tapestry.scriptaculous.path",
- "org/apache/tapestry/scriptaculous_1_7_1_beta_3");
-
- // Likewise for jscalendar, currently version 1.0
-
- configuration.add("tapestry.jscalendar.path", "org/apache/tapestry/jscalendar-1.0");
- configuration.add("tapestry.jscalendar", "classpath:${tapestry.jscalendar.path}");
- }
-
- private final ComponentInstantiatorSource _componentInstantiatorSource;
-
- private final ComponentTemplateSource _componentTemplateSource;
-
- private final UpdateListenerHub _updateListenerHub;
-
- private final ThreadCleanupHub _threadCleanupHub;
-
- private final ChainBuilder _chainBuilder;
-
- private final Request _request;
-
- private final ThreadLocale _threadLocale;
-
- private final RequestGlobals _requestGlobals;
-
- public InternalModule(ComponentInstantiatorSource componentInstantiatorSource,
- UpdateListenerHub updateListenerHub, ThreadCleanupHub threadCleanupHub,
- ComponentTemplateSource componentTemplateSource, ChainBuilder chainBuilder,
- Request request, ThreadLocale threadLocale, RequestGlobals requestGlobals)
- {
- _componentInstantiatorSource = componentInstantiatorSource;
- _updateListenerHub = updateListenerHub;
- _threadCleanupHub = threadCleanupHub;
- _componentTemplateSource = componentTemplateSource;
- _chainBuilder = chainBuilder;
- _request = request;
- _threadLocale = threadLocale;
- _requestGlobals = requestGlobals;
- }
-
- public PageTemplateLocator build(@ContextProvider
- AssetFactory contextAssetFactory,
-
- ComponentClassResolver componentClassResolver)
- {
- return new PageTemplateLocatorImpl(contextAssetFactory.getRootResource(),
- componentClassResolver);
- }
-
- public ComponentInstantiatorSource build(@Builtin
- ClassFactory classFactory,
-
- ComponentClassTransformer transformer,
-
- Logger logger)
- {
- ComponentInstantiatorSourceImpl source = new ComponentInstantiatorSourceImpl(classFactory
- .getClassLoader(), transformer, logger);
-
- _updateListenerHub.addUpdateListener(source);
-
- return source;
- }
-
- public ComponentClassTransformer buildComponentClassTransformer(ServiceResources resources)
- {
- ComponentClassTransformerImpl transformer = resources
- .autobuild(ComponentClassTransformerImpl.class);
-
- _componentInstantiatorSource.addInvalidationListener(transformer);
-
- return transformer;
- }
-
- public PagePool build(Logger logger, PageLoader pageLoader,
- ComponentMessagesSource componentMessagesSource, ComponentClassResolver resolver)
- {
- PagePoolImpl service = new PagePoolImpl(logger, pageLoader, _threadLocale, resolver);
-
- // This covers invalidations due to changes to classes
-
- pageLoader.addInvalidationListener(service);
-
- // This covers invalidation due to changes to message catalogs (properties files)
-
- componentMessagesSource.addInvalidationListener(service);
-
- // ... and this covers invalidations due to changes to templates
-
- _componentTemplateSource.addInvalidationListener(service);
-
- return service;
- }
-
- public PageLoader buildPageLoader(ServiceResources resources)
- {
- PageLoaderImpl service = resources.autobuild(PageLoaderImpl.class);
-
- // Recieve invalidations when the class loader is discarded (due to a component class
- // change). The notification is forwarded to the page loader's listeners.
-
- _componentInstantiatorSource.addInvalidationListener(service);
-
- return service;
- }
-
- @Scope(PERTHREAD_SCOPE)
- public RequestPageCache build(PagePool pagePool)
- {
- RequestPageCacheImpl service = new RequestPageCacheImpl(pagePool);
-
- _threadCleanupHub.addThreadCleanupListener(service);
-
- return service;
- }
-
- public ResourceCache build(ResourceDigestGenerator digestGenerator)
- {
- ResourceCacheImpl service = new ResourceCacheImpl(digestGenerator);
-
- _updateListenerHub.addUpdateListener(service);
-
- return service;
- }
-
- public ComponentTemplateSource build(TemplateParser parser, PageTemplateLocator locator)
- {
- ComponentTemplateSourceImpl service = new ComponentTemplateSourceImpl(parser, locator);
-
- _updateListenerHub.addUpdateListener(service);
-
- return service;
- }
-
- @Marker(ClasspathProvider.class)
- public AssetFactory buildClasspathAssetFactory(ResourceCache resourceCache,
-
- ClasspathAssetAliasManager aliasManager)
- {
- ClasspathAssetFactory factory = new ClasspathAssetFactory(resourceCache, aliasManager);
-
- resourceCache.addInvalidationListener(factory);
-
- return factory;
- }
-
- @Marker(ContextProvider.class)
- public AssetFactory buildContextAssetFactory(ApplicationGlobals globals)
- {
- return new ContextAssetFactory(_request, globals.getContext());
- }
-
- public CookieSink buildCookieSink()
- {
- return new CookieSink()
- {
-
- public void addCookie(Cookie cookie)
- {
- _requestGlobals.getHTTPServletResponse().addCookie(cookie);
- }
-
- };
- }
-
- public CookieSource buildCookieSource()
- {
- return new CookieSource()
- {
-
- public Cookie[] getCookies()
- {
- return _requestGlobals.getHTTPServletRequest().getCookies();
- }
-
- };
- }
-
- /**
- * Builds the PropBindingFactory as a chain of command. The terminator of the chain is
- * responsible for ordinary property names (and property paths). Contributions to the service
- * cover additional special cases, such as simple literal values.
- *
- * @param configuration
- * contributions of special factories for some constants, each contributed factory
- * may return a binding if applicable, or null otherwise
- */
- public BindingFactory buildPropBindingFactory(List<BindingFactory> configuration,
- PropertyConduitSource propertyConduitSource)
- {
- PropBindingFactory service = new PropBindingFactory(propertyConduitSource);
-
- configuration.add(service);
-
- return _chainBuilder.build(BindingFactory.class, configuration);
- }
-
- /**
- * Adds content types for "css" and "js" file extensions.
- */
- public void contributeResourceStreamer(MappedConfiguration<String, String> configuration)
- {
- configuration.add("css", "text/css");
- configuration.add("js", "text/javascript");
- }
-
- /**
- * Adds a filter that sets the application package (for class loading purposes). The filter is
- * ordered before:*.*".
- */
- public void contributeApplicationInitializer(
- OrderedConfiguration<ApplicationInitializerFilter> configuration,
- final ApplicationGlobals applicationGlobals, final PropertyAccess propertyAccess,
- final TypeCoercer typeCoercer)
- {
- final InvalidationListener listener = new InvalidationListener()
- {
- public void objectWasInvalidated()
- {
- propertyAccess.clearCache();
- typeCoercer.clearCache();
- }
- };
-
- ApplicationInitializerFilter clearCaches = new ApplicationInitializerFilter()
- {
- public void initializeApplication(Context context, ApplicationInitializer initializer)
- {
- // Snuck in here is the logic to clear the PropertyAccess service's cache whenever
- // the component class loader is invalidated.
-
- _componentInstantiatorSource.addInvalidationListener(listener);
-
- initializer.initializeApplication(context);
- }
- };
-
- configuration.add("ClearCachesOnInvalidation", clearCaches);
- }
-
- public void contributePropBindingFactory(OrderedConfiguration<BindingFactory> configuration)
- {
- BindingFactory keywordFactory = new BindingFactory()
- {
- private final Map<String, Object> _keywords = newCaseInsensitiveMap();
-
- {
- _keywords.put("true", Boolean.TRUE);
- _keywords.put("false", Boolean.FALSE);
- _keywords.put("null", null);
- }
-
- public Binding newBinding(String description, ComponentResources container,
- ComponentResources component, String expression, Location location)
- {
- String key = expression.trim();
-
- if (_keywords.containsKey(key))
- return new LiteralBinding(description, _keywords.get(key), location);
-
- return null;
- }
- };
-
- BindingFactory thisFactory = new BindingFactory()
- {
-
- public Binding newBinding(String description, ComponentResources container,
- ComponentResources component, String expression, Location location)
- {
- if ("this".equalsIgnoreCase(expression.trim()))
- return new LiteralBinding(description, container.getComponent(), location);
-
- return null;
- }
- };
-
- BindingFactory longFactory = new BindingFactory()
- {
- private final Pattern _pattern = Pattern.compile("^\\s*(-?\\d+)\\s*$");
-
- public Binding newBinding(String description, ComponentResources container,
- ComponentResources component, String expression, Location location)
- {
- Matcher matcher = _pattern.matcher(expression);
-
- if (matcher.matches())
- {
- String value = matcher.group(1);
-
- return new LiteralBinding(description, new Long(value), location);
- }
-
- return null;
- }
- };
-
- BindingFactory intRangeFactory = new BindingFactory()
- {
- private final Pattern _pattern = Pattern
- .compile("^\\s*(-?\\d+)\\s*\\.\\.\\s*(-?\\d+)\\s*$");
-
- public Binding newBinding(String description, ComponentResources container,
- ComponentResources component, String expression, Location location)
- {
- Matcher matcher = _pattern.matcher(expression);
-
- if (matcher.matches())
- {
- int start = Integer.parseInt(matcher.group(1));
- int finish = Integer.parseInt(matcher.group(2));
-
- IntegerRange range = new IntegerRange(start, finish);
-
- return new LiteralBinding(description, range, location);
- }
-
- return null;
- }
- };
-
- BindingFactory doubleFactory = new BindingFactory()
- {
- // So, either 1234. or 1234.56 or .78
- private final Pattern _pattern = Pattern
- .compile("^\\s*(\\-?((\\d+\\.)|(\\d*\\.\\d+)))\\s*$");
-
- public Binding newBinding(String description, ComponentResources container,
- ComponentResources component, String expression, Location location)
- {
- Matcher matcher = _pattern.matcher(expression);
-
- if (matcher.matches())
- {
- String value = matcher.group(1);
-
- return new LiteralBinding(description, new Double(value), location);
- }
-
- return null;
- }
- };
-
- BindingFactory stringFactory = new BindingFactory()
- {
- // This will match embedded single quotes as-is, no escaping necessary.
-
- private final Pattern _pattern = Pattern.compile("^\\s*'(.*)'\\s*$");
-
- public Binding newBinding(String description, ComponentResources container,
- ComponentResources component, String expression, Location location)
- {
- Matcher matcher = _pattern.matcher(expression);
-
- if (matcher.matches())
- {
- String value = matcher.group(1);
-
- return new LiteralBinding(description, value, location);
- }
-
- return null;
- }
- };
-
- // To be honest, order probably doesn't matter.
-
- configuration.add("Keyword", keywordFactory);
- configuration.add("This", thisFactory);
- configuration.add("Long", longFactory);
- configuration.add("IntRange", intRangeFactory);
- configuration.add("Double", doubleFactory);
- configuration.add("StringLiteral", stringFactory);
- }
-
- /**
- * Adds a filter that checks for updates to classes and other resources. It is ordered before:*.
- */
- public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration,
- RequestGlobals requestGlobals,
-
- // @Inject not needed because its a long, not a String
- @Symbol("tapestry.file-check-interval")
- long checkInterval,
-
- @Symbol("tapestry.file-check-update-timeout")
- long updateTimeout,
-
- LocalizationSetter localizationSetter)
- {
- configuration.add("CheckForUpdates", new CheckForUpdatesFilter(_updateListenerHub,
- checkInterval, updateTimeout), "before:*");
-
- configuration.add("Localization", new LocalizationFilter(localizationSetter));
- }
-
- public PersistentFieldStrategy buildClientPersistentFieldStrategy(LinkFactory linkFactory,
- ServiceResources resources)
- {
- ClientPersistentFieldStrategy service = resources
- .autobuild(ClientPersistentFieldStrategy.class);
-
- linkFactory.addListener(service);
-
- return service;
- }
-
- public static void contributeComponentActionRequestHandler(
- OrderedConfiguration<ComponentActionRequestFilter> configuration,
- final RequestEncodingInitializer encodingInitializer)
- {
- ComponentActionRequestFilter filter = new ComponentActionRequestFilter()
- {
- public ActionResponseGenerator handle(String logicalPageName, String nestedComponentId,
- String eventType, String[] context, String[] activationContext,
- ComponentActionRequestHandler handler)
- {
- encodingInitializer.initializeRequestEncoding(logicalPageName);
-
- return handler.handle(
- logicalPageName,
- nestedComponentId,
- eventType,
- context,
- activationContext);
- }
-
- };
-
- configuration.add("SetRequestEncoding", filter, "before:*");
-
- configuration.add("Ajax", new AjaxFilter());
- }
-}
View
612 tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
@@ -14,21 +14,28 @@
package org.apache.tapestry.services;
+import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newCaseInsensitiveMap;
+
import java.io.IOException;
import java.lang.annotation.Annotation;
+import java.net.URL;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletContext;
+import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.tapestry.Asset;
+import org.apache.tapestry.Binding;
import org.apache.tapestry.ComponentResources;
import org.apache.tapestry.Link;
import org.apache.tapestry.MarkupWriter;
@@ -63,103 +70,17 @@
import org.apache.tapestry.internal.bindings.AssetBindingFactory;
import org.apache.tapestry.internal.bindings.BlockBindingFactory;
import org.apache.tapestry.internal.bindings.ComponentBindingFactory;
+import org.apache.tapestry.internal.bindings.LiteralBinding;
import org.apache.tapestry.internal.bindings.LiteralBindingFactory;
import org.apache.tapestry.internal.bindings.MessageBindingFactory;
+import org.apache.tapestry.internal.bindings.PropBindingFactory;
import org.apache.tapestry.internal.bindings.TranslateBindingFactory;
import org.apache.tapestry.internal.bindings.ValidateBindingFactory;
+import org.apache.tapestry.internal.events.InvalidationListener;
import org.apache.tapestry.internal.grid.ListGridDataSource;
import org.apache.tapestry.internal.grid.NullDataSource;
-import org.apache.tapestry.internal.services.AliasImpl;
-import org.apache.tapestry.internal.services.AliasManagerImpl;
-import org.apache.tapestry.internal.services.ApplicationGlobalsImpl;
-import org.apache.tapestry.internal.services.ApplicationStateManagerImpl;
-import org.apache.tapestry.internal.services.ApplicationStatePersistenceStrategySourceImpl;
-import org.apache.tapestry.internal.services.ApplicationStateWorker;
-import org.apache.tapestry.internal.services.AssetDispatcher;
-import org.apache.tapestry.internal.services.AssetInjectionProvider;
-import org.apache.tapestry.internal.services.AssetSourceImpl;
-import org.apache.tapestry.internal.services.BeanBlockSourceImpl;
-import org.apache.tapestry.internal.services.BeanModelSourceImpl;
-import org.apache.tapestry.internal.services.BindingSourceImpl;
-import org.apache.tapestry.internal.services.BlockInjectionProvider;
-import org.apache.tapestry.internal.services.ClassResultProcessor;
-import org.apache.tapestry.internal.services.ClasspathAssetAliasManagerImpl;
-import org.apache.tapestry.internal.services.CommonResourcesInjectionProvider;
-import org.apache.tapestry.internal.services.ComponentActionDispatcher;
-import org.apache.tapestry.internal.services.ComponentActionRequestHandlerImpl;
-import org.apache.tapestry.internal.services.ComponentClassResolverImpl;
-import org.apache.tapestry.internal.services.ComponentDefaultProviderImpl;
-import org.apache.tapestry.internal.services.ComponentInstanceResultProcessor;
-import org.apache.tapestry.internal.services.ComponentInstantiatorSource;
-import org.apache.tapestry.internal.services.ComponentLifecycleMethodWorker;
-import org.apache.tapestry.internal.services.ComponentMessagesSourceImpl;
-import org.apache.tapestry.internal.services.ComponentResourcesInjectionProvider;
-import org.apache.tapestry.internal.services.ComponentSourceImpl;
-import org.apache.tapestry.internal.services.ComponentWorker;
-import org.apache.tapestry.internal.services.ContextImpl;
-import org.apache.tapestry.internal.services.CookiesImpl;
-import org.apache.tapestry.internal.services.DefaultDataTypeAnalyzer;
-import org.apache.tapestry.internal.services.DefaultInjectionProvider;
-import org.apache.tapestry.internal.services.DefaultValidationDelegateCommand;
-import org.apache.tapestry.internal.services.DocumentHeadBuilder;
-import org.apache.tapestry.internal.services.DocumentHeadBuilderImpl;
-import org.apache.tapestry.internal.services.EnumValueEncoderFactory;
-import org.apache.tapestry.internal.services.EnvironmentImpl;
-import org.apache.tapestry.internal.services.EnvironmentalShadowBuilderImpl;
-import org.apache.tapestry.internal.services.EnvironmentalWorker;
-import org.apache.tapestry.internal.services.FieldValidatorDefaultSourceImpl;
-import org.apache.tapestry.internal.services.FieldValidatorSourceImpl;
-import org.apache.tapestry.internal.services.FlashPersistentFieldStrategy;
-import org.apache.tapestry.internal.services.GenericValueEncoderFactory;
-import org.apache.tapestry.internal.services.HeartbeatImpl;
-import org.apache.tapestry.internal.services.InjectContainerWorker;
-import org.apache.tapestry.internal.services.InjectPageWorker;
-import org.apache.tapestry.internal.services.InjectWorker;
-import org.apache.tapestry.internal.services.InternalModule;
-import org.apache.tapestry.internal.services.LinkActionResponseGenerator;
-import org.apache.tapestry.internal.services.LinkFactory;
-import org.apache.tapestry.internal.services.MarkupWriterFactoryImpl;
-import org.apache.tapestry.internal.services.MetaDataLocatorImpl;
-import org.apache.tapestry.internal.services.MetaWorker;
-import org.apache.tapestry.internal.services.MixinAfterWorker;
-import org.apache.tapestry.internal.services.MixinWorker;
-import org.apache.tapestry.internal.services.ObjectComponentEventResultProcessor;
-import org.apache.tapestry.internal.services.OnEventWorker;
-import org.apache.tapestry.internal.services.PageLifecycleAnnotationWorker;
-import org.apache.tapestry.internal.services.PageRenderDispatcher;
-import org.apache.tapestry.internal.services.PageRenderRequestHandlerImpl;
-import org.apache.tapestry.internal.services.PageRenderSupportImpl;
-import org.apache.tapestry.internal.services.ParameterWorker;
-import org.apache.tapestry.internal.services.PersistWorker;
-import org.apache.tapestry.internal.services.PersistentFieldManagerImpl;
-import org.apache.tapestry.internal.services.PropertyConduitSourceImpl;
-import org.apache.tapestry.internal.services.RenderCommandWorker;
-import org.apache.tapestry.internal.services.RequestGlobalsImpl;
-import org.apache.tapestry.internal.services.RequestImpl;
-import org.apache.tapestry.internal.services.RequestPageCache;
-import org.apache.tapestry.internal.services.RequestRenderer;
-import org.apache.tapestry.internal.services.ResourceCache;
-import org.apache.tapestry.internal.services.ResourceDigestGeneratorImpl;
-import org.apache.tapestry.internal.services.ResourceStreamer;
-import org.apache.tapestry.internal.services.ResponseImpl;
-import org.apache.tapestry.internal.services.RetainWorker;
-import org.apache.tapestry.internal.services.RootPathDispatcher;
-import org.apache.tapestry.internal.services.ServiceAnnotationObjectProvider;
-import org.apache.tapestry.internal.services.ServiceInjectionProvider;
-import org.apache.tapestry.internal.services.SessionApplicationStatePersistenceStrategy;
-import org.apache.tapestry.internal.services.SessionPersistentFieldStrategy;
-import org.apache.tapestry.internal.services.StaticFilesFilter;
-import org.apache.tapestry.internal.services.StreamResponseResultProcessor;
-import org.apache.tapestry.internal.services.StringResultProcessor;
-import org.apache.tapestry.internal.services.StringValueEncoder;
-import org.apache.tapestry.internal.services.SupportsInformalParametersWorker;
-import org.apache.tapestry.internal.services.TranslatorDefaultSourceImpl;
-import org.apache.tapestry.internal.services.TranslatorSourceImpl;
-import org.apache.tapestry.internal.services.UnclaimedFieldWorker;
-import org.apache.tapestry.internal.services.UpdateListenerHub;
-import org.apache.tapestry.internal.services.ValidationConstraintGeneratorImpl;
-import org.apache.tapestry.internal.services.ValidationMessagesSourceImpl;
-import org.apache.tapestry.internal.services.ValueEncoderSourceImpl;
+import org.apache.tapestry.internal.services.*;
+import org.apache.tapestry.internal.util.IntegerRange;
import org.apache.tapestry.ioc.AnnotationProvider;
import org.apache.tapestry.ioc.Configuration;
import org.apache.tapestry.ioc.Location;
@@ -174,7 +95,7 @@
import org.apache.tapestry.ioc.annotations.InjectService;
import org.apache.tapestry.ioc.annotations.Marker;
import org.apache.tapestry.ioc.annotations.Primary;
-import org.apache.tapestry.ioc.annotations.SubModule;
+import org.apache.tapestry.ioc.annotations.Scope;
import org.apache.tapestry.ioc.annotations.Symbol;
import org.apache.tapestry.ioc.annotations.Value;
import org.apache.tapestry.ioc.internal.util.InternalUtils;
@@ -188,6 +109,7 @@
import org.apache.tapestry.ioc.services.PropertyShadowBuilder;
import org.apache.tapestry.ioc.services.StrategyBuilder;
import org.apache.tapestry.ioc.services.SymbolSource;
+import org.apache.tapestry.ioc.services.ThreadCleanupHub;
import org.apache.tapestry.ioc.services.ThreadLocale;
import org.apache.tapestry.ioc.services.TypeCoercer;
import org.apache.tapestry.ioc.util.StrategyRegistry;
@@ -210,7 +132,6 @@
/**
* The root module for Tapestry.
*/
-@SubModule(InternalModule.class)
@Marker(Builtin.class)
public final class TapestryModule
{
@@ -240,6 +161,23 @@ public static void bind(ServiceBinder binder)
binder.bind(BeanBlockSource.class, BeanBlockSourceImpl.class);
binder.bind(ComponentDefaultProvider.class, ComponentDefaultProviderImpl.class);
binder.bind(MarkupWriterFactory.class, MarkupWriterFactoryImpl.class);
+
+ binder.bind(TemplateParser.class, TemplateParserImpl.class);
+ binder.bind(PageResponseRenderer.class, PageResponseRendererImpl.class);
+ binder.bind(PageMarkupRenderer.class, PageMarkupRendererImpl.class);
+ binder.bind(ComponentInvocationMap.class, NoOpComponentInvocationMap.class);
+ binder.bind(ObjectRenderer.class, LocationRenderer.class).withId("LocationRenderer");
+ binder.bind(UpdateListenerHub.class, UpdateListenerHubImpl.class);
+ binder.bind(ObjectProvider.class, AssetObjectProvider.class).withId("AssetObjectProvider");
+ binder.bind(LinkFactory.class, LinkFactoryImpl.class);
+ binder.bind(LocalizationSetter.class, LocalizationSetterImpl.class);
+ binder.bind(PageElementFactory.class, PageElementFactoryImpl.class);
+ binder.bind(ClassNameLocator.class, ClassNameLocatorImpl.class);
+ binder.bind(RequestExceptionHandler.class, DefaultRequestExceptionHandler.class);
+ binder.bind(ResourceStreamer.class, ResourceStreamerImpl.class);
+ binder.bind(ClientPersistentFieldStorage.class, ClientPersistentFieldStorageImpl.class);
+ binder.bind(RequestEncodingInitializer.class, RequestEncodingInitializerImpl.class);
+
}
public static Alias build(Logger logger,
@@ -884,12 +822,8 @@ private static void add(OrderedConfiguration<ComponentClassTransformWorker> conf
reverse));
}
- private final ChainBuilder _chainBuilder;
-
private final PipelineBuilder _pipelineBuilder;
- private final RequestGlobals _requestGlobals;
-
private final ApplicationGlobals _applicationGlobals;
private final PropertyShadowBuilder _shadowBuilder;
@@ -900,14 +834,28 @@ private static void add(OrderedConfiguration<ComponentClassTransformWorker> conf
private final StrategyBuilder _strategyBuilder;
- private final ComponentInstantiatorSource _componentInstantiatorSource;
-
private final LinkFactory _linkFactory;
private final PropertyAccess _propertyAccess;
private final ClassFactory _componentClassFactory;
+ private final ComponentInstantiatorSource _componentInstantiatorSource;
+
+ private final ComponentTemplateSource _componentTemplateSource;
+
+ private final UpdateListenerHub _updateListenerHub;
+
+ private final ThreadCleanupHub _threadCleanupHub;
+
+ private final ChainBuilder _chainBuilder;
+
+ private final Request _request;
+
+ private final ThreadLocale _threadLocale;
+
+ private final RequestGlobals _requestGlobals;
+
public TapestryModule(PipelineBuilder pipelineBuilder,
PropertyShadowBuilder shadowBuilder,
@@ -931,7 +879,15 @@ public TapestryModule(PipelineBuilder pipelineBuilder,
PropertyAccess propertyAccess,
@ComponentLayer
- ClassFactory componentClassFactory)
+ ClassFactory componentClassFactory,
+
+ UpdateListenerHub updateListenerHub, ThreadCleanupHub threadCleanupHub,
+
+ ComponentTemplateSource componentTemplateSource,
+
+ Request request,
+
+ ThreadLocale threadLocale)
{
_pipelineBuilder = pipelineBuilder;
_shadowBuilder = shadowBuilder;
@@ -945,6 +901,12 @@ public TapestryModule(PipelineBuilder pipelineBuilder,
_linkFactory = linkFactory;
_propertyAccess = propertyAccess;
_componentClassFactory = componentClassFactory;
+
+ _updateListenerHub = updateListenerHub;
+ _threadCleanupHub = threadCleanupHub;
+ _componentTemplateSource = componentTemplateSource;
+ _request = request;
+ _threadLocale = threadLocale;
}
public Context build(ApplicationGlobals globals)
@@ -1615,4 +1577,454 @@ public static void contributeResourceDigestGenerator(Configuration<String> confi
// Likewise, we don't want people fishing for templates.
configuration.add(InternalConstants.TEMPLATE_EXTENSION);
}
+
+ public static void contributeTemplateParser(MappedConfiguration<String, URL> config)
+ {
+ // Any class inside the internal module would do. Or we could move all these
+ // files to o.a.t.services.
+
+ Class c = UpdateListenerHub.class;
+ config.add("-//W3C//DTD XHTML 1.0 Strict//EN", c.getResource("xhtml1-strict.dtd"));
+ config.add("-//W3C//DTD XHTML 1.0 Transitional//EN", c
+ .getResource("xhtml1-transitional.dtd"));
+ config.add("-//W3C//DTD XHTML 1.0 Frameset//EN", c.getResource("xhtml1-frameset.dtd"));
+ config.add("-//W3C//DTD HTML 4.01//EN", c.getResource("xhtml1-strict.dtd"));
+ config.add("-//W3C//DTD HTML 4.01 Transitional//EN", c
+ .getResource("xhtml1-transitional.dtd"));
+ config.add("-//W3C//DTD HTML 4.01 Frameset//EN", c.getResource("xhtml1-frameset.dtd"));
+ config.add("-//W3C//ENTITIES Latin 1 for XHTML//EN", c.getResource("xhtml-lat1.ent"));
+ config.add("-//W3C//ENTITIES Symbols for XHTML//EN", c.getResource("xhtml-symbol.ent"));
+ config.add("-//W3C//ENTITIES Special for XHTML//EN", c.getResource("xhtml-special.ent"));
+ }
+
+ /**
+ * Contributes factory defaults that map be overridden.
+ *
+ * @see TapestryModule#contributeClasspathAssetAliasManager(MappedConfiguration, String, String)
+ */
+ public static void contributeFactoryDefaults(MappedConfiguration<String, String> configuration)
+ {
+ // Remember this is request-to-request time, presumably it'll take the developer more than
+ // one second to make a change, save it, and switch back to the browser.
+
+ configuration.add("tapestry.file-check-interval", "1000"); // 1 second
+ configuration.add("tapestry.file-check-update-timeout", "50"); // 50 milliseconds
+
+ // This should be overridden for particular applications.
+ configuration.add("tapestry.supported-locales", "en");
+
+ configuration.add("tapestry.default-cookie-max-age", "604800"); // One week
+
+ configuration.add("tapestry.start-page-name", "start");
+
+ // This is designed to make it easy to keep synchronized with script.aculo.ous. As we
+ // support a new version, we create a new folder, and update the path entry. We can then
+ // delete the old version folder (or keep it around). This should be more manageable than
+ // overwriting the local copy with updates. There's also a ClasspathAliasManager
+ // contribution based on the path.
+
+ configuration.add("tapestry.scriptaculous", "classpath:${tapestry.scriptaculous.path}");
+ configuration.add(
+ "tapestry.scriptaculous.path",
+ "org/apache/tapestry/scriptaculous_1_7_1_beta_3");
+
+ // Likewise for jscalendar, currently version 1.0
+
+ configuration.add("tapestry.jscalendar.path", "org/apache/tapestry/jscalendar-1.0");
+ configuration.add("tapestry.jscalendar", "classpath:${tapestry.jscalendar.path}");
+ }
+
+ public PageTemplateLocator build(@ContextProvider
+ AssetFactory contextAssetFactory,
+
+ ComponentClassResolver componentClassResolver)
+ {
+ return new PageTemplateLocatorImpl(contextAssetFactory.getRootResource(),
+ componentClassResolver);
+ }
+
+ public ComponentInstantiatorSource build(@Builtin
+ ClassFactory classFactory,
+
+ ComponentClassTransformer transformer,
+
+ Logger logger)
+ {
+ ComponentInstantiatorSourceImpl source = new ComponentInstantiatorSourceImpl(classFactory
+ .getClassLoader(), transformer, logger);
+
+ _updateListenerHub.addUpdateListener(source);
+
+ return source;
+ }
+
+ public ComponentClassTransformer buildComponentClassTransformer(ServiceResources resources)
+ {
+ ComponentClassTransformerImpl transformer = resources
+ .autobuild(ComponentClassTransformerImpl.class);
+
+ _componentInstantiatorSource.addInvalidationListener(transformer);
+
+ return transformer;
+ }
+
+ public PagePool build(Logger logger, PageLoader pageLoader,
+ ComponentMessagesSource componentMessagesSource, ComponentClassResolver resolver)
+ {
+ PagePoolImpl service = new PagePoolImpl(logger, pageLoader, _threadLocale, resolver);
+
+ // This covers invalidations due to changes to classes
+
+ pageLoader.addInvalidationListener(service);
+
+ // This covers invalidation due to changes to message catalogs (properties files)
+
+ componentMessagesSource.addInvalidationListener(service);
+
+ // ... and this covers invalidations due to changes to templates
+
+ _componentTemplateSource.addInvalidationListener(service);
+
+ return service;
+ }
+
+ public PageLoader buildPageLoader(ServiceResources resources)
+ {
+ PageLoaderImpl service = resources.autobuild(PageLoaderImpl.class);
+
+ // Recieve invalidations when the class loader is discarded (due to a component class
+ // change). The notification is forwarded to the page loader's listeners.
+
+ _componentInstantiatorSource.addInvalidationListener(service);
+
+ return service;
+ }
+
+ @Scope(PERTHREAD_SCOPE)
+ public RequestPageCache build(PagePool pagePool)
+ {
+ RequestPageCacheImpl service = new RequestPageCacheImpl(pagePool);
+
+ _threadCleanupHub.addThreadCleanupListener(service);
+
+ return service;
+ }
+
+ public ResourceCache build(ResourceDigestGenerator digestGenerator)
+ {
+ ResourceCacheImpl service = new ResourceCacheImpl(digestGenerator);
+
+ _updateListenerHub.addUpdateListener(service);
+
+ return service;
+ }
+
+ public ComponentTemplateSource build(TemplateParser parser, PageTemplateLocator locator)
+ {
+ ComponentTemplateSourceImpl service = new ComponentTemplateSourceImpl(parser, locator);
+
+ _updateListenerHub.addUpdateListener(service);
+
+ return service;
+ }
+
+ @Marker(ClasspathProvider.class)
+ public AssetFactory buildClasspathAssetFactory(ResourceCache resourceCache,
+
+ ClasspathAssetAliasManager aliasManager)
+ {
+ ClasspathAssetFactory factory = new ClasspathAssetFactory(resourceCache, aliasManager);
+
+ resourceCache.addInvalidationListener(factory);
+
+ return factory;
+ }
+
+ @Marker(ContextProvider.class)
+ public AssetFactory buildContextAssetFactory(ApplicationGlobals globals)
+ {
+ return new ContextAssetFactory(_request, globals.getContext());
+ }
+
+ public CookieSink buildCookieSink()
+ {
+ return new CookieSink()
+ {
+
+ public void addCookie(Cookie cookie)
+ {
+ _requestGlobals.getHTTPServletResponse().addCookie(cookie);
+ }
+
+ };
+ }
+
+ public CookieSource buildCookieSource()
+ {
+ return new CookieSource()
+ {
+
+ public Cookie[] getCookies()
+ {
+ return _requestGlobals.getHTTPServletRequest().getCookies();
+ }
+
+ };
+ }
+
+ /**
+ * Builds the PropBindingFactory as a chain of command. The terminator of the chain is
+ * responsible for ordinary property names (and property paths). Contributions to the service
+ * cover additional special cases, such as simple literal values.
+ *
+ * @param configuration
+ * contributions of special factories for some constants, each contributed factory
+ * may return a binding if applicable, or null otherwise
+ */
+ public BindingFactory buildPropBindingFactory(List<BindingFactory> configuration,
+ PropertyConduitSource propertyConduitSource)
+ {
+ PropBindingFactory service = new PropBindingFactory(propertyConduitSource);
+
+ configuration.add(service);
+
+ return _chainBuilder.build(BindingFactory.class, configuration);
+ }
+
+ /**
+ * Adds content types for "css" and "js" file extensions.
+ */
+ public void contributeResourceStreamer(MappedConfiguration<String, String> configuration)
+ {
+ configuration.add("css", "text/css");
+ configuration.add("js", "text/javascript");
+ }
+
+ /**
+ * Adds a filter that sets the application package (for class loading purposes). The filter is
+ * ordered before:*.*".
+ */
+ public void contributeApplicationInitializer(
+ OrderedConfiguration<ApplicationInitializerFilter> configuration,
+ final ApplicationGlobals applicationGlobals, final PropertyAccess propertyAccess,
+ final TypeCoercer typeCoercer)
+ {
+ final InvalidationListener listener = new InvalidationListener()
+ {
+ public void objectWasInvalidated()
+ {
+ propertyAccess.clearCache();
+ typeCoercer.clearCache();
+ }
+ };
+
+ ApplicationInitializerFilter clearCaches = new ApplicationInitializerFilter()
+ {
+ public void initializeApplication(Context context, ApplicationInitializer initializer)
+ {
+ // Snuck in here is the logic to clear the PropertyAccess service's cache whenever
+ // the component class loader is invalidated.
+
+ _componentInstantiatorSource.addInvalidationListener(listener);
+
+ initializer.initializeApplication(context);
+ }
+ };
+
+ configuration.add("ClearCachesOnInvalidation", clearCaches);
+ }
+
+ public void contributePropBindingFactory(OrderedConfiguration<BindingFactory> configuration)
+ {
+ BindingFactory keywordFactory = new BindingFactory()
+ {
+ private final Map<String, Object> _keywords = newCaseInsensitiveMap();
+
+ {
+ _keywords.put("true", Boolean.TRUE);
+ _keywords.put("false", Boolean.FALSE);
+ _keywords.put("null", null);
+ }
+
+ public Binding newBinding(String description, ComponentResources container,
+ ComponentResources component, String expression, Location location)
+ {
+ String key = expression.trim();
+
+ if (_keywords.containsKey(key))
+ return new LiteralBinding(description, _keywords.get(key), location);
+
+ return null;
+ }
+ };
+
+ BindingFactory thisFactory = new BindingFactory()
+ {
+
+ public Binding newBinding(String description, ComponentResources container,
+ ComponentResources component, String expression, Location location)
+ {
+ if ("this".equalsIgnoreCase(expression.trim()))
+ return new LiteralBinding(description, container.getComponent(), location);
+
+ return null;
+ }
+ };
+
+ BindingFactory longFactory = new BindingFactory()
+ {
+ private final Pattern _pattern = Pattern.compile("^\\s*(-?\\d+)\\s*$");
+
+ public Binding newBinding(String description, ComponentResources container,
+ ComponentResources component, String expression, Location location)
+ {
+ Matcher matcher = _pattern.matcher(expression);
+
+ if (matcher.matches())
+ {
+ String value = matcher.group(1);
+
+ return new LiteralBinding(description, new Long(value), location);
+ }
+
+ return null;
+ }
+ };
+
+ BindingFactory intRangeFactory = new BindingFactory()
+ {
+ private final Pattern _pattern = Pattern
+ .compile("^\\s*(-?\\d+)\\s*\\.\\.\\s*(-?\\d+)\\s*$");
+
+ public Binding newBinding(String description, ComponentResources container,
+ ComponentResources component, String expression, Location location)
+ {
+ Matcher matcher = _pattern.matcher(expression);
+
+ if (matcher.matches())
+ {
+ int start = Integer.parseInt(matcher.group(1));
+ int finish = Integer.parseInt(matcher.group(2));
+
+ IntegerRange range = new IntegerRange(start, finish);
+
+ return new LiteralBinding(description, range, location);
+ }
+
+ return null;
+ }
+ };
+
+ BindingFactory doubleFactory = new BindingFactory()
+ {
+ // So, either 1234. or 1234.56 or .78
+ private final Pattern _pattern = Pattern
+ .compile("^\\s*(\\-?((\\d+\\.)|(\\d*\\.\\d+)))\\s*$");
+
+ public Binding newBinding(String description, ComponentResources container,
+ ComponentResources component, String expression, Location location)
+ {
+ Matcher matcher = _pattern.matcher(expression);
+
+ if (matcher.matches())
+ {
+ String value = matcher.group(1);
+
+ return new LiteralBinding(description, new Double(value), location);
+ }
+
+ return null;
+ }
+ };
+
+ BindingFactory stringFactory = new BindingFactory()
+ {
+ // This will match embedded single quotes as-is, no escaping necessary.
+
+ private final Pattern _pattern = Pattern.compile("^\\s*'(.*)'\\s*$");
+
+ public Binding newBinding(String description, ComponentResources container,
+ ComponentResources component, String expression, Location location)
+ {
+ Matcher matcher = _pattern.matcher(expression);
+
+ if (matcher.matches())
+ {
+ String value = matcher.group(1);
+
+ return new LiteralBinding(description, value, location);
+ }
+
+ return null;
+ }
+ };
+
+ // To be honest, order probably doesn't matter.
+
+ configuration.add("Keyword", keywordFactory);
+ configuration.add("This", thisFactory);
+ configuration.add("Long", longFactory);
+ configuration.add("IntRange", intRangeFactory);
+ configuration.add("Double", doubleFactory);
+ configuration.add("StringLiteral", stringFactory);
+ }
+
+ /**
+ * Adds a filter that checks for updates to classes and other resources. It is ordered before:*.
+ */
+ public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration,
+ RequestGlobals requestGlobals,
+
+ // @Inject not needed because its a long, not a String
+ @Symbol("tapestry.file-check-interval")
+ long checkInterval,
+
+ @Symbol("tapestry.file-check-update-timeout")
+ long updateTimeout,
+
+ LocalizationSetter localizationSetter)
+ {
+ configuration.add("CheckForUpdates", new CheckForUpdatesFilter(_updateListenerHub,
+ checkInterval, updateTimeout), "before:*");
+
+ configuration.add("Localization", new LocalizationFilter(localizationSetter));
+ }
+
+ public PersistentFieldStrategy buildClientPersistentFieldStrategy(LinkFactory linkFactory,
+ ServiceResources resources)
+ {
+ ClientPersistentFieldStrategy service = resources
+ .autobuild(ClientPersistentFieldStrategy.class);
+
+ linkFactory.addListener(service);
+
+ return service;
+ }
+
+ public static void contributeComponentActionRequestHandler(
+ OrderedConfiguration<ComponentActionRequestFilter> configuration,
+ final RequestEncodingInitializer encodingInitializer)
+ {
+ ComponentActionRequestFilter filter = new ComponentActionRequestFilter()
+ {
+ public ActionResponseGenerator handle(String logicalPageName, String nestedComponentId,
+ String eventType, String[] context, String[] activationContext,
+ ComponentActionRequestHandler handler)
+ {
+ encodingInitializer.initializeRequestEncoding(logicalPageName);
+
+ return handler.handle(
+ logicalPageName,
+ nestedComponentId,
+ eventType,
+ context,
+ activationContext);
+ }
+
+ };
+
+ configuration.add("SetRequestEncoding", filter, "before:*");
+
+ configuration.add("Ajax", new AjaxFilter());
+ }
}
View
2  tapestry-core/src/site/apt/guide/parameters.apt
@@ -87,7 +87,7 @@ Binding Parameters
+---+
<html t:type="layout" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
- <p> Merry Christmas: <t:count end="3"> Ho! </t:comp>
+ <p> Merry Christmas: <t:count end="3"> Ho! </t:count>
</p>
</html>
+---+
View
14 tapestry-ioc/src/site/apt/cookbook/basics.apt
@@ -9,7 +9,7 @@ Basic Services and Injection
In many cases, these conventions are just a little stronger: you may have to do some amount of
extra configuration if you choose to go your own way.
-* Getting Started
+Getting Started
Like anything else, you want to choose a package for your application, such as org.example.myapp.
@@ -19,7 +19,7 @@ Basic Services and Injection
Thus, you might start with a module class org.example.myapp.services.MyAppModule.
-* Simple Services
+Simple Services
The simplest services don't have any special configuration or dependencies. They are defined as services so that
they can be shared.
@@ -62,7 +62,7 @@ public class ExceptionAnalyzerImpl implements ExceptionAnalyzer
And that's the essence of Tapestry IoC right there; the bind() plus the constructor is <all> that's necessary.
-* Service Disambiguation
+Service Disambiguation
In the previous example, we relied on the fact that only a single service implements the PropertyAccess interface.
Had more than one done so, Tapestry would have thrown an exception when the ExceptionAnalyzer service was realized (it isn't
@@ -87,11 +87,10 @@ public class ExceptionAnalyzerImpl implements ExceptionAnalyzer
In fact, there are different implementations of this class: one for context resources (part of the web application), the other
for classpath resources (packaged inside a JAR). The Asset instances are created via
- {{{../../apidocs/org/apache/tapesty/AssetFactory.html}AssetFactory}} services.
+ {{{../../apidocs/org/apache/tapesty/services/AssetFactory.html}AssetFactory}} services.
Tapestry defines two such services, in the
- {{{../../apidocs/org/apache/tapestry/internal/InternalModule.html}InternalModule}} (which is part of the internal implementation of Tapestry,
- as opposed to Tapestry's public APIs).
+ {{{../../apidocs/org/apache/tapestry/services/TapestryModule.html}TapestryModule}}.
+---+
@Marker(ClasspathProvider.class)
@@ -117,7 +116,8 @@ public class ExceptionAnalyzerImpl implements ExceptionAnalyzer
listener of events from another service. For the ContextAssetFactory, we are extracting a value from an injected service and passing
<that> to the constructor.
- What's important is that the services are differentiated not just in terms of their name, but in terms of their <marker annotation>.
+ What's important is that the services are differentiated not just in terms of their id (which is defined by the name of the method,
+ after stripping off "build"), but in terms of their <marker annotation>.
The {{{../../apidocs/org/apache/tapestry/ioc/annotations/Marker.html}Marker}} annotation provides the discriminator. When
the service type is supplemented with the ClasspathProvider annotation, the ClasspathAssetFactory is injected. When the
View
12 tapestry-ioc/src/site/apt/cookbook/index.apt
@@ -4,11 +4,17 @@
Tapestry IoC Cookbook
- Tapestry IoC, though designed specifically for the needs of the Tapestry web framework, also may be employed as a stand-alone IoC container, separate
+ Tapestry IoC, though designed specifically for the needs of the Tapestry web framework, may also be employed as a stand-alone IoC container, separate
from the rest of Tapestry.
Tapestry IoC is a sophisticated tool that takes some experience to use properly.
- The existing documentation is factually correct, but is designed more as a reference, rather than giving the big picture.
+ The existing documentation is factually correct, but is designed more as a reference, rather than giving the big picture. In the Cookbook,
+ we'll try to show how Tapestry IoC is really used, and build up towards that big picture.
- The cookbook will show a bit more about how to use Tapestry IoC, using real examples from the Tapestry code base.
+ The cookbook will show a bit more about how to use Tapestry IoC, using real examples from the Tapestry code base (both the tapestry-ioc
+ and tapestry-core modules).
+
+ A word of caution: several of the examples have been taken from Tapestry's <internal> code base. Tapestry internals are
+ private, subject to change at any time, so be aware that if you go peeking at the internal source code, it may have
+ changed since the corresponding documentation was written.
View
9 tapestry-ioc/src/site/apt/overview.apt
@@ -21,7 +21,14 @@ Tapestry IoC Overview
That's an <unmanaged> system. Most desktop applications are unmanaged, so it's a very familiar pattern, and easy to get your head around.
- Building web applications tends to be quite a different story. It's a very different environment largely because of <multithreading>.
+ By contrast, web application are a <managed> environment. You don't write a main(), you don't control startup. You <configure>
+ the Servlet API to tell it about your servlet classes to be instantiated, and their lifecycle is totally controlled by
+ the servlet container.
+
+ Inversion of Control is just a more general application of this approach. The container is ultimately responsible for
+ instantiating and configuring the objects you tell it about, and running their entire lifecycle of those objects.
+
+ Building web applications are more complicated than monolithic applications, largely because of <multithreading>.
Your code will be servicing many different users simultaneously across many different threads. This tends to complicate the
code you write, since some fundamental aspects of object oriented development get called into question: in particular, the use
of <internal state>, values stored inside instance variables, since in a multi-threaded environment, that's no longer the safe
View
2  tapestry-ioc/src/site/site.xml
@@ -73,6 +73,8 @@
<menu name="Tapestry IoC Cookbook">
<item name="Introduction" href="cookbook/index.html"/>
<item name="Basics" href="cookbook/basics.html"/>
+ <item name="Service Configurations" href="cookbook/servconf.html"/>
+ <item name="Using Patterns" href="cookbook/patterns.html"/>
</menu>
Please sign in to comment.
Something went wrong with that request. Please try again.