Cached Annotation watch property seems to use '==' instead of 'equals'

2008-12-22 Thread Doug Hauge
I'm trying to use the '@Cached' annotation with a watch expression
to cache results of methods in a form contained within a loop. For
some watch expressions, I construct a string, so the code basically
looks like

@Cached(watch="watchKey")
Object getData() {
   // return data;
}

String getWatchKey() {
   return a.toString() + ":" + b.toString();
}

When I do this, though, the cached annotation does not seem to work
properly, in that the 'getData()' method is called multiple times
in a request. The problem seems to be that '==' is used instead of
'equals' in the code 'CachedWorker' generates to compare the result
of the watch expression. Is this intentional, so we need to make sure
the watch expression returns the exact same object if we want to use
a cached value? Or should it be changed to use 'equals'?

Doug


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



How should one create a mixin that can be used to optionally hide a component

2008-11-19 Thread Doug Hauge
We would like to implement a mixin 'IsVisible' that can be applied

to an existing component to specify whether or not the component

should be displayed. Basically, it should evaluate its parameter

and

   1) if false, it should skip all rendering phases of the component

   2) if true, it should continue rendering the component normally

 

This seems to be an ideal use for mixins, I can't seem to find a way

to get it to work that conforms to the documentation at

http://tapestry.apache.org/tapestry5/tapestry-core/guide/rendering.html.

 

The naive implementation 

public class IsVisible {

   @Parameter(required = true)

   private boolean isVisible;



   @SetupRender

   boolean setupRender() {

  return isVisible;

   }

}

 

Works for the most part when returning 'false', but as of Tapestry

5.0.15 returning 'true' causes the component's 'setupRender' to be

skipped. Changing the 'setupRender' signature to

 

Boolean setupRender()

 

and returning 'null' to continue instead of 'true' seemed to work,

but the documentation doesn't indicate that this is allowed, so I

wasn't sure that it is intended behavior and will be supported in

the future.

 

There is another slight problem when returning 'false', in that the

component's 'cleanupRender' will be called even when its

'setupRender' was skipped (similar problem to what was reported in

TAP5-126). This means that the 'IsVisible' cannot be applied to any

component, only those whose 'cleanupRender' was implemented in such

a way that it protects against 'setupRender' not having been called.

This is one instance of a general problem with writing mixins that

are intended to be applied to arbitrary components, in that if a

forward phase is short-circuited by a mixin, that render phase

method is not called for the component, but the corresponding reverse

phase of the component is still called.

 

Regards,

Doug

 



RE: Changing the behavior of short-circuiting render phases (re: TAP5-128, TAP5-126)

2008-11-19 Thread Doug Hauge
Hi Kris,

Thanks, I'll try reopening the issue. From your work on refactoring
the code, do you think the changes that will be needed so solve the
problem are reasonably isolated?

Doug

