KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > picocontainer > defaults > MethodCallingVisitor


1 /*****************************************************************************
2  * Copyright (C) PicoContainer Organization. All rights reserved. *
3  * ------------------------------------------------------------------------- *
4  * The software in this package is published under the terms of the BSD *
5  * style license a copy of which has been included with this distribution in *
6  * the LICENSE.txt file. *
7  *****************************************************************************/

8 package org.picocontainer.defaults;
9
10 import org.picocontainer.PicoContainer;
11 import org.picocontainer.PicoIntrospectionException;
12
13 import java.io.Serializable JavaDoc;
14 import java.lang.reflect.InvocationTargetException JavaDoc;
15 import java.lang.reflect.Method JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.Collections JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20
21
22 /**
23  * A PicoVisitor implementation, that calls methods on the components of a specific type.
24  *
25  * @author Aslak Hellesøy
26  * @author Jörg Schaible
27  * @since 1.2
28  */

29 public class MethodCallingVisitor extends TraversalCheckingVisitor implements Serializable JavaDoc {
30
31     // TODO: we must serialize method with read/writeObject ... and are our parent serializable ???
32
private transient Method JavaDoc method;
33     private final Object JavaDoc[] arguments;
34     private final Class JavaDoc type;
35     private final boolean visitInInstantiationOrder;
36     private final List JavaDoc componentInstances;
37
38     /**
39      * Construct a MethodCallingVisitor for a method with arguments.
40      *
41      * @param method the {@link Method} to invoke
42      * @param ofType the type of the components, that will be invoked
43      * @param visitInInstantiationOrder <code>true</code> if components are visited in instantiation order
44      * @param arguments the arguments for the method invocation (may be <code>null</code>)
45      * @throws NullPointerException if <tt>method</tt>, or <tt>ofType</tt> is <code>null</code>
46      * @since 1.2
47      */

48     public MethodCallingVisitor(Method JavaDoc method, Class JavaDoc ofType, Object JavaDoc[] arguments, boolean visitInInstantiationOrder) {
49         if (method == null) {
50             throw new NullPointerException JavaDoc();
51         }
52         this.method = method;
53         this.arguments = arguments;
54         this.type = ofType;
55         this.visitInInstantiationOrder = visitInInstantiationOrder;
56         this.componentInstances = new ArrayList JavaDoc();
57     }
58
59     /**
60      * Construct a MethodCallingVisitor for standard methods visiting the component in instantiation order.
61      *
62      * @param method the method to invoke
63      * @param ofType the type of the components, that will be invoked
64      * @param arguments the arguments for the method invocation (may be <code>null</code>)
65      * @throws NullPointerException if <tt>method</tt>, or <tt>ofType</tt> is <code>null</code>
66      * @since 1.2
67      */

68     public MethodCallingVisitor(Method JavaDoc method, Class JavaDoc ofType, Object JavaDoc[] arguments) {
69         this(method, ofType, arguments, true);
70     }
71
72     public Object JavaDoc traverse(Object JavaDoc node) {
73         componentInstances.clear();
74         try {
75             super.traverse(node);
76             if (!visitInInstantiationOrder) {
77                 Collections.reverse(componentInstances);
78             }
79             for (Iterator JavaDoc iterator = componentInstances.iterator(); iterator.hasNext();) {
80                 invoke(iterator.next());
81             }
82         } finally {
83             componentInstances.clear();
84         }
85         return Void.TYPE;
86     }
87
88     public void visitContainer(PicoContainer pico) {
89         super.visitContainer(pico);
90         componentInstances.addAll(pico.getComponentInstancesOfType(type));
91     }
92
93     protected Method JavaDoc getMethod() {
94         return method;
95     }
96
97     protected Object JavaDoc[] getArguments() {
98         return arguments;
99     }
100
101     protected void invoke(final Object JavaDoc[] targets) {
102         for (int i = 0; i < targets.length; i++) {
103             invoke(targets[i]);
104         }
105     }
106
107     protected Object JavaDoc invoke(final Object JavaDoc target) {
108         final Method JavaDoc method = getMethod();
109         try {
110             method.invoke(target, getArguments());
111         } catch (IllegalArgumentException JavaDoc e) {
112             throw new PicoIntrospectionException("Can't call " + method.getName() + " on " + target, e);
113         } catch (IllegalAccessException JavaDoc e) {
114             throw new PicoIntrospectionException("Can't call " + method.getName() + " on " + target, e);
115         } catch (InvocationTargetException JavaDoc e) {
116             throw new PicoIntrospectionException("Failed when calling " + method.getName() + " on " + target, e
117                     .getTargetException());
118         }
119         return Void.TYPE;
120     }
121 }
122
Popular Tags