KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > digester > SetRootRule


1 /* $Id: SetRootRule.java 155412 2005-02-26 12:58:36Z dirkv $
2  *
3  * Copyright 2002-2004 The Apache Software Foundation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18
19 package org.apache.commons.digester;
20
21
22 import org.apache.commons.beanutils.MethodUtils;
23
24
25 /**
26  * <p>Rule implementation that calls a method on the root object on the stack,
27  * passing the top object (child) as an argument.
28  * It is important to remember that this rule acts on <code>end</code>.</p>
29  *
30  * <p>This rule now supports more flexible method matching by default.
31  * It is possible that this may break (some) code
32  * written against release 1.1.1 or earlier.
33  * See {@link #isExactMatch()} for more details.</p>
34  */

35
36 public class SetRootRule extends Rule {
37
38
39     // ----------------------------------------------------------- Constructors
40

41
42     /**
43      * Construct a "set root" rule with the specified method name. The
44      * method's argument type is assumed to be the class of the
45      * child object.
46      *
47      * @param digester The associated Digester
48      * @param methodName Method name of the parent method to call
49      *
50      * @deprecated The digester instance is now set in the {@link Digester#addRule} method.
51      * Use {@link #SetRootRule(String methodName)} instead.
52      */

53     public SetRootRule(Digester digester, String JavaDoc methodName) {
54
55         this(methodName);
56
57     }
58
59
60     /**
61      * Construct a "set root" rule with the specified method name.
62      *
63      * @param digester The associated Digester
64      * @param methodName Method name of the parent method to call
65      * @param paramType Java class of the parent method's argument
66      * (if you wish to use a primitive type, specify the corresonding
67      * Java wrapper class instead, such as <code>java.lang.Boolean</code>
68      * for a <code>boolean</code> parameter)
69      *
70      * @deprecated The digester instance is now set in the {@link Digester#addRule} method.
71      * Use {@link #SetRootRule(String methodName,String paramType)} instead.
72      */

73     public SetRootRule(Digester digester, String JavaDoc methodName,
74                        String JavaDoc paramType) {
75
76         this(methodName, paramType);
77
78     }
79
80     /**
81      * Construct a "set root" rule with the specified method name. The
82      * method's argument type is assumed to be the class of the
83      * child object.
84      *
85      * @param methodName Method name of the parent method to call
86      */

87     public SetRootRule(String JavaDoc methodName) {
88
89         this(methodName, null);
90
91     }
92
93
94     /**
95      * Construct a "set root" rule with the specified method name.
96      *
97      * @param methodName Method name of the parent method to call
98      * @param paramType Java class of the parent method's argument
99      * (if you wish to use a primitive type, specify the corresonding
100      * Java wrapper class instead, such as <code>java.lang.Boolean</code>
101      * for a <code>boolean</code> parameter)
102      */

103     public SetRootRule(String JavaDoc methodName,
104                        String JavaDoc paramType) {
105
106         this.methodName = methodName;
107         this.paramType = paramType;
108
109     }
110
111     // ----------------------------------------------------- Instance Variables
112

113
114     /**
115      * The method name to call on the parent object.
116      */

117     protected String JavaDoc methodName = null;
118
119
120     /**
121      * The Java class name of the parameter type expected by the method.
122      */

123     protected String JavaDoc paramType = null;
124     
125     /**
126      * Should we use exact matching. Default is no.
127      */

128     protected boolean useExactMatch = false;
129
130
131     // --------------------------------------------------------- Public Methods
132

133
134     /**
135      * <p>Is exact matching being used.</p>
136      *
137      * <p>This rule uses <code>org.apache.commons.beanutils.MethodUtils</code>
138      * to introspect the relevent objects so that the right method can be called.
139      * Originally, <code>MethodUtils.invokeExactMethod</code> was used.
140      * This matches methods very strictly
141      * and so may not find a matching method when one exists.
142      * This is still the behaviour when exact matching is enabled.</p>
143      *
144      * <p>When exact matching is disabled, <code>MethodUtils.invokeMethod</code> is used.
145      * This method finds more methods but is less precise when there are several methods
146      * with correct signatures.
147      * So, if you want to choose an exact signature you might need to enable this property.</p>
148      *
149      * <p>The default setting is to disable exact matches.</p>
150      *
151      * @return true iff exact matching is enabled
152      * @since Digester Release 1.1.1
153      */

154     public boolean isExactMatch() {
155     
156         return useExactMatch;
157     }
158     
159     
160     /**
161      * <p>Set whether exact matching is enabled.</p>
162      *
163      * <p>See {@link #isExactMatch()}.</p>
164      *
165      * @param useExactMatch should this rule use exact method matching
166      * @since Digester Release 1.1.1
167      */

168     public void setExactMatch(boolean useExactMatch) {
169
170         this.useExactMatch = useExactMatch;
171     }
172
173     /**
174      * Process the end of this element.
175      */

176     public void end() throws Exception JavaDoc {
177
178         // Identify the objects to be used
179
Object JavaDoc child = digester.peek(0);
180         Object JavaDoc parent = digester.root;
181         if (digester.log.isDebugEnabled()) {
182             if (parent == null) {
183                 digester.log.debug("[SetRootRule]{" + digester.match +
184                         "} Call [NULL ROOT]." +
185                         methodName + "(" + child + ")");
186             } else {
187                 digester.log.debug("[SetRootRule]{" + digester.match +
188                         "} Call " + parent.getClass().getName() + "." +
189                         methodName + "(" + child + ")");
190             }
191         }
192
193         // Call the specified method
194
Class JavaDoc paramTypes[] = new Class JavaDoc[1];
195         if (paramType != null) {
196             paramTypes[0] =
197                     digester.getClassLoader().loadClass(paramType);
198         } else {
199             paramTypes[0] = child.getClass();
200         }
201         
202         if (useExactMatch) {
203         
204             MethodUtils.invokeExactMethod(parent, methodName,
205                 new Object JavaDoc[]{ child }, paramTypes);
206                 
207         } else {
208         
209             MethodUtils.invokeMethod(parent, methodName,
210                 new Object JavaDoc[]{ child }, paramTypes);
211         
212         }
213     }
214
215
216     /**
217      * Render a printable version of this Rule.
218      */

219     public String JavaDoc toString() {
220
221         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("SetRootRule[");
222         sb.append("methodName=");
223         sb.append(methodName);
224         sb.append(", paramType=");
225         sb.append(paramType);
226         sb.append("]");
227         return (sb.toString());
228
229     }
230
231
232 }
233
Popular Tags