You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Toby Hobson <to...@btinternet.com> on 2008/05/16 21:13:45 UTC

Possible bug?

Fixed it! this looks like a bug in T5 to me ...

I was trying to pass a "PageResponse" object from the enclosing "Pager" component to the nested "Next" component. All three of these classes were in my web.components package. When I moved PageResponse to another package (in this case my *.model package) it worked as expected. To double check I moved it back and got the old and unhelpful error.

Should I raise a JIRA for this?

Thanks

Toby

----- Original Message ----
From: Toby Hobson <to...@btinternet.com>
To: Tapestry users <us...@tapestry.apache.org>
Sent: Friday, 16 May, 2008 7:30:51 PM
Subject: Re: Making a property available to nested components

I've noticed something ... If I try to pass a string to the nested component it works as expected, it seems there is something about the PageResponse class that it doesn't like. But this is just a normal javabean :

public class PageResponse implements Serializable {
  
  public static final long serialVersionUID = 1L;
  private int startIndex;
  private int endIndex;
  
  ... getters/setters
}

Toby

----- Original Message ----
From: Toby Hobson <to...@btinternet.com>
To: Tapestry users <us...@tapestry.apache.org>
Sent: Friday, 16 May, 2008 6:09:19 PM
Subject: Re: Making a property available to nested components

Thanks Robert I've had a look at that and managed to replace a page property with a value supplied by a component at runtime. One problem I've hit though is when I want to make a property available to a nested component. Probably best explained with the code! Basically i'm trying to write a simple pager which will provide previous and next buttons: I have a Pager component which should make a "PageResponse" object available to nested components (previous and next). 

Pager.java

    private PageResponse response; // This is basically the list of results from the datasource with startIndex, endIndex, totalRecords etc.

    @Inject
    private Environment environment;

    @SetupRender
    void setupRender() {
        response = ds.action(request);
    }
    
    @BeginRender
    void beginRender() {
        environment.push(PageResponse.class, response);
    }
    
    @AfterRender
    void afterRender() {
        environment.pop(PageResponse.class);
    }

I also have a "Previous" component which basically decides if it should render a "previous" actionLink on the page:

Previous.java

    @Environmental
    @Property
    private PageResponse response;
    
    public boolean render() {
        return response.getPageNumber() > 1;
    }

Previous.tml

    <t:if test="render()">
        <t:actionLink t:context="response.pageNumber" t:id="previoust">previous</t:actionLink>
    </t:if>

I also have a "next" component which is basically the same as above

Then on my admin page I have

    <t:pager t:id="pager">
        <t:previous id="previous" /> <t:next id="next" />
    </t:pager>

I was hoping that the "previous" component would be able to see the pageResponse object which is provided by the containing pager component. But I get a very strange and unhelpful error:

Render queue error in BeginRender[Admin:previous.if]: Failure readingparameter 'test' of component Admin:previous.if: No object of typecom.thc.web.components.PageResponse is available from the Environment.Available types are com.thc.web.components.PageResponse,org.apache.tapestry.PageRenderSupport,org.apache.tapestry.ValidationDecorator,org.apache.tapestry.internal.services.ClientBehaviorSupport,org.apache.tapestry.services.Heartbeat.

So it's not available, but it is!! 

Can anyone see any glaring errors with this?

Thanks

Toby

----- Original Message ----
From: Robert Zeigler <ro...@scazdl.org>
To: Tapestry users <us...@tapestry.apache.org>
Sent: Friday, 16 May, 2008 3:32:00 PM
Subject: Re: Making a property available to nested components

Check out the environment service.

Robert

On May 16, 2008, at 5/169:23 AM , Toby Hobson wrote:

> I've managed to achieve something by making the "container" a  
> component AND a property on my test page:
>
> @Property
> @Component(id="container")
> private Container container;
>
> but this seems like a bit of a hack, there must be a neater way of  
> doing this!
>
> Toby
>
> ----- Original Message ----
> From: Toby Hobson <to...@btinternet.com>
> To: tapestry <us...@tapestry.apache.org>
> Sent: Friday, 16 May, 2008 3:15:57 PM
> Subject: Making a property available to nested components
>
> Hi
>
> I am looking to achieve something similar to the way in which JSP  
> custom tags work - I would like to make a property of a component  
> available to nested components/markup e.g.
>
> TestPage.tml:
> <t:container value="container">
>    hello ${container.user.name}
> </t:container>
>
> Container {
>  @Property
>  User user;
>
>  @PageAttached()
>  void attach() {
>  ... load and process "user"
>  }
> }
>
> But i can't find a way to do this. I know it can be done because the  
> loop component works like this.
>
> Does anyone have any ideas?
>
> Thanks
>
> Toby
>
>
>
>


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











Re: Possible bug?

Posted by Robert Zeigler <ro...@scazdl.org>.
Nope.

Not a bug.

Just a result of the way that class loaders, class comparison, etc.  
work in java, and a side-effect of T5's class reloading.

Classes in the .components, .mixins, and .pages are in a separate  
class-loader from everything else.  Class1==Class1 from different  
classloaders is false.  What's more, A.class.equals(A.class) if the  
two "A's" are in different class loaders is also false.

