/* This file is part of the db4o object database http://www.db4o.com
Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com
db4o is free software; you can redistribute it and/or modify it under
the terms of version 3 of the GNU General Public License as published
by the Free Software Foundation.
db4o 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
for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see http://www.gnu.org/licenses/. */
package com.db4o.instrumentation.main;
import java.io.*;
import java.net.*;
import java.util.*;
import EDU.purdue.cs.bloat.context.*;
import EDU.purdue.cs.bloat.editor.*;
import com.db4o.instrumentation.classfilter.*;
import com.db4o.instrumentation.core.*;
import com.db4o.instrumentation.util.*;
/**
* @exclude
*/
public class BloatInstrumentingClassLoader extends BloatingClassLoader {
private final Map _cache = new HashMap();
private final ClassFilter _filter;
private final BloatClassEdit _edit;
private final BloatLoaderContext _loaderContext = new BloatLoaderContext(getEditorContext());
private final ClassLoader _filterLoader;
public BloatInstrumentingClassLoader(URL[] urls, ClassLoader parent, BloatClassEdit edit) {
this(urls, parent, new AcceptAllClassesFilter(), edit);
}
public BloatInstrumentingClassLoader(URL[] urls, ClassLoader parent, ClassFilter filter, BloatClassEdit edit) {
super(urls, parent);
_filter = filter;
_edit = edit;
_filterLoader = new URLClassLoader(urls, parent);
}
protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
if(_cache.containsKey(name)) {
return (Class)_cache.get(name);
}
if(mustDelegate(name)) {
try {
Class originalClazz = getParent().loadClass(name);
return originalClazz;
}
catch(ClassNotFoundException exc) {
}
}
Class clazz = shouldLoadRaw(name) ? findRawClass(name) : findClass(name);
_cache.put(clazz.getName(), clazz);
if(resolve) {
resolveClass(clazz);
}
return clazz;
}
protected boolean mustDelegate(String name) {
return BloatUtil.isPlatformClassName(name)
||((name.startsWith("com.db4o.") && name.indexOf("test.")<0 && name.indexOf("samples.")<0));
}
protected boolean shouldLoadRaw(String name) throws ClassNotFoundException {
if(mustDelegate(name)) {
return true;
}
Class bogusClazz = _filterLoader.loadClass(name);
return !_filter.accept(bogusClazz);
}
private Class findRawClass(String className) throws ClassNotFoundException {
try {
String resourcePath = className.replace('.','/') + ".class";
InputStream resourceStream = getResourceAsStream(resourcePath);
ByteArrayOutputStream rawByteStream = new ByteArrayOutputStream();
byte[] buf = new byte[4096];
int bytesread = 0;
while((bytesread = resourceStream.read(buf)) >= 0) {
rawByteStream.write(buf, 0, bytesread);
}
resourceStream.close();
byte[] rawBytes = rawByteStream.toByteArray();
return super.defineClass(className, rawBytes, 0, rawBytes.length);
} catch (Exception exc) {
throw new ClassNotFoundException(className, exc);
}
}
protected void bloat(ClassEditor ce) {
_edit.enhance(ce, _filterLoader, _loaderContext);
}
}