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.editor.*;
028: import EDU.purdue.cs.bloat.file.*;
029:
030: import com.db4o.foundation.io.*;
031: import com.db4o.instrumentation.core.*;
032: import com.db4o.instrumentation.file.*;
033:
034: public class Db4oFileEnhancer {
035: private final BloatClassEdit _classEdit;
036:
037: public Db4oFileEnhancer(BloatClassEdit classEdit) {
038: _classEdit = classEdit;
039: }
040:
041: public void enhance(String sourceDir, String targetDir,
042: String[] classpath, String packagePredicate)
043: throws Exception {
044: enhance(new DefaultFilePathRoot(new String[] { sourceDir },
045: ".class"), targetDir, classpath, packagePredicate);
046: }
047:
048: public void enhance(FilePathRoot sources, String targetDir,
049: String[] classpath, String packagePredicate)
050: throws Exception {
051: enhance(new DefaultClassSource(), sources, targetDir,
052: classpath, packagePredicate);
053: }
054:
055: private void enhance(ClassSource classSource, FilePathRoot sources,
056: String targetDir, String[] classpath,
057: String packagePredicate) throws Exception {
058: File fTargetDir = new File(targetDir);
059:
060: String[] sourceRoots = sources.rootDirs();
061: for (int rootIdx = 0; rootIdx < sourceRoots.length; rootIdx++) {
062: File rootFile = new File(sourceRoots[rootIdx]);
063: assertSourceDir(rootFile);
064: }
065:
066: ClassFileLoader fileLoader = new ClassFileLoader(classSource);
067: String[] fullClasspath = fullClasspath(sources, classpath);
068: setOutputDir(fileLoader, fTargetDir);
069: setClasspath(fileLoader, fullClasspath);
070:
071: URL[] urls = classpathToURLs(fullClasspath);
072: URLClassLoader classLoader = new URLClassLoader(urls,
073: ClassLoader.getSystemClassLoader());
074: enhance(sources, fTargetDir, classLoader,
075: new BloatLoaderContext(fileLoader), packagePredicate);
076:
077: fileLoader.done();
078: }
079:
080: private void enhance(FilePathRoot sources, File target,
081: ClassLoader classLoader, BloatLoaderContext bloatUtil,
082: String packagePredicate) throws Exception {
083: for (Iterator sourceFileIter = sources.files(); sourceFileIter
084: .hasNext();) {
085: FileWithRoot file = (FileWithRoot) sourceFileIter.next();
086: enhanceFile(file.root(), file.file(), target, classLoader,
087: bloatUtil, packagePredicate);
088: }
089: }
090:
091: private void enhanceFile(File prefix, File source, File target,
092: ClassLoader classLoader, BloatLoaderContext bloatUtil,
093: String packagePredicate) throws IOException {
094: String classPath = source.getCanonicalPath().substring(
095: prefix.getCanonicalPath().length() + 1);
096: String className = classPath.substring(0, classPath.length()
097: - ".class".length());
098: className = className.replace(File.separatorChar, '.');
099:
100: InstrumentationStatus status = InstrumentationStatus.NOT_INSTRUMENTED;
101: try {
102: if (className.startsWith(packagePredicate)) {
103: System.err.println("Processing " + className);
104: ClassEditor classEditor = bloatUtil
105: .classEditor(className);
106: status = _classEdit.enhance(classEditor, classLoader,
107: bloatUtil);
108: System.err.println("enhance " + className + ": "
109: + (status.isInstrumented() ? "ok" : "failed"));
110: }
111: } catch (Exception e) {
112: status = InstrumentationStatus.FAILED;
113: e.printStackTrace();
114: } catch (NoClassDefFoundError e) {
115: System.err.println("Omitting " + className
116: + ": Referenced class " + e.getMessage()
117: + " not found.");
118: } finally {
119: if (!status.isInstrumented()) {
120: File4.copyFile(source, new File(target, classPath));
121: } else {
122: // bloatUtil.commit();
123: }
124: }
125: }
126:
127: private String[] fullClasspath(FilePathRoot sources,
128: String[] classpath) {
129: String[] sourceRoots = sources.rootDirs();
130: String[] fullClasspath = new String[sourceRoots.length
131: + classpath.length];
132: System.arraycopy(sourceRoots, 0, fullClasspath, 0,
133: sourceRoots.length);
134: System.arraycopy(classpath, 0, fullClasspath,
135: sourceRoots.length, classpath.length);
136: return fullClasspath;
137: }
138:
139: private void setOutputDir(ClassFileLoader fileLoader,
140: File fTargetDir) {
141: fileLoader.setOutputDir(fTargetDir);
142: }
143:
144: private void assertSourceDir(File fSourceDir) throws IOException {
145: if (!fSourceDir.isDirectory()) {
146: throw new IOException("No directory: "
147: + fSourceDir.getCanonicalPath());
148: }
149: }
150:
151: private void setClasspath(ClassFileLoader fileLoader,
152: String[] classPath) {
153: for (int pathIdx = 0; pathIdx < classPath.length; pathIdx++) {
154: fileLoader.appendClassPath(classPath[pathIdx]);
155: }
156: }
157:
158: private URL[] classpathToURLs(String[] classPath)
159: throws MalformedURLException {
160: URL[] urls = new URL[classPath.length];
161: for (int pathIdx = 0; pathIdx < classPath.length; pathIdx++) {
162: urls[pathIdx] = new File(classPath[pathIdx]).toURL();
163: }
164: return urls;
165: }
166:
167: }
|