> -Original Message-
> From: Kristian Marinkovic [mailto:[EMAIL PROTECTED]
> Sent: Monday, November 17, 2008 1:28 AM
> To: Tapestry users
> Subject: Re: Changing the behavior of short-circuiting render phases
> (re: TAP5-128, TAP5-126)
> 
> hi doug,
> 
> all we can do is to reopen the bug and vote for it ... :)
> 
> 
> 
> i guess one of the reasons why this issue does not get resolved
> is the added complexity to the page rendering. first because the
> responsible class ComponentPageElementImpl is already very
> complex (>1000 loc) and it would be necessary to add some state
> information to the rendering process. currently the rendering is
> completely stateless only relying on the static structure of the page.
> 
> i've started to refactor ComponentPageElementImpl just to see
> how it could be solved
> 
> 
> 
> g,
> kris
> 
> 
> 
> 
> "Doug Hauge" <[EMAIL PROTECTED]>
> 15.11.2008 01:57
> Bitte antworten an
> "Tapestry users" 
> 
> 
> An
> "Tapestry users" 
> Kopie
> "Doug Hauge" <[EMAIL PROTECTED]>, "Adam Ayres"
> <[EMAIL PROTECTED]>, "Matt Ayres" <[EMAIL PROTECTED]>
> Thema
> Changing the behavior of short-circuiting render phases (re: TAP5-128,
> TAP5-126)
> 
> 
> 
> 
> 
> 
> 
> 
> As of Tapestry 5.0.16 (after the fix for TAP5-128), we are now running
> into
> a problem related to that described in TAP5-126. You closed the TAP5-
> 126
> issue
> saying that the code was behaving as documented and designed, but it
> seems
> that this behavior leads to problems when trying to implement generic
> mixins
> that can safely be added to arbitrary components. I'd like to check
> whether
> there is any possibility of convincing you to change the behavior so
> the
> reverse phases of a component/mixin are only called if the positive
> phase is
> for the same component mixin (e.g. a component's cleanupRender is
> called
> if
> and only if the component's setupRender was called).
> 
> It also seems odd that returning 'true' will cause other methods
within
> the
> same phase to be bypassed. There thus seems to be no way according to
> the
> documentation at
>
http://tapestry.apache.org/tapestry5/tapestry-core/guide/rendering.html
> to design a mixin that will either short-circuit or continue rendering
> as
> if it didn't exist. The Tapestry code still seems to allow the
behavior
> we need by declaring the render phase method to return 'Boolean', and
> return
> 'null' instead of 'true' to continue processing. However, unless I am
> missing
> something obvious, this is not documented behavior, so it is not clear
> that
> I can rely on it continuing to work.
> 
> The fundamental problem with the short-circuiting behavior as
> documented
> is
> that if a mixin short-circuits a render phase by returning either true
> or
> false, any component that contains it must be carefully written so it
> can
> handle it. Consider a component
> 
> class Component {
> 
>void setupRender() {}
> 
>void beginRender() {}
> 
>void afterRender() {}
> 
>void cleanupRender() {}
> }
> 
> Where 'setupRender' constructs some objects from the component
> parameters, 'beginRender' begins
> an HTML element, 'afterRender' closes the HTML element, and
> 'cleanupRender' cleans up.
> 
> And a mixin
> 
> class Mixin {
>Boolean setupRender() { ... }
> 
>Boolean beforeRender() { ... }
> 
>Boolean afterRender() { ... }
> 
>Boolean cleanupRender() { ... }
> }
> 
> We are returning 'Boolean' here instead of 'boolean' so we have the
> option of not short-circuiting
> anything. If this is not considered supported, instead of returning
> 'null' in the examples below
> simply remove the render phase method from the mixin.
> 
> 1) If 'Mixin.setupRender()' returns 'true', then
> 'Component.cleanupRender()' is not called because
> the phase is short-circuited, but 'Component.beginRender()' is called,
> so 'Component.beginRender()'
> would have to be written in such a way that it handles when
> 'Component.setupRender()' is not called.
> 
> 2) If 'Mixin.setupRender()' returns &#x

Changing the behavior of short-circuiting render phases (re: TAP5-128, TAP5-126)

2008-11-14 Thread Doug Hauge

