001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package com.db4o.instrumentation.main;
022:
023: import java.io.*;
024: import java.net.*;
025: import java.util.*;
026:
027: import EDU.purdue.cs.bloat.context.*;
028: import EDU.purdue.cs.bloat.editor.*;
029:
030: import com.db4o.instrumentation.core.*;
031: import com.db4o.instrumentation.filter.*;
032: import com.db4o.instrumentation.util.*;
033:
034: public class BloatInstrumentingClassLoader extends BloatingClassLoader {
035:
036: private final Map _cache = new HashMap();
037: private final ClassFilter _filter;
038: private final BloatClassEdit _edit;
039: private final BloatLoaderContext _loaderContext = new BloatLoaderContext(
040: getClassInfoLoader(), getEditorContext());
041:
042: public BloatInstrumentingClassLoader(URL[] urls,
043: ClassLoader parent, BloatClassEdit edit) {
044: this (urls, parent, new AcceptAllClassesFilter(), edit);
045: }
046:
047: public BloatInstrumentingClassLoader(URL[] urls,
048: ClassLoader parent, ClassFilter filter, BloatClassEdit edit) {
049: super (urls, parent);
050: _filter = filter;
051: _edit = edit;
052: }
053:
054: protected synchronized Class loadClass(String name, boolean resolve)
055: throws ClassNotFoundException {
056: if (_cache.containsKey(name)) {
057: return (Class) _cache.get(name);
058: }
059: Class originalClazz = super .loadClass(name, resolve);
060: if (mustDelegate(name)) {
061: return originalClazz;
062: }
063: Class clazz = (_filter.accept(originalClazz) ? findClass(name)
064: : findRawClass(name));
065: _cache.put(clazz.getName(), clazz);
066: if (resolve) {
067: resolveClass(clazz);
068: }
069: return clazz;
070: }
071:
072: private boolean mustDelegate(String name) {
073: return BloatUtil.isPlatformClassName(name)
074: || ((name.startsWith("com.db4o.")
075: && name.indexOf("test.") < 0 && name
076: .indexOf("samples.") < 0));
077: }
078:
079: private Class findRawClass(String className)
080: throws ClassNotFoundException {
081: try {
082: String resourcePath = className.replace('.', '/')
083: + ".class";
084: InputStream resourceStream = getResourceAsStream(resourcePath);
085: ByteArrayOutputStream rawByteStream = new ByteArrayOutputStream();
086: byte[] buf = new byte[4096];
087: int bytesread = 0;
088: while ((bytesread = resourceStream.read(buf)) >= 0) {
089: rawByteStream.write(buf, 0, bytesread);
090: }
091: resourceStream.close();
092: byte[] rawBytes = rawByteStream.toByteArray();
093: return super .defineClass(className, rawBytes, 0,
094: rawBytes.length);
095: } catch (Exception exc) {
096: throw new ClassNotFoundException(className, exc);
097: }
098: }
099:
100: protected void bloat(ClassEditor ce) {
101: _edit.enhance(ce, getParent(), _loaderContext);
102: }
103:
104: }
|