You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by ravi_eze <ra...@ivycomptech.com> on 2008/05/01 11:04:33 UTC

RE: Simplified usage of:@com.company.Constants.StaticCOnstants

hi,

even this doesnt seem to be working.

is it possible to load the constant class to the context and then display it
form there.? or in that case it expects a setters and getters... or some way
of getting this done.. the code is very bad to read 'cos every time i am
using @com.company.... 

any help???

cheers,
ravi 



Wes Wannemacher wrote:
> 
> Did you try to import your Constants class?
> 
> <%@ page import="com.company.Constants" %>
> 
> <s:property value="@Constants@STATIC_CONSTANTS1" />
> 
> As far as say C.staticconstant1, all I can really say is that the @
> symbol is how you access static vars/methods in OGNL. 
> 
> Another choice might be to use regular ol' EL expressions. 
> 
> -Wes
> 
> On Tue, 2008-04-29 at 21:45 -0700, ravi_eze wrote:
>> hi,
>> 
>> 
>> Does the following work - 
>> 
>> <s:set name="C" value="@com.company.Constants@STATIC_CONSTANTS1" />
>> <s:property value="#C" />
>> 
>> Yes it does. But my requirement is more like i would import the class
>> into
>> some bean/ variable (C) so that i can say C.staticconstant1 etc... but by
>> the approach mentioned above, i should repeat the @com.company.Constant
>> string always which reduces the readability. Hope this adds some clarity.
>> Something similar to import.... and then say Constant....
>> 
>> Also, is com.company.Constants.STATIC_CONSTANTS1 a String?
>> 
>> Yes its a string.  i would be greatful to any further help.
>> 
>> 
>> cheers,
>> ravi 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
> 
> 
> 

-- 
View this message in context: http://www.nabble.com/Simplified-usage-of%3A%40com.company.Constants.StaticCOnstants-tp16941171p16993179.html
Sent from the Struts - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Simplified usage of:@com.company.Constants.StaticCOnstants

Posted by Maxx <ma...@gmail.com>.
On Thu, May 1, 2008 at 5:21 PM, Jeromy Evans
<je...@blueskyminds.com.au> wrote:
>
> I have a solution, but first...
> OGNL only provides access to static fields and static methods.  It cannot
> reference a static class, nor even an inner static class.
>
> http://www.ognl.org/2.6.9/Documentation/html/LanguageGuide/apa.html

Strange... because I succeeded in reading Enum values from an inner
enum class, like:

public interface MyInterface {
  enum MyEnum {
    MY_ENUM_VALUE;
  }
}

Using
  <s:property value="@com.mycompany.some.package.MyInterface$MyEnum@MY_ENUM_VALUE"
/>
prints:
  MY_ENUM_VALUE
(value returned by the .toString() from the Enum class)

Note: it might be dumb to do this, BUT if you use a specific Struts2
(or XWork?) converter to "translate" your enum value into something
different (e.g. introducing a label or something similar that would
returns "My Enum Value" in our example) then it's useful when not only
dealing with the Enum name (i.e. here MY_ENUM_VALUE).

I also succeeded using
  <s:property value="@java.lang.Math@PI" />
that prints:
  2.718281828459045

But strangely, some:
  <s:property value="@com.mycompany.some.package.MyInterface@MY_CONSTANT_VALUE"
/>
does not work... why?!

... all this with Struts 2.0.11.1


> However, there is a bearable solution / hack:
>
> 1. In your Constants *class*, create a public static singleton instance of
> itself.  Lets call it C.  (Remember, OGNL can reference static fields)
> public static final Constants C = new Constants();
>
> 2. [...]

And what if, as from my above explained example, you have an
*interface*, not a class...?

Maxx

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Simplified usage of:@com.company.Constants.StaticCOnstants

Posted by Jeromy Evans <je...@blueskyminds.com.au>.
ravi_eze wrote:
> hi,
>
> even this doesnt seem to be working.
>
> is it possible to load the constant class to the context and then display it
> form there.? or in that case it expects a setters and getters... or some way
> of getting this done.. the code is very bad to read 'cos every time i am
> using @com.company.... 
>
> any help???
>
> cheers,
> ravi 
>
>   
I have a solution, but first...
OGNL only provides access to static fields and static methods.  It 
cannot reference a static class, nor even an inner static class.