As of Tapestry 5.0.16 (after the fix for TAP5-128), we are now running
into
a problem related to that described in TAP5-126. You closed the TAP5-126
issue
saying that the code was behaving as documented and designed, but it
seems
that this behavior leads to problems when trying to implement generic
mixins
that can safely be added to arbitrary components. I'd like to check
whether
there is any possibility of convincing you to change the behavior so the
reverse phases of a component/mixin are only called if the positive
phase is
for the same component mixin (e.g. a component's cleanupRender is called
if
and only if the component's setupRender was called).

It also seems odd that returning 'true' will cause other methods within
the
same phase to be bypassed. There thus seems to be no way according to
the
documentation at
http://tapestry.apache.org/tapestry5/tapestry-core/guide/rendering.html
to design a mixin that will either short-circuit or continue rendering
as
if it didn't exist. The Tapestry code still seems to allow the behavior
we need by declaring the render phase method to return 'Boolean', and
return
'null' instead of 'true' to continue processing. However, unless I am
missing
something obvious, this is not documented behavior, so it is not clear
that
I can rely on it continuing to work.

The fundamental problem with the short-circuiting behavior as documented
is
that if a mixin short-circuits a render phase by returning either true
or
false, any component that contains it must be carefully written so it
can
handle it. Consider a component

class Component {

   void setupRender() {}

   void beginRender() {}

   void afterRender() {}

   void cleanupRender() {}
}

Where 'setupRender' constructs some objects from the component
parameters, 'beginRender' begins
an HTML element, 'afterRender' closes the HTML element, and
'cleanupRender' cleans up.

And a mixin

class Mixin {
   Boolean setupRender() { ... }

   Boolean beforeRender() { ... }

   Boolean afterRender() { ... }

   Boolean cleanupRender() { ... }
}

We are returning 'Boolean' here instead of 'boolean' so we have the
option of not short-circuiting
anything. If this is not considered supported, instead of returning
'null' in the examples below
simply remove the render phase method from the mixin.

1) If 'Mixin.setupRender()' returns 'true', then
'Component.cleanupRender()' is not called because
the phase is short-circuited, but 'Component.beginRender()' is called,
so 'Component.beginRender()'
would have to be written in such a way that it handles when
'Component.setupRender()' is not called.

2) If 'Mixin.setupRender()' returns 'null', but 'Mixin.beforeRender()'
returns 'false', then rendering
is short-circuited to the after render phase and
'Component.beforeRender()' is not called. However, the
'Component.afterRender()' method is called, so it would have to be
written in such a way that it handles
The 'Component.beforeRender()' not being called, in this case it would
have to create a property that
records whether the HTML element was started, and only add an end tag if
it was.

Thus, in the most general case, each render phase in the component would
have to be written assuming
that any subset of its previous render phase methods may not have been
called, which leads to overly
complicated code.

Doug







-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



RE: [T5] Localization

2007-08-28 Thread Doug Hauge
Passing parameters into the message formatter directly from HTML seems more 
natural than having to inject a 'Messages' interface into the page and add an 
accessor method for the message any time the number of format parameters is not 
0.

Doug

