This thread is a little stale, apologies, but it's been a crazy month, and this topic deserves more consideration.

As a long time user of Tapestry (since T3) and an early adopter of T5 (since ~T5.0.0), my experience with type coercion has been love/hate. But mostly hate. When there was only TypeCoercer to think about, things were much simpler. There was only one possible path of type coercion for the entire system, and, importantly, things ... just... worked.

With the introduction of:
  Translator
  ValueEncoder
  PrimaryKeyEncoder

We have not one, but FOUR systems of type coercion.

I know that Howard has expressed concern over separation of concerns as being the motivator for the additional conversion interfaces, but I submit that the additional interfaces, in fact, pollute separation of concerns.

Take Translator: it's trying to act both as a type coercion system (value -> string and back) and as a first-pass validation system.
or:
PrimaryKeyEncoder: acting both as a simplistic batching mechanism (by stashing the set of keys used into the form, and providing a mechanism to convert those keys back to values en masse) and as a type coercion system (value -> serializable and back)

I'm not disputing the utility of any of the functions provided by the various systems. I'm disputing the complexity of the system. For a novice user, it's confusing and adds additional learning-burden that doesn't need to be there.

Consider, for example, trying to learn a few of the built-in components:

textfield: translator
Context of links: /normally/ value encoder and decoder (quietly). Except when your handler takes a type of Object[]. And then you get back strings, and if you don't explicitly arrange for the ValueEncoder to do the decoding, tapestry tries to use TypeCoercer, which screws up. (See example later).

DateField: I would expect translator, but, hey, no, it's not... it's a java.text.DateFormat. Grid: ?? No explicit encoding mechanism provided. Presumably.... value encoder? Loop: PrimaryKeyEncoder (<sarcasm>since, clearly, the only thing we're /ever/ going to loop over is a database entity with a serializable primary key</sarcasm>)
AjaxFormLoop: PrimaryKeyEncoder
Select: PrimaryKeyEnco.... oh... wait... ValueEncoder. Shucks. Just when I thought I was starting to get this straight. Oh, right, unlike with Loop, I might want to use non-entities in a Select. Clear as mud.
textarea: translator
textfield: translator


Because I've been using tapestry, and T5, for a long while now, I can understand the rationale behind each of these choices. But from the perspective of a new user, the framework appears schizophrenic.

In fact, the framework doesn't even always "get it right". Take the following example:

public class SomeComponent {
  @Parameter
  private Object[] parameters;

  @Component(parameters="context=inherit:context")
  private ActionLink someAction;

  @Inject
  private ComponentResources resources;

  void onActionFromSomeAction(Object[] parameters) {
      resources.triggerEvent("SomeComponentEvent",parameters,null);
  }
}

This seems to be perfectly legitimate code. And is potentially a very powerful paradigm. However, try using "SomeComponent" with a hibernate entity encoded via the value encoder in the hibernate module, and the framework explodes. The cause, after some digging, is that the framework encodes values into the url using a value encoder, but the decoding will be done by type coercer (in the above example). There is a workaround: provide your own event context that uses value encoder. But there shouldn't /need/ for a workaround. Type coercion should just work, with absolutely no thought from the user. Ironically, this was the case when all we had was TypeCoercer. But the additional interfaces obscure that simplicity and reliability.

Robert

On Sep 15, 2008, at 9/159:53 AM , Howard Lewis Ship wrote:

On Mon, Sep 15, 2008 at 4:31 AM, Kevin Menard <[EMAIL PROTECTED]> wrote:
I'll test this is the next few days, but don't expect to see anything
problematic.

I guess the whole RC thing snuck up on me though.  I'd really like to
see the whole type coercion system looked at again.  I know we've
ping-ponged on this a few times, but the framework has evolved a fair
bit since then and I do think it's worth another look.  As Robert
pointed out in TAPESTRY-2491, we have four ways of doing type
coercion:

Translators

Very tied into form mechanics; not general purpose; used for moving
between strings and arbitrary values.  User input based, with hooks
for client-side validation.





ValueEncoders

Specific to encoding a value into a string, for use inside a URL or
something similar.  Really means for entity values, rather than user
input values.

PrimaryKeyEncoders

Similar to ValueEncoders, but not necessarily a String, just a
Serializable.  Also meant for entity values. Includes a performance
optimization that allows many entities to be efficiently pre-loaded.

TypeCoercers

Very low-level; used in tapestry-ioc, not just tapestry-core. Designed
to be combinable.   Primarily meant for converting parameters from
actual types to desired types but often used as the basis of the other
three.


While I can appreciate the value of each being used in a particular
context, it seems as though the framework is even inconsistent with
its usage at times.  Any custom implementation of one almost implies
an implementation of the others and more often than not a simple
adapter is used because the code is so common between them all.  It
strikes me as something that's perhaps over-engineered and the
practicality of a single interface may trump the separation of
concerns benefit.  I think it's one of the framework's "gotchas" that
we could address without much hassle.

I still see the simularities as pretty shallow, and the differences as
pretty deep.


If we do decide to keep the system as is, I guess that's fine as well.
It's not really broken.  But, I would like to see some discussion on
it leading to some decisive path.

--
Thanks,
Kevin



On Sat, Sep 13, 2008 at 7:18 PM, Howard Lewis Ship <[EMAIL PROTECTED]> wrote:
I've fixed a few more bugs for 5.0.15 and updated the Maven and
src/bin distributions, as previously discussed here.


I've created and uploaded a release of Tapestry 5.0.15, ready to be
voted upon.  This is the release candidate.

The files are uploaded to:

http://people.apache.org/~hlship/tapestry-releases/

and a Maven repository:

http://people.apache.org/~hlship/tapestry-ibiblio-rsynch-repository/

Please examine these files to determine if a new preview release,
5.0.15, is ready.

I've also created a 5.0.15 tag in Subversion:

http://svn.apache.org/viewvc/tapestry/tapestry5/tags/releases/ 5.0.15/

On a successful vote, I'll move the files from these directories to
the proper distribution directories.

Vote will run for three days; on success I'll move the voted artifacts
into place and send out appropriate notifications.

I'm looking forward to having several weeks of exposure of the release candidate. If no critical, unpatchable errors occur, this can be the 5.0 GA. I'm already looking forward to doing some ambitious things in
the 5.1. release.


Howard M. Lewis Ship: +1 (binding)

--
Howard M. Lewis Ship

Creator Apache Tapestry and Apache HiveMind

---------------------------------------------------------------------
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]





--
Howard M. Lewis Ship

Creator Apache Tapestry and Apache HiveMind

---------------------------------------------------------------------
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]

Reply via email to