All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.bonita.util.Chainer Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (C) 2007  Bull S. A. S.
 * Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois
 * This library is free software; you can redistribute it and/or modify it under the terms
 * of the GNU Lesser General Public License as published by the Free Software Foundation
 * version 2.1 of the License.
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public License along with this
 * program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
 * Floor, Boston, MA  02110-1301, USA.
 * 
 * Modified by Matthieu Chaffotte - BonitaSoft
 **/
package org.ow2.bonita.util;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * Generic chainer.
 * 
 * This {@link InvocationHandler} allows chaining of void only method invocations.
 * 
 * If an exception is raised during the invocation of a void method in the chain, then the forwarding
 * is stopped, and the exception will be raised up.
 * 
 * Note that if a non-void method is invoked, an {@link IllegalArgumentException} is thrown.
 * 
 * @author Pierre Vigneras
 */
public class Chainer implements InvocationHandler {
  // Object methods, should be handled specially here! We don't want
  // them to be forwarded, but still, we want to reply to them!.
  // See Proxy javadoc for details for list of Object methods that are
  // normally forwarded.
  private static final Method TOSTRING_METHOD;
  private static final Method EQUALS_METHOD;
  private static final Method HASHCODE_METHOD;

  static {
    Method tostringMethodTmp = null;
    Method equalsMethodTmp = null;
    Method hashcodeMethodTmp = null;
    try {
      tostringMethodTmp = Object.class.getMethod("toString");
      equalsMethodTmp = Object.class.getMethod("equals", Object.class);
      hashcodeMethodTmp = Object.class.getMethod("hashCode");
    } catch (final NoSuchMethodException nsme) {
      final String message = ExceptionManager.getInstance().getFullMessage("buc_C_1");
      throw new ExceptionInInitializerError(message);
    }
    TOSTRING_METHOD = tostringMethodTmp;
    EQUALS_METHOD = equalsMethodTmp;
    HASHCODE_METHOD = hashcodeMethodTmp;
  }

  private final List chain = Collections.synchronizedList(new LinkedList());

  public void add(final T element) {
    chain.add(element);
  }

  public void add(final int i, final T element) {
    chain.add(i, element);
  }

  public T remove(final int i) {
    return chain.remove(i);
  }

  public T get(final int i) {
    return chain.get(i);
  }

  public boolean contains(final T element) {
    return chain.contains(element);
  }

  public List getAsList() {
    return new LinkedList(chain);
  }

  @Override
  public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
    if (method.getReturnType().equals(Void.TYPE)) {
      for (final T t : chain) {
        try {
          method.invoke(t, args);
        } catch (final InvocationTargetException e) {
          throw e.getCause();
        }
      }
      return null;
    }
    if (method.equals(TOSTRING_METHOD)) {
      return "ChainerProxy: " + chain;
    } else if (method.equals(HASHCODE_METHOD)) {
      return this.hashCode() + chain.hashCode();
    } else if (method.equals(EQUALS_METHOD) && Proxy.isProxyClass(proxy.getClass())) {
      final InvocationHandler invocationHandler = Proxy.getInvocationHandler(proxy);
      return this.equals(invocationHandler);
    }
    final String message = ExceptionManager.getInstance().getFullMessage("buc_C_2");
    throw new IllegalArgumentException(message);
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy