Package org.jboss.classpool.spi

Source Code of org.jboss.classpool.spi.ClassPoolRepository$DefaultClassLoaderRegistryHandler

/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This 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; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.classpool.spi;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;

import javassist.ClassPool;

import org.jboss.classpool.scoped.ScopedClassPool;
import org.jboss.classpool.scoped.ScopedClassPoolFactory;
import org.jboss.classpool.scoped.ScopedClassPoolRepositoryImpl;



/**
* Singleton classpool repository.
*
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
* @author <a href="flavia.rainone@jboss.com">Flavia Rainone</a>
* @version $Revision: 104194 $
*/
public class ClassPoolRepository extends ScopedClassPoolRepositoryImpl
{
   private final static ClassPoolRepository instance = new ClassPoolRepository();
  
   private volatile List<ClassPoolRepositoryCallback> callbacks;
  
   private ClassLoaderRegistryHandler registryHandler;
  
   /**
    * Returns the singleton instance.
    *
    * @return the singleton repository instance
    */
   public static ClassPoolRepository getInstance()
   {
      return instance;
   }
  
   /**
    * Constructor.
    */
   protected ClassPoolRepository()
   {
      super(AbstractClassPoolFactory.getSystemClassPool());
      registryHandler = new DefaultClassLoaderRegistryHandler();
      super.setClassPoolFactory(new AbstractClassPoolFactory());
   }
  
   /**
    * Defines the ClassPoolFactory that will be used by this repository.
    * @param factory the ClassPoolFactory that is responsible for creating ClassPools for this repository.
    *                if this factory implements {@link ClassLoaderRegistryHandlerFactory} interface,
    *                it will also be responsible for creating a ClassLoaderRegistryHandler for this
    *                repository
    */
   @Override
   public void setClassPoolFactory(ScopedClassPoolFactory factory)
   {
      if (factory instanceof ClassLoaderRegistryHandlerFactory)
      {
         ClassLoaderRegistryHandlerFactory registryHandlerFactory = (ClassLoaderRegistryHandlerFactory) factory;
         registryHandler = registryHandlerFactory.create(new DefaultClassLoaderRegistryHandler());
      }
      super.setClassPoolFactory(factory);
   }

   /**
    * Adds a callback object for notifications on classloader registration.
    * 
    * @param callback the callback object
    * @see ClassPoolRepositoryCallback
    * @throws IllegalArgumentException if the passed in callback was null
    */
   public void addClassPoolRepositoryCallback(ClassPoolRepositoryCallback callback)
   {
      if (callback == null)
         throw new IllegalArgumentException("Null callback");
      if (callbacks == null)
      {
         synchronized(this)
         {
            if (callbacks == null)
            {
               callbacks = new CopyOnWriteArrayList<ClassPoolRepositoryCallback>();
            }
         }
      }
      callbacks.add(callback);
   }
  
   /**
    * Returns the callback objects.
    * @return the callback objects in an unmodifiable list. If there are none an empty list is returned
    */
   public List<ClassPoolRepositoryCallback> getClassPoolRepositoryCallbacks()
   {
      List<ClassPoolRepositoryCallback> cbs = callbacks;
      if (cbs == null || cbs.size() == 0)
         return Collections.<ClassPoolRepositoryCallback>emptyList();
      return Collections.unmodifiableList(callbacks);
   }
  
   /**
    * Removes a callback object. If the callback object is null, or it cannot be found in the list, no error is thrown.
    * @param callback the callback object
    */
   public boolean removeClassPoolRepositoryCallback(ClassPoolRepositoryCallback callback)
   {
      if (callback == null)
         return false;
      if (callbacks == null)
         return false;
      return callbacks.remove(callback);
   }

   /**
    * Registers {@code classLoader} and returns the corresponding {@code ClassPool}.
    *
    * @param classLoader the ClassLoader to be added to this repository
    * @return the ClassPool corresponding to {@code classLoader}
    */
   public ClassPool registerClassLoader(ClassLoader classLoader)
   {
      ClassPool classPool = registryHandler.registerClassLoader(classLoader);
      // TODO review classPool != null check for AOP tests
      if (callbacks != null && callbacks.size() > 0)
      {
         for (ClassPoolRepositoryCallback callback : callbacks)
         {
            callback.classLoaderRegistered(classLoader);
         }
      }
      return classPool;
   }

   /**
    * Unregisters {@code classLoader}.
    *
    * @param classLoader the ClassLoader to be removed from this repository
    */
   public void unregisterClassLoader(ClassLoader classLoader)
   {
      registryHandler.unregisterClassLoader(classLoader);
      if (callbacks != null && callbacks.size() > 0)
      {
         for (ClassPoolRepositoryCallback callback : callbacks)
         {
            callback.classLoaderUnregistered(classLoader);
         }
      }
   }
  
   private class DefaultClassLoaderRegistryHandler implements ClassLoaderRegistryHandler
   {
      private final  ConcurrentMap<ClassLoader, Boolean> currentClassLoaders = new ConcurrentHashMap<ClassLoader, Boolean>();

      public ClassPool registerClassLoader(ClassLoader classLoader)
      {
         if (classLoader == null)
         {
            classLoader = SecurityActions.getContextClassLoader();
         }
        
         if (currentClassLoaders.putIfAbsent(classLoader, Boolean.TRUE) != null)
         {
            return null;
         }

         ScopedClassPool classPool = (ScopedClassPool) ClassPoolRepository.super.registerClassLoader(classLoader);
         currentClassLoaders.remove(classLoader);
         return classPool;
      }


      public void unregisterClassLoader(ClassLoader classLoader)
      {
         ClassPoolRepository.super.unregisterClassLoader(classLoader);
      }
     
      public void setSuccessor(ClassLoaderRegistryHandler handler)
      {
         throw new IllegalStateException("Default ClassLoaderRegistryHandler cannot have a sucessor");
      }
   }
}
TOP

Related Classes of org.jboss.classpool.spi.ClassPoolRepository$DefaultClassLoaderRegistryHandler

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.