package hello.services;

import java.io.IOException;

import org.apache.tapestry5.*;
import org.apache.tapestry5.ioc.MappedConfiguration;
import org.apache.tapestry5.ioc.OrderedConfiguration;
import org.apache.tapestry5.ioc.ServiceBinder;
import org.apache.tapestry5.ioc.annotations.Local;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.RequestFilter;
import org.apache.tapestry5.services.RequestHandler;
import org.apache.tapestry5.services.Response;
import org.slf4j.Logger;

/**
 * This module is automatically included as part of the Tapestry IoC Registry, it's a good place to
 * configure and extend Tapestry, or to place your own service definitions.
 */
public class AppModule
{
    public static void bind(ServiceBinder binder)
    {
        // binder.bind(MyServiceInterface.class, MyServiceImpl.class);

        // Make bind() calls on the binder object to define most IoC services.
        // Use service builder methods (example below) when the implementation
        // is provided inline, or requires more initialization than simply
        // invoking the constructor.
    }

    public static void contributeFactoryDefaults(
            MappedConfiguration<String, Object> configuration)
    {
        // The application version number is incorprated into URLs for some
        // assets. Web browsers will cache assets because of the far future expires
        // header. If existing assets are changed, the version number should also
        // change, to force the browser to download new versions. This overrides Tapesty's default
        // (a random hexadecimal number), but may be further overriden by DevelopmentModule or
        // QaModule.
        configuration.override(SymbolConstants.APPLICATION_VERSION, "1.0-SNAPSHOT");
    }

    public static void contributeApplicationDefaults(
            MappedConfiguration<String, Object> configuration)
    {
        // Contributions to ApplicationDefaults will override any contributions to
        // FactoryDefaults (with the same key). Here we're restricting the supported
        // locales to just "en" (English). As you add localised message catalogs and other assets,
        // you can extend this list of locales (it's a comma separated series of locale names;
        // the first locale name is the default when there's no reasonable match).
        configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en");
    }


    /**
     * This is a service definition, the service will be named "TimingFilter". The interface,
     * RequestFilter, is used within the RequestHandler service pipeline, which is built from the
     * RequestHandler service configuration. Tapestry IoC is responsible for passing in an
     * appropriate Logger instance. Requests for static resources are handled at a higher level, so
     * this filter will only be invoked for Tapestry related requests.
     * <p/>
     * <p/>
     * Service builder methods are useful when the implementation is inline as an inner class
     * (as here) or require some other kind of special initialization. In most cases,
     * use the static bind() method instead.
     * <p/>
     * <p/>
     * If this method was named "build", then the service id would be taken from the
     * service interface and would be "RequestFilter".  Since Tapestry already defines
     * a service named "RequestFilter" we use an explicit service id that we can reference
     * inside the contribution method.
     */
    public RequestFilter buildTimingFilter(final Logger log)
    {
        return new RequestFilter()
        {
            public boolean service(Request request, Response response, RequestHandler handler)
                    throws IOException
            {
                long startTime = System.currentTimeMillis();

                try
                {
                    // The responsibility of a filter is to invoke the corresponding method
                    // in the handler. When you chain multiple filters together, each filter
                    // received a handler that is a bridge to the next filter.

                    return handler.service(request, response);
                } finally
                {
                    long elapsed = System.currentTimeMillis() - startTime;

                    log.info(String.format("Request time: %d ms", elapsed));
                }
            }
        };
    }

    /**
     * This is a contribution to the RequestHandler service configuration. This is how we extend
     * Tapestry using the timing filter. A common use for this kind of filter is transaction
     * management or security. The @Local annotation selects the desired service by type, but only
     * from the same module.  Without @Local, there would be an error due to the other service(s)
     * that implement RequestFilter (defined in other modules).
     */
    public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration,
                                         @Local
                                         RequestFilter filter)
    {
        // Each contribution to an ordered configuration has a name, When necessary, you may
        // set constraints to precisely control the invocation order of the contributed filter
        // within the pipeline.

        configuration.add("Timing", filter);
    }
}

@@ -167,347 +167,19 @@
 ioc.
-OrderedConfiguration;%0Aimport org.apache.tapestry5.ioc.ServiceBinder;%0Aimport org.apache.tapestry5.ioc.annotations.Local;%0Aimport org.apache.tapestry5.services.Request;%0Aimport org.apache.tapestry5.services.RequestFilter;%0Aimport org.apache.tapestry5.services.RequestHandler;%0Aimport org.apache.tapestry5.services.Response;%0Aimport org.slf4j.Logg
+ServiceBind
 er;%0A
@@ -2029,16 +2029,16 @@
 match).%0A
+
         
@@ -2107,2936 +2107,6 @@
   %7D%0A
-%0A%0A    /**%0A     * This is a service definition, the service will be named %22TimingFilter%22. The interface,%0A     * RequestFilter, is used within the RequestHandler service pipeline, which is built from the%0A     * RequestHandler service configuration. Tapestry IoC is responsible for passing in an%0A     * appropriate Logger instance. Requests for static resources are handled at a higher level, so%0A     * this filter will only be invoked for Tapestry related requests.%0A     * %3Cp/%3E%0A     * %3Cp/%3E%0A     * Service builder methods are useful when the implementation is inline as an inner class%0A     * (as here) or require some other kind of special initialization. In most cases,%0A     * use the static bind() method instead.%0A     * %3Cp/%3E%0A     * %3Cp/%3E%0A     * If this method was named %22build%22, then the service id would be taken from the%0A     * service interface and would be %22RequestFilter%22.  Since Tapestry already defines%0A     * a service named %22RequestFilter%22 we use an explicit service id that we can reference%0A     * inside the contribution method.%0A     */%0A    public RequestFilter buildTimingFilter(final Logger log)%0A    %7B%0A        return new RequestFilter()%0A        %7B%0A            public boolean service(Request request, Response response, RequestHandler handler)%0A                    throws IOException%0A            %7B%0A                long startTime = System.currentTimeMillis();%0A%0A                try%0A                %7B%0A                    // The responsibility of a filter is to invoke the corresponding method%0A                    // in the handler. When you chain multiple filters together, each filter%0A                    // received a handler that is a bridge to the next filter.%0A%0A                    return handler.service(request, response);%0A                %7D finally%0A                %7B%0A                    long elapsed = System.currentTimeMillis() - startTime;%0A%0A                    log.info(String.format(%22Request time: %25d ms%22, elapsed));%0A                %7D%0A            %7D%0A        %7D;%0A    %7D%0A%0A    /**%0A     * This is a contribution to the RequestHandler service configuration. This is how we extend%0A     * Tapestry using the timing filter. A common use for this kind of filter is transaction%0A     * management or security. The @Local annotation selects the desired service by type, but only%0A     * from the same module.  Without @Local, there would be an error due to the other service(s)%0A     * that implement RequestFilter (defined in other modules).%0A     */%0A    public void contributeRequestHandler(OrderedConfiguration%3CRequestFilter%3E configuration,%0A                                         @Local%0A                                         RequestFilter filter)%0A    %7B%0A        // Each contribution to an ordered configuration has a name, When necessary, you may%0A        // set constraints to precisely control the invocation order of the contributed filter%0A        // within the pipeline.%0A%0A        configuration.add(%22Timing%22, filter);%0A    %7D%0A
 %7D%0A

Remove timing filter