You are viewing a plain text version of this content. The canonical link for it is here.
Posted to taglibs-dev@jakarta.apache.org by Pierre Delisle <pi...@sun.com> on 2001/03/20 17:55:45 UTC

Re: BeanMessage Tag proposal

"Craig R. McClanahan" wrote:
> I'm doing a little experimenting with the various styles to doing this --
> and not just for <bean:message> arguments.  It would be interesting to see
> if we can define a <bean:setProperty property="xxx" value="yyy"/> tag that
> sets the corresponding property on the tag instance we are nested
> in.  This would solve the nested arguments case.  Taking an argX (or
> maybe "args"?) as above would also be useful in the particular case of
> <bean:message>.
> 
> There is some complexity here with how tag instance recycling works, but
> it may actually be feasible to have a nested setter that works generally.

There has been an interesting thread on taglibs-dev on the topic 
of 'tag pipelining'.

I've included below the last proposal I made on that topic.
A key aspect of that proposal is that a "datasource" tag
directly sets an attribute of a "datasink" tag to improve performance
by avoiding "double buffering".

If you're interested in the full story, I'd suggest you check the archives
of taglibs-dev.

Would be great to have the struts community involved 
on these discussions.

Thanks,

    -- Pierre

-------- Original Message --------
Subject: Re: Amended tag pipelining proposal (was Re: PROPOSAL: tag pipelining)
Date: Fri, 02 Mar 2001 05:44:44 -0800
From: Pierre Delisle <pi...@sun.com>
Reply-To: taglibs-dev@jakarta.apache.org
To: taglibs-dev@jakarta.apache.org
References: <0e...@citria.com>

....
Following my last email and your amended proposal, here is
(yet :-)) another proposal. We're getting there :-)

    -- Pierre

-----
The 'pipe' model is a way by which attributes in a 'consumer/datasink tag'
can be set implicitely via nested tags that are 'producer/datasource' tags.

The set of rules/guidelines would be as follows:

-----
DataSink Tag (aka Data Counsumer Tag)

To take advantage of the 'pipe model' (i.e. allowing attributes
values to be set from nested tags), a "consumer/datasink" tag should
design these 'pipe' attributes in the following way:

- The type of that attribute should be 'Object'

   e.g. public void setFoo(Object object)

The tag should clearly document which data types it supports for
those attributes (e.g. String, InputSteam, Reader, etc...).
And with the current restrictions in the spec (which will hopefully
we lifted in 1.2 final), these attributes would be set directly
within the tag in the following way:

     <x:mytag foo="<%= .... %>" />

It should also be clear that the value specified for these attributes
is the 'real' data; not the name that refers to something that
can go out and fetch the data. Nested tags that comply with the
pipe model are to be used for that specific purpose.

To clearly identify a tag as a consumer-tag in the pipe model,
it must implement interface PipeTag.

     interface PipeSinkTag {   // or PipeConsumerTag?
         public void setPipeData(Object object) throws JspException;
     }

Method setPipeData is used to cover the case where 
a single attribute in the consumer tag can be set via nested tags. 
This attribute can be set via a pipe implicitely, without 
specifiying any attribute name.

For example:

    <x:mytag>
      <http:request url="..."/>
    </x:mytag>

where the value of the default attribute in mytag would be set 
via the pipe setup by the http tag.

The setPipeData() method should simply make a call to setFoo(object), assuming
'foo' is that default attribute.

If more than one attribute can be set via nested tags, then 
setPipeData could be used for the attribute that's identified
as the 'default' one, or simply disallowed (i.e. pipe attribute names
would have to be stated explicetely in the producer tag).

Here is an example of a non 'default' attributes being set via nested
tags using the pipe model:

   <xsl:apply>
     <jdbc:...  pipeProperty="xml"/> 
     <io:resource name="/xsl/employees.xsl" pipeAttribute="xsl"/> 
   </xsl:apply>

-----
DataSource Tag (aka Data Producer Tag)

Ideally, any tag that 'produces' data (i.e. is a source of data)
should play by the rules of the pipe model, allowing tag users 
to easily reuse the data produced by these tags within any 
'consumer/datasink' tag.

To be a DataSource tag in the pipe model, a tag must abide by the
following rules:

- must support attribute 'pipeAttribute'

- must setup the 'pipe' whenever the data source object is ready
  for consumption
             
  This is done  by calling the following static method on the
  'Pipe' class:

    public static boolean setPipe(Object dataSource, 
                                  String pipeAttribute) 

  where 'dataSource' is the dataSource object that will be consumed
  by the tag on the other side of the pipe

  where 'pipeAttribute' is the consumer tag attribute to which this 
  dataSource should be applied (can be null is no pipeAttribute attribute was 
  specified in the tag; in which case the 'default' attribute will be used in
the 
  consumer tag).

  If this method returns true, this means that the tag is engaged
  in a pipe with a parent tag as the source of data for that pipe.

  If the call returns false, this means that the tag is not engaged
  in a pipe. It is up to the tag to proceed with the data in the
  appropriate way, which is problably to simply write the data
  to the 'previous out'.

-----
Analysis

This is very close to James original proposal, with the
following clarifications:

- pipes are a great way to set attribute values via nested tags
  (no need to have tags support multiple types of data sources,
   this is all taken care via the reuse of other tags and the
  pipe model)

- pipe roles are clearly indentified:
  DataSink/Consumer tags, and DataSource/Producer tags)

- no need for tags to define attributes as tags; this is
  all taken care of by the pipe model.

- no need for the <tag:set> tag

  By making attribute 'pipeProperty' mandatory in DataSource tag,
  we remove the need for <tag:set>. This also takes care of my
  original concern about only supporting a single 'default'
  property

- easy to write DataSource tags (The Pipe class will take care
  of setting up the pipe)

  In my first comment on James proposal, I had argued that setting
  up the pipe could be tricky. However, as James had replied,
  this can be handled via what I now refer to as the Pipe class.
  Also, the burden of type casting is pushed back to the DataSink
  tag which accepts Object. (utility classes could be made
  available there too).

- *fairly* easy to write DataSink tags

  In my first comment on James Proposal, I had argued that
  "it would be great if the producer tag could be linked 
  to a consumer tag's attribute directly, without having
  to implement an interface..."

  This proposal would allow that since we now have a
  mandatory 'pipeProperty' in the producer tag. However,
  it probably is a good idea to explicitely identify
  tags has citizens in the pipe community. (should we
  have a PipeSourceTag interface simply as a marker
  interface for datasource tags?)

-----
An issue:

As I was writing this, it came up to me that maybe
we'd want a callback from the consumer to the producer.

e.g.:

  the producer would setup the pipe with this:

    public static boolean setPipe(PipeSourceTag thisTag,
                                  Object dataSource, 
                                  String pipeProperty) 

  where thisTag is simply the instance of the producer tag.

  this could have been used once the 'pipe is consumed'
  by the consumer tag to make a call to something like
  thisTag.closePipe() to allow the dataSource to make any required
  cleanup.

  But I don't think there is a need for this since this should normally 
  be taken care of by the tag's release() method.

  And the PipeSourceTag interface would then be required.

  Comments?