You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Daniel Jue <te...@gmail.com> on 2014/09/24 05:36:01 UTC

Getting BeanDisplay to skip empty fields altogether

Hey list!  I have several dozen code-generated beans that I'd like to
display as bean models.  Problem is, many of the beans' fields are either
null or empty string, so I don't want their <dt> labels to even show up,
much less the NotEmpty mixin putting a &nbsp;

The idea is to skip rendering any fields that would have output equal to
the empty string or null (and possibly even skipping if it were only
whitespace)

So far I've gone down the path of overriding the BeanDisplay class and
using my own tml file to try and wrap the <dt>/<dd> in a <t:if> with a test
on the object.  It's not working quite yet, but I think this might work.  I
need to get a handle on what the property value is going to be so I can
test against that.

Is anything else you would suggest?

Thanks,

Dan

Re: Getting BeanDisplay to skip empty fields altogether

Posted by Thiago H de Paula Figueiredo <th...@gmail.com>.
On Wed, 24 Sep 2014 13:37:11 -0300, Daniel Jue <te...@gmail.com> wrote:

> Your code works as is, but I still stuck it in a custom
> MeaningfulBeanDisplay component in it's setupRender method, because I  
> don't want to write this logic for every model for every POJO.   
> Sometimes I'll
> have 5-10 of these POJOs on one page.

You can still use BeanDisplay unchanged, put this logic inside a service  
and use it. I hope your MeaningfulBeanDisplay just wraps BeanDisplay,  
instead of copying and adapting its source.

A different solution would be to create a binding prefix to provide the  
BeanModel given the object and use something like <t:beandisplay  
object="object" model="mymodel:object"/>

 From 5.4 on, you can completely replace a component by another  
automatically by contributing to the ComponentOverride service. Example:

@Contribute(ComponentReplacer.class)
public static void overrideBeanDisplay(MappedConfiguration<Class, Class>  
configuration) {
	configuration.add(BeanDisplay.class, MeaningfulBeanDisplay.class);
}

> Great job Thiago, thank you thank you!

My pleasure! :)

-- 
Thiago H. de Paula Figueiredo
Tapestry, Java and Hibernate consultant and developer
http://machina.com.br

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


Re: Getting BeanDisplay to skip empty fields altogether

Posted by Daniel Jue <te...@gmail.com>.
Thiago, that was perfect!  I had in-fact gone down the reflection route and
was getting into trouble since the propertyNames aren't really the method
or field names.   I forgot about using conduits manually that way!

Your code works as is, but I still stuck it in a custom
MeaningfulBeanDisplay component in it's setupRender method, because I don't
want to write this logic for every model for every POJO.  Sometimes I'll
have 5-10 of these POJOs on one page.

Great job Thiago, thank you thank you!

On Wed, Sep 24, 2014 at 10:52 AM, Thiago H de Paula Figueiredo <
thiagohp@gmail.com> wrote:

> On Wed, 24 Sep 2014 10:59:50 -0300, Chris Mylonas <ch...@opencsta.org>
> wrote:
>
>  Hi Daniel,
>>
>
> Hi, guys!
>
>  Disclaimer:  I don't pretend to know anything about BeanModels,
>> BeanModelSources and Grids.....however
>>
>
> I know a thing or two about them. :)
>
>  Sounds like a bit of reflection to get field names on your POJOs and
>> BeanModel.exclude().exclude().exclude().....exclude() or a bit of
>> recursion til the end of an arraylist of empty/whitespace field values is
>> reached.
>>
>
> Actually, no reflection needed. BeanModelSource already does this part for
> you.
>
> Not tested code below. Code could be more concise, but I wanted to show
> the parts involved.
>
> @Property
> private Object object; // actually, it can be any type
>
> @Inject
> private BeanModelSource beanModelSource;
>
> @Inject
> private Messages messages;
>
> BeanModel getModel() {
>         BeanModel beanModel = beanModelSource.createDisplayModel(object.getClass(),
> messages);
>         List<String> propertyNames = beanModel.getPropertyNames();
>         for (String propertyName : propertyNames) {
>                 PropertyModel propertyModel = beanModel.get(propertyName);
>                 PropertyConduit conduit = propertyModel.getConduit();
>                 Object propertyValue = conduit.get(object);
>                 if (propertyValue == null) { // or any other logic you want
>                         beanModel.remove(propertyName)
>                 }
>         }
> }
>
> <t:beandisplay object="object" model="model"/>
>
> --
> Thiago H. de Paula Figueiredo
> Tapestry, Java and Hibernate consultant and developer
> http://machina.com.br
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

Re: Getting BeanDisplay to skip empty fields altogether

Posted by Thiago H de Paula Figueiredo <th...@gmail.com>.
On Wed, 24 Sep 2014 10:59:50 -0300, Chris Mylonas <ch...@opencsta.org>  
wrote:

> Hi Daniel,

Hi, guys!

> Disclaimer:  I don't pretend to know anything about BeanModels,  
> BeanModelSources and Grids.....however

I know a thing or two about them. :)

> Sounds like a bit of reflection to get field names on your POJOs and  
> BeanModel.exclude().exclude().exclude().....exclude() or a bit of  
> recursion til the end of an arraylist of empty/whitespace field values  
> is reached.