> -Original Message-
> From: Massimo Lusetti [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, August 28, 2007 2:32 PM
> To: Tapestry users
> Subject: Re: [T5] Localization
> 
> On 8/28/07, Christoph Jaeger <[EMAIL PROTECTED]> wrote:
> 
> > If not, does this seem difficult to implement?
> 
> Using normal ResourceBundle features? And doing that inside javacode
> where logic belongs?
> 
> --
> Massimo
> http://meridio.blogspot.com
> 
> -
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>> -Original Message-
>> From: Christoph Jaeger [mailto:[EMAIL PROTECTED]
>> Sent: Tuesday, August 28, 2007 2:13 PM
>> To: users@tapestry.apache.org
>> Subject: [T5] Localization
>> 
>> Hi,
>> 
>> is there a way to use messages with parameters directly from a HTML
>> template?
>> 
>> Something like:
>> 
>> ${message:results,prop:numberOfDatasets}
>> 
>> with
>> 
>> Page.java
>> 
>> ...
>> public int getNumberOfDatasets()
>> {
>>   return numberOfDatasets;
>> }
>> ...
>> 
>> Page_en.properties:
>> 
>> results: Found %d datasets.
>> 
>> Page_de.properties:
>> 
>> results: %d Datensätze gefunden.
>> 
>> If not, does this seem difficult to implement?
>> 
>> Thanks,
>> 
>> Best Regards,
>> 
>> Christoph Jäger
>> 
>> -
>> To unsubscribe, e-mail: [EMAIL PROTECTED]
>> For additional commands, e-mail: [EMAIL PROTECTED]

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



T5: Tapestry message localization, java.util.Formatter vs. java.text.MessageFormat

2007-08-17 Thread Doug Hauge
Is there some reason Tapestry chose to use 'java.util.Formatter' style
formatting as opposed to 'java.text.MessageFormat' style? The latter
seems preferable for localization, primarily because it has the 'choice'
format type. We would like to use the 'java.text.MessageFormat' style
for our application, and are considering providing our own
implementation of the 'MessageFormatter' service, but the question
becomes how to use this formatting for only our messages. We have
considered decorating the 'ComponentMessagesSource' service, but this
would then apply to all component messages, including those for core
components, which have some text properties that use
'java.util.Formatter' style formatting. We could override these messages
as described in
http://wiki.apache.org/tapestry/Tapestry5HowToOverrideTheDefaultErrorMes
sageBanner, but that seems a bit brittle.

Does anyone else have any need to use 'java.text.MessageFormat' style
formatting, or are we the only ones? Do the solutions mentioned above
sound reasonable?

Thanks,
Doug


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



RE: T5: Changing locale within OnActivate event

2007-08-17 Thread Doug Hauge
I was afraid that would be the answer (I couldn't see any other way
after looking at the code). I was wanting to avoid having to add
duplicate redirection logic to each page, but I'll give it a try and see
how it works. Thanks for the response.

Doug

> -Original Message-
> From: Jesse Kuhnert [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, August 14, 2007 7:22 PM
> To: Tapestry users
> Subject: Re: T5: Changing locale within OnActivate event
> 
> If it's anything like T4 you'll have to either do a redirect back to
> the same page or whatever mechanism is in place to "make a page
> active" somehow and have it do that to the same page.
> 
> All the i18n stuff probably happens in the very beginning while
> setting up the page/components/resources so it has to start over if
> you want to change locales.  I'm sure you know more than I do about
> redirects/page activations in T5 though.
> 
> On 8/14/07, Doug Hauge <[EMAIL PROTECTED]> wrote:
> > In several of our pages, the default locale we want to use for
> messages
> > depends on its activation context. We tried updating the locale
using
> > 'ThreadLocale' from within the activate event handler, but it seems
> that
> > this is too late, for the page has already been loaded and all
> messages
> > in the template resolved using whatever locale was in effect at the
> time
> > of loading. Is there some way we can force the messages to be
> reloaded
> > after setting the thread locale in the activate event handler, or is
> > there some point before the page is loaded at which we can access
the
> > page class and the activation context in order to set the locale?
> >
> > Thanks,
> > Doug
> >
> >
> >
-
> > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > For additional commands, e-mail: [EMAIL PROTECTED]
> >
> >
> 
> 
> --
> Jesse Kuhnert
> Tapestry/Dojo team member/developer
> 
> Open source based consulting work centered around
> dojo/tapestry/tacos/hivemind. http://blog.opencomponentry.com
> 
> -
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



T5: Changing locale within OnActivate event

2007-08-14 Thread Doug Hauge
In several of our pages, the default locale we want to use for messages
depends on its activation context. We tried updating the locale using
'ThreadLocale' from within the activate event handler, but it seems that
this is too late, for the page has already been loaded and all messages
in the template resolved using whatever locale was in effect at the time
of loading. Is there some way we can force the messages to be reloaded
after setting the thread locale in the activate event handler, or is
there some point before the page is loaded at which we can access the
page class and the activation context in order to set the locale?

Thanks,
Doug


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Problem with non-ASCII form parameters in form containing upload component

2007-07-06 Thread Doug Hauge
I am running into an encoding problem with form parameter values that
contain non-ASCII characters in a form that contains an upload
component. Without the upload component everything works fine. The
problem appears to be in the handling of strings in
'multipart/form-data', in that both Firefox and Mozilla seem to send
strings encoded as UTF-8, but don't specify a character set, and the
upload component interprets these as ISO-8559-1. This actually seems to
be the correct response to incorrect behavior by the browsers, but in
practice we need to find a workaround. I can't find a way to get around
this without modifying the tapestry-upload project, and I was wondering
if anyone could suggest a better solution, and if not whether Tapestry
itself will deal with this in the future

Our simple, hack workaround is to modify
'MultipartDecoderImpl.processFileItems(...)' to call

wrapper.addParameter(item.getFieldName(), item.getString("UTF8"))

instead of

wrapper.addParameter(item.getFieldName(), item.getString())

To improve this, I think we would need

1) To have a way of passing in an appropriate default encoding to use.
We could contribute a 'HttpServletRequestHandler' that sets the
request's default character encoding, but is there a way to guarantee
that our handler would be called before the
'MultipartServletRequestFilter'?

2) Even if did (1), we would need a way to use this encoding to parse
strings multipart form fields. Passing the encoding to
'FileItem.getString()' is undesirable because it would not handle the
case where the part's 'charset' parameter was explicitly set. The
parameterless version of 'FileItem.getString()' cannot be used, however,
because it explicitly defaults to 'ISO-8859-1' if the character set is
not specified (e.g. it uses neither the request's character encoding or
the header encoding set by 'FileUpload.setHeaderEncoding'). I can't find
a nice way to do this without duplicating some code in
'commons-fileupload' or relying on public methods of 'DiskFileItem' that
aren't in the 'FileItem' interface.

Thanks,
Doug



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



T5: Passing parameters to deeply nested components without having to pass it to all intervening components

2007-06-22 Thread Doug Hauge
Is there a way to pass a parameter from an outer component to a deeply
nested inner component without having to explicitly pass the parameter
to all intervening components? Basically, we have a parameter, 'node',
whose value is calculated at the page level when handling the 'activate'
event from the activation parameters. Suppose we have components 'A',
'B', 'C', 'D', where the page references 'A', 'A' references 'B', 'B'
references 'C', and 'C' references 'D'. Component 'D' needs the value of
'node', but 'A', 'B', and 'C' don't, so we would like to avoid having to
declare the 'node' parameter in those intervening components and passing
the value in explicitly. I can't seem to find a way to do this. I have
considered

1) Creating a service for calculating the code, but the calculation
requires page parameters, and I can't think of a way to access to these
from a service builder method (outside of nasty hacks like setting the
value in a thread local variable).

