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(); } } } }