Accessing local variables via EL in custom tag handler

View: New views
5 Messages — Rating Filter:   Alert me  

Accessing local variables via EL in custom tag handler

by rajesh.jag :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I'm using Facelets 1.1.13 with Seam 1.2.1 under WebLogic 10, and have
written a custom tag handler, to implement a tag library in my
application.

Here's what I do:


        public final class MyTagHandler extends TagHandler {
       
            private final TagAttribute value;
            // Some more attributes
       
            public MyTagHandler(TagConfig config) {
                super(config);
                this.value = this.getAttribute("value");
            }
       
            public void apply(FaceletContext ctx, UIComponent parent)
                    throws IOException, FacesException,
FaceletException, ELException {
            // Some processing goes here.
            Object value = getValue(ctx);
            // More processing
              return;
            }
       
            public Object getValue(FaceletContext ctx) {
                if (this.value != null) {
                    return this.value.getObject(ctx);
                } else {
                    return null;
                }
            }
       
        .
        .
        .
       
        }


This is how I set it up in the taglib.xml:

        <facelet-taglib>
         <namespace>http://mydomain.net/tags</namespace>
         <tag>
          <tag-name>mytag</tag-name>
          <handler-class>net.mydomain.MyTagHandler</handler-class>
         </tag>
        </facelet-taglib>

This is how the tag is used in the XHTML files:

        <myprefix:mytag value="somevalue">

If "somevalue" is a literal, this works fine.
If "somevalue" is an EL expression of the form "#{customer.name}" (where
the bean "customer" has a property "name")
        a. If "customer" is a component defined in faces-config.xml,
then it works fine
        b. If "customer" is outjected (using the @Out Seam annotation)
to - say - the session scope, then this works fine
        c. If "customers" (plural), is a component which has multiple
customers, and I use a tag like <c:forEach> or <h:dataTable> to loop
over each customer, like so:

                <c:forEach items="#{customers}" var="customer">
                  <myprefix:mytag value="#{customer.name}">
                </c:forEach>

        then "getValue(ctx)" as written above in the "apply" method,
evaluates to "null".

If I use "this.value.getValue(ctx);" instead of
"this.value.getObject(ctx);", it's the same thing.
If I use code like "this.value.getValueExpression(ctx,
String.class).getValue(ctx)" instead, I get an empty string.
If I use code like "this.value.getValueExpression(ctx,
String.class).getType(ctx)" instead, I get the following exception:

Feb 20, 2008 8:06:37 PM com.sun.facelets.FaceletViewHandler
handleRenderException
SEVERE: Error Rendering View[/mypage.xhtml]
javax.el.PropertyNotFoundException: /mypage.xhtml @97,66
value="${customer.name}": Target Unreachable, identifier 'customer'
resolved to null
        at
com.sun.facelets.el.TagValueExpression.getType(TagValueExpression.java:6
2)
        at
net.mydomain.MyTagHandler.getValue(DisplayStringParamTagHandler.java:122
)
        at
net.mydomain.MyTagHandler.apply(DynamicDisplayStringHandler.java:81)
        at
com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandl
er.java:47)
        at
com.sun.facelets.tag.jsf.ComponentHandler.applyNextHandler(ComponentHand
ler.java:314)
        at
com.sun.facelets.tag.jsf.ComponentHandler.apply(ComponentHandler.java:16
9)
        at
com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandl
er.java:47)
        at
com.sun.facelets.tag.jsf.ComponentHandler.applyNextHandler(ComponentHand
ler.java:314)
        at
com.sun.facelets.tag.jsf.ComponentHandler.apply(ComponentHandler.java:16
9)
        at
com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandl
er.java:47)
        at
com.sun.facelets.tag.jsf.core.ViewHandler.apply(ViewHandler.java:109)
        at
com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandl
er.java:47)
        at
com.sun.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:4
9)
        at
com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandl
er.java:47)
        at
com.sun.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:25)
        at
com.sun.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:95)
        at
com.sun.facelets.FaceletViewHandler.buildView(FaceletViewHandler.java:50
3)
        at
com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:5
46)
        at
org.ajax4jsf.framework.ViewHandlerWrapper.renderView(ViewHandlerWrapper.
java:108)
        at
org.ajax4jsf.framework.ajax.AjaxViewHandler.renderView(AjaxViewHandler.j
ava:229)
        at
org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderRespon
seExecutor.java:41)
        at
org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:132
)
        at
javax.faces.webapp.FacesServlet.service(FacesServlet.java:140)
        at
weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(St
ubSecurityHelper.java:226)
        at
weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityH
elper.java:124)
        at
weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:2
83)
        at
weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
        at
weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:
42)
        at
org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:6
3)
        at
org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
        at
org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:4
9)
        at
org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:57)


Note that code like -

                <c:forEach items="#{customers}" var="customer">
                  #{customer.name}
                </c:forEach>

- works just fine.

I'm guessing that maybe the ELContext that the "customer" variable is
stored to, is different than the one my tag tries to use. What I can't
understand is "Why?", and "How do I fix it?"

Any insights into this would be highly appreciated.

Regards,
Rajesh

