001: package net.sourceforge.squirrel_sql.fw.util;
002:
003: /*
004: * Copyright (C) 2001-2002 Colin Bell
005: * colbell@users.sourceforge.net
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: import java.io.File;
022: import java.io.IOException;
023: import java.net.URL;
024: import java.net.URLClassLoader;
025: import java.util.ArrayList;
026: import java.util.HashMap;
027: import java.util.Iterator;
028: import java.util.List;
029: import java.util.Map;
030: import java.util.zip.ZipEntry;
031: import java.util.zip.ZipFile;
032:
033: import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
034:
035: @SuppressWarnings("unchecked")
036: public class MyURLClassLoader extends URLClassLoader {
037: /** Internationalized strings for this class. */
038: private static final StringManager s_stringMgr = StringManagerFactory
039: .getStringManager(MyURLClassLoader.class);
040:
041: private Map<String, Class> _classes = new HashMap<String, Class>();
042:
043: ArrayList<ClassLoaderListener> listeners = new ArrayList<ClassLoaderListener>();
044:
045: public MyURLClassLoader(String fileName) throws IOException {
046: this (new File(fileName).toURL());
047: }
048:
049: public MyURLClassLoader(URL url) {
050: this (new URL[] { url });
051: }
052:
053: public MyURLClassLoader(URL[] urls) {
054: super (urls, ClassLoader.getSystemClassLoader());
055: }
056:
057: public void addClassLoaderListener(ClassLoaderListener listener) {
058: if (listener != null) {
059: listeners.add(listener);
060: }
061: }
062:
063: /**
064: * Notify listeners that we're loading the specified file.
065: *
066: * @param filename the name of the file (doesn't include path)
067: */
068: private void notifyListenersLoadedZipFile(String filename) {
069: Iterator<ClassLoaderListener> i = listeners.iterator();
070: while (i.hasNext()) {
071: ClassLoaderListener listener = i.next();
072: listener.loadedZipFile(filename);
073: }
074: }
075:
076: /**
077: * Notify listeners that we've finished loading files.
078: */
079: private void notifyListenersFinished() {
080: Iterator<ClassLoaderListener> i = listeners.iterator();
081: while (i.hasNext()) {
082: ClassLoaderListener listener = i.next();
083: listener.finishedLoadingZipFiles();
084: }
085: }
086:
087: public void removeClassLoaderListener(ClassLoaderListener listener) {
088: listeners.remove(listener);
089: }
090:
091: public Class[] getAssignableClasses(Class type, ILogger logger) {
092: List<Class> classes = new ArrayList<Class>();
093: URL[] urls = getURLs();
094: for (int i = 0; i < urls.length; ++i) {
095: URL url = urls[i];
096: File file = new File(url.getFile());
097: if (!file.isDirectory() && file.exists() && file.canRead()) {
098: ZipFile zipFile = null;
099: try {
100: zipFile = new ZipFile(file);
101: } catch (IOException ex) {
102: Object[] args = { file.getAbsolutePath(), };
103: String msg = s_stringMgr.getString(
104: "MyURLClassLoader.errorLoadingFile", args);
105: logger.error(msg, ex);
106: continue;
107: }
108: notifyListenersLoadedZipFile(file.getName());
109:
110: for (Iterator it = new EnumerationIterator(zipFile
111: .entries()); it.hasNext();) {
112: Class cls = null;
113: String entryName = ((ZipEntry) it.next()).getName();
114: String className = Utilities
115: .changeFileNameToClassName(entryName);
116: if (className != null) {
117: try {
118: cls = Class.forName(className, false, this );
119: } catch (Throwable th) {
120: // Object[] args = {className};
121: // String msg = s_stringMgr.getString(
122: // "MyURLClassLoader.errorLoadingClass", args);
123: // logger.error(msg, th);
124:
125: // During assignable checks many classes can't be loaded but don't cause problems either.
126: // So we just issue an info.
127: Object[] args = new Object[] { className,
128: file.getAbsolutePath(),
129: type.getName(), th.toString() };
130: // i18n[MyURLClassLoader.noAssignCheck=Failed to load {0} in {1} to check if it is assignable to {2}. Reason: {3}]
131: String msg = s_stringMgr.getString(
132: "MyURLClassLoader.noAssignCheck",
133: args);
134: logger.info(msg);
135: }
136: if (cls != null) {
137: if (type.isAssignableFrom(cls)) {
138: classes.add(cls);
139: }
140: }
141: }
142: }
143: }
144: }
145: notifyListenersFinished();
146: return classes.toArray(new Class[classes.size()]);
147: }
148:
149: protected synchronized Class findClass(String className)
150: throws ClassNotFoundException {
151: Class cls = _classes.get(className);
152: if (cls == null) {
153: cls = super .findClass(className);
154: _classes.put(className, cls);
155: }
156: return cls;
157: }
158:
159: @SuppressWarnings("unused")
160: protected void classHasBeenLoaded(Class cls) {
161: // Empty
162: }
163: }
|