javassist.ClassPoolTail Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package javassist;
import java.io.*;
import java.util.jar.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Hashtable;
final class ClassPathList {
ClassPathList next;
ClassPath path;
ClassPathList(ClassPath p, ClassPathList n) {
next = n;
path = p;
}
}
final class DirClassPath implements ClassPath {
String directory;
DirClassPath(String dirName) {
directory = dirName;
}
public InputStream openClassfile(String classname) {
try {
char sep = File.separatorChar;
String filename = directory + sep
+ classname.replace('.', sep) + ".class";
return new FileInputStream(filename.toString());
}
catch (FileNotFoundException e) {}
catch (SecurityException e) {}
return null;
}
public URL find(String classname) {
char sep = File.separatorChar;
String filename = directory + sep
+ classname.replace('.', sep) + ".class";
File f = new File(filename);
if (f.exists())
try {
return f.getCanonicalFile().toURI().toURL();
}
catch (MalformedURLException e) {}
catch (IOException e) {}
return null;
}
public void close() {}
public String toString() {
return directory;
}
}
final class JarDirClassPath implements ClassPath {
JarClassPath[] jars;
JarDirClassPath(String dirName) throws NotFoundException {
File[] files = new File(dirName).listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
name = name.toLowerCase();
return name.endsWith(".jar") || name.endsWith(".zip");
}
});
if (files != null) {
jars = new JarClassPath[files.length];
for (int i = 0; i < files.length; i++)
jars[i] = new JarClassPath(files[i].getPath());
}
}
public InputStream openClassfile(String classname) throws NotFoundException {
if (jars != null)
for (int i = 0; i < jars.length; i++) {
InputStream is = jars[i].openClassfile(classname);
if (is != null)
return is;
}
return null; // not found
}
public URL find(String classname) {
if (jars != null)
for (int i = 0; i < jars.length; i++) {
URL url = jars[i].find(classname);
if (url != null)
return url;
}
return null; // not found
}
public void close() {
if (jars != null)
for (int i = 0; i < jars.length; i++)
jars[i].close();
}
}
final class JarClassPath implements ClassPath {
JarFile jarfile;
String jarfileURL;
JarClassPath(String pathname) throws NotFoundException {
try {
jarfile = new JarFile(pathname);
jarfileURL = new File(pathname).getCanonicalFile()
.toURI().toURL().toString();
return;
}
catch (IOException e) {}
throw new NotFoundException(pathname);
}
public InputStream openClassfile(String classname)
throws NotFoundException
{
try {
String jarname = classname.replace('.', '/') + ".class";
JarEntry je = jarfile.getJarEntry(jarname);
if (je != null)
return jarfile.getInputStream(je);
else
return null; // not found
}
catch (IOException e) {}
throw new NotFoundException("broken jar file?: "
+ jarfile.getName());
}
public URL find(String classname) {
String jarname = classname.replace('.', '/') + ".class";
JarEntry je = jarfile.getJarEntry(jarname);
if (je != null)
try {
return new URL("jar:" + jarfileURL + "!/" + jarname);
}
catch (MalformedURLException e) {}
return null; // not found
}
public void close() {
try {
jarfile.close();
jarfile = null;
}
catch (IOException e) {}
}
public String toString() {
return jarfile == null ? "" : jarfile.toString();
}
}
final class ClassPoolTail {
protected ClassPathList pathList;
public ClassPoolTail() {
pathList = null;
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("[class path: ");
ClassPathList list = pathList;
while (list != null) {
buf.append(list.path.toString());
buf.append(File.pathSeparatorChar);
list = list.next;
}
buf.append(']');
return buf.toString();
}
public synchronized ClassPath insertClassPath(ClassPath cp) {
pathList = new ClassPathList(cp, pathList);
return cp;
}
public synchronized ClassPath appendClassPath(ClassPath cp) {
ClassPathList tail = new ClassPathList(cp, null);
ClassPathList list = pathList;
if (list == null)
pathList = tail;
else {
while (list.next != null)
list = list.next;
list.next = tail;
}
return cp;
}
public synchronized void removeClassPath(ClassPath cp) {
ClassPathList list = pathList;
if (list != null)
if (list.path == cp)
pathList = list.next;
else {
while (list.next != null)
if (list.next.path == cp)
list.next = list.next.next;
else
list = list.next;
}
cp.close();
}
public ClassPath appendSystemPath() {
return appendClassPath(new ClassClassPath());
}
public ClassPath insertClassPath(String pathname)
throws NotFoundException
{
return insertClassPath(makePathObject(pathname));
}
public ClassPath appendClassPath(String pathname)
throws NotFoundException
{
return appendClassPath(makePathObject(pathname));
}
private static ClassPath makePathObject(String pathname)
throws NotFoundException
{
String lower = pathname.toLowerCase();
if (lower.endsWith(".jar") || lower.endsWith(".zip"))
return new JarClassPath(pathname);
int len = pathname.length();
if (len > 2 && pathname.charAt(len - 1) == '*'
&& (pathname.charAt(len - 2) == '/'
|| pathname.charAt(len - 2) == File.separatorChar)) {
String dir = pathname.substring(0, len - 2);
return new JarDirClassPath(dir);
}
return new DirClassPath(pathname);
}
/**
* This method does not close the output stream.
*/
void writeClassfile(String classname, OutputStream out)
throws NotFoundException, IOException, CannotCompileException
{
InputStream fin = openClassfile(classname);
if (fin == null)
throw new NotFoundException(classname);
try {
copyStream(fin, out);
}
finally {
fin.close();
}
}
/*
-- faster version --
void checkClassName(String classname) throws NotFoundException {
if (find(classname) == null)
throw new NotFoundException(classname);
}
-- slower version --
void checkClassName(String classname) throws NotFoundException {
InputStream fin = openClassfile(classname);
try {
fin.close();
}
catch (IOException e) {}
}
*/
/**
* Opens the class file for the class specified by
* classname
.
*
* @param classname a fully-qualified class name
* @return null if the file has not been found.
* @throws NotFoundException if any error is reported by ClassPath.
*/
InputStream openClassfile(String classname)
throws NotFoundException
{
ClassPathList list = pathList;
InputStream ins = null;
NotFoundException error = null;
while (list != null) {
try {
ins = list.path.openClassfile(classname);
}
catch (NotFoundException e) {
if (error == null)
error = e;
}
if (ins == null)
list = list.next;
else
return ins;
}
if (error != null)
throw error;
else
return null; // not found
}
/**
* Searches the class path to obtain the URL of the class file
* specified by classname. It is also used to determine whether
* the class file exists.
*
* @param classname a fully-qualified class name.
* @return null if the class file could not be found.
*/
public URL find(String classname) {
ClassPathList list = pathList;
URL url = null;
while (list != null) {
url = list.path.find(classname);
if (url == null)
list = list.next;
else
return url;
}
return null;
}
/**
* Reads from an input stream until it reaches the end.
*
* @return the contents of that input stream
*/
public static byte[] readStream(InputStream fin) throws IOException {
byte[][] bufs = new byte[8][];
int bufsize = 4096;
for (int i = 0; i < 8; ++i) {
bufs[i] = new byte[bufsize];
int size = 0;
int len = 0;
do {
len = fin.read(bufs[i], size, bufsize - size);
if (len >= 0)
size += len;
else {
byte[] result = new byte[bufsize - 4096 + size];
int s = 0;
for (int j = 0; j < i; ++j) {
System.arraycopy(bufs[j], 0, result, s, s + 4096);
s = s + s + 4096;
}
System.arraycopy(bufs[i], 0, result, s, size);
return result;
}
} while (size < bufsize);
bufsize *= 2;
}
throw new IOException("too much data");
}
/**
* Reads from an input stream and write to an output stream
* until it reaches the end. This method does not close the
* streams.
*/
public static void copyStream(InputStream fin, OutputStream fout)
throws IOException
{
int bufsize = 4096;
byte[] buf = null;
for (int i = 0; i < 64; ++i) {
if (i < 8) {
bufsize *= 2;
buf = new byte[bufsize];
}
int size = 0;
int len = 0;
do {
len = fin.read(buf, size, bufsize - size);
if (len >= 0)
size += len;
else {
fout.write(buf, 0, size);
return;
}
} while (size < bufsize);
fout.write(buf);
}
throw new IOException("too much data");
}
}