devdaily home | apple | java | perl | unix | directory | blog

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*****************************************************************************
 * Copyright (C) PicoContainer Organization. All rights reserved.            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *****************************************************************************/
package org.picocontainer.visitors;

import org.picocontainer.PicoContainer;
import org.picocontainer.PicoCompositionException;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


/**
 * A PicoVisitor implementation, that calls methods on the components of a specific type.
 * 
 * @author Aslak Hellesøy
 * @author Jörg Schaible
 */
public class MethodCallingVisitor extends TraversalCheckingVisitor implements Serializable {

    // TODO: we must serialize method with read/writeObject ... and are our parent serializable ???
    private transient Method method;
    private final Object[] arguments;
    private final Class type;
    private final boolean visitInInstantiationOrder;
    private final List componentInstances;

    /**
     * Construct a MethodCallingVisitor for a method with arguments.
     * 
     * @param method the {@link Method} to invoke
     * @param ofType the type of the components, that will be invoked
     * @param visitInInstantiationOrder <code>true if components are visited in instantiation order
     * @param arguments the arguments for the method invocation (may be <code>null)
     * @throws NullPointerException if <tt>method, or ofType is null
     */
    public MethodCallingVisitor(Method method, Class ofType, Object[] arguments, boolean visitInInstantiationOrder) {
        if (method == null) {
            throw new NullPointerException();
        }
        this.method = method;
        this.arguments = arguments;
        this.type = ofType;
        this.visitInInstantiationOrder = visitInInstantiationOrder;
        this.componentInstances = new ArrayList();
    }

    /**
     * Construct a MethodCallingVisitor for standard methods visiting the component in instantiation order.
     * 
     * @param method the method to invoke
     * @param ofType the type of the components, that will be invoked
     * @param arguments the arguments for the method invocation (may be <code>null)
     * @throws NullPointerException if <tt>method, or ofType is null
     */
    public MethodCallingVisitor(Method method, Class ofType, Object[] arguments) {
        this(method, ofType, arguments, true);
    }

    public Object traverse(Object node) {
        componentInstances.clear();
        try {
            super.traverse(node);
            if (!visitInInstantiationOrder) {
                Collections.reverse(componentInstances);
            }
            for (Object componentInstance : componentInstances) {
                invoke(componentInstance);
            }
        } finally {
            componentInstances.clear();
        }
        return Void.TYPE;
    }

    public void visitContainer(PicoContainer pico) {
        super.visitContainer(pico);
        componentInstances.addAll(pico.getComponents(type));
    }

    protected Method getMethod() {
        return method;
    }

    protected Object[] getArguments() {
        return arguments;
    }

    protected void invoke(final Object[] targets) {
        for (Object target : targets) {
            invoke(target);
        }
    }

    protected Class<Void> invoke(final Object target) {
        final Method method = getMethod();
        try {
            method.invoke(target, getArguments());
        } catch (IllegalArgumentException e) {
            throw new PicoCompositionException("Can't call " + method.getName() + " on " + target, e);
        } catch (IllegalAccessException e) {
            throw new PicoCompositionException("Can't call " + method.getName() + " on " + target, e);
        } catch (InvocationTargetException e) {
            throw new PicoCompositionException("Failed when calling " + method.getName() + " on " + target, e
                    .getTargetException());
        }
        return Void.TYPE;
    }
}




Copyright 1998-2008 Alvin Alexander
All Rights Reserved.
 
devdaily.com is based in louisville, kentucky, and this web site is hosted by godaddy.com