Re: JSTL and Java Constants
On 8/31/05, Martin Cooper [EMAIL PROTECTED] wrote: On 8/30/05, Rahul Akolkar [EMAIL PROTECTED] wrote: snip/ 2) Another approach that some choose is to provide a Constants bean that supplies getters for the constants, which is what we ended up doing for the RDC taglib. Isn't that effectively the same thing, once all is said and done? Wouldn't accessing a Constants bean be identical to accessing the constants from a map provided by this tag? snip/ Was enumerating all the options, the tag is a convenient option, no doubt. -Rahul -- Martin Cooper - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JSTL and Java Constants
On 8/31/05, Luca Passani [EMAIL PROTECTED] wrote: Martin Cooper wrote: Done. I think. At least, everything seems to have worked out, so it should be available in the next nightly build of Unstandard. will I need to wait tomorrow to download? great. I am eager to try it. Urk. I just checked, and it looks like Unstandard is not included in the nighly builds. Glenn, if you're reading this, could you add it please? In the meantime, I've put my local build up here: http://people.apache.org/~martinc/taglibs/unstandard/ One little doubt: |un:useConstants var=const className=java.lang.Integer / The constants are defined in an interface (not a class). || public interface ContentType { public static final int FOLDER = 1;|| public static final int URL = 2; : } ||Will the tag work the same? Yes, it will work the same. -- Martin Cooper Thanks Luca || | - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JSTL and Java Constants
Martin Cooper wrote: Yes, it will work the same. It works like a charm. You rock. Thanks Luca - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JSTL and Java Constants
I would like to do something like: a) c:when test=${item.type == ContentType.URL} This won't work. I could hack it around with a scriptlet and an import at the top of my JSP, but that seems to me like violating the separation between View and Control You may want to see this - http://forums.java.sun.com/thread.jspa?threadID=508847messageID=2543490 One big tradeoff with that approach is that you have to specify your constants in one Constant class where they may not naturally belong. Another one would be that you would have to import all external constants into that class, thereby creating double maintenance work. And a third would be that you'd need to import the constant class at the top of each page. My workaround for the fact that you directly can't reach a static variable in a java class is to make invoke a static method through the EL which in turns does some reflective parsing to find the constant. It would look like this: c:when test=${item.type == fn:const('URL')} You could create several different extractor methods to have different level of generality in the method so that you can reach constants in a predefined class, in a package, or with the full class name: c:when test=${item.type == fn:const('ActionHandler.URL')} or c:when test=${item.type == fn:const('java.lang.Integer.MAX_VALUE')} With this approach you are guaranteed to not have any hard coded magic values in your jsp. I do not have the code that does the extraction here at my work, but if you are interested, I can send it over or post it here. Regards, Erik Beijnoff - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JSTL and Java Constants
Erik, Please posting the code , I am also interested. Thanks John Erik Beijnoff [EMAIL PROTECTED] Erik Beijnoff [EMAIL PROTECTED] 08/31/2005 02:59 PM Please respond to Tag Libraries Users List To: taglibs-user@jakarta.apache.org cc: Subject: Re: JSTL and Java Constants I would like to do something like: a) c:when test=${item.type == ContentType.URL} This won't work. I could hack it around with a scriptlet and an import at the top of my JSP, but that seems to me like violating the separation between View and Control You may want to see this - http://forums.java.sun.com/thread.jspa?threadID=508847messageID=2543490 One big tradeoff with that approach is that you have to specify your constants in one Constant class where they may not naturally belong. Another one would be that you would have to import all external constants into that class, thereby creating double maintenance work. And a third would be that you'd need to import the constant class at the top of each page. My workaround for the fact that you directly can't reach a static variable in a java class is to make invoke a static method through the EL which in turns does some reflective parsing to find the constant. It would look like this: c:when test=${item.type == fn:const('URL')} You could create several different extractor methods to have different level of generality in the method so that you can reach constants in a predefined class, in a package, or with the full class name: c:when test=${item.type == fn:const('ActionHandler.URL')} or c:when test=${item.type == fn:const('java.lang.Integer.MAX_VALUE')} With this approach you are guaranteed to not have any hard coded magic values in your jsp. I do not have the code that does the extraction here at my work, but if you are interested, I can send it over or post it here. Regards, Erik Beijnoff - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] The information contained in this message may be CONFIDENTIAL and is for the intended addressee only. Any unauthorized use, dissemination of the information, or copying of this message is prohibited. If you are not the intended addressee, please notify the sender immediately and delete this message.
RE: JSTL and Java Constants
Please posting the code , I am also interested. Thanks John The big tradeoff is of course the extra fn:xxx('...') that needs to be written in the code. But a big plus is that once direct retrieval of constants from java classes is integrated into the EL, a conversion is simple a matter of search and replace. I've extracted the relevant classes into a package attached to this message, although I'm not sure if this list accepts attachments. The classes have been extracted from a larger context and converted from Java 5 and may therefore be erraneous, although they have been tested. Second, the implementation could have been simpler, but it was built with a field cache to make sure repeated retrieval of fields is efficient, so I included that cache too. If you have any questions about the code, please feel free to ask. Regards Erik Beijnoff Anyway, first out is the EL static function mapping file and it's associated .tld: --- import java.math.BigInteger; import fieldreflector.FieldReflector; import fieldreflector.ReflectionException; /** * These classes are static helper functions used by JSP pages. These are for * example helper methods to find fields in classes. */ public class ELFunctions{ //Cached reference to the math package prefix private static final String mathPackagePrefix; private static final String bigIntClassPrefix; static{ mathPackagePrefix= BigInteger.class.getPackage().getName() + .; bigIntClassPrefix= BigInteger.class.getName() + .; } /* Private constructor */ private ELFunctions(){ //Do nothing } /** * Retrieves a public static field from a class, and returns the field value. * * @param fullName the full class name followed by the variable name with *dot notation: java.lang.Integer.MAX_VALUE */ public static Object getConstant(final String fullName) throws ReflectionException{ return FieldReflector.getFieldValue(fullName); } /** * Retrieves a public field from a class in the java.math package, * and returns the field value br/br/ * * @param name the action class name followed by the variable name with *dot notation: BigInteger.ONE * @return the extracted variable value */ public static Object getMathConstant(final String name) throws ReflectionException{ return getConstant(mathPackagePrefix + name); } /** * Retrieves a public field from a class in the java.math.BigInteger class, * and returns the field value. br/br/ * * @param name the action class name followed by the variable name with *dot notation: ONE * @return the extracted variable value */ public static Object getBigIntConstant(final String name) throws ReflectionException{ return getConstant(bigIntClassPrefix + name); } } ?xml version=1.0 encoding=ISO-8859-1? taglib version=2.0 xmlns=http://java.sun.com/xml/ns/j2ee; xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance tlib-version2.0/tlib-version short-namecommons/short-name urihttp://com.commons.tag/uri function nameconst/name function-classELFunctions/function-class function-signature java.lang.String getConstant( java.lang.String) /function-signature /function function namemathConst/name function-classELFunctions/function-class function-signature java.lang.String getMathConstant( java.lang.String) /function-signature /function function namebigIntConst/name function-classELFunctions/function-class function-signature java.lang.String getBigIntConstant java.lang.String) /function-signature /function /taglib --- A few example ways to extract the constants are included, with the java.math package as example. Every invokation of a field is stored in a field cache, since reflection may be a bit slow. This cache is listed in the three following files. But as mentioned, they are really not needed if you want to make the implementation simpler. Then the reflection code can be incorporated
Re: JSTL and Java Constants
You may want to see this - http://forums.java.sun.com/thread.jspa?threadID=508847messageID=2543490 Cheers, Sudhaker Raj http://thej2ee.com On 8/30/05, Luca Passani [EMAIL PROTECTED] wrote: Hi there, here is my big problem today. I am using JSTL in some JSPs. SInce this is a struts project, I would like to keep my views totally separated from the Java APIs. For this reason, I need your advice about the most elegant to compare a given object type (an int constant) with the possible values using the COSTANT name, instead of the corresponding int. The API defines the types of my object as: public interface ContentType { public static final int FOLDER = 1; public static final int URL = 2; } in my JSP I have (loop over collection of items with getType() returning the type int) c:forEach var=item items=${content_list} c:choose c:when test=${item.type == 2} a href=${item.value}c:out value=${item.name http://item.name }//a /c:when : I would like to do something like: a) c:when test=${item.type == ContentType.URL} This won't work. I could hack it around with a scriptlet and an import at the top of my JSP, but that seems to me like violating the separation between View and Control b) I could do something like this in my action: String type_url = 5; request.setAttribute(url, type_url); and then c:when test=${item.type == url} but makes me wonder if having this code in the action really makes sense. Any ideas? Thanks Luca - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] -- Cheers, Sudhaker Raj http://thej2ee.com
Re: JSTL and Java Constants
And If you can't extend from that class then you can write adapter for that class. Something like this Using in a JSP page: [code] %@ taglib prefix=c uri=http://java.sun.com/jstl/core; % jsp:useBean id=Constants class=com.utils.JSTLMyConstants/ c:out value=${Constants.name http://Constants.name}/br c:out value=${Constants.age}/ c:forEach var=day items=${Constants.daysOfTheWeek} c:out value=${day}/ /c:forEach [/code] Where adapter class is [code] package com.utils; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; /** * Class to reveal java constants to JSTL Expression Language * Uses reflection to scan the declared fields of a Constants class * Adds these fields to the Map. * Map is unmodifiable after initialization. */ public class JSTLMyConstants extends HashMap { private boolean initialised = false; private static final Class adaptee = MyConstant.class; public JSTLMyConstants() { Class c = adaptee; Field[] fields = c.getDeclaredFields(); for (int i = 0; i fields.length; i++) { Field field = fields[i]; int modifier = field.getModifiers(); if (Modifier.isFinal(modifier) !Modifier.isPrivate(modifier)) try { this.put(field.getName(), field.get(this)); } catch (IllegalAccessException e) {} } initialised = true; } public void clear() { if (!initialised) super.clear(); else throw new UnsupportedOperationException(Cannot modify this map); } public Object put(Object key, Object value) { if (!initialised) return super.put(key, value); else throw new UnsupportedOperationException(Cannot modify this map); } public void putAll(Map m) { if (!initialised) super.putAll(m); else throw new UnsupportedOperationException(Cannot modify this map); } public Object remove(Object key) { if (!initialised) return super.remove(key); else throw new UnsupportedOperationException(Cannot modify this map); } } [/code] // Main constant class [code] package com.utils; public interface MyConstant { public static final int age = 30; public static final String name = Sudhaker Raj; public static final String programmingSkill = Awesome; public static final String[] daysOfTheWeek = { Sun, Mon, Tue, Wed, Thu, Fri, Sat, Sun }; } [/code] Hope this helps. On 8/30/05, Luca Passani [EMAIL PROTECTED] wrote: Sudhaker Raj wrote: You may want to see this - http://forums.java.sun.com/thread.jspa?threadID=508847messageID=2543490 very smart. A bit overkill for my problem, but very smart... Thanks Luca - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] -- Cheers, Sudhaker Raj http://thej2ee.com
Re: JSTL and Java Constants
Take a look at the 'bind' tag in the Jakarta Taglibs Unstandard tag library. See: http://jakarta.apache.org/taglibs/sandbox/doc/unstandard-doc/index.html#bind I have a useConstants tag that I've been meaning to donate that exposes all of the constants in a class, but I haven't got around to that yet. -- Martin Cooper On 8/30/05, Luca Passani [EMAIL PROTECTED] wrote: Hi there, here is my big problem today. I am using JSTL in some JSPs. SInce this is a struts project, I would like to keep my views totally separated from the Java APIs. For this reason, I need your advice about the most elegant to compare a given object type (an int constant) with the possible values using the COSTANT name, instead of the corresponding int. The API defines the types of my object as: public interface ContentType { public static final int FOLDER = 1; public static final int URL = 2; } in my JSP I have (loop over collection of items with getType() returning the type int) c:forEach var=item items=${content_list} c:choose c:when test=${item.type == 2} a href=${item.value}c:out value=${item.name http://item.name }//a /c:when : I would like to do something like: a) c:when test=${item.type == ContentType.URL} This won't work. I could hack it around with a scriptlet and an import at the top of my JSP, but that seems to me like violating the separation between View and Control b) I could do something like this in my action: String type_url = 5; request.setAttribute(url, type_url); and then c:when test=${item.type == url} but makes me wonder if having this code in the action really makes sense. Any ideas? Thanks Luca - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JSTL and Java Constants
Martin Cooper wrote: Take a look at the 'bind' tag in the Jakarta Taglibs Unstandard tag library. See: http://jakarta.apache.org/taglibs/sandbox/doc/unstandard-doc/index.html#bind interesting. Do you have an example of how that should be used? Thanks Luca - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JSTL and Java Constants
On 8/30/05, Luca Passani [EMAIL PROTECTED] wrote: Martin Cooper wrote: Take a look at the 'bind' tag in the Jakarta Taglibs Unstandard tag library. See: http://jakarta.apache.org/taglibs/sandbox/doc/unstandard-doc/index.html#bind interesting. Do you have an example of how that should be used? I believe it's something like: un:bind var=TheConstant type=com.yourco.ContentType field=URL / and then you can use 'TheConstant' when you want the value. My useConstants tag works like this: un:useConstants var=TheConstants className=com.yourco.ContentType / and then 'TheConstants' contains a map of all constants in the class, so you can use, for example: ${TheConstants.URL} -- Martin Cooper Thanks Luca - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JSTL and Java Constants
Martin Cooper wrote: and then 'TheConstants' contains a map of all constants in the class, so you can use, for example: ${TheConstants.URL} bang on. That would be cool. I have worked my problem around in my application, but your solution would be better, since it would decouple my action from the underlying API. Should I hold my breath? Thanks Luca - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JSTL and Java Constants
On 8/30/05, Luca Passani [EMAIL PROTECTED] wrote: Martin Cooper wrote: and then 'TheConstants' contains a map of all constants in the class, so you can use, for example: ${TheConstants.URL} bang on. That would be cool. I have worked my problem around in my application, but your solution would be better, since it would decouple my action from the underlying API. Should I hold my breath? Well, I might have a go at adding it tonight, if I have time. It's been a *long* time since I've tried to build Taglibs, though, so if I have trouble with that, it might not happen, since I don't want to break the nightly builds. -- Martin Cooper Thanks Luca - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JSTL and Java Constants
On 8/30/05, Martin Cooper [EMAIL PROTECTED] wrote: On 8/30/05, Luca Passani [EMAIL PROTECTED] wrote: Martin Cooper wrote: and then 'TheConstants' contains a map of all constants in the class, so you can use, for example: ${TheConstants.URL} bang on. That would be cool. I have worked my problem around in my application, but your solution would be better, since it would decouple my action from the underlying API. Should I hold my breath? Well, I might have a go at adding it tonight, if I have time. It's been a *long* time since I've tried to build Taglibs, though, so if I have trouble with that, it might not happen, since I don't want to break the nightly builds. Done. I think. At least, everything seems to have worked out, so it should be available in the next nightly build of Unstandard. -- Martin Cooper -- Martin Cooper Thanks Luca - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]