http://www.ognl.org/2.6.9/Documentation/html/LanguageGuide/apa.html

It's terrible that struts2 provides no feedback all for all those 
invalid ONGL expressions.  It only provides feedback for valid 
expressions referencing invalid properties.

<s:set value="@com.blueskyminds.web.test.Constants" var="C"/>
008-05-02 00:36:18,747 WARN  [http-8080-Processor23] [OgnlValueStack] 
Could not find property [@com.blueskyminds.web.test.Constants]
<s:set value="@com.blueskyminds.web.test.Constants@InnerClass" var="I"/>
008-05-02 00:36:18,747 WARN  [http-8080-Processor23] [OgnlValueStack] 
Could not find property [@com.blueskyminds.web.test.Constants@InnerClass]

However, there is a bearable solution / hack:

1. In your Constants class, create a public static singleton instance of 
itself.  Lets call it C.  (Remember, OGNL can reference static fields)
public static final Constants C = new Constants();

2. In your Constants class, create a static getter for each constant.  
Thank goodness for the IDE's auto-generation of getters.

public static final String TEST_CONSTANT1 = "test1";
public static String getTEST_CONSTANT1() {
   return TEST_CONSTANT1;
}

3. Get get static field C and put it into scope

<s:set value="@com.blueskyminds.web.test.Constants@C" var="C"/>

4. Access its properties using dot notation. 
<s:property value="#C.TEST_CONSTANT1"/>

Note: You can't access the static fields of an instance, so you can't 
use #C@TEST_CONSTANT1.  It likes a static property.

Tested in Struts 2.1.1 with OGNL 2.6.11.  Dumb. 

To summarize:

package com.blueskyminds.web.test;
public class Constants {

    public static final String TEST_CONSTANT1 = "test1";

    // hack for OGNL follows:
    public static final Constants C = new Constants();

    public static String getTEST_CONSTANT1() {
        return TEST_CONSTANT1;
    }
}

In the JSP:
<s:set value="@com.blueskyminds.web.test.Constants@C" var="C"/>
<s:property value="#C.TEST_CONSTANT1"/>

*Note: this is code for 2.1.  In 2.0, the s:set tag uses the id 
attribute instead of var (I think).
*Note again: <s:property value="#C@TEST_CONSTANT1"/> does not work. OGNL 
won't find a static field of an instance.

regards,
 Jeromy Evans




---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Simplified usage of:@com.company.Constants.StaticCOnstants

Posted by Ramanathan RV <ra...@gmail.com>.
Hello,

This has always been a problem. And a quick and decent way of solving this
is to forget OGNL and write your own implementation. Below listed the code
from AppFuse project which essentially creates a tag to expose all the
constants.

*package com.company.app.webapp.taglib;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.TagSupport;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.loandukaan.app.Constants;


/**
 * <p>This class is designed to put all the public variables in a class to a
 * specified scope - designed for exposing a Constants class to Tag
 * Libraries.</p>
 *
 * <p>It is designed to be used as follows:
 * <pre>&lt;tag:constants /&gt;</pre>
 * </p>
 *
 * <p>Optional values are "className" (fully qualified) and "scope".</p>
 *
 * <p>
 * <a href="BaseAction.java.html"><i>View Source</i></a>
 * </p>
 *
 * @author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
 */
public class ConstantsTag extends TagSupport {
    private static final long serialVersionUID = 3258417209566116146L;
    private final Log log = LogFactory.getLog(ConstantsTag.class);

    /**
     * The class to expose the variables from.
     */
    private String clazz = Constants.class.getName();

    /**
     * The scope to be put the variable in.
     */
    protected String scope;

    /**
     * The single variable to expose.
     */
    protected String var;