In general, only store page classes .pages, component classes  
in .components, and mixin classes in .mixins.  Any other class  
(including ASO's, environmentals, services, interfaces, etc.) should  
be located elsewhere.

Robert

On May 16, 2008, at 5/162:13 PM , Toby Hobson wrote:

> Fixed it! this looks like a bug in T5 to me ...
>
> I was trying to pass a "PageResponse" object from the enclosing  
> "Pager" component to the nested "Next" component. All three of these  
> classes were in my web.components package. When I moved PageResponse  
> to another package (in this case my *.model package) it worked as  
> expected. To double check I moved it back and got the old and  
> unhelpful error.
>
> Should I raise a JIRA for this?
>
> Thanks
>
> Toby
>
> ----- Original Message ----
> From: Toby Hobson <to...@btinternet.com>
> To: Tapestry users <us...@tapestry.apache.org>
> Sent: Friday, 16 May, 2008 7:30:51 PM
> Subject: Re: Making a property available to nested components
>
> I've noticed something ... If I try to pass a string to the nested  
> component it works as expected, it seems there is something about  
> the PageResponse class that it doesn't like. But this is just a  
> normal javabean :
>
> public class PageResponse implements Serializable {
>
>  public static final long serialVersionUID = 1L;
>  private int startIndex;
>  private int endIndex;
>
>  ... getters/setters
> }
>
> Toby
>
> ----- Original Message ----
> From: Toby Hobson <to...@btinternet.com>
> To: Tapestry users <us...@tapestry.apache.org>
> Sent: Friday, 16 May, 2008 6:09:19 PM
> Subject: Re: Making a property available to nested components
>
> Thanks Robert I've had a look at that and managed to replace a page  
> property with a value supplied by a component at runtime. One  
> problem I've hit though is when I want to make a property available  
> to a nested component. Probably best explained with the code!  
> Basically i'm trying to write a simple pager which will provide  
> previous and next buttons: I have a Pager component which should  
> make a "PageResponse" object available to nested components  
> (previous and next).
>
> Pager.java
>
>    private PageResponse response; // This is basically the list of  
> results from the datasource with startIndex, endIndex, totalRecords  
> etc.
>
>    @Inject
>    private Environment environment;
>
>    @SetupRender
>    void setupRender() {
>        response = ds.action(request);
>    }
>
>    @BeginRender
>    void beginRender() {
>        environment.push(PageResponse.class, response);
>    }
>
>    @AfterRender
>    void afterRender() {
>        environment.pop(PageResponse.class);
>    }
>
> I also have a "Previous" component which basically decides if it  
> should render a "previous" actionLink on the page:
>
> Previous.java
>
>    @Environmental
>    @Property
>    private PageResponse response;
>
>    public boolean render() {
>        return response.getPageNumber() > 1;
>    }
>
> Previous.tml
>
>    <t:if test="render()">
>        <t:actionLink t:context="response.pageNumber"  
> t:id="previoust">previous</t:actionLink>
>    </t:if>
>
> I also have a "next" component which is basically the same as above
>
> Then on my admin page I have
>
>    <t:pager t:id="pager">
>        <t:previous id="previous" /> <t:next id="next" />
>    </t:pager>
>
> I was hoping that the "previous" component would be able to see the  
> pageResponse object which is provided by the containing pager  
> component. But I get a very strange and unhelpful error:
>
> Render queue error in BeginRender[Admin:previous.if]: Failure  
> readingparameter 'test' of component Admin:previous.if: No object of  
> typecom.thc.web.components.PageResponse is available from the  
> Environment.Available types are  
> com 
> .thc 
> .web 
> .components 
> .PageResponse 
> ,org 
> .apache 
> .tapestry 
> .PageRenderSupport 
> ,org 
> .apache 
> .tapestry 
> .ValidationDecorator 
> ,org 
> .apache 
> .tapestry 
> .internal 
> .services 
> .ClientBehaviorSupport,org.apache.tapestry.services.Heartbeat.
>
> So it's not available, but it is!!
>
> Can anyone see any glaring errors with this?
>
> Thanks
>
> Toby
>
> ----- Original Message ----
> From: Robert Zeigler <ro...@scazdl.org>
> To: Tapestry users <us...@tapestry.apache.org>
> Sent: Friday, 16 May, 2008 3:32:00 PM
> Subject: Re: Making a property available to nested components
>
> Check out the environment service.
>
> Robert
>
> On May 16, 2008, at 5/169:23 AM , Toby Hobson wrote:
>
>> I've managed to achieve something by making the "container" a
>> component AND a property on my test page:
>>
>> @Property
>> @Component(id="container")
>> private Container container;
>>
>> but this seems like a bit of a hack, there must be a neater way of
>> doing this!
>>
>> Toby
>>
>> ----- Original Message ----
>> From: Toby Hobson <to...@btinternet.com>
>> To: tapestry <us...@tapestry.apache.org>
>> Sent: Friday, 16 May, 2008 3:15:57 PM
>> Subject: Making a property available to nested components
>>
>> Hi
>>
>> I am looking to achieve something similar to the way in which JSP
>> custom tags work - I would like to make a property of a component
>> available to nested components/markup e.g.
>>
>> TestPage.tml:
>> <t:container value="container">
>>   hello ${container.user.name}
>> </t:container>
>>
>> Container {
>> @Property
>> User user;
>>
>> @PageAttached()
>> void attach() {
>> ... load and process "user"
>> }
>> }
>>
>> But i can't find a way to do this. I know it can be done because the
>> loop component works like this.
>>
>> Does anyone have any ideas?
>>
>> Thanks
>>
>> Toby
>>
>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>
>
>
>
>
>
>
>
>


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