commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Thomas Nichols <>
Subject Re: [jelly] Using BeanTagLibrary for "action" tags
Date Mon, 03 Mar 2003 15:58:11 GMT
Hi James,

At 22:54 25/02/2003 +0000, James Strachan wrote:
>From: "Thomas Nichols" <>
> > Hello,
> >
> > Is it possible to use BeanTagLibrary and have the top-level tags - i.e.
> > those registered with registerBean() - actually DO something? The plumbing
> > used in
> > jelly-tags/bean/src/test/org/apache/commons/jelly/tags/bean/
> > works a treat, and requires a minimal amount of glue (most of which can be
> > abstracted into super classes - great.)
> > However, though this is useful for "data assembly" I want the top-level
> > to perform an action - which I'm currently doing using a standard
> > TagLibrary impl and TagSupport-derived tag classes. With the existing
> > ("imperative") code, doTag() is invoked for the top-level, registered,
> > so I can take appropriate actions. How do I do this using the plumbing of
> > BeanTagLibrary?
> >
> > I'm trying to get the following -
> > <sync>
> >    <input1><file name="reggae.xml"/></input1>
> >    <input2><url value=""/></input2>
> > </sync>
> >
> > The inputX, url and file classes are just data wrappers, BeanTagLibrary
> > handles this very elegantly if I have
> >      registerBean (sync, Sync.class) in  MyTagLibrary ctor. I want to
> > invoke the "sync" processing on the collected data once the input1 and
> > input2 elements have been parsed. Is this possible?
> >
> > The refactoring has made for a cleaner architecture IMHO - worth the pain,
> > for me at least.
>Good idea Thomas.
>I've just patched the Bean tag library so that you can register a Method (or
>method name) which can be passed into the BeanTagLibrary.registerBean()
>method or used by the <beandef/> tag to specify a zero argument 'doit'
>method. So this method could be run() for Runnable objects or execute() for
>Ant like tasks etc.

This is excellent - thanks very much, I can successfully trigger processing 
on a beantag with an "execute" method, the child beantags get processed 
first and addFoo methods ensure they get registered with their parent.

I'm not sure I yet understand fully how BeanTagLibrary works. Within the 
root (level0) "j:jelly" tag I want to have a sequence of level1 
"action"  tags (e.g. "blah:sync") and beneath each of those a 
"data-assembly" hierarchy of beans. Astonishingly, this actually works:

<j:jelly xmlns:j.... xmlns:bean... xmlns:blah... >
     <bean:customer ...>
         <bean:product .../>

However ... :-)

The current impl assumes that a bean either has a name 
("var"), or can be added to its parent (which needs an addFoo() method), or 
that its parent is a collection. This is not true for my "bean" 
-- which isn't really a bean at all, I just need to register it in the 
MyOwnBeanTagLibrary ctor.

Now, if I register Sync with
registerBean ("sync", Sync.class, "execute");
all is hunky dory - but I get a warning from BeanTag.processBean(), lines 

                 else if(var == null) { //warn if the bean gets lost in space
                     log.warn( "Could not add bean to parent for bean: " + 
bean );

If I register the sync tag (bean:sync) with registerTag() instead of 
registerBean(), and give it a doTag(), then the data-assembly logic does 
not get invoked. The doTag() gets invoked fine, but the beans aren't processed.


1. Can I have the "sync" tag registered with a vanilla TagSupport-derived 
class, but have the beans still processed? I'd like to keep a single taglib 
if possible.

2. Is my use case general enough to warrant taking out that "Could not add 
bean to parent" warning, or at least making the trigger different?

3. If #2 == false, how can I programmatically assign a (meaningless) 'var' 
name to the sync tag, to suppress that message?

Not particularly keen on ice cream, but I do like jelly.
Onwards and upwards,

View raw message