KickJava   Java API By Example, From Geeks To Geeks.

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


1 /* $Id: FactoryCreateRule.java 179716 2005-06-03 04:06:00Z skitching $
2  *
3  * Copyright 2001-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 import org.xml.sax.Attributes JavaDoc;
22
23 import org.apache.commons.collections.ArrayStack;
24
25
26 /**
27  * <p>Rule implementation that uses an {@link ObjectCreationFactory} to create
28  * a new object which it pushes onto the object stack. When the element is
29  * complete, the object will be popped.</p>
30  *
31  * <p>This rule is intended in situations where the element's attributes are
32  * needed before the object can be created. A common senario is for the
33  * ObjectCreationFactory implementation to use the attributes as parameters
34  * in a call to either a factory method or to a non-empty constructor.
35  */

36
37 public class FactoryCreateRule extends Rule {
38
39     // ----------------------------------------------------------- Fields
40

41     /** Should exceptions thrown by the factory be ignored? */
42     private boolean ignoreCreateExceptions;
43     /** Stock to manage */
44     private ArrayStack exceptionIgnoredStack;
45
46     // ----------------------------------------------------------- Constructors
47

48
49     /**
50      * Construct a factory create rule that will use the specified
51      * class name to create an {@link ObjectCreationFactory} which will
52      * then be used to create an object and push it on the stack.
53      *
54      * @param digester The associated Digester
55      * @param className Java class name of the object creation factory class
56      *
57      * @deprecated The digester instance is now set in the {@link Digester#addRule} method.
58      * Use {@link #FactoryCreateRule(String className)} instead.
59      */

60     public FactoryCreateRule(Digester digester, String JavaDoc className) {
61
62         this(className);
63
64     }
65
66
67     /**
68      * Construct a factory create rule that will use the specified
69      * class to create an {@link ObjectCreationFactory} which will
70      * then be used to create an object and push it on the stack.
71      *
72      * @param digester The associated Digester
73      * @param clazz Java class name of the object creation factory class
74      *
75      * @deprecated The digester instance is now set in the {@link Digester#addRule} method.
76      * Use {@link #FactoryCreateRule(Class clazz)} instead.
77      */

78     public FactoryCreateRule(Digester digester, Class JavaDoc clazz) {
79
80         this(clazz);
81
82     }
83
84
85     /**
86      * Construct a factory create rule that will use the specified
87      * class name (possibly overridden by the specified attribute if present)
88      * to create an {@link ObjectCreationFactory}, which will then be used
89      * to instantiate an object instance and push it onto the stack.
90      *
91      * @param digester The associated Digester
92      * @param className Default Java class name of the factory class
93      * @param attributeName Attribute name which, if present, contains an
94      * override of the class name of the object creation factory to create.
95      *
96      * @deprecated The digester instance is now set in the {@link Digester#addRule} method.
97      * Use {@link #FactoryCreateRule(String className, String attributeName)} instead.
98      */

99     public FactoryCreateRule(Digester digester,
100                              String JavaDoc className, String JavaDoc attributeName) {
101
102         this(className, attributeName);
103
104     }
105
106
107     /**
108      * Construct a factory create rule that will use the specified
109      * class (possibly overridden by the specified attribute if present)
110      * to create an {@link ObjectCreationFactory}, which will then be used
111      * to instantiate an object instance and push it onto the stack.
112      *
113      * @param digester The associated Digester
114      * @param clazz Default Java class name of the factory class
115      * @param attributeName Attribute name which, if present, contains an
116      * override of the class name of the object creation factory to create.
117      *
118      * @deprecated The digester instance is now set in the {@link Digester#addRule} method.
119      * Use {@link #FactoryCreateRule(Class clazz, String attributeName)} instead.
120      */

121     public FactoryCreateRule(Digester digester,
122                              Class JavaDoc clazz, String JavaDoc attributeName) {
123
124         this(clazz, attributeName);
125
126     }
127
128
129     /**
130      * Construct a factory create rule using the given, already instantiated,
131      * {@link ObjectCreationFactory}.
132      *
133      * @param digester The associated Digester
134      * @param creationFactory called on to create the object.
135      *
136      * @deprecated The digester instance is now set in the {@link Digester#addRule} method.
137      * Use {@link #FactoryCreateRule(ObjectCreationFactory creationFactory)} instead.
138      */

139     public FactoryCreateRule(Digester digester,
140                              ObjectCreationFactory creationFactory) {
141
142         this(creationFactory);
143
144     }
145
146     /**
147      * <p>Construct a factory create rule that will use the specified
148      * class name to create an {@link ObjectCreationFactory} which will
149      * then be used to create an object and push it on the stack.</p>
150      *
151      * <p>Exceptions thrown during the object creation process will be propagated.</p>
152      *
153      * @param className Java class name of the object creation factory class
154      */

155     public FactoryCreateRule(String JavaDoc className) {
156
157         this(className, false);
158
159     }
160
161
162     /**
163      * <p>Construct a factory create rule that will use the specified
164      * class to create an {@link ObjectCreationFactory} which will
165      * then be used to create an object and push it on the stack.</p>
166      *
167      * <p>Exceptions thrown during the object creation process will be propagated.</p>
168      *
169      * @param clazz Java class name of the object creation factory class
170      */

171     public FactoryCreateRule(Class JavaDoc clazz) {
172
173         this(clazz, false);
174
175     }
176
177
178     /**
179      * <p>Construct a factory create rule that will use the specified
180      * class name (possibly overridden by the specified attribute if present)
181      * to create an {@link ObjectCreationFactory}, which will then be used
182      * to instantiate an object instance and push it onto the stack.</p>
183      *
184      * <p>Exceptions thrown during the object creation process will be propagated.</p>
185      *
186      * @param className Default Java class name of the factory class
187      * @param attributeName Attribute name which, if present, contains an
188      * override of the class name of the object creation factory to create.
189      */

190     public FactoryCreateRule(String JavaDoc className, String JavaDoc attributeName) {
191
192         this(className, attributeName, false);
193
194     }
195
196
197     /**
198      * <p>Construct a factory create rule that will use the specified
199      * class (possibly overridden by the specified attribute if present)
200      * to create an {@link ObjectCreationFactory}, which will then be used
201      * to instantiate an object instance and push it onto the stack.</p>
202      *
203      * <p>Exceptions thrown during the object creation process will be propagated.</p>
204      *
205      * @param clazz Default Java class name of the factory class
206      * @param attributeName Attribute name which, if present, contains an
207      * override of the class name of the object creation factory to create.
208      */

209     public FactoryCreateRule(Class JavaDoc clazz, String JavaDoc attributeName) {
210
211         this(clazz, attributeName, false);
212
213     }
214
215
216     /**
217      * <p>Construct a factory create rule using the given, already instantiated,
218      * {@link ObjectCreationFactory}.</p>
219      *
220      * <p>Exceptions thrown during the object creation process will be propagated.</p>
221      *
222      * @param creationFactory called on to create the object.
223      */

224     public FactoryCreateRule(ObjectCreationFactory creationFactory) {
225
226         this(creationFactory, false);
227
228     }
229     
230     /**
231      * Construct a factory create rule that will use the specified
232      * class name to create an {@link ObjectCreationFactory} which will
233      * then be used to create an object and push it on the stack.
234      *
235      * @param className Java class name of the object creation factory class
236      * @param ignoreCreateExceptions if true, exceptions thrown by the object
237      * creation factory
238      * will be ignored.
239      */

240     public FactoryCreateRule(String JavaDoc className, boolean ignoreCreateExceptions) {
241
242         this(className, null, ignoreCreateExceptions);
243
244     }
245
246
247     /**
248      * Construct a factory create rule that will use the specified
249      * class to create an {@link ObjectCreationFactory} which will
250      * then be used to create an object and push it on the stack.
251      *
252      * @param clazz Java class name of the object creation factory class
253      * @param ignoreCreateExceptions if true, exceptions thrown by the
254      * object creation factory
255      * will be ignored.
256      */

257     public FactoryCreateRule(Class JavaDoc clazz, boolean ignoreCreateExceptions) {
258
259         this(clazz, null, ignoreCreateExceptions);
260
261     }
262
263
264     /**
265      * Construct a factory create rule that will use the specified
266      * class name (possibly overridden by the specified attribute if present)
267      * to create an {@link ObjectCreationFactory}, which will then be used
268      * to instantiate an object instance and push it onto the stack.
269      *
270      * @param className Default Java class name of the factory class
271      * @param attributeName Attribute name which, if present, contains an
272      * override of the class name of the object creation factory to create.
273      * @param ignoreCreateExceptions if true, exceptions thrown by the object
274      * creation factory will be ignored.
275      */

276     public FactoryCreateRule(
277                                 String JavaDoc className,
278                                 String JavaDoc attributeName,
279                                 boolean ignoreCreateExceptions) {
280
281         this.className = className;
282         this.attributeName = attributeName;
283         this.ignoreCreateExceptions = ignoreCreateExceptions;
284
285     }
286
287
288     /**
289      * Construct a factory create rule that will use the specified
290      * class (possibly overridden by the specified attribute if present)
291      * to create an {@link ObjectCreationFactory}, which will then be used
292      * to instantiate an object instance and push it onto the stack.
293      *
294      * @param clazz Default Java class name of the factory class
295      * @param attributeName Attribute name which, if present, contains an
296      * override of the class name of the object creation factory to create.
297      * @param ignoreCreateExceptions if true, exceptions thrown by the object
298      * creation factory will be ignored.
299      */

300     public FactoryCreateRule(
301                                 Class JavaDoc clazz,
302                                 String JavaDoc attributeName,
303                                 boolean ignoreCreateExceptions) {
304
305         this(clazz.getName(), attributeName, ignoreCreateExceptions);
306
307     }
308
309
310     /**
311      * Construct a factory create rule using the given, already instantiated,
312      * {@link ObjectCreationFactory}.
313      *
314      * @param creationFactory called on to create the object.
315      * @param ignoreCreateExceptions if true, exceptions thrown by the object
316      * creation factory will be ignored.
317      */

318     public FactoryCreateRule(
319                             ObjectCreationFactory creationFactory,
320                             boolean ignoreCreateExceptions) {
321
322         this.creationFactory = creationFactory;
323         this.ignoreCreateExceptions = ignoreCreateExceptions;
324     }
325
326     // ----------------------------------------------------- Instance Variables
327

328
329     /**
330      * The attribute containing an override class name if it is present.
331      */

332     protected String JavaDoc attributeName = null;
333
334
335     /**
336      * The Java class name of the ObjectCreationFactory to be created.
337      * This class must have a no-arguments constructor.
338      */

339     protected String JavaDoc className = null;
340
341
342     /**
343      * The object creation factory we will use to instantiate objects
344      * as required based on the attributes specified in the matched XML
345      * element.
346      */

347     protected ObjectCreationFactory creationFactory = null;
348
349
350     // --------------------------------------------------------- Public Methods
351

352
353     /**
354      * Process the beginning of this element.
355      *
356      * @param attributes The attribute list of this element
357      */

358     public void begin(String JavaDoc namespace, String JavaDoc name, Attributes JavaDoc attributes) throws Exception JavaDoc {
359         
360         if (ignoreCreateExceptions) {
361         
362             if (exceptionIgnoredStack == null) {
363                 exceptionIgnoredStack = new ArrayStack();
364             }
365             
366             try {
367                 Object JavaDoc instance = getFactory(attributes).createObject(attributes);
368                 
369                 if (digester.log.isDebugEnabled()) {
370                     digester.log.debug("[FactoryCreateRule]{" + digester.match +
371                             "} New " + instance.getClass().getName());
372                 }
373                 digester.push(instance);
374                 exceptionIgnoredStack.push(Boolean.FALSE);
375                 
376             } catch (Exception JavaDoc e) {
377                 // log message and error
378
if (digester.log.isInfoEnabled()) {
379                     digester.log.info("[FactoryCreateRule] Create exception ignored: " +
380                         ((e.getMessage() == null) ? e.getClass().getName() : e.getMessage()));
381                     if (digester.log.isDebugEnabled()) {
382                         digester.log.debug("[FactoryCreateRule] Ignored exception:", e);
383                     }
384                 }
385                 exceptionIgnoredStack.push(Boolean.TRUE);
386             }
387             
388         } else {
389             Object JavaDoc instance = getFactory(attributes).createObject(attributes);
390             
391             if (digester.log.isDebugEnabled()) {
392                 digester.log.debug("[FactoryCreateRule]{" + digester.match +
393                         "} New " + instance.getClass().getName());
394             }
395             digester.push(instance);
396         }
397     }
398
399
400     /**
401      * Process the end of this element.
402      */

403     public void end(String JavaDoc namespace, String JavaDoc name) throws Exception JavaDoc {
404         
405         // check if object was created
406
// this only happens if an exception was thrown and we're ignoring them
407
if (
408                 ignoreCreateExceptions &&
409                 exceptionIgnoredStack != null &&
410                 !(exceptionIgnoredStack.empty())) {
411                 
412             if (((Boolean JavaDoc) exceptionIgnoredStack.pop()).booleanValue()) {
413                 // creation exception was ignored
414
// nothing was put onto the stack
415
if (digester.log.isTraceEnabled()) {
416                     digester.log.trace("[FactoryCreateRule] No creation so no push so no pop");
417                 }
418                 return;
419             }
420         }
421
422         Object JavaDoc top = digester.pop();
423         if (digester.log.isDebugEnabled()) {
424             digester.log.debug("[FactoryCreateRule]{" + digester.match +
425                     "} Pop " + top.getClass().getName());
426         }
427
428     }
429
430
431     /**
432      * Clean up after parsing is complete.
433      */

434     public void finish() throws Exception JavaDoc {
435
436         if (attributeName != null) {
437             creationFactory = null;
438         }
439
440     }
441
442
443     /**
444      * Render a printable version of this Rule.
445      */

446     public String JavaDoc toString() {
447
448         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("FactoryCreateRule[");
449         sb.append("className=");
450         sb.append(className);
451         sb.append(", attributeName=");
452         sb.append(attributeName);
453         if (creationFactory != null) {
454             sb.append(", creationFactory=");
455             sb.append(creationFactory);
456         }
457         sb.append("]");
458         return (sb.toString());
459
460     }
461
462
463     // ------------------------------------------------------ Protected Methods
464

465
466     /**
467      * Return an instance of our associated object creation factory,
468      * creating one if necessary.
469      *
470      * @param attributes Attributes passed to our factory creation element
471      *
472      * @exception Exception if any error occurs
473      */

474     protected ObjectCreationFactory getFactory(Attributes JavaDoc attributes)
475             throws Exception JavaDoc {
476
477         if (creationFactory == null) {
478             String JavaDoc realClassName = className;
479             if (attributeName != null) {
480                 String JavaDoc value = attributes.getValue(attributeName);
481                 if (value != null) {
482                     realClassName = value;
483                 }
484             }
485             if (digester.log.isDebugEnabled()) {
486                 digester.log.debug("[FactoryCreateRule]{" + digester.match +
487                         "} New factory " + realClassName);
488             }
489             Class JavaDoc clazz = digester.getClassLoader().loadClass(realClassName);
490             creationFactory = (ObjectCreationFactory)
491                     clazz.newInstance();
492             creationFactory.setDigester(digester);
493         }
494         return (creationFactory);
495
496     }
497 }
498
Popular Tags