2) Creating a new parameter binding factory that traverses up component
containers until it finds one that has the named binding. However,
'ComponentResources' can get a binding type and see if a parameter is
bound, but it does not provide access to the parameter binding itself.
'InternalComponentResources' provides read and write access to the
parameter, but we aren't supposed to use internal services.

Am I missing something?

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



T5: Problems with Upload component interaction with non-Tapestry servlets

2007-06-21 Thread Doug Hauge
We are running Tapestry in a hybrid environment, where some pages are
handled by Tapestry and the rest are handled by a legacy servlet. We are
using the new Upload component, and are running into a problem where
requests with multipart content are processed by services installed by
the Upload component even if the page is not a Tapestry page, which
interferes with the processing of multipart content on our pages. What
seems to happen is

1) A request with multipart content is received
2) Control is passed to the Tapestry Filter
3) Before determining whether the request is for a tapestry page, the
MultipartServletRequestFilter process the request
4) The Tapestry Filter decides it does not recognize the page, and
passes the request on to our servlet
5) Our servlet tries to process the multipart request, but fails because
the request stream has already been read

We have a workaround where we turn our servlet into a filter that is
included before the Tapestry filter, but we run into the same problem in
reverse: our filter processes the multipart request before passing
control to the Tapestry filter, preventing it from being able to process
the multipart request. We can avoid the problem if we can recognize
whether we should pass control on to Tapestry before we process the
multipart request, but I do not know of a way to ask Tapestry if a URL
is for one of its pages (and doing the same for ours would be a bit of
work at this time). 

I guess there are two fundamental questions

1) Should Tapestry avoid having its handlers process a request until it
knows that it is processing a Tapestry page?
2) Is there a call we can make to determine whether Tapestry will handle
a given URL?

Thanks,
Doug

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



