Package net.sourceforge.squirrel_sql.fw.util

Source Code of net.sourceforge.squirrel_sql.fw.util.MyURLClassLoader

package net.sourceforge.squirrel_sql.fw.util;

/*
* Copyright (C) 2001-2002 Colin Bell
* colbell@users.sourceforge.net
*
* 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; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import net.sourceforge.squirrel_sql.fw.util.log.ILogger;

@SuppressWarnings("unchecked")
public class MyURLClassLoader extends URLClassLoader
{
  /** Internationalized strings for this class. */
  private static final StringManager s_stringMgr =
    StringManagerFactory.getStringManager(MyURLClassLoader.class);

  private Map<String, Class> _classes = new HashMap<String, Class>();

  ArrayList<ClassLoaderListener> listeners = new ArrayList<ClassLoaderListener>();

  public MyURLClassLoader(String fileName) throws IOException
  {
    this(new File(fileName).toURI().toURL());
  }

  public MyURLClassLoader(URL url)
  {
    this(new URL[] { url });
  }

  public MyURLClassLoader(URL[] urls)
  {
    super(urls, ClassLoader.getSystemClassLoader());
  }

  public void addClassLoaderListener(ClassLoaderListener listener)
  {
    if (listener != null)
    {
      listeners.add(listener);
    }
  }

  /**
   * Notify listeners that we're loading the specified file.
   *
   * @param filename
   *           the name of the file (doesn't include path)
   */
  private void notifyListenersLoadedZipFile(String filename)
  {
    Iterator<ClassLoaderListener> i = listeners.iterator();
    while (i.hasNext())
    {
      ClassLoaderListener listener = i.next();
      listener.loadedZipFile(filename);
    }
  }

  /**
   * Notify listeners that we've finished loading files.
   */
  private void notifyListenersFinished()
  {
    Iterator<ClassLoaderListener> i = listeners.iterator();
    while (i.hasNext())
    {
      ClassLoaderListener listener = i.next();
      listener.finishedLoadingZipFiles();
    }
  }

  public void removeClassLoaderListener(ClassLoaderListener listener)
  {
    listeners.remove(listener);
  }

  public Class[] getAssignableClasses(Class type, ILogger logger)
  {
    List<Class> classes = new ArrayList<Class>();
    URL[] urls = getURLs();
    for (int i = 0; i < urls.length; ++i)
    {
      URL url = urls[i];

      File file = getFileFromUrl(logger, url);
         if (file == null) {
           continue;
         }
        
      if (!file.isDirectory() && file.exists() && file.canRead())
      {
        ZipFile zipFile = null;
        try
        {
          zipFile = new ZipFile(file);
        } catch (IOException ex)
        {
          Object[] args = { file.getAbsolutePath(), };
          String msg = s_stringMgr.getString("MyURLClassLoader.errorLoadingFile", args);
          logger.error(msg, ex);
          continue;
        }
        notifyListenersLoadedZipFile(file.getName());

        for (Iterator it = new EnumerationIterator(zipFile.entries()); it.hasNext();)
        {
          Class cls = null;
          String entryName = ((ZipEntry) it.next()).getName();
          String className = Utilities.changeFileNameToClassName(entryName);
          if (className != null)
          {
            try
            {
              cls = Class.forName(className, false, this);
            } catch (Throwable th)
            {
              if (logger.isInfoEnabled())
              {
                // During assignable checks many classes can't be loaded but don't cause problems
                // either. So we just issue an info.
                Object[] args =
                  new Object[] { className, file.getAbsolutePath(), type.getName(), th.toString() };
                // i18n[MyURLClassLoader.noAssignCheck=Failed to load {0} in {1} to check if it is
                // assignable to {2}. Reason: {3}]
                String msg = s_stringMgr.getString("MyURLClassLoader.noAssignCheck", args);

                logger.info(msg);
              }
            }
            if (cls != null)
            {
              if (type.isAssignableFrom(cls))
              {
                classes.add(cls);
              }
            }
          }
        }
      }
    }
    notifyListenersFinished();
    return classes.toArray(new Class[classes.size()]);
  }

  /**
   * Returns a File object whose absolute path is equivalent to the specified URL (minus any URL encoding
   * fragments)
   *
   * @param logger
   *        the log to use for exceptions
   * @param url
   *        the URL to get a File for
   * @return a valid File, or null if the URL cannot be converted to a File object
   */
  private File getFileFromUrl(ILogger logger, URL url)
   {
     File file = null;
     try
     {
       // Bug 2480365: It is very important to get the URI from the URL and not simply do
       // new File(url.getFile()).  In the case where the path contains spaces, they get encoded as %20 in
       // the string returned from url.getFile().  java.io.File doesn't know how to deal with them
       // (i.e. replace them with spaces) and the resulting File is rendered non-existent.
       URI fileUri = url.toURI();
       if (logger.isDebugEnabled()) {
         logger.debug("getFileFromUrl: fileUri.getPath()="+fileUri.getPath());
       }
        file = new File(url.toURI());
     } catch (URISyntaxException e)
     {
       logger.error("getAssignableClasses: Unable to convert URL ("+url+") to a URI:"+e.getMessage(),e);
     }
     return file;
   }

  protected synchronized Class findClass(String className) throws ClassNotFoundException
  {
    Class cls = _classes.get(className);
    if (cls == null)
    {
      cls = super.findClass(className);
      _classes.put(className, cls);
    }
    return cls;
  }

  @SuppressWarnings("unused")
  protected void classHasBeenLoaded(Class cls)
  {
    // Empty
  }
}
TOP

Related Classes of net.sourceforge.squirrel_sql.fw.util.MyURLClassLoader

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.