appclassloader.java

来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· Java 代码 · 共 303 行

JAVA
303
字号
/* * Java core library component. * * Copyright (c) 1997, 1998 *      Transvirtual Technologies, Inc.  All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. */package kaffe.lang;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.net.MalformedURLException;import java.net.URL;import java.net.URLClassLoader;import java.security.SecureClassLoader;import java.security.CodeSource;import java.security.cert.Certificate;import java.util.Enumeration;import java.util.StringTokenizer;import java.util.Vector;import java.util.zip.ZipEntry;import java.util.zip.ZipFile;import java.util.jar.JarFile;import java.util.jar.Attributes;import java.util.jar.Manifest;/** * ClassLoader used to load application classes from the CLASSPATH. */public class AppClassLoader extends URLClassLoader {	private static final AppClassLoader SINGLETON =		new AppClassLoader();		/**	 * One source of classes.	 */	private abstract class Source {		Source next;                CodeSource codeSource;		abstract Class findClass (String name, String fileName);		abstract void findResources (Vector v, String name);	}	/**	 * A source which is a directory. 	 */	private final class DirSource extends Source {		File dir;                		DirSource (File f) throws IOException {			dir = f.getCanonicalFile ();		}		Class findClass (String name, String fileName) {			File file = new File (dir, fileName);			if (!file.exists ()) {				return null;			}			try {				int length = (int)file.length();				FileInputStream in = new FileInputStream (file);				byte[] buf = new byte[length];				for (int j=0; j<length; j+=in.read (buf, j, length-j));				if (codeSource == null) {					try {						codeSource = new CodeSource (dir.toURL(), new Certificate[0]);					} catch (MalformedURLException _) {}				}				Class ret = defineClass (name, buf, 0, length, codeSource);				String pkgName = PackageHelper.getPackageName(ret);				if (getPackage(pkgName) == null) {					definePackage(pkgName, null, null, null, null, null, null, null);                                }				return ret;			} catch (Exception _) {}			return null;		}				void findResources (Vector v, String name) {			File file = new File (dir, name);			if (file.exists ()) {				try {					v.add (file.toURL());				} catch (MalformedURLException _) {}			}		}		public String toString() {			return "DirSource[dir=" + this.dir + "]";		}	}	/**	 * A source which is a jar file.	 */	private final class JarSource extends Source {		JarFile jar;		String urlPrefix;                File file;		public JarSource (File file) throws IOException {			File canonicalFile = file.getCanonicalFile ();			this.jar = new JarFile (canonicalFile);                         this.urlPrefix = "jar:file:"+canonicalFile.getPath().replace(File.separatorChar, '/') + "!/";			this.file = canonicalFile;		}				Class findClass (String name, String fileName) {			ZipEntry classFile = jar.getEntry(fileName);			if (classFile==null) {				return null;			}               		int length = (int)classFile.getSize();               		byte[] buf = new byte[length];             		try {				InputStream in = jar.getInputStream(classFile);				for (int j=0;j<length;j+=in.read(buf, j, length-j));									if (codeSource == null) {					try {						codeSource = new CodeSource (file.toURL(), new Certificate[0]);					} catch (MalformedURLException _) {}       				}		                                Class ret = defineClass (name, buf, 0, length, codeSource);				String pkgName = PackageHelper.getPackageName(ret);				if (getPackage(pkgName) == null) {					Manifest mf = jar.getManifest();					if (mf == null) {						definePackage(pkgName, null, null, null, null, null, null, null);					} else {						Attributes attrs = jar.getManifest().getAttributes (pkgName);						if (attrs == null) {							attrs = jar.getManifest().getMainAttributes();						}                       			 			definePackage(pkgName,                                  			attrs.getValue(Attributes.Name.SPECIFICATION_TITLE),	                                		attrs.getValue(Attributes.Name.SPECIFICATION_VERSION),        	                        		attrs.getValue(Attributes.Name.SPECIFICATION_VENDOR),                	                		attrs.getValue(Attributes.Name.IMPLEMENTATION_TITLE),                        	        		attrs.getValue(Attributes.Name.IMPLEMENTATION_VERSION),                                			attrs.getValue(Attributes.Name.IMPLEMENTATION_VENDOR),                                			null);					}				}				return ret;			} catch (IOException _) {}			return null;		}		void findResources (Vector v, String name) {			ZipEntry resourceFile = jar.getEntry (name);			if (resourceFile!=null && !resourceFile.isDirectory()) {				try {					v.addElement(new URL(urlPrefix + resourceFile.getName()));				} catch (MalformedURLException _) {_.printStackTrace();}			}		}				public String toString() {			return "JarSource[file=" + this.file + "]";		}	}/* linked list of Sources as extracted from classpath */private Source sources;	public static ClassLoader getSingleton() {	return SINGLETON;}private String listPath() {	String retval = "";	Source curr;	curr = this.sources;	while( curr != null )	{		retval += curr + File.pathSeparator;		curr = curr.next;	}	return retval;}public void addSource(String path) {	File f = new File (path);		if (!f.exists()) {		return;	}		Source s = null;		try {		if (f.isDirectory()) {			s = new DirSource (f.getAbsoluteFile ());		} else {			s = new JarSource (f.getAbsoluteFile ());		}		if (this.sources == null) {			this.sources = s;		} else {			Source last;			for( last = this.sources;			     last.next != null;			     last = last.next );			last.next = s;		}	} catch (Exception _) { }}	private AppClassLoader() {	super(new URL[0]);	StringTokenizer tok = new StringTokenizer (System.getProperty("java.class.path"), File.pathSeparator);        while (tok.hasMoreTokens ())        {		this.addSource(tok.nextToken().trim()); 	}    	   }/* * Search through the CLASSPATH directories and ZIP files to find * the named resource (which may appear more than once). Make sure * it really exists in each place before adding it. */public Enumeration findResources(String name) throws IOException {	Vector v = new Vector();	if (name.charAt(0) == '/') {		name = name.substring (1);	}			for (Source i=this.sources; i!=null; i=i.next) {		i.findResources (v, name);	}	return v.elements();}public URL findResource (String name) {	Vector v = new Vector();	if (name.charAt(0) == '/') {		name = name.substring (1);	}	for (Source i=this.sources; i!=null && v.size()==0; i=i.next) {		i.findResources (v, name);	}	if (v.size()>0) {		return (URL)v.elementAt(0);	} else {		return null;	}}protected Class findClass(String name) throws ClassNotFoundException {	Class ret = null;		String fileName = name.replace ('.', '/') + ".class";	for (Source i=this.sources; i!=null && ret==null; i=i.next) {		ret = i.findClass (name, fileName);	}	// throw an error, if nobody is able to find that class        if (ret == null) {		throw new ClassNotFoundException (name);	} 	return ret;}}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?