Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
// Copyright 2006, 2007, 2008, 2009, 2010 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.tapestry5.services;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.regex.Pattern;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.tapestry5.*;
import org.apache.tapestry5.ajax.MultiZoneUpdate;
import org.apache.tapestry5.annotations.*;
import org.apache.tapestry5.annotations.ContentType;
import org.apache.tapestry5.beaneditor.Validate;
import org.apache.tapestry5.corelib.ClientValidation;
import org.apache.tapestry5.corelib.LoopFormState;
import org.apache.tapestry5.corelib.SubmitMode;
import org.apache.tapestry5.corelib.data.BlankOption;
import org.apache.tapestry5.corelib.data.GridPagerPosition;
import org.apache.tapestry5.corelib.data.InsertPosition;
import org.apache.tapestry5.grid.GridDataSource;
import org.apache.tapestry5.internal.AssetConstants;
import org.apache.tapestry5.internal.DefaultNullFieldStrategy;
import org.apache.tapestry5.internal.DefaultValidationDecorator;
import org.apache.tapestry5.internal.InternalConstants;
import org.apache.tapestry5.internal.InternalSymbols;
import org.apache.tapestry5.internal.PropertyOverridesImpl;
import org.apache.tapestry5.internal.TapestryInternalUtils;
import org.apache.tapestry5.internal.ZeroNullFieldStrategy;
import org.apache.tapestry5.internal.beaneditor.EnvironmentMessages;
import org.apache.tapestry5.internal.beaneditor.MessagesConstraintGenerator;
import org.apache.tapestry5.internal.beaneditor.PrimitiveFieldConstraintGenerator;
import org.apache.tapestry5.internal.beaneditor.ValidateAnnotationConstraintGenerator;
import org.apache.tapestry5.internal.bindings.*;
import org.apache.tapestry5.internal.grid.CollectionGridDataSource;
import org.apache.tapestry5.internal.grid.NullDataSource;
import org.apache.tapestry5.internal.gzip.GZipFilter;
import org.apache.tapestry5.internal.renderers.AvailableValuesRenderer;
import org.apache.tapestry5.internal.renderers.ComponentResourcesRenderer;
import org.apache.tapestry5.internal.renderers.EventContextRenderer;
import org.apache.tapestry5.internal.renderers.ListRenderer;
import org.apache.tapestry5.internal.renderers.LocationRenderer;
import org.apache.tapestry5.internal.renderers.ObjectArrayRenderer;
import org.apache.tapestry5.internal.renderers.RequestRenderer;
import org.apache.tapestry5.internal.services.*;
import org.apache.tapestry5.internal.services.ajax.AjaxFormUpdateFilter;
import org.apache.tapestry5.internal.services.ajax.JavaScriptSupportImpl;
import org.apache.tapestry5.internal.services.assets.AssetPathConstructorImpl;
import org.apache.tapestry5.internal.services.assets.ClasspathAssetRequestHandler;
import org.apache.tapestry5.internal.services.assets.ContextAssetRequestHandler;
import org.apache.tapestry5.internal.services.assets.StackAssetRequestHandler;
import org.apache.tapestry5.internal.services.javascript.CoreJavaScriptStack;
import org.apache.tapestry5.internal.services.javascript.DateFieldStack;
import org.apache.tapestry5.internal.services.javascript.JavaScriptStackPathConstructor;
import org.apache.tapestry5.internal.services.javascript.JavaScriptStackSourceImpl;
import org.apache.tapestry5.internal.services.linktransform.LinkTransformerImpl;
import org.apache.tapestry5.internal.services.linktransform.LinkTransformerInterceptor;
import org.apache.tapestry5.internal.services.messages.PropertiesFileParserImpl;
import org.apache.tapestry5.internal.services.meta.ContentTypeExtractor;
import org.apache.tapestry5.internal.services.meta.MetaAnnotationExtractor;
import org.apache.tapestry5.internal.services.meta.MetaWorkerImpl;
import org.apache.tapestry5.internal.services.templates.DefaultTemplateLocator;
import org.apache.tapestry5.internal.services.templates.PageTemplateLocator;
import org.apache.tapestry5.internal.transform.*;
import org.apache.tapestry5.internal.translator.NumericTranslator;
import org.apache.tapestry5.internal.translator.NumericTranslatorSupport;
import org.apache.tapestry5.internal.translator.StringTranslator;
import org.apache.tapestry5.internal.util.PrimaryKeyEncoder2ValueEncoder;
import org.apache.tapestry5.internal.util.RenderableAsBlock;
import org.apache.tapestry5.internal.util.StringRenderable;
import org.apache.tapestry5.internal.validator.ValidatorMacroImpl;
import org.apache.tapestry5.ioc.*;
import org.apache.tapestry5.ioc.annotations.*;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.services.*;
import org.apache.tapestry5.ioc.util.AvailableValues;
import org.apache.tapestry5.ioc.util.IdAllocator;
import org.apache.tapestry5.ioc.util.StrategyRegistry;
import org.apache.tapestry5.ioc.util.TimeInterval;
import org.apache.tapestry5.json.JSONArray;
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.runtime.Component;
import org.apache.tapestry5.runtime.ComponentResourcesAware;
import org.apache.tapestry5.runtime.RenderCommand;
import org.apache.tapestry5.runtime.RenderQueue;
import org.apache.tapestry5.services.ajax.MultiZoneUpdateEventResultProcessor;
import org.apache.tapestry5.services.assets.AssetPathConstructor;
import org.apache.tapestry5.services.assets.AssetRequestHandler;
import org.apache.tapestry5.services.javascript.JavaScriptStack;
import org.apache.tapestry5.services.javascript.JavaScriptStackSource;
import org.apache.tapestry5.services.javascript.JavaScriptSupport;
import org.apache.tapestry5.services.javascript.StylesheetLink;
import org.apache.tapestry5.services.linktransform.ComponentEventLinkTransformer;
import org.apache.tapestry5.services.linktransform.LinkTransformer;
import org.apache.tapestry5.services.linktransform.PageRenderLinkTransformer;
import org.apache.tapestry5.services.messages.ComponentMessagesSource;
import org.apache.tapestry5.services.messages.PropertiesFileParser;
import org.apache.tapestry5.services.meta.FixedExtractor;
import org.apache.tapestry5.services.meta.MetaDataExtractor;
import org.apache.tapestry5.services.meta.MetaWorker;
import org.apache.tapestry5.services.templates.ComponentTemplateLocator;
import org.apache.tapestry5.util.StringToEnumCoercion;
import org.apache.tapestry5.validator.Email;
import org.apache.tapestry5.validator.Max;
import org.apache.tapestry5.validator.MaxLength;
import org.apache.tapestry5.validator.Min;
import org.apache.tapestry5.validator.MinLength;
import org.apache.tapestry5.validator.None;
import org.apache.tapestry5.validator.Regexp;
import org.apache.tapestry5.validator.Required;
import org.apache.tapestry5.validator.ValidatorMacro;
import org.slf4j.Logger;
/**
* The root module for Tapestry.
*/
@SuppressWarnings(
{ "JavaDoc" })
@Marker(Core.class)
@SubModule(InternalModule.class)
public final class TapestryModule
{
private final PipelineBuilder pipelineBuilder;
private final ApplicationGlobals applicationGlobals;
private final PropertyShadowBuilder shadowBuilder;
private final Environment environment;
private final StrategyBuilder strategyBuilder;
private final PropertyAccess propertyAccess;
private final ChainBuilder chainBuilder;
private final Request request;
private final Response response;
private final RequestGlobals requestGlobals;
private final EnvironmentalShadowBuilder environmentalBuilder;
private final EndOfRequestEventHub endOfRequestEventHub;
/**
* We inject all sorts of common dependencies (including builders) into the
* module itself (note: even though some of
* these service are defined by the module itself, that's ok because
* services are always lazy proxies). This isn't
* about efficiency (it may be slightly more efficient, but not in any
* noticable way), it's about eliminating the
* need to keep injecting these dependencies into individual service builder
* and contribution methods.
*/
public TapestryModule(PipelineBuilder pipelineBuilder,
PropertyShadowBuilder shadowBuilder,
RequestGlobals requestGlobals,
ApplicationGlobals applicationGlobals,
ChainBuilder chainBuilder,
Environment environment,
StrategyBuilder strategyBuilder,
PropertyAccess propertyAccess,
Request request,
Response response,
EnvironmentalShadowBuilder environmentalBuilder,
EndOfRequestEventHub endOfRequestEventHub)
{
this.pipelineBuilder = pipelineBuilder;
this.shadowBuilder = shadowBuilder;
this.requestGlobals = requestGlobals;
this.applicationGlobals = applicationGlobals;
this.chainBuilder = chainBuilder;
this.environment = environment;
this.strategyBuilder = strategyBuilder;
this.propertyAccess = propertyAccess;
this.request = request;
this.response = response;
this.environmentalBuilder = environmentalBuilder;
this.endOfRequestEventHub = endOfRequestEventHub;
}
// A bunch of classes "promoted" from inline inner class to nested classes,
// just so that the stack trace would be more readable. Most of these
// are teminators for pipeline services.
/**
* @since 5.1.0.0
*/
private class ApplicationInitializerTerminator implements ApplicationInitializer
{
public void initializeApplication(Context context)
{
applicationGlobals.storeContext(context);
}
}
/**
* @since 5.1.0.0
*/
private class HttpServletRequestHandlerTerminator implements HttpServletRequestHandler
{
private final RequestHandler handler;
private final String applicationCharset;
private final SessionPersistedObjectAnalyzer analyzer;
public HttpServletRequestHandlerTerminator(RequestHandler handler, String applicationCharset,
SessionPersistedObjectAnalyzer analyzer)
{
this.handler = handler;
this.applicationCharset = applicationCharset;
this.analyzer = analyzer;
}
public boolean service(HttpServletRequest servletRequest, HttpServletResponse servletResponse)
throws IOException
{
requestGlobals.storeServletRequestResponse(servletRequest, servletResponse);
Request request = new RequestImpl(servletRequest, applicationCharset, analyzer);
Response response = new ResponseImpl(servletRequest, servletResponse);
// TAP5-257: Make sure that the "initial guess" for request/response
// is available, even if
// some filter in the RequestHandler pipeline replaces them.
requestGlobals.storeRequestResponse(request, response);
// Transition from the Servlet API-based pipeline, to the
// Tapestry-based pipeline.
return handler.service(request, response);
}
}
/**
* @since 5.1.0.0
*/
private class ServletApplicationInitializerTerminator implements ServletApplicationInitializer
{
private final ApplicationInitializer initializer;
public ServletApplicationInitializerTerminator(ApplicationInitializer initializer)
{
this.initializer = initializer;
}
public void initializeApplication(ServletContext servletContext)
{
applicationGlobals.storeServletContext(servletContext);
// And now, down the (Web) ApplicationInitializer pipeline ...
ContextImpl context = new ContextImpl(servletContext);
applicationGlobals.storeContext(context);
initializer.initializeApplication(context);
}
}
/**
* @since 5.1.0.0
*/
private class RequestHandlerTerminator implements RequestHandler
{
private final Dispatcher masterDispatcher;
public RequestHandlerTerminator(Dispatcher masterDispatcher)
{
this.masterDispatcher = masterDispatcher;
}
public boolean service(Request request, Response response) throws IOException
{
// Update RequestGlobals with the current request/response (in case
// some filter replaced the
// normal set).
requestGlobals.storeRequestResponse(request, response);
return masterDispatcher.dispatch(request, response);
}
}
public static void bind(ServiceBinder binder)
{
binder.bind(ClasspathAssetAliasManager.class, ClasspathAssetAliasManagerImpl.class);
binder.bind(PersistentLocale.class, PersistentLocaleImpl.class);
binder.bind(ApplicationStateManager.class, ApplicationStateManagerImpl.class);
binder.bind(ApplicationStatePersistenceStrategySource.class,
ApplicationStatePersistenceStrategySourceImpl.class);
binder.bind(BindingSource.class, BindingSourceImpl.class);
binder.bind(FieldValidatorSource.class, FieldValidatorSourceImpl.class);
binder.bind(ApplicationGlobals.class, ApplicationGlobalsImpl.class);
binder.bind(AssetSource.class, AssetSourceImpl.class);
binder.bind(Cookies.class, CookiesImpl.class);
binder.bind(FieldValidatorDefaultSource.class, FieldValidatorDefaultSourceImpl.class);
binder.bind(RequestGlobals.class, RequestGlobalsImpl.class);
binder.bind(ResourceDigestGenerator.class, ResourceDigestGeneratorImpl.class);
binder.bind(ValidationConstraintGenerator.class, ValidationConstraintGeneratorImpl.class);
binder.bind(EnvironmentalShadowBuilder.class, EnvironmentalShadowBuilderImpl.class);
binder.bind(ComponentSource.class, ComponentSourceImpl.class);
binder.bind(BeanModelSource.class, BeanModelSourceImpl.class);
binder.bind(BeanBlockSource.class, BeanBlockSourceImpl.class);
binder.bind(ComponentDefaultProvider.class, ComponentDefaultProviderImpl.class);
binder.bind(MarkupWriterFactory.class, MarkupWriterFactoryImpl.class);
binder.bind(FieldValidationSupport.class, FieldValidationSupportImpl.class);
binder.bind(ObjectRenderer.class, LocationRenderer.class).withId("LocationRenderer");
binder.bind(ObjectProvider.class, AssetObjectProvider.class).withId("AssetObjectProvider");
binder.bind(RequestExceptionHandler.class, DefaultRequestExceptionHandler.class);
binder.bind(ComponentEventResultProcessor.class, ComponentInstanceResultProcessor.class).withId(
"ComponentInstanceResultProcessor");
binder.bind(NullFieldStrategySource.class, NullFieldStrategySourceImpl.class);
binder.bind(HttpServletRequestFilter.class, IgnoredPathsFilter.class).withId("IgnoredPathsFilter");
binder.bind(ContextValueEncoder.class, ContextValueEncoderImpl.class);
binder.bind(BaseURLSource.class, BaseURLSourceImpl.class);
binder.bind(BeanBlockOverrideSource.class, BeanBlockOverrideSourceImpl.class);
binder.bind(AliasManager.class, AliasManagerImpl.class).withId("AliasOverrides");
binder.bind(HiddenFieldLocationRules.class, HiddenFieldLocationRulesImpl.class);
binder.bind(PageDocumentGenerator.class, PageDocumentGeneratorImpl.class);
binder.bind(ResponseRenderer.class, ResponseRendererImpl.class);
binder.bind(FieldTranslatorSource.class, FieldTranslatorSourceImpl.class);
binder.bind(BindingFactory.class, MessageBindingFactory.class).withId("MessageBindingFactory");
binder.bind(BindingFactory.class, ValidateBindingFactory.class).withId("ValidateBindingFactory");
binder.bind(BindingFactory.class, TranslateBindingFactory.class).withId("TranslateBindingFactory");
binder.bind(BindingFactory.class, AssetBindingFactory.class).withId("AssetBindingFactory");
binder.bind(BindingFactory.class, ContextBindingFactory.class).withId("ContextBindingFactory");
binder.bind(BindingFactory.class, NullFieldStrategyBindingFactory.class).withId(
"NullFieldStrategyBindingFactory");
binder.bind(BindingFactory.class, SymbolBindingFactory.class).withId("SymbolBindingFactory");
binder.bind(URLEncoder.class, URLEncoderImpl.class);
binder.bind(ContextPathEncoder.class, ContextPathEncoderImpl.class);
binder.bind(ApplicationStatePersistenceStrategy.class, SessionApplicationStatePersistenceStrategy.class)
.withId("SessionApplicationStatePersistenceStrategy");
binder.bind(AssetPathConverter.class, IdentityAssetPathConverter.class);
binder.bind(NumericTranslatorSupport.class);
binder.bind(ClientDataEncoder.class, ClientDataEncoderImpl.class);
binder.bind(ComponentEventLinkEncoder.class, ComponentEventLinkEncoderImpl.class);
binder.bind(PageRenderLinkSource.class, PageRenderLinkSourceImpl.class);
binder.bind(ClientInfrastructure.class, ClientInfrastructureImpl.class);
binder.bind(URLRewriter.class, URLRewriterImpl.class);
binder.bind(ValidatorMacro.class, ValidatorMacroImpl.class);
binder.bind(PropertiesFileParser.class, PropertiesFileParserImpl.class);
binder.bind(PageActivator.class, PageActivatorImpl.class);
binder.bind(Dispatcher.class, AssetDispatcher.class).withId("AssetDispatcher");
binder.bind(AssetPathConstructor.class, AssetPathConstructorImpl.class);
binder.bind(JavaScriptStackSource.class, JavaScriptStackSourceImpl.class);
binder.bind(TranslatorAlternatesSource.class, TranslatorAlternatesSourceImpl.class);
binder.bind(MetaWorker.class, MetaWorkerImpl.class);
binder.bind(LinkTransformer.class, LinkTransformerImpl.class);
binder.bind(SelectModelFactory.class, SelectModelFactoryImpl.class);
}
// ========================================================================
//
// Service Builder Methods (static)
//
// ========================================================================
@PreventServiceDecoration
public static Alias buildAlias(Logger logger,
@Symbol(InternalSymbols.ALIAS_MODE)
String mode,
@InjectService("AliasOverrides")
AliasManager overridesManager,
Collection configuration)
{
AliasManager manager = new AliasManagerImpl(logger, configuration);
return new AliasImpl(manager, mode, overridesManager);
}
// ========================================================================
//
// Service Contribution Methods (static)
//
// ========================================================================
/**
* Contributes the factory for serveral built-in binding prefixes ("asset",
* "block", "component", "literal", prop",
* "nullfieldstrategy", "message", "validate", "translate", "var").
*/
public static void contributeBindingSource(MappedConfiguration configuration,
@InjectService("PropBindingFactory")
BindingFactory propBindingFactory,
@InjectService("MessageBindingFactory")
BindingFactory messageBindingFactory,
@InjectService("ValidateBindingFactory")
BindingFactory validateBindingFactory,
@InjectService("TranslateBindingFactory")
BindingFactory translateBindingFactory,
@InjectService("AssetBindingFactory")
BindingFactory assetBindingFactory,
@InjectService("NullFieldStrategyBindingFactory")
BindingFactory nullFieldStrategyBindingFactory,
@InjectService("ContextBindingFactory")
BindingFactory contextBindingFactory,
@InjectService("SymbolBindingFactory")
BindingFactory symbolBindingFactory)
{
configuration.add(BindingConstants.LITERAL, new LiteralBindingFactory());
configuration.add(BindingConstants.COMPONENT, new ComponentBindingFactory());
configuration.add(BindingConstants.VAR, new RenderVariableBindingFactory());
configuration.add(BindingConstants.BLOCK, new BlockBindingFactory());
configuration.add(BindingConstants.PROP, propBindingFactory);
configuration.add(BindingConstants.MESSAGE, messageBindingFactory);
configuration.add(BindingConstants.VALIDATE, validateBindingFactory);
configuration.add(BindingConstants.TRANSLATE, translateBindingFactory);
configuration.add(BindingConstants.ASSET, assetBindingFactory);
configuration.add(BindingConstants.NULLFIELDSTRATEGY, nullFieldStrategyBindingFactory);
configuration.add(BindingConstants.CONTEXT, contextBindingFactory);
configuration.add(BindingConstants.SYMBOL, symbolBindingFactory);
}
public static void contributeClasspathAssetAliasManager(MappedConfiguration configuration,
@Symbol(SymbolConstants.APPLICATION_VERSION)
String applicationVersion,
@Symbol(InternalConstants.TAPESTRY_APP_PACKAGE_PARAM)
String appPackage,
ComponentClassResolver resolver)
{
configuration.add("tapestry", "org/apache/tapestry5");
configuration.add("app", toPackagePath(appPackage));
// Each library gets a mapping or its folder automatically
Map folderToPackageMapping = resolver.getFolderToPackageMapping();
for (String folder : folderToPackageMapping.keySet())
{
configuration.add(folder, toPackagePath(folderToPackageMapping.get(folder)));
}
}
/**
* Contributes an handler for each mapped classpath alias, as well handlers for context assets
* and stack assets (combined {@link JavaScriptStack} files).
*/
public static void contributeAssetDispatcher(MappedConfiguration configuration,
@ContextProvider
AssetFactory contextAssetFactory,
@Autobuild
StackAssetRequestHandler stackAssetRequestHandler,
ResourceCache resourceCache,
ClasspathAssetAliasManager classpathAssetAliasManager, ResourceStreamer streamer,
AssetResourceLocator assetResourceLocator)
{
resourceCache.addInvalidationListener(stackAssetRequestHandler);
Map mappings = classpathAssetAliasManager.getMappings();
for (String folder : mappings.keySet())
{
String path = mappings.get(folder);
configuration.add(folder, new ClasspathAssetRequestHandler(streamer, assetResourceLocator, path));
}
configuration.add(RequestConstants.CONTEXT_FOLDER,
new ContextAssetRequestHandler(streamer, contextAssetFactory.getRootResource()));
configuration.add(RequestConstants.STACK_FOLDER, stackAssetRequestHandler);
}
private static String toPackagePath(String packageName)
{
return packageName.replace('.', '/');
}
public static void contributeComponentClassResolver(Configuration configuration)
{
configuration.add(new LibraryMapping("core", "org.apache.tapestry5.corelib"));
}
/**
* Adds a number of standard component class transform workers:
*
*
Retain
*
Allows fields to retain their values between requests
*
Persist
*
Allows fields to store their their value persistently between requests
*
Parameter
*
Identifies parameters based on the {@link org.apache.tapestry5.annotations.Parameter} annotation
*
Component
*
Defines embedded components based on the {@link org.apache.tapestry5.annotations.Component} annotation
*
Mixin
*
Adds a mixin as part of a component's implementation
*
Environment
*
Allows fields to contain values extracted from the {@link org.apache.tapestry5.services.Environment} service
*
Inject
*
Used with the {@link org.apache.tapestry5.ioc.annotations.Inject} annotation, when a value is supplied
*
InjectService
*
Handles the {@link org.apache.tapestry5.ioc.annotations.InjectService} annotation
*
InjectPage
*
Adds code to allow access to other pages via the {@link org.apache.tapestry5.annotations.InjectPage} field
* annotation
*
InjectBlock
*
Allows a block from the template to be injected into a field
*
IncludeStylesheet
*
Supports the {@link org.apache.tapestry5.annotations.IncludeStylesheet} annotation
*
IncludeJavaScriptLibrary
*
Supports the {@link org.apache.tapestry5.annotations.IncludeJavaScriptLibrary} annotation
*
Import
*
Supports the {@link Import} annotation
*
SupportsInformalParameters
*
Checks for the annotation
*
Meta
*
Checks for meta data annotations and adds it to the component model
*
ApplicationState
*
Converts fields that reference application state objects
*
UnclaimedField
*
Identifies unclaimed fields and resets them to null/0/false at the end of the request
*
RenderCommand
*
Ensures all components also implement {@link org.apache.tapestry5.runtime.RenderCommand}
*
RenderPhase
*
Link in render phaes methods
*
InvokePostRenderCleanupOnResources
*
Makes sure {@link org.apache.tapestry5.internal.InternalComponentResources#postRenderCleanup()} is invoked
* after a component finishes rendering
*
GenerateAccessors
*
Generates accessor methods if {@link org.apache.tapestry5.annotations.Property} annotation is present
*
Cached
*
Checks for the {@link org.apache.tapestry5.annotations.Cached} annotation
*
Log
*
Checks for the {@link org.apache.tapestry5.annotations.Log} annotation
*
PageReset
*
Checks for the {@link PageReset} annotation
*
HeartbeatDeferred
*
Support for the {@link HeartbeatDeferred} annotation
*
ActivationRequestParameter
*
Support for the {@link ActivationRequestParameter} annotation
*
*/
public static void contributeComponentClassTransformWorker(
OrderedConfiguration configuration,
MetaWorker metaWorker,
ComponentClassResolver resolver)
{
configuration.addInstance("Cached", CachedWorker.class);
configuration.add("Meta", metaWorker);
configuration.addInstance("Inject", InjectWorker.class);
configuration.addInstance("InjectService", InjectServiceWorker.class);
configuration.add("MixinAfter", new MixinAfterWorker());
configuration.add("Component", new ComponentWorker(resolver));
configuration.add("Mixin", new MixinWorker(resolver));
configuration
.addInstance("ActivationRequestParameter", ActivationRequestParameterWorker.class, "after:OnEvent");
configuration.addInstance("OnEvent", OnEventWorker.class);
configuration.add("SupportsInformalParameters", new SupportsInformalParametersWorker());
configuration.addInstance("InjectPage", InjectPageWorker.class);
configuration.addInstance("InjectContainer", InjectContainerWorker.class);
configuration.addInstance("InjectComponent", InjectComponentWorker.class);
configuration.add("RenderCommand", new RenderCommandWorker());
// Default values for parameters are often some form of injection, so
// make sure
// that Parameter fields are processed after injections.
configuration.addInstance("Parameter", ParameterWorker.class, "after:Inject*");
// bind parameter should always go after parameter to make sure all
// parameters
// have been properly setup.
configuration.addInstance("BindParameter", BindParameterWorker.class, "after:Parameter");
configuration.addInstance("RenderPhase", RenderPhaseMethodWorker.class);
// Ideally, these should be ordered pretty late in the process to make
// sure there are no
// side effects with other workers that do work inside the page
// lifecycle methods.
add(configuration, PageLoaded.class, TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, "pageLoaded");
add(configuration, PageAttached.class, TransformConstants.CONTAINING_PAGE_DID_ATTACH_SIGNATURE, "pageAttached");
add(configuration, PageDetached.class, TransformConstants.CONTAINING_PAGE_DID_DETACH_SIGNATURE, "pageDetached");
configuration.add("Retain", new RetainWorker());
configuration.addInstance("Persist", PersistWorker.class);
configuration.addInstance("DiscardAfter", DiscardAfterWorker.class);
configuration.addInstance("IncludeStylesheet", IncludeStylesheetWorker.class, "after:SetupRender");
configuration
.addInstance("IncludeJavaScriptLibrary", IncludeJavaScriptLibraryWorker.class, "after:SetupRender");
configuration.addInstance("Import", ImportWorker.class, "after:SetupRender");
configuration.add("InvokePostRenderCleanupOnResources", new InvokePostRenderCleanupOnResourcesWorker());
configuration.add("Property", new PropertyWorker());
// These must come after Property, since they actually delete fields
// that may still have the annotation
configuration.addInstance("ApplicationState", ApplicationStateWorker.class, "after:Property");
configuration.addInstance("Environment", EnvironmentalWorker.class, "after:Property");
configuration.addInstance("Log", LogWorker.class);
configuration.addInstance("PageReset", PageResetAnnotationWorker.class);
// This one is always last. Any additional private fields that aren't
// annotated will
// be converted to clear out at the end of the request.
configuration.addInstance("UnclaimedField", UnclaimedFieldWorker.class, "after:*");
configuration.add("PageActivationContext", new PageActivationContextWorker(), "after:OnEvent");
configuration.addInstance("SessionAttribute", SessionAttributeWorker.class);
configuration.addInstance("HeartbeatDeferred", HeartbeatDeferredWorker.class, "after:RenderPhase");
}
/**
*
*
Annotation
*
Checks for {@link org.apache.tapestry5.beaneditor.DataType} annotation
*
Default (ordered last)
*
* {@link org.apache.tapestry5.internal.services.DefaultDataTypeAnalyzer} service (
* {@link #contributeDefaultDataTypeAnalyzer(org.apache.tapestry5.ioc.MappedConfiguration)} )
*
*/
public static void contributeDataTypeAnalyzer(OrderedConfiguration configuration,
@InjectService("DefaultDataTypeAnalyzer")
DataTypeAnalyzer defaultDataTypeAnalyzer)
{
configuration.add("Annotation", new AnnotationDataTypeAnalyzer());
configuration.add("Default", defaultDataTypeAnalyzer, "after:*");
}
/**
* Maps property types to data type names:
*
*
String --> text
*
Number --> number
*
Enum --> enum
*
Boolean --> boolean
*
Date --> date
*
*/
public static void contributeDefaultDataTypeAnalyzer(MappedConfiguration configuration)
{
// This is a special case contributed to avoid exceptions when a
// property type can't be
// matched. DefaultDataTypeAnalyzer converts the empty string to null.
configuration.add(Object.class, "");
configuration.add(String.class, "text");
configuration.add(Number.class, "number");
configuration.add(Enum.class, "enum");
configuration.add(Boolean.class, "boolean");
configuration.add(Date.class, "date");
configuration.add(Calendar.class, "calendar");
}
@Contribute(BeanBlockSource.class)
public static void provideDefaultBeanBlocks(Configuration configuration)
{
addEditBlock(configuration, "text");
addEditBlock(configuration, "number");
addEditBlock(configuration, "enum");
addEditBlock(configuration, "boolean");
addEditBlock(configuration, "date");
addEditBlock(configuration, "password");
addEditBlock(configuration, "calendar");
// longtext uses a text area, not a text field
addEditBlock(configuration, "longtext");
addDisplayBlock(configuration, "enum");
addDisplayBlock(configuration, "date");
addDisplayBlock(configuration, "calendar");
// Password and long text have special output needs.
addDisplayBlock(configuration, "password");
addDisplayBlock(configuration, "longtext");
}
private static void addEditBlock(Configuration configuration, String dataType)
{
addEditBlock(configuration, dataType, dataType);
}
private static void addEditBlock(Configuration configuration, String dataType, String blockId)
{
configuration.add(new EditBlockContribution(dataType, "PropertyEditBlocks", blockId));
}
private static void addDisplayBlock(Configuration configuration, String dataType)
{
addDisplayBlock(configuration, dataType, dataType);
}
private static void addDisplayBlock(Configuration configuration, String dataType,
String blockId)
{
configuration.add(new DisplayBlockContribution(dataType, "PropertyDisplayBlocks", blockId));
}
/**
* Contributes the basic set of validators:
*
*
required
*
minlength
*
maxlength
*
min
*
max
*
regexp
*
email
*
none
*
*/
public static void contributeFieldValidatorSource(MappedConfiguration configuration)
{
configuration.add("required", new Required());
configuration.add("minlength", new MinLength());
configuration.add("maxlength", new MaxLength());
configuration.add("min", new Min());
configuration.add("max", new Max());
configuration.add("regexp", new Regexp());
configuration.add("email", new Email());
configuration.add("none", new None());
}
/**
* Contributes the base set of injection providers:
*
*
Default
*
based on {@link MasterObjectProvider}
*
Block
*
injects fields of type Block
*
ComponentResources
*
give component access to its resources
*
CommonResources
*
access to properties of resources (log, messages, etc.)
*
Asset
*
injection of assets (triggered via {@link Path} annotation), with the path relative to the component class
*
Service
*
ordered last, for use when Inject is present and nothing else works, matches field type against Tapestry IoC
* services
*
*/
public static void contributeInjectionProvider(OrderedConfiguration configuration,
MasterObjectProvider masterObjectProvider,
ObjectLocator locator,
SymbolSource symbolSource,
AssetSource assetSource)
{
configuration.add("Default", new DefaultInjectionProvider(masterObjectProvider, locator));
configuration.add("ComponentResources", new ComponentResourcesInjectionProvider());
// This comes after default, to deal with conflicts between injecting a
// String as the
// component id, and injecting a string with @Symbol or @Value.
configuration.add("CommonResources", new CommonResourcesInjectionProvider(), "after:Default");
configuration.add("Asset", new AssetInjectionProvider(symbolSource, assetSource), "before:Default");
configuration.add("Block", new BlockInjectionProvider(), "before:Default");
// This needs to be the last one, since it matches against services
// and might blow up if there is no match.
configuration.add("Service", new ServiceInjectionProvider(locator), "after:*");
}
/**
* Contributes two object providers:
*
*
Alias
*
Searches by type among {@linkplain AliasContribution
* contributions} to the {@link Alias} service
*
Asset
*
*
Checks for the {@link Path} annotation, and injects an {@link Asset}
*
Service
*
Injects based on the {@link Service} annotation, if present
*
ApplicationMessages
*
Injects the global application messages
*
*/
public static void contributeMasterObjectProvider(OrderedConfiguration configuration,
@Local
final Alias alias,
@InjectService("AssetObjectProvider")
ObjectProvider assetObjectProvider,
ObjectLocator locator)
{
// There's a nasty web of dependencies related to Alias; this wrapper
// class lets us defer instantiating the Alias service implementation just long enough
// to defuse those dependencies. The @Local annotation prevents a recursive call through
// the MasterObjectProvider to resolve the Alias service itself; that is
// MasterObjectProvider gets built using this proxy, then the proxy will trigger the
// construction of AliasImpl (which itself needs MasterObjectProvider to resolve some
// dependencies).
ObjectProvider wrapper = new ObjectProvider()
{
public T provide(Class objectType, AnnotationProvider annotationProvider, ObjectLocator locator)
{
return alias.getObjectProvider().provide(objectType, annotationProvider, locator);
}
};
configuration.add("Alias", wrapper, "after:ServiceOverride");
configuration.add("Asset", assetObjectProvider, "before:AnnotationBasedContributions");
configuration.add("Service", new ServiceAnnotationObjectProvider(), "before:AnnotationBasedContributions");
configuration.add("ApplicationMessages", new ApplicationMessageCatalogObjectProvider(locator),
"before:AnnotationBasedContributions");
}
/**
*
*
StoreIntoGlobals
*
Stores the request and response into {@link org.apache.tapestry5.services.RequestGlobals} at the start of the
* pipeline
*
IgnoredPaths
*
Identifies requests that are known (via the IgnoredPathsFilter service's configuration) to be mapped to other
* applications
*
GZip
*
Handles GZIP compression of response streams (if supported by client)
*/
public void contributeHttpServletRequestHandler(OrderedConfiguration configuration,
@Symbol(SymbolConstants.GZIP_COMPRESSION_ENABLED)
boolean gzipCompressionEnabled,
@Autobuild
GZipFilter gzipFilter,
@InjectService("IgnoredPathsFilter")
HttpServletRequestFilter ignoredPathsFilter)
{
configuration.add("IgnoredPaths", ignoredPathsFilter);
configuration.add("GZIP", gzipCompressionEnabled ? gzipFilter : null, "after:IgnoredPaths");
HttpServletRequestFilter storeIntoGlobals = new HttpServletRequestFilter()
{
public boolean service(HttpServletRequest request, HttpServletResponse response,
HttpServletRequestHandler handler) throws IOException
{
requestGlobals.storeServletRequestResponse(request, response);
return handler.service(request, response);
}
};
configuration.add("StoreIntoGlobals", storeIntoGlobals, "before:*");
}
/**
* Continues a number of filters into the RequestHandler service:
*
*
StaticFiles
*
Checks to see if the request is for an actual file, if so, returns true to let the servlet container process
* the request
*
CheckForUpdates
*
Periodically fires events that checks to see if the file system sources for any cached data has changed (see
* {@link org.apache.tapestry5.internal.services.CheckForUpdatesFilter}).
*
ErrorFilter
*
Catches request errors and lets the {@link org.apache.tapestry5.services.RequestExceptionHandler} handle them
*
*
StoreIntoGlobals
*
Stores the request and response into the {@link org.apache.tapestry5.services.RequestGlobals} service (this
* is repeated at the end of the pipeline, in case any filter substitutes the request or response).
*
*/
public void contributeRequestHandler(OrderedConfiguration configuration, Context context,
@Symbol(SymbolConstants.FILE_CHECK_INTERVAL)
@IntermediateType(TimeInterval.class)
long checkInterval,
@Symbol(SymbolConstants.FILE_CHECK_UPDATE_TIMEOUT)
@IntermediateType(TimeInterval.class)
long updateTimeout,
UpdateListenerHub updateListenerHub,
URLRewriter urlRewriter)
{
RequestFilter staticFilesFilter = new StaticFilesFilter(context);
RequestFilter storeIntoGlobals = new RequestFilter()
{
public boolean service(Request request, Response response, RequestHandler handler) throws IOException
{
requestGlobals.storeRequestResponse(request, response);
return handler.service(request, response);
}
};
RequestFilter fireEndOfRequestEvent = new RequestFilter()
{
public boolean service(Request request, Response response, RequestHandler handler) throws IOException
{
try
{
return handler.service(request, response);
}
finally
{
endOfRequestEventHub.fire();
}
}
};
configuration.add("CheckForUpdates",
new CheckForUpdatesFilter(updateListenerHub, checkInterval, updateTimeout), "before:*");
// we just need the URLRewriterRequestFilter if we have URL rewriter
// rules, of course.
if (urlRewriter.hasRequestRules())
{
URLRewriterRequestFilter urlRewriterRequestFilter = new URLRewriterRequestFilter(urlRewriter);
configuration.add("URLRewriter", urlRewriterRequestFilter, "before:StaticFiles");
}
configuration.add("StaticFiles", staticFilesFilter);
configuration.addInstance("ErrorFilter", RequestErrorFilter.class);
configuration.add("StoreIntoGlobals", storeIntoGlobals, "after:StaticFiles", "before:ErrorFilter");
configuration.add("EndOfRequest", fireEndOfRequestEvent, "after:StoreIntoGlobals", "before:ErrorFilter");
}
/**
* Contributes the basic set of translators:
*
*
string
*
byte
*
short
*
integer
*
long
*
float
*
double
*
BigInteger
*
BigDecimal
*
*/
public static void contributeTranslatorSource(MappedConfiguration configuration,
NumericTranslatorSupport support)
{
configuration.add(String.class, new StringTranslator());
Class[] types = new Class[]
{ Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, BigInteger.class,
BigDecimal.class };
for (Class type : types)
{
String name = type.getSimpleName().toLowerCase();
configuration.add(type, new NumericTranslator(name, type, support));
}
}
/**
* Adds coercions:
*
*
String to {@link SelectModel}
*
String to {@link InsertPosition}
*
Map to {@link oSelectModel}
*
Collection to {@link GridDataSource}
*
null to {@link GridDataSource}
*
String to {@link GridPagerPosition}
*
List to {@link SelectModel}
*
{@link .ComponentResourcesAware} (typically, a component) to {@link ComponentResources}
*
String to {@link BlankOption}
*
{@link ComponentResources} to {@link PropertyOverrides}
*
String to {@link Renderable}
*
{@link Renderable} to {@link Block}
*
String to {@link DateFormat}
*
{@link PrimaryKeyEncoder} to {@link ValueEncoder}
*
String to {@link Resource} (via {@link AssetSource#resourceForPath(String)})
*
{@link Renderable} to {@link RenderCommand}
*
String to {@link LoopFormState}
*
String to {@link SubmitMode}
*
String to {@link Pattern}
*
String to {@link DateFormat}
*
*/
public static void contributeTypeCoercer(Configuration configuration,
@Builtin
TypeCoercer coercer,
@Builtin
final ThreadLocale threadLocale,
@Core
final AssetSource assetSource)
{
configuration.add(CoercionTuple.create(ComponentResources.class, PropertyOverrides.class,
new Coercion()
{
public PropertyOverrides coerce(ComponentResources input)
{
return new PropertyOverridesImpl(input);
}
}));
configuration.add(CoercionTuple.create(String.class, SelectModel.class, new Coercion()
{
public SelectModel coerce(String input)
{
return TapestryInternalUtils.toSelectModel(input);
}
}));
configuration.add(CoercionTuple.create(Map.class, SelectModel.class, new Coercion