001 // Copyright 2007, 2008 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.tapestry5.tutorial.services;
016
017 import org.apache.tapestry5.SymbolConstants;
018 import org.apache.tapestry5.ioc.MappedConfiguration;
019 import org.apache.tapestry5.ioc.OrderedConfiguration;
020 import org.apache.tapestry5.ioc.annotations.Local;
021 import org.apache.tapestry5.services.Request;
022 import org.apache.tapestry5.services.RequestFilter;
023 import org.apache.tapestry5.services.RequestHandler;
024 import org.apache.tapestry5.services.Response;
025 import org.slf4j.Logger;
026
027 import java.io.IOException;
028
029 /**
030 * This module is automatically included as part of the Tapestry IoC Registry, it's a good place to configure and extend
031 * Tapestry, or to place your own services.
032 */
033 public class AppModule
034 {
035 public static void contributeApplicationDefaults(
036 MappedConfiguration<String, String> configuration)
037 {
038 // Contributions to ApplicationDefaults will override any contributions to
039 // FactoryDefaults (with the same key). Here we're restricting the supported
040 // locales to just "en" (English). As you add localised message catalogs and other assets,
041 // you can extend this list of locales (it's a comma seperated series of locale names;
042 // the first locale name is the default when there's no reasonable match).
043
044 configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en");
045 configuration.add(SymbolConstants.PRODUCTION_MODE, "false");
046 }
047
048 /**
049 * This is a service definition, the service will be named TimingFilter. The interface, RequestFilter, is used
050 * within the RequestHandler service pipeline, which is built from the RequestHandler service configuration.
051 * Tapestry IoC is responsible for passing in an appropriate Log instance. Requests for static resources are handled
052 * at a higher level, so this filter will only be invoked for Tapestry related requests.
053 */
054 public RequestFilter buildTimingFilter(final Logger logger)
055 {
056 return new RequestFilter()
057 {
058 public boolean service(Request request, Response response, RequestHandler handler)
059 throws IOException
060 {
061 long startTime = System.currentTimeMillis();
062
063 try
064 {
065 // The reponsibility of a filter is to invoke the corresponding method
066 // in the handler. When you chain multiple filters together, each filter
067 // received a handler that is a bridge to the next filter.
068
069 return handler.service(request, response);
070 }
071 finally
072 {
073 long elapsed = System.currentTimeMillis() - startTime;
074
075 logger.info(String.format("Request time: %d ms", elapsed));
076 }
077 }
078 };
079 }
080
081 /**
082 * This is a contribution to the RequestHandler service configuration. This is how we extend Tapestry using the
083 * timing filter. A common use for this kind of filter is transaction management or security.
084 */
085 public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration,
086
087 @Local
088 RequestFilter filter)
089 {
090 // Each contribution to an ordered configuration has a name, When necessary, you may
091 // set constraints to precisely control the invocation order of the contributed filter
092 // within the pipeline.
093
094 configuration.add("Timing", filter);
095 }
096 }