Package org.jboss.weld.integration.deployer.env.bda

Source Code of org.jboss.weld.integration.deployer.env.bda.ClasspathFactory

/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file 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.weld.integration.deployer.env.bda;

import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.WeakHashMap;

import org.jboss.classloader.plugins.loader.ClassLoaderToLoaderAdapter;
import org.jboss.classloader.spi.ClassLoaderDomain;
import org.jboss.classloader.spi.ClassLoaderSystem;
import org.jboss.classloader.spi.Loader;
import org.jboss.classloading.spi.dependency.Module;
import org.jboss.logging.Logger;

/**
* Given the ClassLoader that is loading an archive during deployment, this factory
* creates the corresponding classpath.
*
* @author <a href="mailto:flavia.rainone@jboss.com">Flavia Rainone</a>
* @author <a href="mailto:ales.justin@jboss.org">Ales Justin</a>
* @version $Revision: 108370 $
*/
class ClasspathFactory
{
   // the log
   private static Logger log = Logger.getLogger(ClasspathFactory.class);

   // the instance
   private static final ClasspathFactory instance = new ClasspathFactory();
  
   /**
    * Returns the singleton instance.
    *
    * @return the ClasspathFactory instance
    */
   public static final ClasspathFactory getInstance()
   {
      return instance;
   }
  
   // the ClassLoaderSystem
   private volatile ClassLoaderSystem system;

   // the default domain
   private volatile ClassLoaderDomain defaultDomain;

   // the default classpath, corresponds to DefaultDomain
   private volatile Classpath defaultClasspath;

   // lib archives provider
   private LibraryArchivesProvider libArchivesProvider;

   // a list of domains
   private final Map<Loader, WeakReference<Classpath>> domainToClasspath;

   private ClasspathFactory()
   {
      domainToClasspath = new WeakHashMap<Loader, WeakReference<Classpath>>();
   }

   protected ClassLoaderSystem getSystem()
   {
      if (system == null)
         setSystem(ClassLoaderSystem.getInstance());
        
      return system;
   }

   public void setSystem(ClassLoaderSystem system)
   {
      if (system == null)
         throw new IllegalArgumentException("Null system");

      this.system = system;
      defaultDomain = system.getDefaultDomain();
      defaultClasspath = new ClasspathImpl(defaultDomain.getName());
   }

   public void setLibArchivesProvider(LibraryArchivesProvider libArchivesProvider)
   {
      this.libArchivesProvider = libArchivesProvider;
   }

   /**
    * Create libs.
    *
    * A bit of impl detail, in case we change the actual behavior:
    *  libs will be automatically added to default classpath,
    *  hence no need for explicit addition.
    *
    * @throws Exception for any error
    */
   public void create() throws Exception
   {
      if (libArchivesProvider != null)
         libArchivesProvider.getLibraries();
   }

   /**
    * Creates the Classpath corresponding to ClassLoader.
    *
    * @param classLoader the ClassLoader
    * @return            a classpath that contains a list of the archives visible to ClassLoader
    */
   public Classpath create(ClassLoader classLoader)
   {
      Module module = SecurityActions.getModuleForClassLoader(classLoader);
      ClassLoaderDomain domain = null;
      ClassLoaderSystem cls = getSystem(); // intialize system
      // TODO -- why this check for a parent domain name?
      if (module != null && module.getDeterminedParentDomainName() != null)
      {
         domain = cls.getDomain(module.getDeterminedDomainName());
      }
      return getClasspath(domain);
   }

   @SuppressWarnings({"SynchronizeOnNonFinalField", "SynchronizationOnLocalVariableOrMethodParameter"})
   private Classpath getClasspath(Loader domain)
   {
      if (domain == null || domain == defaultDomain)
      {
         return defaultClasspath;
      }
      synchronized(domain)
      {
         Classpath classpath = getCachedClasspath(domain);
         if (classpath == null)
         {
            if (domain instanceof ClassLoaderToLoaderAdapter)
            {
               ClassLoaderToLoaderAdapter cl2la = (ClassLoaderToLoaderAdapter) domain;
               ClassLoader unitLoader = SecurityActions.getClassLoader(cl2la);
               ArchiveInfo archiveInfo = unitLoader == null? null: ArchiveInfo.getInstance(unitLoader);
               if (archiveInfo == null)
               {
                  classpath = new NoDuplicatesClasspath(domain.toString());
               }
               else
               {
                  classpath = archiveInfo.getClasspathAdapter();
               }
            }
            else
            {
               if (domain instanceof ClassLoaderDomain)
               {
                  ClassLoaderDomain clDomain = (ClassLoaderDomain) domain;
                  Classpath parentClasspath = getClasspath(clDomain.getParent());
                  classpath = new NoDuplicatesClasspath(clDomain.getName(), parentClasspath);
               }
               else
               {
                  throw new RuntimeException("Domain is of unexpected type: " + domain + " - " + domain.getClass());
               }
            }
            addClasspathToCache(domain, classpath);
         }
         return classpath;
      }
   }

   private Classpath getCachedClasspath(Loader domain)
   {
      WeakReference<Classpath> ref = domainToClasspath.get(domain);
      if (ref == null)
      {
         return null;
      }
      return ref.get();
   }

   private void addClasspathToCache(Loader domain, Classpath domainClasspath)
   {
      domainToClasspath.put(domain, new WeakReference<Classpath>(domainClasspath));
   }
}
TOP

Related Classes of org.jboss.weld.integration.deployer.env.bda.ClasspathFactory

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.