mirror of
https://github.com/2003scape/deep-c-rsc.git
synced 2024-03-22 05:49:51 -04:00
724 lines
20 KiB
Java
724 lines
20 KiB
Java
/*
|
|
* @(#) $(JCGO)/goclsp/vm/java/lang/VMClassLoader.java --
|
|
* VM specific methods for Java "ClassLoader" class.
|
|
**
|
|
* Project: JCGO (http://www.ivmaisoft.com/jcgo/)
|
|
* Copyright (C) 2001-2010 Ivan Maidanski <ivmai@ivmaisoft.com>
|
|
* All rights reserved.
|
|
**
|
|
* Class specification origin: GNU Classpath v0.93 vm/reference
|
|
*/
|
|
|
|
/*
|
|
* This is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, 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
|
|
* General Public License (GPL) for more details.
|
|
**
|
|
* Linking this library statically or dynamically with other modules is
|
|
* making a combined work based on this library. Thus, the terms and
|
|
* conditions of the GNU General Public License cover the whole
|
|
* combination.
|
|
**
|
|
* As a special exception, the copyright holders of this library give you
|
|
* permission to link this library with independent modules to produce an
|
|
* executable, regardless of the license terms of these independent
|
|
* modules, and to copy and distribute the resulting executable under
|
|
* terms of your choice, provided that you also meet, for each linked
|
|
* independent module, the terms and conditions of the license of that
|
|
* module. An independent module is a module which is not derived from
|
|
* or based on this library. If you modify this library, you may extend
|
|
* this exception to your version of the library, but you are not
|
|
* obligated to do so. If you do not wish to do so, delete this
|
|
* exception statement from your version.
|
|
*/
|
|
|
|
package java.lang;
|
|
|
|
import gnu.classpath.Configuration;
|
|
import gnu.classpath.SystemProperties;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
|
|
import java.lang.ref.SoftReference;
|
|
|
|
import java.net.MalformedURLException;
|
|
import java.net.URL;
|
|
import java.net.URLConnection;
|
|
import java.net.URLStreamHandler;
|
|
|
|
import java.security.ProtectionDomain;
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
import java.util.Date;
|
|
import java.util.Enumeration;
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
import java.util.Locale;
|
|
import java.util.Map;
|
|
import java.util.Vector;
|
|
|
|
import java.util.zip.ZipEntry;
|
|
import java.util.zip.ZipFile;
|
|
|
|
final class VMClassLoader /* hard-coded class name */
|
|
{
|
|
|
|
static final class ClassParser /* hard-coded class name */
|
|
{ /* used by VM classes only */
|
|
|
|
private static final int USHORT_SIZE = 2;
|
|
|
|
private static final int INT_SIZE = 4;
|
|
|
|
private static final int LONG_SIZE = 8;
|
|
|
|
private static final int MIN_MAJOR_VER = 45;
|
|
|
|
private static final int MAJOR_VER_OFFSET = INT_SIZE + USHORT_SIZE;
|
|
|
|
private static final int CONSTPOOL_COUNT_OFFSET =
|
|
MAJOR_VER_OFFSET + USHORT_SIZE;
|
|
|
|
private static final int CONST_POOL_OFFSET =
|
|
CONSTPOOL_COUNT_OFFSET + USHORT_SIZE;
|
|
|
|
private static final int BODY_BYTES_MINLEN = USHORT_SIZE * 7;
|
|
|
|
private static final int CONST_TAG_CLASS = 7;
|
|
private static final int CONST_TAG_FIELDREF = 9;
|
|
private static final int CONST_TAG_METHODREF = 10;
|
|
private static final int CONST_TAG_INTERFACEMETHODREF = 11;
|
|
private static final int CONST_TAG_STRING = 8;
|
|
private static final int CONST_TAG_INTEGER = 3;
|
|
private static final int CONST_TAG_FLOAT = 4;
|
|
private static final int CONST_TAG_LONG = 5;
|
|
private static final int CONST_TAG_DOUBLE = 6;
|
|
private static final int CONST_TAG_NAMEANDTYPE = 12;
|
|
private static final int CONST_TAG_UTF8 = 1;
|
|
|
|
static
|
|
{
|
|
if (!"".equals("")) /* hack */
|
|
defineClass0X(null, null, new byte[0]); /* hack */
|
|
}
|
|
|
|
private ClassParser() {}
|
|
|
|
static final Class defineClass0X(String name, Object loader,
|
|
byte[] bytes) /* hard-coded method signature */
|
|
throws ClassCastException
|
|
{ /* called from native code */
|
|
return defineClass((ClassLoader) loader, name, bytes, 0, bytes.length,
|
|
null);
|
|
}
|
|
|
|
static final String decodeJavaClassName(byte[] bytes, int offset, int len)
|
|
{ /* used by VM classes only */
|
|
if (bytes.length - offset < len || (offset | len) < 0)
|
|
throw new ArrayIndexOutOfBoundsException();
|
|
if (len < CONST_POOL_OFFSET || bytes[offset] != (byte) 0xca ||
|
|
bytes[offset + 1] != (byte) 0xfe || bytes[offset + 2] != (byte) 0xba ||
|
|
bytes[offset + 3] != (byte) 0xbe ||
|
|
getUShortAt(bytes, offset + MAJOR_VER_OFFSET) < MIN_MAJOR_VER)
|
|
throw new ClassFormatError();
|
|
int cpEndOfs = getJavaClassConstPoolEntryOfs(getUShortAt(bytes,
|
|
offset + CONSTPOOL_COUNT_OFFSET), bytes, offset);
|
|
if (offset + len - cpEndOfs < BODY_BYTES_MINLEN)
|
|
throw new ClassFormatError();
|
|
int thisClassEntryOfs = getJavaClassConstPoolEntryOfs(getUShortAt(bytes,
|
|
cpEndOfs + USHORT_SIZE), bytes, offset);
|
|
if (thisClassEntryOfs >= cpEndOfs ||
|
|
bytes[thisClassEntryOfs] != CONST_TAG_CLASS)
|
|
throw new ClassFormatError();
|
|
int nameEntryOfs = getJavaClassConstPoolEntryOfs(getUShortAt(bytes,
|
|
thisClassEntryOfs + 1), bytes, offset);
|
|
if (nameEntryOfs >= cpEndOfs || bytes[nameEntryOfs] != CONST_TAG_UTF8)
|
|
throw new ClassFormatError();
|
|
String name = new String(bytes, 0, nameEntryOfs + (1 + USHORT_SIZE),
|
|
getUShortAt(bytes, nameEntryOfs + 1));
|
|
if (name.length() == 0 || name.indexOf('.') >= 0)
|
|
throw new ClassFormatError();
|
|
return name.replace('/', '.');
|
|
}
|
|
|
|
private static int getJavaClassConstPoolEntryOfs(int index, byte[] bytes,
|
|
int offset)
|
|
{
|
|
offset += CONST_POOL_OFFSET;
|
|
int bytesLen = bytes.length;
|
|
while (--index > 0 && bytesLen - offset > USHORT_SIZE)
|
|
switch (bytes[offset])
|
|
{
|
|
case CONST_TAG_UTF8:
|
|
offset += getUShortAt(bytes, offset + 1) + (1 + USHORT_SIZE);
|
|
break;
|
|
case CONST_TAG_CLASS:
|
|
case CONST_TAG_STRING:
|
|
offset += 1 + USHORT_SIZE;
|
|
break;
|
|
case CONST_TAG_INTEGER:
|
|
case CONST_TAG_FLOAT:
|
|
case CONST_TAG_FIELDREF:
|
|
case CONST_TAG_METHODREF:
|
|
case CONST_TAG_INTERFACEMETHODREF:
|
|
case CONST_TAG_NAMEANDTYPE:
|
|
offset += 1 + INT_SIZE;
|
|
break;
|
|
case CONST_TAG_LONG:
|
|
case CONST_TAG_DOUBLE:
|
|
offset += 1 + LONG_SIZE;
|
|
index--;
|
|
break;
|
|
default:
|
|
throw new ClassFormatError();
|
|
}
|
|
if (index != 0 || offset < 0)
|
|
throw new ClassFormatError();
|
|
return offset;
|
|
}
|
|
|
|
private static int getUShortAt(byte[] bytes, int offset)
|
|
{
|
|
return ((bytes[offset] & 0xff) << 8) | (bytes[offset + 1] & 0xff);
|
|
}
|
|
}
|
|
|
|
private static final class StaticData
|
|
{
|
|
|
|
static final HashMap bootJars = new HashMap();
|
|
|
|
static final String JAVA_BOOT_CLASS_PATH = removeNonExistingPaths(
|
|
SystemProperties.getProperty("java.boot.class.path", "."));
|
|
|
|
static final HashMap definedPackages = getBootDefinedPackages();
|
|
|
|
private static HashMap getBootDefinedPackages()
|
|
{
|
|
HashMap map = new HashMap();
|
|
String[] packages = getBootPackages();
|
|
if (packages != null)
|
|
{
|
|
String specName = SystemProperties.getProperty("java.specification.name");
|
|
String vendor = SystemProperties.getProperty("java.specification.vendor");
|
|
String version =
|
|
SystemProperties.getProperty("java.specification.version");
|
|
for (int i = 0; i < packages.length; i++)
|
|
{
|
|
String name = packages[i];
|
|
map.put(name, new Package(name, specName, vendor, version,
|
|
"GNU Classpath", "GNU", Configuration.CLASSPATH_VERSION, null, null));
|
|
}
|
|
}
|
|
return map;
|
|
}
|
|
}
|
|
|
|
private static final class AppClassLoader extends ClassLoader
|
|
{
|
|
|
|
AppClassLoader()
|
|
{
|
|
super(null);
|
|
}
|
|
|
|
protected URL findResource(String name)
|
|
{
|
|
Vector list = new Vector(1);
|
|
findResourcesInner(list, name, true,
|
|
SystemProperties.getProperty("java.class.path", "."));
|
|
return list.size() > 0 ? (URL) list.elementAt(0) : null;
|
|
}
|
|
|
|
protected Enumeration findResources(String name)
|
|
throws IOException
|
|
{
|
|
Vector list = new Vector();
|
|
findResourcesInner(list, name, false,
|
|
SystemProperties.getProperty("java.class.path", "."));
|
|
return list.elements();
|
|
}
|
|
|
|
protected Package getPackage(String name)
|
|
{
|
|
Package pkg = super.getPackage(name);
|
|
if (pkg == null)
|
|
{
|
|
pkg = new Package(name, null, null, null, null, null, null, null, this);
|
|
synchronized (this.definedPackages)
|
|
{
|
|
this.definedPackages.put(name, pkg);
|
|
}
|
|
}
|
|
return pkg;
|
|
}
|
|
|
|
public String toString()
|
|
{
|
|
return getClass().getName();
|
|
}
|
|
}
|
|
|
|
private static final class JarUrlStreamHandler extends URLStreamHandler
|
|
{
|
|
|
|
private SimpleDateFormat dateFormat;
|
|
|
|
JarUrlStreamHandler() {}
|
|
|
|
protected URLConnection openConnection(URL url)
|
|
{
|
|
return
|
|
new URLConnection(url)
|
|
{
|
|
|
|
private ZipFile zip;
|
|
|
|
private ZipEntry entry;
|
|
|
|
public synchronized void connect()
|
|
throws MalformedURLException
|
|
{
|
|
if (!connected)
|
|
{
|
|
URL url = getURL();
|
|
String spec = url.getFile();
|
|
int pos;
|
|
if (!"jar".equals(url.getProtocol()) || (pos = spec.indexOf("!/")) < 0)
|
|
throw new MalformedURLException("not jar: " + url.toString());
|
|
ZipFile zip = openUrlZipFile(spec.substring(0, pos), null);
|
|
if (zip == null || (entry =
|
|
zip.getEntry(unquoteUrl(spec.substring(pos + 2)))) == null)
|
|
throw new MalformedURLException("not found: " + url.toString());
|
|
this.zip = zip;
|
|
connected = true;
|
|
}
|
|
}
|
|
|
|
public InputStream getInputStream()
|
|
throws IOException
|
|
{
|
|
if (!connected)
|
|
connect();
|
|
return zip.getInputStream(entry);
|
|
}
|
|
|
|
public String getHeaderField(String name)
|
|
{
|
|
if (!connected)
|
|
{
|
|
try
|
|
{
|
|
connect();
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
if (name.equals("content-type"))
|
|
return guessContentTypeFromName(entry.getName());
|
|
if (name.equals("content-length"))
|
|
return Long.toString(entry.getSize());
|
|
if (name.equals("last-modified"))
|
|
synchronized (JarUrlStreamHandler.this)
|
|
{
|
|
if (dateFormat == null)
|
|
dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss 'GMT'",
|
|
Locale.US);
|
|
return dateFormat.format(new Date(entry.getTime()));
|
|
}
|
|
return null;
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
private static volatile URLStreamHandler jarUrlStreamHandler;
|
|
|
|
private static final VMClass.IdentityHashMap defnClassToLoader =
|
|
new VMClass.IdentityHashMap();
|
|
|
|
private static final VMClass.IdentityHashMap definedClassToPDomain =
|
|
new VMClass.IdentityHashMap();
|
|
|
|
static
|
|
{
|
|
compareClassNames0X("", boolean.class); /* hack */
|
|
}
|
|
|
|
private VMClassLoader() {}
|
|
|
|
static final Class defineClass(ClassLoader cl, String name, byte[] data,
|
|
int offset, int len, ProtectionDomain pd)
|
|
{
|
|
/* implemented for the pre-compiled classes only */
|
|
String className = ClassParser.decodeJavaClassName(data, offset, len);
|
|
if (name != null && !name.equals(className))
|
|
throw new NoClassDefFoundError("invalid class name: " + name);
|
|
if (className.startsWith("java."))
|
|
throw new SecurityException("prohibited package name: " +
|
|
className.substring(0, className.lastIndexOf('.')));
|
|
Class aclass = loadClass0(className, 0);
|
|
if (aclass != null)
|
|
{
|
|
if (cl != null)
|
|
synchronized (defnClassToLoader)
|
|
{
|
|
Object old = defnClassToLoader.put(aclass, cl);
|
|
if (old != null && old != cl)
|
|
defnClassToLoader.put(aclass, old);
|
|
}
|
|
if (pd != null)
|
|
synchronized (definedClassToPDomain)
|
|
{
|
|
Object old = definedClassToPDomain.put(aclass, pd);
|
|
if (old != null && old != pd)
|
|
definedClassToPDomain.put(aclass, old);
|
|
}
|
|
return aclass;
|
|
}
|
|
throw new InternalError(
|
|
"VMClassLoader.defineClass() not implemented, class " + className);
|
|
}
|
|
|
|
static final Class defineClassWithTransformers(ClassLoader cl, String name,
|
|
byte[] data, int offset, int len, ProtectionDomain pd)
|
|
{
|
|
/* not implemented */
|
|
return defineClass(cl, name, data, offset, len, pd);
|
|
}
|
|
|
|
static final void resolveClass(Class aclass)
|
|
{
|
|
/* dummy */
|
|
}
|
|
|
|
static final Class loadClass(String name, boolean resolve)
|
|
throws ClassNotFoundException
|
|
{
|
|
if (name.length() == 0)
|
|
throw new ClassNotFoundException(name);
|
|
Class aclass = loadClass0(name, 0);
|
|
if (resolve && aclass != null)
|
|
resolveClass(aclass);
|
|
return aclass;
|
|
}
|
|
|
|
static URL getResource(String name)
|
|
{
|
|
Vector list = new Vector(1);
|
|
findResourcesInner(list, name, true, StaticData.JAVA_BOOT_CLASS_PATH);
|
|
return list.size() > 0 ? (URL) list.elementAt(0) : null;
|
|
}
|
|
|
|
static Enumeration getResources(String name)
|
|
{
|
|
Vector list = new Vector();
|
|
findResourcesInner(list, name, false, StaticData.JAVA_BOOT_CLASS_PATH);
|
|
return list.elements();
|
|
}
|
|
|
|
static Package getPackage(String name)
|
|
{
|
|
return (Package) StaticData.definedPackages.get(name);
|
|
}
|
|
|
|
static Package[] getPackages()
|
|
{
|
|
int size = StaticData.definedPackages.size();
|
|
Package[] packages = new Package[size];
|
|
Iterator itr = StaticData.definedPackages.values().iterator();
|
|
for (int i = 0; i < size; i++)
|
|
packages[i] = (Package) itr.next();
|
|
return packages;
|
|
}
|
|
|
|
static String[] getBootPackages()
|
|
{
|
|
return new String[0];
|
|
}
|
|
|
|
static final Class getPrimitiveClass(char ch)
|
|
{
|
|
int type = "VZBCSIJFD".indexOf(ch, 0);
|
|
return type >= 0 ? getPrimitiveClass0(type) : null;
|
|
}
|
|
|
|
static final boolean defaultAssertionStatus()
|
|
{
|
|
/* not implemented */
|
|
return true;
|
|
}
|
|
|
|
static final Map packageAssertionStatus()
|
|
{
|
|
/* not implemented */
|
|
return new HashMap();
|
|
}
|
|
|
|
static final Map classAssertionStatus()
|
|
{
|
|
/* not implemented */
|
|
return new HashMap();
|
|
}
|
|
|
|
static ClassLoader getSystemClassLoader()
|
|
{
|
|
return "gnu.java.net.content.text.plain".equals( /* hack */
|
|
"gnu.java.net.protocol.file.Handler") ? null : /* hack */
|
|
new AppClassLoader();
|
|
}
|
|
|
|
static Class findLoadedClass(ClassLoader cl, String name)
|
|
{
|
|
Class aclass = loadClass0(name, 0);
|
|
if (aclass != null && getLoaderOfDefinedClass(aclass) == cl)
|
|
return aclass;
|
|
return null;
|
|
}
|
|
|
|
static final ClassLoader getLoaderOfDefinedClass(Class klass)
|
|
{ /* used by VM classes only */
|
|
synchronized (defnClassToLoader)
|
|
{
|
|
return (ClassLoader) defnClassToLoader.get(klass);
|
|
}
|
|
}
|
|
|
|
static final ProtectionDomain getProtectionDomain(Class klass)
|
|
{ /* used by VM classes only */
|
|
Class aclass;
|
|
while ((aclass = klass.getComponentType()) != null)
|
|
klass = aclass;
|
|
synchronized (definedClassToPDomain)
|
|
{
|
|
return (ProtectionDomain) definedClassToPDomain.get(klass);
|
|
}
|
|
}
|
|
|
|
static final Class getNextInnerClass(String name)
|
|
{ /* used by VM classes only */
|
|
return loadClass0(name, 1);
|
|
}
|
|
|
|
private static int unescapeUrlChar(String spec, int pos)
|
|
throws MalformedURLException
|
|
{
|
|
if (pos + 2 >= spec.length() || spec.charAt(pos) != '%')
|
|
throw new MalformedURLException(spec);
|
|
int high = Character.digit(spec.charAt(pos + 1), 16);
|
|
int low = Character.digit(spec.charAt(pos + 2), 16);
|
|
if ((high | low) < 0)
|
|
throw new MalformedURLException(spec);
|
|
return (high << 4) | low;
|
|
}
|
|
|
|
static String unquoteUrl(String spec)
|
|
throws MalformedURLException
|
|
{ /* used by VM classes only */
|
|
int pos = spec.indexOf('%');
|
|
if (pos < 0)
|
|
return spec;
|
|
StringBuilder sb = new StringBuilder(spec.length());
|
|
int prev = 0;
|
|
do
|
|
{
|
|
sb.append(spec.substring(prev, pos));
|
|
int c = unescapeUrlChar(spec, pos);
|
|
if ((c & 0x80) != 0)
|
|
{
|
|
pos += 3;
|
|
int c2 = unescapeUrlChar(spec, pos);
|
|
if ((c2 & 0xc0) != 0x80)
|
|
throw new MalformedURLException(spec);
|
|
if ((c & 0xe0) == 0xc0)
|
|
c = ((c & 0x1f) << 6) | (c2 & 0x3f);
|
|
else
|
|
{
|
|
pos += 3;
|
|
int c3 = unescapeUrlChar(spec, pos);
|
|
if ((c3 & 0xc0) != 0x80 || (c & 0xf0) != 0xe0)
|
|
throw new MalformedURLException(spec);
|
|
c = ((c & 0xf) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f);
|
|
}
|
|
}
|
|
sb.append((char) c);
|
|
prev = pos + 3;
|
|
} while ((pos = spec.indexOf('%', prev)) >= 0);
|
|
return sb.append(spec.substring(prev)).toString();
|
|
}
|
|
|
|
static final ZipFile openUrlZipFile(String baseSpec, File file)
|
|
{ /* used by VM classes only */
|
|
SoftReference ref;
|
|
synchronized (StaticData.bootJars)
|
|
{
|
|
ref = (SoftReference) StaticData.bootJars.get(baseSpec);
|
|
}
|
|
ZipFile zip;
|
|
if (ref == null || (zip = (ZipFile) ref.get()) == null)
|
|
{
|
|
if (file == null)
|
|
{
|
|
if (baseSpec.length() <= 6 || !baseSpec.startsWith("file:"))
|
|
return null;
|
|
String path;
|
|
try
|
|
{
|
|
path = unquoteUrl(baseSpec.substring(5));
|
|
}
|
|
catch (MalformedURLException e)
|
|
{
|
|
return null;
|
|
}
|
|
if (path.charAt(0) != '/' ||
|
|
!(file = new File(path.substring(1))).isAbsolute())
|
|
file = new File(path);
|
|
}
|
|
zip = null;
|
|
try
|
|
{
|
|
zip = new ZipFile(file);
|
|
}
|
|
catch (IOException e) {}
|
|
catch (SecurityException e) {}
|
|
if (zip != null)
|
|
{
|
|
ref = new SoftReference(zip);
|
|
synchronized (StaticData.bootJars)
|
|
{
|
|
StaticData.bootJars.put(baseSpec, ref);
|
|
}
|
|
}
|
|
}
|
|
return zip;
|
|
}
|
|
|
|
static final String removeNonExistingPaths(String pathList)
|
|
{ /* used by VM classes only */
|
|
StringBuilder sb = new StringBuilder(pathList.length());
|
|
int pos = 0;
|
|
int nextPos;
|
|
do
|
|
{
|
|
nextPos = pathList.indexOf(File.pathSeparatorChar, pos);
|
|
if (nextPos < 0)
|
|
nextPos = pathList.length();
|
|
File file = new File(pos < nextPos ?
|
|
pathList.substring(pos, nextPos) : ".");
|
|
try
|
|
{
|
|
if (!file.exists())
|
|
file = null;
|
|
}
|
|
catch (SecurityException e) {}
|
|
if (file != null)
|
|
{
|
|
if (sb.length() > 0)
|
|
sb.append(File.pathSeparatorChar);
|
|
sb.append(file.getPath());
|
|
}
|
|
pos = nextPos + 1;
|
|
} while (pathList.length() > nextPos);
|
|
return sb.toString();
|
|
}
|
|
|
|
static final void findResourcesInner(Vector list, String name,
|
|
boolean findSingle, String pathList)
|
|
{ /* used by VM classes only */
|
|
int pos;
|
|
int nextPos = 0;
|
|
do
|
|
{
|
|
if (name.length() <= nextPos)
|
|
return;
|
|
pos = nextPos;
|
|
char ch;
|
|
while ((ch = name.charAt(nextPos++)) == '.')
|
|
if (name.length() <= nextPos)
|
|
return;
|
|
if (ch != '/' && ch != File.separatorChar)
|
|
break;
|
|
} while (true);
|
|
if (pos > 0)
|
|
{
|
|
name = name.substring(pos);
|
|
pos = 0;
|
|
}
|
|
do
|
|
{
|
|
nextPos = pathList.indexOf(File.pathSeparatorChar, pos);
|
|
if (nextPos < 0)
|
|
nextPos = pathList.length();
|
|
File file = new File(pos < nextPos ?
|
|
pathList.substring(pos, nextPos) : ".");
|
|
try
|
|
{
|
|
String baseSpec = file.toURL().toString();
|
|
if (baseSpec.endsWith("/"))
|
|
{
|
|
File f = new File(file, name);
|
|
if (f.exists())
|
|
{
|
|
list.addElement(f.toURL());
|
|
if (findSingle)
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ZipFile zip = openUrlZipFile(baseSpec, file);
|
|
if (zip != null && zip.getEntry(name) != null)
|
|
{
|
|
String spec = baseSpec + "!/" + name;
|
|
try
|
|
{
|
|
list.addElement(new URL("jar", null, spec));
|
|
}
|
|
catch (MalformedURLException x)
|
|
{
|
|
URLStreamHandler handler = jarUrlStreamHandler;
|
|
if (handler == null)
|
|
jarUrlStreamHandler = handler = new JarUrlStreamHandler();
|
|
list.addElement(new URL("jar", null, -1, spec, handler));
|
|
}
|
|
if (findSingle)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
catch (SecurityException e) {}
|
|
catch (MalformedURLException e)
|
|
{
|
|
try
|
|
{
|
|
if (file.exists())
|
|
throw (Error) (new InternalError("findResources")).initCause(e);
|
|
}
|
|
catch (SecurityException x) {}
|
|
}
|
|
pos = nextPos + 1;
|
|
} while (pathList.length() > nextPos);
|
|
}
|
|
|
|
static final int compareClassNames0X(String name, Class aclass)
|
|
{ /* called from native code */
|
|
return name.compareTo(aclass.getName());
|
|
}
|
|
|
|
private static native Class getPrimitiveClass0(int type); /* JVM-core */
|
|
|
|
private static native Class loadClass0(String name,
|
|
int nextInner); /* JVM-core */
|
|
}
|