RE: T5: Customizing generation of client id from component id

2007-03-23 Thread Doug Hauge

Thanks for the response. We are in the process of migrating our
application to Tapestry, and in the process making it more easily
customizable and testable. The solution we are looking for seems
to be a reasonable way to satisfy the following constraints:

1) Within a component, identifiers given to sub-components should 
be as simple as possible while being descriptive. For most components,
little thought should be required about what other components might
appear in the page. 

2) Within a page, components should be able to be rearranged, added,
and removed without affecting the identifier given to the associated
element(s) in the rendered HTML. Such an immutable identifier is
useful for Selenium tests that are valid across such page modifications.

3) In keeping with the DRY principle, we would like to avoid requiring
a mixin or other boilerplate code to be included in all our components
in order to construct unique identifiers.

The problem is that (1) can easily lead to a case where multiple
components specify the same component id for their children, because
the component writer has no knowledge of what other components may
be placed in the page, and in order to keep the component id simple
we don't want to require the component writer to always apply a
prefix to increase the likelihood of uniqueness. All that we want to
require of the component writer is that within the component, all the
identifiers are unique. There might also be cases where the same
component is included multiple times within a page, either directly
or indirectly. 

Note that an ideal solution for us would also allow us to similarly
transform id attributes on HTML elements in the template. If we can't,
we either have to avoid specifying identifiers on raw HTML elements
or to make sure that all components that may ever be placed
on a page choose identifiers that are unique among those components.

We have a temporary solution now that uses a mixin that traverses the
DOM and adjusts identifiers in its 'afterRender' method, but this
violates (3) and is a bit of a kludge.

Thanks,
Doug

> -Original Message-
> From: Howard Lewis Ship [mailto:[EMAIL PROTECTED]
> Sent: Friday, March 23, 2007 3:56 PM
> To: Tapestry users
> Subject: Re: T5: Customizing generation of client id from component id
> 
> I'm afraid that's a use case that wasn't foremost in my mind when
> coding this stuff up for T5.  Still, if you explicitly set component
> ids, it's highly unlikely that they'll change dramatically from one
> build to the next ... could you elaborate on the situation that drove
> you towards this kind of solution?
> 
> On 3/23/07, Doug Hauge <[EMAIL PROTECTED]> wrote:
> > Is there a way to customize the generation of a unique client id
from a
> > component id? We would like to generate the unique id in such a way
that
> > it would not change across most modifications to a page, mainly so
> > Selenium tests can be written that will work across page redesign.
The
> > current method of appending a suffix to a component id does not seem
to
> > allow this, so we would like to be able to generate a unique id by
> > prepending the component ids of ancestral components. We could
> > potentially implement our own PageRenderSupport service, but the
> > 'allocateClientId' method only takes a string parameter, so we don't
> > have the context we would need (in particular, the
ComponentResources of
> > the component for which we are generating the id).
> >
> >
> >
> > Thanks,
> >
> > Doug
> >
> >
> >
> >
> >
> >
> 
> 
> --
> Howard M. Lewis Ship
> TWD Consulting, Inc.
> Independent J2EE / Open-Source Java Consultant
> Creator and PMC Chair, Apache Tapestry
> Creator, Apache HiveMind
> 
> Professional Tapestry training, mentoring, support
> and project work.  http://howardlewisship.com
> 
> -
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



T5: Customizing generation of client id from component id

2007-03-23 Thread Doug Hauge
Is there a way to customize the generation of a unique client id from a
component id? We would like to generate the unique id in such a way that
it would not change across most modifications to a page, mainly so
Selenium tests can be written that will work across page redesign. The
current method of appending a suffix to a component id does not seem to
allow this, so we would like to be able to generate a unique id by
prepending the component ids of ancestral components. We could
potentially implement our own PageRenderSupport service, but the
'allocateClientId' method only takes a string parameter, so we don't
have the context we would need (in particular, the ComponentResources of
the component for which we are generating the id). 

 

Thanks,

Doug