You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Lutz Hühnken <lh...@googlemail.com> on 2012/01/25 21:02:15 UTC

Re: Want locale to be part of every uri

Hi Nillehammer,

I was facing the same task and took the liberty of using your code -
works like a charm! Thanks for that!

One thing though... it will redirect with a "302 - Found" code, while
I need it to return a "301 - moved permanently".

Maybe it's because it is late, but I can't seem to figure out how to
change that. Do I need to add a custom ComponentEventResultProcessor?
For a custom result type, as "Link" is already being handled?

Or am I overlooking something?

I appreciate your help,

Lutz



On Fri, Jul 1, 2011 at 2:54 AM, Nillehammer
<ta...@winfonet.eu> wrote:
> Hi Thiago,
>
>> I've never tried a ComponentRequestFilter for doing things that involved
>> redirection, as they are invoked way later in the Tapestry processing
>> pipeline. Please post if it works. ;)
>
> It turned out that ComponentRequestFilter has several advandatages over
> RequestFilter:
> 1.) If a locale is present in the uri, the PersistentLocale is set. No
> workaround using ComponentEventLinkEncoder's decodeXXX methods needed.
> 2.) The ThreadLocale already contains a supported locale that can be safely
> used to set the PersistentLocale. In RequestFilter the ThreadLocale is still
> the raw one taken from the request. Which might not be in supported-locales.
> 3.) The methods handlePageRender(...) and handleComponentEvent(...) are a
> directer way of distiguishing between the two types. In
> RequestFilter.service(...) you would have to distinguish them on your own by
> decoding the request with ComponentEventLinkEncoder.
> 4.) In handleComponentEvent you only have to set the persistent locale.
> Tapestry generates redirects for component events anyway. So you don't need
> to bother.
>
> The only (slightly) hard part is building a redirect mechanism in
> handlePageRender(...). I surfed through Tapestry's source code and found out
> that PageRenderRequestHandlerImpl uses a ComponentEventResultProcessor for
> that purpose. I have done that too.
>
> Thanks to you and Howard for helping. And speeking of locales. Its almost
> 03:00 am local time now. I really need to go to bed. My boss is gonna kill
> me, if I oversleep (again).
> Cheers, nillehammer
>
> P.S. The code:
> PersistentLocaleFilter.java:
> /**
>  * Checks, if persistent locale is set. If not will do so and send redirect,
> if
>  * necessary.
>  */
> final class PersistentLocaleFilter implements ComponentRequestFilter {
>
>    /**
>     * Used to set the persistent locale (that's what this filter is all
> about).
>     */
>    private final PersistentLocale persistentLocale;
>
>    /**
>     * Used to determine current locale, if persistent locale is not set.
>     */
>    private final ThreadLocale threadLocale;
>
>    /**
>     * Used to generate a page render link in
>     * {@link #handlePageRender(PageRenderRequestParameters,
> ComponentRequestHandler)}
>     * .
>     */
>    private final ComponentEventLinkEncoder componentEventLinkEncoder;
>
>    /**
>     * Used to add request parameters to the page render link.
>     */
>    private final Request request;
>
>    /**
>     * Used to process the page render link as a redirect.
>     */
>    private final ComponentEventResultProcessor<Link>
> componentEventResultProcessor;
>
>    /**
>     * Constructor injecting all dependencies.
>     *
>     * @param persistentLocale
>     * @param threadLocale
>     * @param componentEventLinkEncoder
>     * @param request
>     * @param componentEventResultProcessor
>     */
>    PersistentLocaleFilter(final PersistentLocale persistentLocale,
>            final ThreadLocale threadLocale,
>            final ComponentEventLinkEncoder componentEventLinkEncoder,
>            final Request request,
>            final ComponentEventResultProcessor<Link>
> componentEventResultProcessor) {
>
>        this.persistentLocale = persistentLocale;
>
>        this.threadLocale = threadLocale;
>
>        this.componentEventLinkEncoder = componentEventLinkEncoder;
>
>        this.request = request;
>
>        this.componentEventResultProcessor = componentEventResultProcessor;
>    }
>
>    /**
>     * Sets persistent locale if necessary and hands over to the rest of the
>     * chain. Tapestry is generating redirects for component events anyway,
> so we
>     * do not need to do that.
>     */
>    @Override
>    public final void handleComponentEvent(
>            final ComponentEventRequestParameters parameters,
>            final ComponentRequestHandler handler ) throws IOException {
>
>        setPersistentLocaleIfNecessary();
>
>        handler.handleComponentEvent(parameters);
>    }
>
>    /**
>     * Sets persistent locale if necessary and creates a page render link to
>     * redirect to.
>     */
>    @Override
>    public final void handlePageRender(
>            final PageRenderRequestParameters parameters,
>            final ComponentRequestHandler handler ) throws IOException {
>
>        if (setPersistentLocaleIfNecessary()) {
>
>            final Link pageRedirectLink = this.componentEventLinkEncoder
>                    .createPageRenderLink(parameters);
>
>            /*
>             * pageRedirectLink lacks possible request parameters. We add
> them
>             * manually. Anchor needs not be added. It stays in the address
> bar by
>             * some magic I don't understand.
>             */
>            for (final String paramName : this.request.getParameterNames()) {
>
>                pageRedirectLink.addParameter(paramName,
>                        this.request.getParameter(paramName));
>            }
>
>
>  this.componentEventResultProcessor.processResultValue(pageRedirectLink);
>
>            return;
>        }
>
>        handler.handlePageRender(parameters);
>    }
>
>    /**
>     * Checks if persistent locale is set and will set it if necessary.
>     *
>     * @return true, if persistent locale WAS NOT set and therefore had to be
> set,
>     *         otherwise false
>     */
>    private final boolean setPersistentLocaleIfNecessary() {
>
>        if (!this.persistentLocale.isSet()) {
>
>            /*
>             * ThreadLocale contains a supported locale. So we can safely use
> that
>             * here. No need for LocalizationSetter.
>             */
>            this.persistentLocale.set(this.threadLocale.getLocale());
>
>            return true;
>        }
>
>        return false;
>    }
> }
>
> And in AppModule.java:
>    public static final ComponentRequestFilter buildPersistentLocaleFilter(
>            final PersistentLocale persistentLocale,
>            final ThreadLocale threadLocale,
>            final ComponentEventLinkEncoder componentEventLinkEncoder,
>            final Request request,
>            @InjectService("ComponentEventResultProcessor")
>                final ComponentEventResultProcessor<Link>
> componentEventResultProcessor ) {
>
>        return new PersistentLocaleFilter(persistentLocale, threadLocale,
>                componentEventLinkEncoder, request,
> componentEventResultProcessor);
>    }
>
>    public static final void contributeComponentRequestHandler(
>            final OrderedConfiguration<ComponentRequestFilter> configuration,
>            @InjectService("persistentLocaleFilter") final
> ComponentRequestFilter persistentLocaleFilter ) {
>
>        configuration.add("persistentLocaleFilter", persistentLocaleFilter,
>                "before:*");
>    }
>
>
> --
> http://www.winfonet.eu
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>



-- 
altocon GmbH
http://www.altocon.de/
Software Development, Consulting
Hamburg, Germany

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org