blob: 2647bce608a39b977de82a19ba2a906f458a9c6c [file] [log] [blame] [edit]
/*******************************************************************************
* Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.tools.workbench.test.mappingsmodel.spi.meta;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import org.eclipse.persistence.tools.workbench.test.utility.JavaTools;
import org.eclipse.persistence.tools.workbench.utility.ClassTools;
import org.eclipse.persistence.tools.workbench.utility.io.FileTools;
import org.eclipse.persistence.tools.workbench.utility.io.IndentingPrintWriter;
/**
* This tool can be used to create a two versions of the same class that
* can be used to test class loading. Create the files by calling #setUp()
* and delete them by calling #tearDown(). The various files and directories
* are stored in public instance variables. The names used for these are
* stored in public static variables.
*
* The different versions will be compiled into:
* - two different subdirectories (subdir1 and subdir2)
* - two different jar files (jarFile1 and jarFile2)
* - two different zip files (zipFile1 and zipFile2)
*
* The two versions of the class will differ by the presence of a single
* method: the version in subdir1/jarFile1/zipFile1 will have a single
* method named #version1(); while, predictably, the version in
* subdir2/jarFile2/zipFile2 will have a single method named #version2();
* and the presence of a single attribute, similarly named.
*/
public class ClasspathTestTool {
public String name;
public File workingDirectory;
public File subdir1;
public File subdir2;
public File jarFile1;
public File jarFile2;
public File zipFile1;
public File zipFile2;
public static final String PKG_QUALIFIER_1 = "foo";
public static final String PKG_QUALIFIER_2 = "bar";
public static final String PKG_NAME = PKG_QUALIFIER_1 + "." + PKG_QUALIFIER_2;
public static final String SHORT_TEST_CLASS_NAME = ClassTools.shortNameFor(ClasspathTestTool.class) + "TestClass";
public static final String TEST_CLASS_NAME = PKG_NAME + "." + SHORT_TEST_CLASS_NAME;
public static final String VERSION_MEMBER_PREFIX = "version";
public ClasspathTestTool(String name) {
super();
this.name = name;
}
public void setUp() throws Exception {
this.workingDirectory = this.buildWorkingDirectory(this.name);
}
public void tearDown() throws Exception {
FileTools.deleteDirectory(this.workingDirectory);
}
/**
* build a temporary directory with two different versions
* of a Java source file; then compile them and package
* them into jars and zips
*/
private File buildWorkingDirectory(String dirName) throws Exception {
File dir = FileTools.emptyTemporaryDirectory(dirName);
this.subdir1 = this.buildSourceSubdir(dir, 1);
this.jarFile1 = buildJarFile(this.subdir1, 1);
this.zipFile1 = buildZipFile(this.subdir1, 1);
this.subdir2 = this.buildSourceSubdir(dir, 2);
this.jarFile2 = buildJarFile(this.subdir2, 2);
this.zipFile2 = buildZipFile(this.subdir2, 2);
return dir;
}
/**
* build a subdirectory "foo\bar" with the .java and .class
* files for the class ClassPathEntryTestsTestClass
*/
private File buildSourceSubdir(File parentDir, int version) throws Exception {
File subdir = new File(parentDir, "subdir" + version);
subdir.mkdir();
File fooDir = new File(subdir, PKG_QUALIFIER_1);
fooDir.mkdir();
File barDir = new File(fooDir, PKG_QUALIFIER_2);
barDir.mkdir();
File sourceFile = new File(barDir, SHORT_TEST_CLASS_NAME + ".java");
IndentingPrintWriter pw = new IndentingPrintWriter(new FileWriter(sourceFile));
this.printSourceOn(pw, version);
pw.close();
this.compile(sourceFile);
return subdir;
}
private void printSourceOn(IndentingPrintWriter pw, int version) {
printSourceOn(pw, version, this.buildSourceExtender());
}
/**
* subclasses can override this method if they want to add
* to the source code generated for testing
*/
protected SourceExtender buildSourceExtender() {
return buildNullSourceExtender();
}
/**
* build an archive of the specified subdirectory
*/
private File buildJarFile(File subdir, int version) throws Exception {
String jarFileName = subdir.getParentFile().getName() + version + ".jar";
File jarFile = new File(subdir.getParentFile(), jarFileName);
this.jar(jarFile, subdir);
return jarFile;
}
/**
* build a zip of the specified subdirectory
*/
private File buildZipFile(File subdir, int version) throws Exception {
String zipFileName = subdir.getParentFile().getName() + version + ".zip";
File zipFile = new File(subdir.getParentFile(), zipFileName);
this.zip(zipFile, subdir);
return zipFile;
}
private void compile(File sourceFile) throws IOException, InterruptedException {
JavaTools.compile(sourceFile);
}
private void jar(File jarFile, File directory) throws IOException, InterruptedException {
JavaTools.jar(jarFile, directory);
}
private void zip(File zipFile, File directory) throws IOException, InterruptedException {
JavaTools.zip(zipFile, directory);
}
public static SourceExtender buildNullSourceExtender() {
return new SourceExtender() {
public void extendSourceOn(IndentingPrintWriter pw, int version) {
// do nothing
}
};
}
private static void printSourceOn(IndentingPrintWriter pw, int version, SourceExtender extender) {
pw.print("package ");
pw.print(PKG_NAME);
pw.println(';');
pw.print("public class ");
pw.print(SHORT_TEST_CLASS_NAME);
pw.println(" {");
pw.indent();
pw.print("public java.lang.String ");
pw.print(VERSION_MEMBER_PREFIX);
pw.print(version);
pw.println(" = \"version" + version + "\";");
pw.print("public void ");
pw.print(VERSION_MEMBER_PREFIX);
pw.print(version);
pw.println("() {");
pw.indent();
pw.println("System.out.println(\"version" + version + "\");");
pw.undent();
pw.println("}");
extender.extendSourceOn(pw, version);
pw.undent();
pw.println("}");
}
/**
* use this method to check the formatting of the source file
*/
public static String buildSource(int version) {
StringWriter sw = new StringWriter(200);
IndentingPrintWriter pw = new IndentingPrintWriter(sw);
pw.println();
pw.println();
printSourceOn(pw, version, buildNullSourceExtender());
pw.println();
return sw.toString();
}
public static interface SourceExtender {
void extendSourceOn(IndentingPrintWriter pw, int version);
}
}