001 package org.crsh.util;
002
003 import org.slf4j.Logger;
004 import org.slf4j.LoggerFactory;
005
006 import java.lang.reflect.Constructor;
007 import java.lang.reflect.InvocationHandler;
008 import java.lang.reflect.Method;
009 import java.lang.reflect.Proxy;
010
011 /**
012 * Use sun.misc.Handler proprietary API for handling INT signal. This class use reflection and does not
013 * import sun.misc.* package.
014 *
015 * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
016 */
017 public class InterruptHandler {
018
019 /** . */
020 private final Runnable runnable;
021
022 /** . */
023 private final Logger log = LoggerFactory.getLogger(InterruptHandler.class);
024
025 private final InvocationHandler handler = new InvocationHandler() {
026 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
027 Class<?>[] parameterTypes = method.getParameterTypes();
028 if (method.getName().equals("hashCode") && parameterTypes.length == 0) {
029 return System.identityHashCode(runnable);
030 } else if (method.getName().equals("equals") && parameterTypes.length == 1 && parameterTypes[0] == Object.class) {
031 return runnable.equals(args[0]);
032 } else if (method.getName().equals("toString") && parameterTypes.length == 0) {
033 return runnable.toString();
034 } else if (method.getName().equals("handle")) {
035 runnable.run();
036 return null;
037 } else {
038 throw new UnsupportedOperationException("Method " + method + " not implemented");
039 }
040 }
041 };
042
043 public InterruptHandler(Runnable runnable) {
044 this.runnable = runnable;
045 }
046
047 public void install() {
048 ClassLoader cl = Thread.currentThread().getContextClassLoader();
049 Class<?> signalHandlerClass;
050 Class<?> signalClass;
051 Method handle;
052 Object INT;
053 try {
054 signalHandlerClass = cl.loadClass("sun.misc.SignalHandler");
055 signalClass = cl.loadClass("sun.misc.Signal");
056 handle = signalClass.getDeclaredMethod("handle", signalClass, signalHandlerClass);
057 Constructor ctor = signalClass.getConstructor(String.class);
058 INT = ctor.newInstance("INT");
059 }
060 catch (Exception e) {
061 return;
062 }
063
064 //
065 Object proxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[]{signalHandlerClass}, handler);
066
067 //
068 try {
069 handle.invoke(null, INT, proxy);
070 }
071 catch (Exception e) {
072 log.error("Could not install signal handler", e);
073 }
074 }
075 }