craigmcc 01/08/20 12:18:42 Modified: digester/src/java/org/apache/commons/digester CallMethodRule.java CallParamRule.java Digester.java Log: Allow multiple CallMethodRule rules to be fired on the same pattern. The problem was that each CallMethodRule was pushing its parameter array onto the object stack, which interfered with the ultimate method call on the "top" data object. This was fixed by using a separate stack for the the parameter arrays. As long as you group the CallMethodRule and all its associated CallParamRules together when creating rules, you can now have an unlimited number of them for a particular matching pattern. Submitted by: Jason van Zyl <[EMAIL PROTECTED]> Revision Changes Path 1.7 +6 -6 jakarta-commons/digester/src/java/org/apache/commons/digester/CallMethodRule.java Index: CallMethodRule.java =================================================================== RCS file: /home/cvs/jakarta-commons/digester/src/java/org/apache/commons/digester/CallMethodRule.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- CallMethodRule.java 2001/08/20 18:28:40 1.6 +++ CallMethodRule.java 2001/08/20 19:18:42 1.7 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-commons/digester/src/java/org/apache/commons/digester/CallMethodRule.java,v 1.6 2001/08/20 18:28:40 craigmcc Exp $ - * $Revision: 1.6 $ - * $Date: 2001/08/20 18:28:40 $ + * $Header: /home/cvs/jakarta-commons/digester/src/java/org/apache/commons/digester/CallMethodRule.java,v 1.7 2001/08/20 19:18:42 craigmcc Exp $ + * $Revision: 1.7 $ + * $Date: 2001/08/20 19:18:42 $ * * ==================================================================== * @@ -77,7 +77,7 @@ * * @author Craig McClanahan * @author Scott Sanders - * @version $Revision: 1.6 $ $Date: 2001/08/20 18:28:40 $ + * @version $Revision: 1.7 $ $Date: 2001/08/20 19:18:42 $ */ public class CallMethodRule extends Rule { @@ -217,7 +217,7 @@ String parameters[] = new String[paramCount]; for (int i = 0; i < parameters.length; i++) parameters[i] = null; - digester.push(parameters); + digester.pushParams(parameters); } } @@ -244,7 +244,7 @@ // Retrieve or construct the parameter values array String parameters[] = null; if (paramCount > 0) - parameters = (String[]) digester.pop(); + parameters = (String[]) digester.popParams(); else { parameters = new String[1]; parameters[0] = bodyText; 1.5 +5 -5 jakarta-commons/digester/src/java/org/apache/commons/digester/CallParamRule.java Index: CallParamRule.java =================================================================== RCS file: /home/cvs/jakarta-commons/digester/src/java/org/apache/commons/digester/CallParamRule.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- CallParamRule.java 2001/08/20 18:28:40 1.4 +++ CallParamRule.java 2001/08/20 19:18:42 1.5 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-commons/digester/src/java/org/apache/commons/digester/CallParamRule.java,v 1.4 2001/08/20 18:28:40 craigmcc Exp $ - * $Revision: 1.4 $ - * $Date: 2001/08/20 18:28:40 $ + * $Header: /home/cvs/jakarta-commons/digester/src/java/org/apache/commons/digester/CallParamRule.java,v 1.5 2001/08/20 19:18:42 craigmcc Exp $ + * $Revision: 1.5 $ + * $Date: 2001/08/20 19:18:42 $ * * ==================================================================== * @@ -73,7 +73,7 @@ * by a surrounding CallMethodRule rule. * * @author Craig McClanahan - * @version $Revision: 1.4 $ $Date: 2001/08/20 18:28:40 $ + * @version $Revision: 1.5 $ $Date: 2001/08/20 19:18:42 $ */ public class CallParamRule extends Rule { @@ -169,7 +169,7 @@ */ public void end() throws Exception { - String parameters[] = (String[]) digester.peek(); + String parameters[] = (String[]) digester.peekParams(); parameters[paramIndex] = bodyText; } 1.14 +93 -18 jakarta-commons/digester/src/java/org/apache/commons/digester/Digester.java Index: Digester.java =================================================================== RCS file: /home/cvs/jakarta-commons/digester/src/java/org/apache/commons/digester/Digester.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- Digester.java 2001/08/13 18:59:46 1.13 +++ Digester.java 2001/08/20 19:18:42 1.14 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-commons/digester/src/java/org/apache/commons/digester/Digester.java,v 1.13 2001/08/13 18:59:46 craigmcc Exp $ - * $Revision: 1.13 $ - * $Date: 2001/08/13 18:59:46 $ + * $Header: /home/cvs/jakarta-commons/digester/src/java/org/apache/commons/digester/Digester.java,v 1.14 2001/08/20 19:18:42 craigmcc Exp $ + * $Revision: 1.14 $ + * $Date: 2001/08/20 19:18:42 $ * * ==================================================================== * @@ -106,7 +106,7 @@ * * @author Craig McClanahan * @author Scott Sanders - * @version $Revision: 1.13 $ $Date: 2001/08/13 18:59:46 $ + * @version $Revision: 1.14 $ $Date: 2001/08/20 19:18:42 $ */ public class Digester extends DefaultHandler { @@ -209,6 +209,13 @@ /** + * The parameters stack being utilized by CallMethodRule and + * CallParamRule rules. + */ + protected ArrayStack params = new ArrayStack(); + + + /** * The SAXParser we will use to parse the input stream. */ protected SAXParser parser = null; @@ -576,18 +583,19 @@ public void endElement(String namespaceURI, String localName, String qName) throws SAXException { - // if (debug >= 3) - // log("endElement(" + match + ")"); + if (debug >= 3) + log("endElement(" + match + ")"); List rules = getRules().match(match); // Fire "body" events for all relevant rules if (rules != null) { - // if (debug >= 3) - // log(" Firing 'body' events for " + rules.size() + " rules"); String bodyText = this.bodyText.toString().trim(); for (int i = 0; i < rules.size(); i++) { try { - ((Rule) rules.get(i)).body(bodyText); + Rule rule = (Rule) rules.get(i); + if (debug >= 4) + log(" Fire body() for " + rule); + rule.body(bodyText); } catch (Exception e) { log("Body event threw exception", e); throw new SAXException(e); @@ -600,12 +608,13 @@ // Fire "end" events for all relevant rules in reverse order if (rules != null) { - // if (debug >= 3) - // log(" Firing 'end' events for " + rules.size() + " rules"); for (int i = 0; i < rules.size(); i++) { int j = (rules.size() - i) - 1; try { - ((Rule) rules.get(j)).end(); + Rule rule = (Rule) rules.get(j); + if (debug >= 4) + log(" Fire end() for " + rule); + rule.end(); } catch (Exception e) { log("End event threw exception", e); throw new SAXException(e); @@ -733,18 +742,19 @@ else sb.append(localName); match = sb.toString(); - // if (debug >= 3) - // log("startElement(" + match + ")"); + if (debug >= 3) + log("startElement(" + match + ")"); // Fire "begin" events for all relevant rules List rules = getRules().match(match); if (rules != null) { - // if (debug >= 3) - // log(" Firing 'begin' events for " + rules.size() + " rules"); String bodyText = this.bodyText.toString(); for (int i = 0; i < rules.size(); i++) { try { - ((Rule) rules.get(i)).begin(list); + Rule rule = (Rule) rules.get(i); + if (debug >= 4) + log(" Fire begin() for " + rule); + rule.begin(list); } catch (Exception e) { log("Begin event threw exception", e); throw new SAXException(e); @@ -1302,7 +1312,7 @@ } - // -------------------------------------------------------- Stack Methods + // --------------------------------------------------- Object Stack Methods /** @@ -1312,6 +1322,7 @@ match = ""; bodyTexts.clear(); + params.clear(); stack.clear(); getRules().clear(); @@ -1381,6 +1392,9 @@ } + // ------------------------------------------------ Parameter Stack Methods + + // -------------------------------------------------------- Package Methods @@ -1410,6 +1424,67 @@ List getRules(String match) { return (getRules().match(match)); + + } + + + /** + * Return the top object on the stack without removing it. If there are + * no objects on the stack, return <code>null</code>. + */ + Object peekParams() { + + try { + return (params.peek()); + } catch (EmptyStackException e) { + return (null); + } + + } + + + /** + * Return the n'th object down the stack, where 0 is the top element + * and [getCount()-1] is the bottom element. If the specified index + * is out of range, return <code>null</code>. + * + * @param n Index of the desired element, where 0 is the top of the stack, + * 1 is the next element down, and so on. + */ + Object peekParams(int n) { + + try { + return (params.peek(n)); + } catch (EmptyStackException e) { + return (null); + } + + } + + + /** + * Pop the top object off of the stack, and return it. If there are + * no objects on the stack, return <code>null</code>. + */ + Object popParams() { + + try { + return (params.pop()); + } catch (EmptyStackException e) { + return (null); + } + + } + + + /** + * Push a new object onto the top of the object stack. + * + * @param object The new object + */ + void pushParams(Object object) { + + params.push(object); }