I had a quick look through and I have an observation if you're interested 
in performance stuff:

(One of) the slowest aspects of reflection is Class.forName().  When I've 
used reflection in the past, I created a static Map classes = new 
HashMap(), which I use as a cache, with the class name as the key and the 
class itself as the value.

Hmm - the amount of time it's taking me to explain this I might as well 
code it myself :o)

Here you go (attached).  Haven't tested it, so usual caveats apply.

Cheers,
Dan/tastapod

At 18:14 06/04/2001 -0400, you wrote:
>Since I had already modified the Iterate tag to support sliding windows, I
>went ahead and incorporated Rafael's sorting tag and enhanced it to support
>descending order.  I've only attached the IterateTag.java and a sample tld
>if anyone would like to use it.
>
>Michael
>
>-----Original Message-----
>From: [EMAIL PROTECTED]
>[mailto:[EMAIL PROTECTED]]On Behalf Of Rafael Alvarez
>Sent: Tuesday, March 06, 2001 9:42 AM
>To: Orion-Interest
>Subject: Re: A modification to ejbtags.jar
>
>
>Ok. that resolve it :)
>I made two mistakes:
>1) This mail was intended for Karl, but I misclicked in my email
>manager.
>2) The version I sent is not a working one. I just realized that I
>lost the last version in the last crash of our CVS... Mea culpa not
>having a backup.
>
>Anyway, here is the working version.
>
>
>I'm interested in performance metrics, since it uses reflection...
>
>
>--
>Best regards,
>  Rafael                            mailto:[EMAIL PROTECTED]
>
>

--
Dan North
VP Development  -  Cadrion Software Ltd  -  +44 (0)20 7440 9550

CONFIDENTIALITY
This e-mail and any attachments are confidential
and may also be privileged. If you are not the named recipient,
please notify the sender immediately and do not disclose the
contents to another person, use it for any purpose, or store
or copy the information in any medium
package com.evermind.ejb.taglib;

import java.util.*;
import javax.ejb.*;
import javax.naming.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import javax.servlet.http.*;

import java.lang.reflect.*;

/**
 *  IterateTag
 *
 *@author     Magnus Stenman
 *@created    April 6, 2001
 */
public class IterateTag extends BodyTagSupport {
        // iterator
        private PagedIterator it = new PagedIterator();

        // temporary variables
        private Vector vector = null;
        private String type = null;
        private int startRow = 1;
        private int displayRows = 1000;
        private String orderBy = null;
        private boolean descending = false;


        /**
         *  Sets the Collection attribute of the IterateTag object
         *
         *@param  collection  The new Collection value
         */
        public void setCollection(Collection collection) {
                this.vector = new Vector(collection);
        }


        /**
         *  Sets the Type attribute of the IterateTag object
         *
         *@param  type  The new Type value
         */
        public void setType(String type) {
                this.type = type;
        }


        /**
         *  Sets the StartRow attribute of the IterateTag object
         *
         *@param  startRow  The new StartRow value
         */
        public void setStartRow(int startRow) {
                this.startRow = startRow;
        }


        /**
         *  Sets the DisplayRows attribute of the IterateTag object
         *
         *@param  displayRows  The new DisplayRows value
         */
        public void setDisplayRows(int displayRows) {
                this.displayRows = displayRows;
        }


        /**
         *  Sets the OrderBy attribute of the IterateTag object
         *
         *@param  orderBy  The new OrderBy value
         */
        public void setOrderBy(String orderBy) {
                this.orderBy = orderBy;
        }


        /**
         *  Sets the Descending attribute of the IterateTag object
         *
         *@param  descending  The new Descending value
         */
        public void setDescending(boolean descending) {
                this.descending = descending;
        }


        /**
         *  Description of the Method
         *
         *@return                   Description of the Returned Value
         *@exception  JspException  Description of Exception
         */
        public int doStartTag() throws JspException {

                if (this.orderBy != null) {
                        System.out.println("Order by = " + orderBy);
                        CompareInstances compare = new CompareInstances(this.type,
                                        this.orderBy, this.descending);
                        Collections.sort(vector, compare);
                }

                it.setIterator(vector.iterator());
                it.setStartRow(startRow);
                it.setDisplayRows(displayRows);

                return doAfterBody();
        }


        /**
         *  Description of the Method
         *
         *@return    Description of the Returned Value
         */
        public int doEndTag() {
                return EVAL_PAGE;
        }


        /**
         *  Description of the Method
         *
         *@return                   Description of the Returned Value
         *@exception  JspException  Description of Exception
         */
        public int doAfterBody() throws JspException {
                if (it.hasNext()) {
                        pageContext.setAttribute(this.getId(), it.next());

                        return BodyTag.EVAL_BODY_TAG;
                }
                else {
                        try {
                                if (bodyContent != null) {
                                        
bodyContent.writeOut(bodyContent.getEnclosingWriter());
                                }
                        }
                        catch (java.io.IOException e) {
                                throw new JspException("IO Error: " + e.getMessage());
                        }

                        return BodyTag.SKIP_BODY;
                }
        }


