>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-version>2.0</tlib-version>
        <short-name>commons</short-name>
                
        <uri>http://com.commons.tag</uri>


        <function>
            <name>const</name>
            <function-class>ELFunctions</function-class>
            <function-signature>
                java.lang.String
                        getConstant(
                                java.lang.String)
            </function-signature>
        </function>     
        
        <function> 
            <name>mathConst</name>
            <function-class>ELFunctions</function-class>
            <function-signature>
                java.lang.String
                        getMathConstant(
                                java.lang.String)
            </function-signature>
        </function>     
        
        <function> 
            <name>bigIntConst</name>
            <function-class>ELFunctions</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 directly into ELFunctions.java. :


----------------------------------------------------------------------------
------

package fieldreflector;

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

/**
 * This class indexes all fields of a class and all its superclasses. It is 
 * used as a lookup cache for fields of a class.
 */
public class ClassFieldCache{
        //Holds all fields
        private final Map fields= new HashMap();

        /**
         * Constructor. Indexes all fields of a specific class and all
         * its superclasses.
         * 
         * @param clazz the class to index
         */
        public ClassFieldCache(final Class clazz){
                Class loopClazz= clazz;
                while(loopClazz != null){
                        Field[] loopFields= loopClazz.getFields();
                        for(int i= 0; i < loopFields.length; i++){
                                final Field field= loopFields[i];
                                final String name= field.getName();

                                fields.put(name, field);
                        }

                        loopClazz= loopClazz.getSuperclass();
                }
        }

        /**
         * Get a field of the class. If the field does not 
         * exist, null is returned.
         * 
         * @param name the name of the field to find.
         */
        public Field getField(final String name){
                return (Field)fields.get(name);
        }
}

-------------------------------------------------------------------------

package fieldreflector;

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

/**
 * This is the main class for the FieldReflector package. The main purpose
 * of this package is to speed up reflective field access through
caching.<br/><br/>
 * 
 * The FieldReflector provides simple reflective access to fields of 
 * classes.<br/><br/>
 * 
 * Examples: <br/>
 * 
 * Object value = FieldReflector.getFieldValue(clazz, fieldName); <br/><br/>
 * 
 * Class clazz= FieldReflector.getFieldType(clazz, fieldName); <br/><br/>
 */
public class FieldReflector{
        //All class caches. Are built when the reflector is used.
        private static final Map CACHES= new HashMap();

        /**
         * Retrieved a public static field from a class, and prints the
String
         * representation of the variable.
         * 
         * @param fullName the full class name followed by the variable name
with
         *                dot notation: "java.lang.Integer.MAX_VALUE"
         */
        public static Object getFieldValue(final String fullName) throws
ReflectionException{
                final int dotIndex= fullName.lastIndexOf(".");
                final String className= fullName.substring(0, dotIndex);
                final String variable= fullName.substring(dotIndex + 1);

                final Class clazz;
                try{
                        clazz= Class.forName(className);
                }catch(ClassNotFoundException e){
                        throw new ReflectionException("The class " +
className
                                        + " could not be found.");
                }

                return getFieldValue(clazz, variable);
        }

        /**
         * Gets a field value from a class.
         * 
         * @param clazz the class to parse for the field
         * @param name the name of the field
         */
        public static Object getFieldValue(final Class clazz, final String
name)
                        throws ReflectionException{
                final Field field= getField(clazz, name);

                Object value= null;
                try{
                        value= field.get(null);
                }catch(IllegalAccessException e){
                        throw new ReflectionException("You don't have rigth
to access this field", e);
                }

                return value;
        }

        /**
         * Returns the type of a field on a class.
         * 
         * @param clazz the clazz to parse for the field type
         * @param name the name of the field
         */
        public static Class getFieldType(final Class clazz, final String
name)
                        throws ReflectionException{
                return getField(clazz, name).getType();
        }

        /*
         * Used to get a field from an class.
         * 
         * @param class the class to parse for the field
         * @param name the name of the field
         */
        private static Field getField(final Class clazz, final String name)
                        throws ReflectionException{
                final String className= clazz.getName();

                ClassFieldCache cache=
(ClassFieldCache)CACHES.get(className);
                if(cache == null){
                        cache= new ClassFieldCache(clazz);
                        CACHES.put(className, cache);
                }

                final Field field= cache.getField(name);
                if(field == null){
                        throw new IllegalArgumentException("There is no
field with name '" + name
                                        + "' on " + clazz.getName());
                }

                return field;
        }
}

-----------------------------------------------------------------------


package fieldreflector;

/**
 * This is an exception for the reflection package
 */
public class ReflectionException extends Exception{
        /**
         * Constructor
         * 
         * @param message a message from the exception
         */
        public ReflectionException(final String message){
                super(message);
        }

        /**
         * Constructor
         * 
         * @param message a message from the exception
         * @param nested a nested exception
         */
        public ReflectionException(final String message, final Throwable
nested){
                super(message, nested);
        }
}

---------------------------------------------------------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to