Actually, no reflection needed. BeanModelSource already does this part for  
you.

Not tested code below. Code could be more concise, but I wanted to show  
the parts involved.

@Property
private Object object; // actually, it can be any type

@Inject
private BeanModelSource beanModelSource;

@Inject
private Messages messages;

BeanModel getModel() {
	BeanModel beanModel =  
beanModelSource.createDisplayModel(object.getClass(), messages);
	List<String> propertyNames = beanModel.getPropertyNames();
	for (String propertyName : propertyNames) {
		PropertyModel propertyModel = beanModel.get(propertyName);
		PropertyConduit conduit = propertyModel.getConduit();
		Object propertyValue = conduit.get(object);
		if (propertyValue == null) { // or any other logic you want
			beanModel.remove(propertyName)
		}
	}
}

<t:beandisplay object="object" model="model"/>

-- 
Thiago H. de Paula Figueiredo
Tapestry, Java and Hibernate consultant and developer
http://machina.com.br

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


Re: Getting BeanDisplay to skip empty fields altogether

Posted by Chris Mylonas <ch...@opencsta.org>.
Hi Daniel,

Disclaimer:  I don't pretend to know anything about BeanModels,  
BeanModelSources and Grids.....however

Sounds like a bit of reflection to get field names on your POJOs and  
BeanModel.exclude().exclude().exclude().....exclude() or a bit of  
recursion til the end of an arraylist of empty/whitespace field values is  
reached.

Without actually having done either in years, am i being simple?

Sounds kind of like in network programming with sending results to  
specific clients, each connected in their own thread - it's just iterating  
a list - not pretty but fast.  Or reading bytes out of a buffer - again,  
not an elegant task, but fast.


Chris


On Wed, 24 Sep 2014 23:39:59 +1000, Daniel Jue <te...@gmail.com> wrote:

> Thanks Lance, I think on the surface my problem seems like the one you  
> gave
> the answer for, but in my case it's different.  I don't know which fields
> I'll need to exclude until I know whether the value is null or  
> empty-string
> for the instance of the bean.  For example, one of my classes is a POJO
> generated from elsewhere which has dozens of fields.  For any given
> instance of that POJO, only 30% of the field might be filled with
> meaningful, non blank data.  But it's not always the same columns/fields
> that need to be skipped/excluded.  I don't want to write manual glue code
> for these, because they are code generated from a schema that changes
> often. (not to mention I have close to 100 of these bean types already)
>
> My first attempt at using my own MeaningfulBeanDisplay component based  
> off
> BeanDisplay is not doing what I want yet.  Seems like it's hard to get a
> handle on the value that the propertyModel is going to try and resolve,
> since it needs to go through the BeanDisplay's PropertyDisplay component
> before we start to touch the actual value.
>
> On Wed, Sep 24, 2014 at 1:40 AM, Lance Java <la...@googlemail.com>
> wrote:
>
>> BeanDisplay, BeanEditor and Grid all use a BeanModel to show the fields.
>>
>> You could either set the "exclude" parameter to the component. Or you  
>> can
>> call BeanModel.exclude(...) explicitly.
>>
>> It might be easiest to decorate the BeanModelSource service in  
>> tapestry-ioc
>> (used when you don't explicitly provide a BeanModel).
>>


-- 
Using Opera's mail client: http://www.opera.com/mail/

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


Re: Getting BeanDisplay to skip empty fields altogether

Posted by Daniel Jue <te...@gmail.com>.
Thanks Lance, I think on the surface my problem seems like the one you gave
the answer for, but in my case it's different.  I don't know which fields
I'll need to exclude until I know whether the value is null or empty-string
for the instance of the bean.  For example, one of my classes is a POJO
generated from elsewhere which has dozens of fields.  For any given
instance of that POJO, only 30% of the field might be filled with
meaningful, non blank data.  But it's not always the same columns/fields
that need to be skipped/excluded.  I don't want to write manual glue code
for these, because they are code generated from a schema that changes
often. (not to mention I have close to 100 of these bean types already)

My first attempt at using my own MeaningfulBeanDisplay component based off
BeanDisplay is not doing what I want yet.  Seems like it's hard to get a
handle on the value that the propertyModel is going to try and resolve,
since it needs to go through the BeanDisplay's PropertyDisplay component
before we start to touch the actual value.

On Wed, Sep 24, 2014 at 1:40 AM, Lance Java <la...@googlemail.com>
wrote:

> BeanDisplay, BeanEditor and Grid all use a BeanModel to show the fields.
>
> You could either set the "exclude" parameter to the component. Or you can
> call BeanModel.exclude(...) explicitly.
>
> It might be easiest to decorate the BeanModelSource service in tapestry-ioc
> (used when you don't explicitly provide a BeanModel).
>

Re: Getting BeanDisplay to skip empty fields altogether

Posted by Lance Java <la...@googlemail.com>.
BeanDisplay, BeanEditor and Grid all use a BeanModel to show the fields.

You could either set the "exclude" parameter to the component. Or you can
call BeanModel.exclude(...) explicitly.

It might be easiest to decorate the BeanModelSource service in tapestry-ioc
(used when you don't explicitly provide a BeanModel).