The information contained in this electronic message and any attachments to this message are intended for the exclusive use of the addressee(s) and may contain proprietary, confidential or privileged information. If you are not the intended recipient, you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately and destroy all copies of this message and any attachments.

WARNING: Computer viruses can be transmitted via email. The recipient should check this email and any attachments for the presence of viruses. The company accepts no liability for any damage caused by any virus transmitted by this email.

www.wipro.com


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


Re: Accessing local variables via EL in custom tag handler

by Yann Simon :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi

2008/2/20, rajesh.jag@... <rajesh.jag@...>:
        public final class MyTagHandler extends TagHandler {

            private final TagAttribute value;
            // Some more attributes

            public MyTagHandler(TagConfig config) {
                super(config);
                this.value = this.getAttribute("value");
            }

            public void apply(FaceletContext ctx, UIComponent parent)
                    throws IOException, FacesException,
FaceletException, ELException {
            // Some processing goes here.
            Object value = getValue(ctx);
            // More processing
              return;
            }

            public Object getValue(FaceletContext ctx) {
                if (this.value != null) {
                    return this.value.getObject(ctx);
                } else {
                    return null;
                }
            }

        .
        .
        .

        }

just use:
 
public Object getValue(FaceletContext ctx) {
                if (this.value != null) {
                    return this.value.getObject(ctx);
                } else {

ValueExpression ve = getValueExpression( "value" );
        if ( ve != null ) {
            try {
                this.value = (String) ve.getValue( getFacesContext().getELContext() );
            } catch ( ELException e ) {
                throw new FacesException( e );
            }
        }

                    return this.value;
                }
            }

Yann

RE: Re: Accessing local variables via EL in custom tag handler

by rajesh.jag :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks Yann,

Which object am I supposed to call

        getValueExpression( "value" )

on? The TagHandler class doesn't have any such method.

Please note that this.value isn't null. It's a TagAttribute object. It's
this.value.getObject(ctx) that returns null.
So the code would never go into the "else" block.
And Seam uses JSF 1.1, so getFacesContext().getELContext() doesn't
exist.

Regards,
Rajesh

________________________________

From: Yann Simon [mailto:yann.simon.fr@...]
Sent: Wednesday, February 20, 2008 9:00 PM
To: users@...
Subject: Re: Accessing local variables via EL in custom tag handler


Hi


2008/2/20, rajesh.jag@... <rajesh.jag@...>:

                public final class MyTagHandler extends TagHandler {
       
                    private final TagAttribute value;
                    // Some more attributes
       
                    public MyTagHandler(TagConfig config) {
                        super(config);
                        this.value = this.getAttribute("value");
                    }
       
                    public void apply(FaceletContext ctx, UIComponent
parent)
                            throws IOException, FacesException,
        FaceletException, ELException {
                    // Some processing goes here.
                    Object value = getValue(ctx);
                    // More processing
                      return;
                    }
       
                    public Object getValue(FaceletContext ctx) {
                        if (this.value != null) {
                            return this.value.getObject(ctx);
                        } else {
                            return null;
                        }
                    }
       
                .
                .
                .
       
                }


just use:


public Object getValue(FaceletContext ctx) {
                if (this.value != null) {
                    return this.value.getObject(ctx);
                } else {

ValueExpression ve = getValueExpression( "value" );
        if ( ve != null ) {
            try {
                this.value = (String) ve.getValue(
getFacesContext().getELContext() );
            } catch ( ELException e ) {
                throw new FacesException( e );
            }
        }

                    return this.value;
                }
            }

Yann


The information contained in this electronic message and any attachments to this message are intended for the exclusive use of the addressee(s) and may contain proprietary, confidential or privileged information. If you are not the intended recipient, you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately and destroy all copies of this message and any attachments.

WARNING: Computer viruses can be transmitted via email. The recipient should check this email and any attachments for the presence of viruses. The company accepts no liability for any damage caused by any virus transmitted by this email.

www.wipro.com


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


Re: Re: Accessing local variables via EL in custom tag handler

by Yann Simon :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2008/2/20, rajesh.jag@... <rajesh.jag@...>:
Thanks Yann,

Which object am I supposed to call

        getValueExpression( "value" )

on? The TagHandler class doesn't have any such method.

Please note that this.value isn't null. It's a TagAttribute object. It's
this.value.getObject(ctx) that returns null.
So the code would never go into the "else" block.
And Seam uses JSF 1.1, so getFacesContext().getELContext() doesn't
exist.

Regards,
Rajesh

Sorry, I use this because my components extends UIComponent.

I have no experience with TagHandler.

Re: Accessing local variables via EL in custom tag handler

by Ignas L :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

This link might help you or others: http://www.ilikespam.com/blog/c:foreach-vs-ui:repeat-in-facelets

rajesh.jag wrote:
Hi,

I'm using Facelets 1.1.13 with Seam 1.2.1 under WebLogic 10, and have
written a custom tag handler, to implement a tag library in my
application.

