Package org.jboss.forge.furnace.proxy

Source Code of org.jboss.forge.furnace.proxy.ClassLoaderInterceptor

/*
* Copyright 2012 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Eclipse Public License version 1.0, available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.jboss.forge.furnace.proxy;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;

import org.jboss.forge.furnace.exception.ContainerException;
import org.jboss.forge.furnace.util.ClassLoaders;

/**
* @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
*/
public class ClassLoaderInterceptor implements ForgeProxy
{
   private static final Method EQUALS_METHOD;

   static
   {
      try
      {
         EQUALS_METHOD = Object.class.getMethod("equals", Object.class);
      }
      catch (NoSuchMethodException | SecurityException e)
      {
         throw new RuntimeException("Could not reflect Object.equals()", e);
      }
   }

   private static final ThreadLocal<ClassLoader> currentLoader = new ThreadLocal<>();

   private final ClassLoader loader;
   private final Object delegate;

   public ClassLoaderInterceptor(ClassLoader loader, Object delegate)
   {
      this.loader = loader;
      this.delegate = delegate;
   }

   @Override
   public Object invoke(final Object self, final Method thisMethod, final Method proceed, final Object[] args)
            throws Throwable
   {
      if (Thread.currentThread().isInterrupted())
      {
         throw new ContainerException("Thread.interrupt() requested.");
      }

      Callable<Object> task = new Callable<Object>()
      {
         @Override
         public Object call() throws Exception
         {
            try
            {
               if (thisMethod.getDeclaringClass().getName().equals(ForgeProxy.class.getName()))
               {
                  if (thisMethod.getName().equals("getDelegate"))
                     return ClassLoaderInterceptor.this.getDelegate();
                  if (thisMethod.getName().equals("getHandler"))
                     return ClassLoaderInterceptor.this.getHandler();
               }
            }
            catch (Exception e)
            {
            }

            ClassLoader previousLoader = null;
            Object result;
            try
            {
               previousLoader = setCurrentLoader(loader);

               if (thisMethod.equals(EQUALS_METHOD))
               {
                  Object object = args[0];
                  Object unwrapped = Proxies.unwrap(object);
                  args[0] = unwrapped;
               }

               result = thisMethod.invoke(delegate, args);
            }
            catch (InvocationTargetException e)
            {
               if (e.getCause() instanceof Exception)
                  throw (Exception) e.getCause();
               throw e;
            }
            finally
            {
               setCurrentLoader(previousLoader);
            }
            return result;
         }
      };

      Object result = ClassLoaders.executeIn(loader, task);

      if (Thread.currentThread().isInterrupted())
      {
         throw new ContainerException("Thread.interrupt() requested.");
      }

      return result;
   }

   public static ClassLoader getCurrentloader()
   {
      return currentLoader.get();
   }

   private static ClassLoader setCurrentLoader(ClassLoader loader)
   {
      ClassLoader previous = currentLoader.get();
      currentLoader.set(loader);
      return previous;
   }

   @Override
   public Object getDelegate() throws Exception
   {
      return delegate;
   }

   @Override
   public Object getHandler() throws Exception
   {
      return this;
   }

}
TOP

Related Classes of org.jboss.forge.furnace.proxy.ClassLoaderInterceptor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.