        /**
         *  Description of the Class
         *
         *@author     mthird
         *@created    April 6, 2001
         */
        private class CompareInstances implements Comparator {
                private static final Map classes = new HashMap();

                Class type;
                Method method;
                boolean descending;


                /**
                 *  Constructor for the CompareInstances object
                 *
                 *@param  type              Description of Parameter
                 *@param  orderField        Description of Parameter
                 *@param  descending        Description of Parameter
                 *@exception  JspException  Description of Exception
                 */
                public CompareInstances(String type, String orderField,
                                boolean descending) throws JspException {
                        try {
                                this.type = getType( type );
                                String field = "get" + 
Character.toUpperCase(orderField.charAt(0))
                                                 + orderField.substring(1);
                                System.out.println("Field name = " + field);
                                this.method = this.type.getMethod(field, null);
                                this.descending = descending;
                        }
                        catch (NoSuchMethodException e) {
                                throw new JspException("No such method " + this.method 
+ " in class " + this.type);
                        }
                }

                /**
                 * Find the class corresponding to the given class name.  If it 
doesn't exist in the
                 * cache, create it and add it for next time.
                 */
                private Class getType( String type ) throws JspException {
                        try {
                                Class result = ( Class )classes.get( type );

                                if ( result == null ) {
                                        result = Class.forName( type );
                                        classes.put( type, result );
                                }
                                return result;
                        }
                        catch (ClassNotFoundException e) {
                                throw new JspException("Error finding " + type);
                        }
                }


                /**
                 *  Description of the Method
                 *
                 *@param  o1  Description of Parameter
                 *@param  o2  Description of Parameter
                 *@return     Description of the Returned Value
                 */
                public int compare(Object o1, Object o2) {

                        String field1 = "";
                        String field2 = "";

                        try {

                                field1 = this.method.invoke(o1, null).toString();

                        }
                        catch (java.lang.IllegalAccessException e) {
                                throw new RuntimeException("Error invoking " +
                                                this.type.getName() + "." + 
this.method.getName() + " :  Not a non-parameter method.");
                        }
                        catch (java.lang.reflect.InvocationTargetException e) {
                                throw new RuntimeException("Exception thrown while 
invoking " +
                                                this.type.getName() + "." + 
this.method.getName() + " : " + e.getMessage());
                        }

                        try {

                                field2 = this.method.invoke(o2, null).toString();

                        }
                        catch (java.lang.IllegalAccessException e) {
                                throw new RuntimeException("Error invoking " +
                                                this.type.getName() + "." + 
this.method.getName() + " :  Not a non-parameter method.");
                        }
                        catch (java.lang.reflect.InvocationTargetException e) {
                                throw new RuntimeException("Exception thrown while 
invoking " +
                                                this.type.getName() + "." + 
this.method.getName() + " : " + e.getMessage());
                        }

                        int order = field1.compareTo(field2);

                        if (descending) {
                                order = -order;
                        }
                        return order;
                }
        }


        /**
         *  Description of the Class
         *
         *@author     MThird
         *@created    April 6, 2001
         */
        private class PagedIterator {

                private Iterator it = null;
                private int startRow = 0;
                private int displayRows = 0;

                private int current = 0;


                /**
                 *  Constructor for the PagedIterator object
                 */
                public PagedIterator() {
                }


                /**
                 *  Sets the StartRow attribute of the PagedIterator object
                 *
                 *@param  startRow  The new StartRow value
                 */
                public void setStartRow(int startRow) {
                        this.startRow = startRow;
                }


                /**
                 *  Sets the DisplayRows attribute of the PagedIterator object
                 *
                 *@param  displayRows  The new DisplayRows value
                 */
                public void setDisplayRows(int displayRows) {
                        this.displayRows = displayRows;
                }


                /**
                 *  Sets the Iterator attribute of the PagedIterator object
                 *
                 *@param  it  The new Iterator value
                 */
                public void setIterator(Iterator it) {
                        this.it = it;
                }


                /**
                 *  Description of the Method
                 *
                 *@return    Description of the Returned Value
                 */
                public boolean hasNext() {
                        if (it.hasNext() && current < (displayRows + startRow - 1)) {
                                return true;
                        }
                        else {
                                return false;
                        }
                }


                /**
                 *  Description of the Method
                 *
                 *@return    Description of the Returned Value
                 */
                public Object next() {
                        // position iterator to the requested start
                        while (current < startRow - 1) {
                                current++;
                                it.next();
                        }

                        if (this.hasNext()) {
                                current++;
                                return it.next();
                        }
                        else {
                                throw new NoSuchElementException();
                        }
                }
        }
}

Reply via email to