    /**
     * Main method that does processing and exposes Constants in specified
scope
     * @return int
     * @throws JspException if processing fails
     */
    @Override
    public int doStartTag() throws JspException {
        // Using reflection, get the available field names in the class
        Class c = null;
        int toScope = PageContext.PAGE_SCOPE;

        if (scope != null) {
            toScope = getScope(scope);
        }

        try {
            c = Class.forName(clazz);
        } catch (ClassNotFoundException cnf) {
            log.error("ClassNotFound - maybe a typo?");
            throw new JspException(cnf.getMessage());
        }

        try {
            // if var is null, expose all variables
            if (var == null) {
                Field[] fields = c.getDeclaredFields();

                AccessibleObject.setAccessible(fields, true);

                for (Field field : fields) {
                    pageContext.setAttribute(field.getName(),
field.get(this), toScope);
                }
            } else {
                try {
                    Object value = c.getField(var).get(this);
                    pageContext.setAttribute(c.getField(var).getName(),
value, toScope);
                } catch (NoSuchFieldException nsf) {
                    log.error(nsf.getMessage());
                    throw new JspException(nsf);
                }
            }
        } catch (IllegalAccessException iae) {
            log.error("Illegal Access Exception - maybe a classloader
issue?");
            throw new JspException(iae);
        }

        // Continue processing this page
        return (SKIP_BODY);
    }

    public void setClassName(String clazz) {
        this.clazz = clazz;
    }

    public String getClassName() {
        return this.clazz;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }

    public String getScope() {
        return (this.scope);
    }

    public void setVar(String var) {
        this.var = var;
    }

    public String getVar() {
        return (this.var);
    }

    /**
     * Release all allocated resources.
     */
    public void release() {
        super.release();
        clazz = null;
        scope = Constants.class.getName();
    }

    /**
     * Maps lowercase JSP scope names to their PageContext integer constant
     * values.
     */
    private static final Map<String, Integer> SCOPES = new HashMap<String,
Integer>();

    /**
     * Initialize the scope names map and the encode variable
     */
    static {
        SCOPES.put("page", PageContext.PAGE_SCOPE);
        SCOPES.put("request", PageContext.REQUEST_SCOPE);
        SCOPES.put("session", PageContext.SESSION_SCOPE);
        SCOPES.put("application", PageContext.APPLICATION_SCOPE);
    }

    /**
     * Converts the scope name into its corresponding PageContext constant
value.
     * @param scopeName Can be "page", "request", "session", or
"application" in any
     * case.
     * @return The constant representing the scope (ie.
PageContext.REQUEST_SCOPE).
     * @throws JspException if the scopeName is not a valid name.
     */
    public int getScope(String scopeName) throws JspException {
        Integer scope = (Integer) SCOPES.get(scopeName.toLowerCase());

        if (scope == null) {
            throw new JspException("Scope '" + scopeName + "' not a valid
option");
        }

        return scope;
    }
}
*


On Thu, May 1, 2008 at 2:34 PM, ravi_eze <ra...@ivycomptech.com>wrote:

>
> hi,
>
> even this doesnt seem to be working.
>
> is it possible to load the constant class to the context and then display
> it
> form there.? or in that case it expects a setters and getters... or some
> way
> of getting this done.. the code is very bad to read 'cos every time i am
> using @com.company....
>
> any help???
>
> cheers,
> ravi
>
>
>
> Wes Wannemacher wrote:
> >
> > Did you try to import your Constants class?
> >
> > <%@ page import="com.company.Constants" %>
> >
> > <s:property value="@Constants@STATIC_CONSTANTS1" />
> >
> > As far as say C.staticconstant1, all I can really say is that the @
> > symbol is how you access static vars/methods in OGNL.
> >
> > Another choice might be to use regular ol' EL expressions.
> >
> > -Wes
> >
> > On Tue, 2008-04-29 at 21:45 -0700, ravi_eze wrote:
> >> hi,
> >>
> >>
> >> Does the following work -
> >>
> >> <s:set name="C" value="@com.company.Constants@STATIC_CONSTANTS1" />
> >> <s:property value="#C" />
> >>
> >> Yes it does. But my requirement is more like i would import the class
> >> into
> >> some bean/ variable (C) so that i can say C.staticconstant1 etc... but
> by
> >> the approach mentioned above, i should repeat the @com.company.Constant
> >> string always which reduces the readability. Hope this adds some
> clarity.
> >> Something similar to import.... and then say Constant....
> >>
> >> Also, is com.company.Constants.STATIC_CONSTANTS1 a String?
> >>
> >> Yes its a string.  i would be greatful to any further help.
> >>
> >>
> >> cheers,
> >> ravi
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> > For additional commands, e-mail: user-help@struts.apache.org
> >
> >
> >
>
> --
> View this message in context:
> http://www.nabble.com/Simplified-usage-of%3A%40com.company.Constants.StaticCOnstants-tp16941171p16993179.html
> Sent from the Struts - User mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>


-- 
Thanks
Ram