Source Code Cross Referenced for CallMethodRule.java in  » Library » Apache-commons-digester-1.8-src » org » apache » commons » digester » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Library » Apache commons digester 1.8 src » org.apache.commons.digester 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* $Id: CallMethodRule.java 471661 2006-11-06 08:09:25Z skitching $
002:         *
003:         * Licensed to the Apache Software Foundation (ASF) under one or more
004:         * contributor license agreements.  See the NOTICE file distributed with
005:         * this work for additional information regarding copyright ownership.
006:         * The ASF licenses this file to You under the Apache License, Version 2.0
007:         * (the "License"); you may not use this file except in compliance with
008:         * the License.  You may obtain a copy of the License at
009:         * 
010:         *      http://www.apache.org/licenses/LICENSE-2.0
011:         * 
012:         * Unless required by applicable law or agreed to in writing, software
013:         * distributed under the License is distributed on an "AS IS" BASIS,
014:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015:         * See the License for the specific language governing permissions and
016:         * limitations under the License.
017:         */
018:
019:        package org.apache.commons.digester;
020:
021:        import org.apache.commons.beanutils.ConvertUtils;
022:        import org.apache.commons.beanutils.MethodUtils;
023:        import org.xml.sax.Attributes;
024:
025:        /**
026:         * <p>Rule implementation that calls a method on an object on the stack
027:         * (normally the top/parent object), passing arguments collected from 
028:         * subsequent <code>CallParamRule</code> rules or from the body of this
029:         * element. </p>
030:         *
031:         * <p>By using {@link #CallMethodRule(String methodName)} 
032:         * a method call can be made to a method which accepts no
033:         * arguments.</p>
034:         *
035:         * <p>Incompatible method parameter types are converted 
036:         * using <code>org.apache.commons.beanutils.ConvertUtils</code>.
037:         * </p>
038:         *
039:         * <p>This rule now uses {@link MethodUtils#invokeMethod} by default.
040:         * This increases the kinds of methods successfully and allows primitives
041:         * to be matched by passing in wrapper classes.
042:         * There are rare cases when {@link MethodUtils#invokeExactMethod} 
043:         * (the old default) is required.
044:         * This method is much stricter in it's reflection.
045:         * Setting the <code>UseExactMatch</code> to true reverts to the use of this 
046:         * method.</p>
047:         *
048:         * <p>Note that the target method is invoked when the  <i>end</i> of
049:         * the tag the CallMethodRule fired on is encountered, <i>not</i> when the
050:         * last parameter becomes available. This implies that rules which fire on
051:         * tags nested within the one associated with the CallMethodRule will 
052:         * fire before the CallMethodRule invokes the target method. This behaviour is
053:         * not configurable. </p>
054:         *
055:         * <p>Note also that if a CallMethodRule is expecting exactly one parameter
056:         * and that parameter is not available (eg CallParamRule is used with an
057:         * attribute name but the attribute does not exist) then the method will
058:         * not be invoked. If a CallMethodRule is expecting more than one parameter,
059:         * then it is always invoked, regardless of whether the parameters were
060:         * available or not; missing parameters are converted to the appropriate target
061:         * type by calling ConvertUtils.convert. Note that the default ConvertUtils
062:         * converters for the String type returns a null when passed a null, meaning
063:         * that CallMethodRule will passed null for all String parameters for which
064:         * there is no parameter info available from the XML. However parameters of
065:         * type Float and Integer will be passed a real object containing a zero value
066:         * as that is the output of the default ConvertUtils converters for those
067:         * types when passed a null. You can register custom converters to change
068:         * this behaviour; see the beautils library documentation for more info.</p>
069:         *
070:         * <p>Note that when a constructor is used with paramCount=0, indicating that
071:         * the body of the element is to be passed to the target method, an empty 
072:         * element will cause an <i>empty string</i> to be passed to the target method,
073:         * not null. And if automatic type conversion is being applied (ie if the 
074:         * target function takes something other than a string as a parameter) then 
075:         * the conversion will fail if the converter class does not accept an empty 
076:         * string as valid input.</p>
077:         * 
078:         * <p>CallMethodRule has a design flaw which can cause it to fail under
079:         * certain rule configurations. All CallMethodRule instances share a single
080:         * parameter stack, and all CallParamRule instances simply store their data
081:         * into the parameter-info structure that is on the top of the stack. This
082:         * means that two CallMethodRule instances cannot be associated with the
083:         * same pattern without getting scrambled parameter data. This same issue
084:         * also applies when a CallMethodRule matches some element X, a different 
085:         * CallMethodRule matches a child element Y and some of the CallParamRules 
086:         * associated with the first CallMethodRule match element Y or one of its 
087:         * child elements. This issue has been present since the very first release
088:         * of Digester. Note, however, that this configuration of CallMethodRule
089:         * instances is not commonly required.</p>
090:         */
091:
092:        public class CallMethodRule extends Rule {
093:
094:            // ----------------------------------------------------------- Constructors
095:
096:            /**
097:             * Construct a "call method" rule with the specified method name.  The
098:             * parameter types (if any) default to java.lang.String.
099:             *
100:             * @param digester The associated Digester
101:             * @param methodName Method name of the parent method to call
102:             * @param paramCount The number of parameters to collect, or
103:             *  zero for a single argument from the body of this element.
104:             *
105:             *
106:             * @deprecated The digester instance is now set in the {@link Digester#addRule} method. 
107:             * Use {@link #CallMethodRule(String methodName,int paramCount)} instead.
108:             */
109:            public CallMethodRule(Digester digester, String methodName,
110:                    int paramCount) {
111:
112:                this (methodName, paramCount);
113:
114:            }
115:
116:            /**
117:             * Construct a "call method" rule with the specified method name.
118:             *
119:             * @param digester The associated Digester
120:             * @param methodName Method name of the parent method to call
121:             * @param paramCount The number of parameters to collect, or
122:             *  zero for a single argument from the body of ths element
123:             * @param paramTypes The Java class names of the arguments
124:             *  (if you wish to use a primitive type, specify the corresonding
125:             *  Java wrapper class instead, such as <code>java.lang.Boolean</code>
126:             *  for a <code>boolean</code> parameter)
127:             *
128:             * @deprecated The digester instance is now set in the {@link Digester#addRule} method. 
129:             * Use {@link #CallMethodRule(String methodName,int paramCount, String [] paramTypes)} instead.
130:             */
131:            public CallMethodRule(Digester digester, String methodName,
132:                    int paramCount, String paramTypes[]) {
133:
134:                this (methodName, paramCount, paramTypes);
135:
136:            }
137:
138:            /**
139:             * Construct a "call method" rule with the specified method name.
140:             *
141:             * @param digester The associated Digester
142:             * @param methodName Method name of the parent method to call
143:             * @param paramCount The number of parameters to collect, or
144:             *  zero for a single argument from the body of ths element
145:             * @param paramTypes The Java classes that represent the
146:             *  parameter types of the method arguments
147:             *  (if you wish to use a primitive type, specify the corresonding
148:             *  Java wrapper class instead, such as <code>java.lang.Boolean.TYPE</code>
149:             *  for a <code>boolean</code> parameter)
150:             *
151:             * @deprecated The digester instance is now set in the {@link Digester#addRule} method. 
152:             * Use {@link #CallMethodRule(String methodName,int paramCount, Class [] paramTypes)} instead.
153:             */
154:            public CallMethodRule(Digester digester, String methodName,
155:                    int paramCount, Class paramTypes[]) {
156:
157:                this (methodName, paramCount, paramTypes);
158:            }
159:
160:            /**
161:             * Construct a "call method" rule with the specified method name.  The
162:             * parameter types (if any) default to java.lang.String.
163:             *
164:             * @param methodName Method name of the parent method to call
165:             * @param paramCount The number of parameters to collect, or
166:             *  zero for a single argument from the body of this element.
167:             */
168:            public CallMethodRule(String methodName, int paramCount) {
169:                this (0, methodName, paramCount);
170:            }
171:
172:            /**
173:             * Construct a "call method" rule with the specified method name.  The
174:             * parameter types (if any) default to java.lang.String.
175:             *
176:             * @param targetOffset location of the target object. Positive numbers are
177:             * relative to the top of the digester object stack. Negative numbers 
178:             * are relative to the bottom of the stack. Zero implies the top
179:             * object on the stack.
180:             * @param methodName Method name of the parent method to call
181:             * @param paramCount The number of parameters to collect, or
182:             *  zero for a single argument from the body of this element.
183:             */
184:            public CallMethodRule(int targetOffset, String methodName,
185:                    int paramCount) {
186:
187:                this .targetOffset = targetOffset;
188:                this .methodName = methodName;
189:                this .paramCount = paramCount;
190:                if (paramCount == 0) {
191:                    this .paramTypes = new Class[] { String.class };
192:                } else {
193:                    this .paramTypes = new Class[paramCount];
194:                    for (int i = 0; i < this .paramTypes.length; i++) {
195:                        this .paramTypes[i] = String.class;
196:                    }
197:                }
198:
199:            }
200:
201:            /**
202:             * Construct a "call method" rule with the specified method name.  
203:             * The method should accept no parameters.
204:             *
205:             * @param methodName Method name of the parent method to call
206:             */
207:            public CallMethodRule(String methodName) {
208:
209:                this (0, methodName, 0, (Class[]) null);
210:
211:            }
212:
213:            /**
214:             * Construct a "call method" rule with the specified method name.  
215:             * The method should accept no parameters.
216:             *
217:             * @param targetOffset location of the target object. Positive numbers are
218:             * relative to the top of the digester object stack. Negative numbers 
219:             * are relative to the bottom of the stack. Zero implies the top
220:             * object on the stack.
221:             * @param methodName Method name of the parent method to call
222:             */
223:            public CallMethodRule(int targetOffset, String methodName) {
224:
225:                this (targetOffset, methodName, 0, (Class[]) null);
226:
227:            }
228:
229:            /**
230:             * Construct a "call method" rule with the specified method name and
231:             * parameter types. If <code>paramCount</code> is set to zero the rule
232:             * will use the body of this element as the single argument of the
233:             * method, unless <code>paramTypes</code> is null or empty, in this
234:             * case the rule will call the specified method with no arguments.
235:             *
236:             * @param methodName Method name of the parent method to call
237:             * @param paramCount The number of parameters to collect, or
238:             *  zero for a single argument from the body of ths element
239:             * @param paramTypes The Java class names of the arguments
240:             *  (if you wish to use a primitive type, specify the corresonding
241:             *  Java wrapper class instead, such as <code>java.lang.Boolean</code>
242:             *  for a <code>boolean</code> parameter)
243:             */
244:            public CallMethodRule(String methodName, int paramCount,
245:                    String paramTypes[]) {
246:                this (0, methodName, paramCount, paramTypes);
247:            }
248:
249:            /**
250:             * Construct a "call method" rule with the specified method name and
251:             * parameter types. If <code>paramCount</code> is set to zero the rule
252:             * will use the body of this element as the single argument of the
253:             * method, unless <code>paramTypes</code> is null or empty, in this
254:             * case the rule will call the specified method with no arguments.
255:             *
256:             * @param targetOffset location of the target object. Positive numbers are
257:             * relative to the top of the digester object stack. Negative numbers 
258:             * are relative to the bottom of the stack. Zero implies the top
259:             * object on the stack.
260:             * @param methodName Method name of the parent method to call
261:             * @param paramCount The number of parameters to collect, or
262:             *  zero for a single argument from the body of ths element
263:             * @param paramTypes The Java class names of the arguments
264:             *  (if you wish to use a primitive type, specify the corresonding
265:             *  Java wrapper class instead, such as <code>java.lang.Boolean</code>
266:             *  for a <code>boolean</code> parameter)
267:             */
268:            public CallMethodRule(int targetOffset, String methodName,
269:                    int paramCount, String paramTypes[]) {
270:
271:                this .targetOffset = targetOffset;
272:                this .methodName = methodName;
273:                this .paramCount = paramCount;
274:                if (paramTypes == null) {
275:                    this .paramTypes = new Class[paramCount];
276:                    for (int i = 0; i < this .paramTypes.length; i++) {
277:                        this .paramTypes[i] = String.class;
278:                    }
279:                } else {
280:                    // copy the parameter class names into an array
281:                    // the classes will be loaded when the digester is set 
282:                    this .paramClassNames = new String[paramTypes.length];
283:                    for (int i = 0; i < this .paramClassNames.length; i++) {
284:                        this .paramClassNames[i] = paramTypes[i];
285:                    }
286:                }
287:
288:            }
289:
290:            /**
291:             * Construct a "call method" rule with the specified method name and
292:             * parameter types. If <code>paramCount</code> is set to zero the rule
293:             * will use the body of this element as the single argument of the
294:             * method, unless <code>paramTypes</code> is null or empty, in this
295:             * case the rule will call the specified method with no arguments.
296:             *
297:             * @param methodName Method name of the parent method to call
298:             * @param paramCount The number of parameters to collect, or
299:             *  zero for a single argument from the body of ths element
300:             * @param paramTypes The Java classes that represent the
301:             *  parameter types of the method arguments
302:             *  (if you wish to use a primitive type, specify the corresonding
303:             *  Java wrapper class instead, such as <code>java.lang.Boolean.TYPE</code>
304:             *  for a <code>boolean</code> parameter)
305:             */
306:            public CallMethodRule(String methodName, int paramCount,
307:                    Class paramTypes[]) {
308:                this (0, methodName, paramCount, paramTypes);
309:            }
310:
311:            /**
312:             * Construct a "call method" rule with the specified method name and
313:             * parameter types. If <code>paramCount</code> is set to zero the rule
314:             * will use the body of this element as the single argument of the
315:             * method, unless <code>paramTypes</code> is null or empty, in this
316:             * case the rule will call the specified method with no arguments.
317:             *
318:             * @param targetOffset location of the target object. Positive numbers are
319:             * relative to the top of the digester object stack. Negative numbers 
320:             * are relative to the bottom of the stack. Zero implies the top
321:             * object on the stack.
322:             * @param methodName Method name of the parent method to call
323:             * @param paramCount The number of parameters to collect, or
324:             *  zero for a single argument from the body of ths element
325:             * @param paramTypes The Java classes that represent the
326:             *  parameter types of the method arguments
327:             *  (if you wish to use a primitive type, specify the corresonding
328:             *  Java wrapper class instead, such as <code>java.lang.Boolean.TYPE</code>
329:             *  for a <code>boolean</code> parameter)
330:             */
331:            public CallMethodRule(int targetOffset, String methodName,
332:                    int paramCount, Class paramTypes[]) {
333:
334:                this .targetOffset = targetOffset;
335:                this .methodName = methodName;
336:                this .paramCount = paramCount;
337:                if (paramTypes == null) {
338:                    this .paramTypes = new Class[paramCount];
339:                    for (int i = 0; i < this .paramTypes.length; i++) {
340:                        this .paramTypes[i] = String.class;
341:                    }
342:                } else {
343:                    this .paramTypes = new Class[paramTypes.length];
344:                    for (int i = 0; i < this .paramTypes.length; i++) {
345:                        this .paramTypes[i] = paramTypes[i];
346:                    }
347:                }
348:
349:            }
350:
351:            // ----------------------------------------------------- Instance Variables
352:
353:            /**
354:             * The body text collected from this element.
355:             */
356:            protected String bodyText = null;
357:
358:            /** 
359:             * location of the target object for the call, relative to the
360:             * top of the digester object stack. The default value of zero
361:             * means the target object is the one on top of the stack.
362:             */
363:            private int targetOffset = 0;
364:
365:            /**
366:             * The method name to call on the parent object.
367:             */
368:            protected String methodName = null;
369:
370:            /**
371:             * The number of parameters to collect from <code>MethodParam</code> rules.
372:             * If this value is zero, a single parameter will be collected from the
373:             * body of this element.
374:             */
375:            protected int paramCount = 0;
376:
377:            /**
378:             * The parameter types of the parameters to be collected.
379:             */
380:            protected Class paramTypes[] = null;
381:
382:            /**
383:             * The names of the classes of the parameters to be collected.
384:             * This attribute allows creation of the classes to be postponed until the digester is set.
385:             */
386:            private String paramClassNames[] = null;
387:
388:            /**
389:             * Should <code>MethodUtils.invokeExactMethod</code> be used for reflection.
390:             */
391:            protected boolean useExactMatch = false;
392:
393:            // --------------------------------------------------------- Public Methods
394:
395:            /**
396:             * Should <code>MethodUtils.invokeExactMethod</code>
397:             * be used for the reflection.
398:             */
399:            public boolean getUseExactMatch() {
400:                return useExactMatch;
401:            }
402:
403:            /**
404:             * Set whether <code>MethodUtils.invokeExactMethod</code>
405:             * should be used for the reflection.
406:             */
407:            public void setUseExactMatch(boolean useExactMatch) {
408:                this .useExactMatch = useExactMatch;
409:            }
410:
411:            /**
412:             * Set the associated digester.
413:             * If needed, this class loads the parameter classes from their names.
414:             */
415:            public void setDigester(Digester digester) {
416:                // call superclass
417:                super .setDigester(digester);
418:                // if necessary, load parameter classes
419:                if (this .paramClassNames != null) {
420:                    this .paramTypes = new Class[paramClassNames.length];
421:                    for (int i = 0; i < this .paramClassNames.length; i++) {
422:                        try {
423:                            this .paramTypes[i] = digester.getClassLoader()
424:                                    .loadClass(this .paramClassNames[i]);
425:                        } catch (ClassNotFoundException e) {
426:                            // use the digester log
427:                            digester.getLogger().error(
428:                                    "(CallMethodRule) Cannot load class "
429:                                            + this .paramClassNames[i], e);
430:                            this .paramTypes[i] = null; // Will cause NPE later
431:                        }
432:                    }
433:                }
434:            }
435:
436:            /**
437:             * Process the start of this element.
438:             *
439:             * @param attributes The attribute list for this element
440:             */
441:            public void begin(Attributes attributes) throws Exception {
442:
443:                // Push an array to capture the parameter values if necessary
444:                if (paramCount > 0) {
445:                    Object parameters[] = new Object[paramCount];
446:                    for (int i = 0; i < parameters.length; i++) {
447:                        parameters[i] = null;
448:                    }
449:                    digester.pushParams(parameters);
450:                }
451:
452:            }
453:
454:            /**
455:             * Process the body text of this element.
456:             *
457:             * @param bodyText The body text of this element
458:             */
459:            public void body(String bodyText) throws Exception {
460:
461:                if (paramCount == 0) {
462:                    this .bodyText = bodyText.trim();
463:                }
464:
465:            }
466:
467:            /**
468:             * Process the end of this element.
469:             */
470:            public void end() throws Exception {
471:
472:                // Retrieve or construct the parameter values array
473:                Object parameters[] = null;
474:                if (paramCount > 0) {
475:
476:                    parameters = (Object[]) digester.popParams();
477:
478:                    if (digester.log.isTraceEnabled()) {
479:                        for (int i = 0, size = parameters.length; i < size; i++) {
480:                            digester.log.trace("[CallMethodRule](" + i + ")"
481:                                    + parameters[i]);
482:                        }
483:                    }
484:
485:                    // In the case where the target method takes a single parameter
486:                    // and that parameter does not exist (the CallParamRule never
487:                    // executed or the CallParamRule was intended to set the parameter
488:                    // from an attribute but the attribute wasn't present etc) then
489:                    // skip the method call.
490:                    //
491:                    // This is useful when a class has a "default" value that should
492:                    // only be overridden if data is present in the XML. I don't
493:                    // know why this should only apply to methods taking *one*
494:                    // parameter, but it always has been so we can't change it now.
495:                    if (paramCount == 1 && parameters[0] == null) {
496:                        return;
497:                    }
498:
499:                } else if (paramTypes != null && paramTypes.length != 0) {
500:                    // Having paramCount == 0 and paramTypes.length == 1 indicates
501:                    // that we have the special case where the target method has one
502:                    // parameter being the body text of the current element.
503:
504:                    // There is no body text included in the source XML file,
505:                    // so skip the method call
506:                    if (bodyText == null) {
507:                        return;
508:                    }
509:
510:                    parameters = new Object[1];
511:                    parameters[0] = bodyText;
512:                    if (paramTypes.length == 0) {
513:                        paramTypes = new Class[1];
514:                        paramTypes[0] = String.class;
515:                    }
516:
517:                } else {
518:                    // When paramCount is zero and paramTypes.length is zero it
519:                    // means that we truly are calling a method with no parameters.
520:                    // Nothing special needs to be done here.
521:                    ;
522:                }
523:
524:                // Construct the parameter values array we will need
525:                // We only do the conversion if the param value is a String and
526:                // the specified paramType is not String. 
527:                Object paramValues[] = new Object[paramTypes.length];
528:                for (int i = 0; i < paramTypes.length; i++) {
529:                    // convert nulls and convert stringy parameters 
530:                    // for non-stringy param types
531:                    if (parameters[i] == null
532:                            || (parameters[i] instanceof  String && !String.class
533:                                    .isAssignableFrom(paramTypes[i]))) {
534:
535:                        paramValues[i] = ConvertUtils.convert(
536:                                (String) parameters[i], paramTypes[i]);
537:                    } else {
538:                        paramValues[i] = parameters[i];
539:                    }
540:                }
541:
542:                // Determine the target object for the method call
543:                Object target;
544:                if (targetOffset >= 0) {
545:                    target = digester.peek(targetOffset);
546:                } else {
547:                    target = digester.peek(digester.getCount() + targetOffset);
548:                }
549:
550:                if (target == null) {
551:                    StringBuffer sb = new StringBuffer();
552:                    sb.append("[CallMethodRule]{");
553:                    sb.append(digester.match);
554:                    sb.append("} Call target is null (");
555:                    sb.append("targetOffset=");
556:                    sb.append(targetOffset);
557:                    sb.append(",stackdepth=");
558:                    sb.append(digester.getCount());
559:                    sb.append(")");
560:                    throw new org.xml.sax.SAXException(sb.toString());
561:                }
562:
563:                // Invoke the required method on the top object
564:                if (digester.log.isDebugEnabled()) {
565:                    StringBuffer sb = new StringBuffer("[CallMethodRule]{");
566:                    sb.append(digester.match);
567:                    sb.append("} Call ");
568:                    sb.append(target.getClass().getName());
569:                    sb.append(".");
570:                    sb.append(methodName);
571:                    sb.append("(");
572:                    for (int i = 0; i < paramValues.length; i++) {
573:                        if (i > 0) {
574:                            sb.append(",");
575:                        }
576:                        if (paramValues[i] == null) {
577:                            sb.append("null");
578:                        } else {
579:                            sb.append(paramValues[i].toString());
580:                        }
581:                        sb.append("/");
582:                        if (paramTypes[i] == null) {
583:                            sb.append("null");
584:                        } else {
585:                            sb.append(paramTypes[i].getName());
586:                        }
587:                    }
588:                    sb.append(")");
589:                    digester.log.debug(sb.toString());
590:                }
591:
592:                Object result = null;
593:                if (useExactMatch) {
594:                    // invoke using exact match
595:                    result = MethodUtils.invokeExactMethod(target, methodName,
596:                            paramValues, paramTypes);
597:
598:                } else {
599:                    // invoke using fuzzier match
600:                    result = MethodUtils.invokeMethod(target, methodName,
601:                            paramValues, paramTypes);
602:                }
603:
604:                processMethodCallResult(result);
605:            }
606:
607:            /**
608:             * Clean up after parsing is complete.
609:             */
610:            public void finish() throws Exception {
611:
612:                bodyText = null;
613:
614:            }
615:
616:            /**
617:             * Subclasses may override this method to perform additional processing of the 
618:             * invoked method's result.
619:             *
620:             * @param result the Object returned by the method invoked, possibly null
621:             */
622:            protected void processMethodCallResult(Object result) {
623:                // do nothing
624:            }
625:
626:            /**
627:             * Render a printable version of this Rule.
628:             */
629:            public String toString() {
630:
631:                StringBuffer sb = new StringBuffer("CallMethodRule[");
632:                sb.append("methodName=");
633:                sb.append(methodName);
634:                sb.append(", paramCount=");
635:                sb.append(paramCount);
636:                sb.append(", paramTypes={");
637:                if (paramTypes != null) {
638:                    for (int i = 0; i < paramTypes.length; i++) {
639:                        if (i > 0) {
640:                            sb.append(", ");
641:                        }
642:                        sb.append(paramTypes[i].getName());
643:                    }
644:                }
645:                sb.append("}");
646:                sb.append("]");
647:                return (sb.toString());
648:
649:            }
650:
651:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.