Levi Cook wrote:
> 
> ----- Original Message -----
> From: "Paul Speed" <[EMAIL PROTECTED]>
> To: <[EMAIL PROTECTED]>
> Sent: Monday, June 25, 2001 12:42 PM
> Subject: Re: Struts 1.1 TODO List -- Event and Listener Model
> 
> >
> >
> > Levi Cook wrote:
> > >
> > >
> > > Conversion: Property editors getAsText & setAsText- all request
> attributes
> > > are strings, turning them into full-fledged java objects is why this
> > > infrastructure exists.
> >
> > I hate to keep being the PropertyEditor stick in the mud. :)  But
> > a property editor is a huge amount of overhead just to do text
> > conversion...
> 
> No problem, I'm a stick in the mud too..

Heh.  And we may have split this argument into too many forks, but
I'm going to try to hit them all.

Just for background, I've developed an entire Swing framework built
on property editors.  Even in swing-land, property editors are a pain
in the butt.  In retrospect I wish I had done something different.
More interspersed...  (and it's long too)

> 
> So what defines huge? 4-5 years ago Java was doomed because carrying around
> a runtime environment and placing its footprint into memory was considered
> ridiculous. Similar arguments have been applied to single ancestor
> inheritance models becuase every object in the system has all the attributes
> and methods of the common ancestor, whether they need it or not. This can be
> very wasteful of space and cpu time, right?? On one end these issues could
> be a source of endless debate. On the other, we could funnel it away behind
> a more request-response oriented interface.

By huge I mean contains a lot of cruft that won't be utilized by
form processing.

Development and life cycle of a property editor implementation:

Create a new property editor class called BigDecimalEditor.

Extend PropertyEditorSupport so that you don't have to create 
default implementations for all of the component based methods
and just override setAsText() and getAsText() to properly convert
to and from String.

Register the BigDecimalEditor class with the PropertyEditorManager
or just let it search for it by itself since in this case BigDecimals
will use BigDecimalEditor.

Now, when editing a bean that has a BigDecimal property:

Get the bean property and clone it, or if null create a new 
BigDecimal.  (Note: cannot use shared mutable objects in editors
because it breaks the property editor spec.)  I mention the idiom
in that way because for generic handling you need to make sure
the property editor is initialized using setValue()... however,
in this case we can take a short-cut and just use the string from
the form bean if we really wanted to.

Ask PropertyEditorManager to create a new PropertyEditor for the
BigDecimal.class.  It will do its search for the right class and
instantiate a new BigDecimalEditor instance for us.

Now, we call setValue() with our BigDecimal and/or we call 
setAsText() with the string value from the form bean.

After that, we call getValue() to get the converted BigDecimal
object.

What does this mean?  All data types must have explicit classes
defining their type so the lookup will work.  All data types
that have different parsing restrictions must have their own
property editor class.  For example, a BigDecimalEditor that
allows only two decimal places to be entered would have to
be a different class for the property and a different class for
the property type than a BigDecimalEditor that allowed up to
four decimal places.

This is all because property editors are designed to hold their
value outside of the bean.  This means that a new property editor
instance must be created for each property.  (To do it the normal
way.)  It also means that mapping is based on class and therefore
allows no special setup for a given property editor instance.

An alternative to PropertyEditors would be some kind of Converter
objects.  Converter _instances_ could be registered for different
types.  This allows the same converter class to be reused but with
different setup, ie: 2 decimal places versus 4, etc..  If you create
an abstraction for types to wrap Class then you can even have 
different converters for what is essentially the same property type,
ie: you don't have to define two subclasses of BigDecimal: 
BigDecimalFour, BigDecimalTwo... you'd only have to define two 
different type keys and somehow associate them with your properties.
(We use extra meta-data to extend standard bean info in our 
framework.)

This approach (not withstanding it's own issues) is at least cleaner
in that all that's necessary for object conversion is a lookup and
a method call.  Make a call to the ConversionManager (or whatever)
to retrieve a Converter instance, then call its 
Object convert( String s ) method.

> 
> > especially considering that there is already a FormBean
> > that can hold string versions of all of the form fields.
> 
> Yet this is precisely where the rubber meets the road in our problem. The
> challenge isn't in carrying around String representation, it lies within
> validation, conversion, and possibly even runtime representation.

Right, but property editors give you none of that.  They just provide
an interesting place to put a setAsText() method.  Everything else 
they do is extra fluff.

> 
> The real challenge, IMHO, is to find an abstraction that allows extension
> but doesn't force an implementation. As long as we're at it, I don't think
> its that bad of an idea to capitolize on a language established idiom that
> developers might already be familiar with.

It's possible.  PropertyEditors seem to have their most use in 
bean box type of IDE's where a developer would nee to configure
a bean instance using a dynamically generated property sheet.

> 
> >
> > PropertyEditors are designed to take the value out of the bean and
> > hold it while it is being dynamically edited, then stored back into
> > the bean when editing has completed.
> 
> Isn't this essentially the role an ActionForm plays where its typical
> counterpart is a value-object from your problem domain? I see either case
> simply as adapter's for producing objects your system knows about.

Right, but FormBean is an adapter for the whole bean... not just one
property at a time.  This is especially nice when three string form
fields turn into one bean property.  (Which is exactly why I've never
proposed the Converter concept mentioned above; it doesn't handle 
cases where properties don't map directly.)

PropertyEditors have a lot of stuff built into them to handle the
dynamic nature of a UI component.  This extra stuff isn't really 
utilized in a request/respone paradigm since everything always 
happens in a specific order and almost always as a result of the 
set method being called on the form bean.

> 
> > This is nice for a GUI where a component essentially gets its own
> > value to play with until editing has finished.  It means that each
> > property editor has its own code to handle property change listeners,
> > etc..  All of which seems to be overkill in a request/response type
> > of environment.
> 
> Similar to "huge-overhead", overkill is pretty hard to quantify-- 
> Some would argue that J2EE containers are overkill, and in some 
> contexts they are.  Their key value lies within the quality of
> abstraction they are able to provide.

Yes, I would argue that J2EE containers are definitely overkill if
all your entity beans define is a toString() method that returns the 
contents of their database record's fields.  Primarily because it 
ignores all of the benefits of J2EE for absolutely no gain.

Although much less obvious, I see using PropertyEditors in a similar
light.  The only part of the framework that would be being used is
essentially the setAsText() method (which the javadocs say can
throw an IllegalArgumentException if it doesn't take string values
for conversion).  Moreover, by confining yourself to what boils down
to being a convenience method on a class that wasn't intended for
data conversion, you lose all opportunities at doing something more
appropriate to that task.  (For example, a real exception hierarchy
might be nice.)

> 
> >
> > Furthermore, the complete property editor framework is designed to
> > have specific property editor classes associated with specific
> > object types.  I've found this to be extremely limiting since it
> > requires a different property editor subclass for even slightly
> > different behavior.  For example, if you have one type that allows
> > 3 decimal places and another that allows only 2, you have to create
> > two separate property editor classes.  Not much fun.
> 
> When's a DateEditor not enough to handle dates-- Beyond that we can't
> dictate how struts implementations should represent their data elements. In
> one system it may be adequate to represent an email address with a String;
> another might require a full-blown Email class.
> 
> >
> > So, given that, the only way I can see to logically use
> > PropertyEditors in a web environment involves looking up the
> > appropriate editor, calling setAsText() and then immediately calling
> > getValue().  Seems wasteful when a specific conversion object could
> > boil it down to Object convertValue( String someText ).
> >
> > Not to mention the fact that property editors don't even have
> > to implement the text methods.
> 
> Its an interface, an implied contract.. If its defined and does nothing,
> fine, that's the implementors decision and responsibility. For example, this
> class compiles and I can new as many of these as I like, but I'm hard
> pressed to find value in it, becuase the implementer chose not to define any
> worthwhile behaviors.
> 
> public final class FooBar {}

One of the stated benefits of using property editors in the first
place was the fact that it might allow reuse of existing code.  The
thing is, the property editor spec allows property editor 
implementations to essenatially leave the setAsText() and getAsText()
methods empty.  In fact, out of 50+ different property editors that
I have personally implemented, not a single one of them implemented
setAsText().  This is because they all return custom GUI components
and deal with the object values directly.  Outside of a dynamic UI
environment, property editors have little value... so I'd suspect
leaving these methods blank is more common than not.

> 
> >
> > In my opinion, a special set of interfaces designed for a web
> > environments needs is probably a better idea.  A web server app
> > is very different than a Swing UI.  In Swing, my gui components
> > usually know what kinds of objects they are dealing with and are
> > coded specifically for them. (For example, a calendar component
> > used to enter dates.)  In the web world, form data always starts
> > as strings.  The data is going to flow through a different kind
> > of pipeline that includes validation that would never have to be
> > done in a more robust UI.
> >
> > I don't know what the real solution is, but my gut tells me it isn't
> > PropertyEditors.  So I share the guilt. ;)
> >
> 
> I agree that this could very well turn out be the case, but all things being
> equal, I see this as the next logical step for BeanUtils, PropertyUtils and
> indirectly, the systems that rely on them.

It could be.  One place where the "property based" approaches fall
down is the case where property validation cannot be done without
looking at the other properties of the bean.  This is especially 
true for the VetoableChangeListener concept.  It's a nice idea, but
I've never bean able to use it in practice because of the frequent
dependency between properties.  For example, if some field can't be
more than some other, you'd better be sure you check them in the
right order.  If the second field also can't be too much larger
than the first, you have a real problem.

Even ignoring business level validation for a moment and just 
concentrating on just the level of validation necessary to convert
from String to Object, there are cases where several of the string
fields combine to form one Object.  Any decent framework will 
support that.  I personally believe it will involve putting a
conversion step between the FormBean and the Bean and not just
each property by itself.  Basic processing may come down to doing
one property at a time, but the bean-level abstraction would support
the multi-property issues as well.

This has been an interesting discussion though.  Never in my 
lurkingest dreams did I think my property editor knowledge would
ever be useful or timely. ;)

-Paul Speed

Reply via email to