Here's what I do:


        public final class MyTagHandler extends TagHandler {
       
            private final TagAttribute value;
            // Some more attributes
       
            public MyTagHandler(TagConfig config) {
                super(config);
                this.value = this.getAttribute("value");
            }
       
            public void apply(FaceletContext ctx, UIComponent parent)
                    throws IOException, FacesException,
FaceletException, ELException {
            // Some processing goes here.
            Object value = getValue(ctx);
            // More processing
              return;
            }
       
            public Object getValue(FaceletContext ctx) {
                if (this.value != null) {
                    return this.value.getObject(ctx);
                } else {
                    return null;
                }
            }
       
        .
        .
        .
       
        }


This is how I set it up in the taglib.xml:

        <facelet-taglib>
         <namespace>http://mydomain.net/tags</namespace>
         <tag>
          <tag-name>mytag</tag-name>
          <handler-class>net.mydomain.MyTagHandler</handler-class>
         </tag>
        </facelet-taglib>

This is how the tag is used in the XHTML files:

        <myprefix:mytag value="somevalue">

If "somevalue" is a literal, this works fine.
If "somevalue" is an EL expression of the form "#{customer.name}" (where
the bean "customer" has a property "name")
        a. If "customer" is a component defined in faces-config.xml,
then it works fine
        b. If "customer" is outjected (using the @Out Seam annotation)
to - say - the session scope, then this works fine
        c. If "customers" (plural), is a component which has multiple
customers, and I use a tag like <c:forEach> or <h:dataTable> to loop
over each customer, like so:

                <c:forEach items="#{customers}" var="customer">
                  <myprefix:mytag value="#{customer.name}">
                </c:forEach>

        then "getValue(ctx)" as written above in the "apply" method,
evaluates to "null".

If I use "this.value.getValue(ctx);" instead of
"this.value.getObject(ctx);", it's the same thing.
If I use code like "this.value.getValueExpression(ctx,
String.class).getValue(ctx)" instead, I get an empty string.
If I use code like "this.value.getValueExpression(ctx,
String.class).getType(ctx)" instead, I get the following exception:

Feb 20, 2008 8:06:37 PM com.sun.facelets.FaceletViewHandler
handleRenderException
SEVERE: Error Rendering View[/mypage.xhtml]
javax.el.PropertyNotFoundException: /mypage.xhtml @97,66
value="${customer.name}": Target Unreachable, identifier 'customer'
resolved to null
        at
com.sun.facelets.el.TagValueExpression.getType(TagValueExpression.java:6
2)
        at
net.mydomain.MyTagHandler.getValue(DisplayStringParamTagHandler.java:122
)
        at
net.mydomain.MyTagHandler.apply(DynamicDisplayStringHandler.java:81)
        at
com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandl
er.java:47)
        at
com.sun.facelets.tag.jsf.ComponentHandler.applyNextHandler(ComponentHand
ler.java:314)
        at
com.sun.facelets.tag.jsf.ComponentHandler.apply(ComponentHandler.java:16
9)
        at
com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandl
er.java:47)
        at
com.sun.facelets.tag.jsf.ComponentHandler.applyNextHandler(ComponentHand
ler.java:314)
        at
com.sun.facelets.tag.jsf.ComponentHandler.apply(ComponentHandler.java:16
9)
        at
com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandl
er.java:47)
        at
com.sun.facelets.tag.jsf.core.ViewHandler.apply(ViewHandler.java:109)
        at
com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandl
er.java:47)
        at
com.sun.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:4
9)
        at
com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandl
er.java:47)
        at
com.sun.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:25)
        at
com.sun.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:95)
        at
com.sun.facelets.FaceletViewHandler.buildView(FaceletViewHandler.java:50
3)
        at
com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:5
46)
        at
org.ajax4jsf.framework.ViewHandlerWrapper.renderView(ViewHandlerWrapper.
java:108)
        at
org.ajax4jsf.framework.ajax.AjaxViewHandler.renderView(AjaxViewHandler.j
ava:229)
        at
org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderRespon
seExecutor.java:41)
        at
org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:132
)
        at
javax.faces.webapp.FacesServlet.service(FacesServlet.java:140)
        at
weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(St
ubSecurityHelper.java:226)
        at
weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityH
elper.java:124)
        at
weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:2
83)
        at
weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
        at
weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:
42)
        at
org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:6
3)
        at
org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
        at
org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:4
9)
        at
org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:57)


Note that code like -

                <c:forEach items="#{customers}" var="customer">
                  #{customer.name}
                </c:forEach>

- works just fine.

I'm guessing that maybe the ELContext that the "customer" variable is
stored to, is different than the one my tag tries to use. What I can't
understand is "Why?", and "How do I fix it?"

Any insights into this would be highly appreciated.

Regards,
Rajesh

The information contained in this electronic message and any attachments to this message are intended for the exclusive use of the addressee(s) and may contain proprietary, confidential or privileged information. If you are not the intended recipient, you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately and destroy all copies of this message and any attachments.

WARNING: Computer viruses can be transmitted via email. The recipient should check this email and any attachments for the presence of viruses. The company accepts no liability for any damage caused by any virus transmitted by this email.

www.wipro.com


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@facelets.dev.java.net
For additional commands, e-mail: users-help@facelets.dev.java.net