blob: c07dee08496787a02fbd218f489b218744b8ca7b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.nbbuild;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.StringTokenizer;
import java.util.zip.ZipFile;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Java;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
/** Invokes signature tests.
* @author Michal Zlamal
*/
public class Sigtest extends Task {
File fileName;
Path classpath;
String packages;
ActionType action;
File sigtestJar;
File report;
boolean failOnError = true;
String version;
private String release;
public void setFileName(File f) {
fileName = f;
}
public void setReport(File f) {
report = f;
}
public void setPackages(String s) {
packages = s;
}
public void setAction(ActionType s) {
action = s;
}
public void setRelease(String r) {
release = r;
}
public void setClasspath(Path p) {
if (classpath == null) {
classpath = p;
} else {
classpath.append(p);
}
}
public Path createClasspath () {
if (classpath == null) {
classpath = new Path(getProject());
}
return classpath.createPath();
}
public void setClasspathRef(Reference r) {
createClasspath().setRefid(r);
}
public void setVersion(String v) {
version = v;
}
public void setSigtestJar(File f) {
sigtestJar = f;
}
public void setFailOnError(boolean b) {
failOnError = b;
}
@Override
public void execute() throws BuildException {
if (fileName == null) {
throw new BuildException("FileName has to filed", getLocation());
}
if (packages == null) {
throw new BuildException("Packages has to filed", getLocation());
}
if (action == null) {
throw new BuildException("Action has to filed", getLocation());
}
if (classpath == null) {
throw new BuildException("Classpath has to filed", getLocation());
}
if (sigtestJar == null) {
throw new BuildException("SigtestJar has to filed", getLocation());
}
if (packages.equals("-")) {
log("No public packages, skipping");
return;
}
if (!sigtestJar.exists()) {
throw new BuildException("Cannot find JAR with testing infrastructure: " + sigtestJar);
}
try {
ZipFile zip = new ZipFile(sigtestJar);
String c2 = "org/netbeans/apitest/Sigtest.class";
if (zip.getEntry(c2) != null) {
log("Using " + c2 + " found in " + sigtestJar, Project.MSG_DEBUG);
zip.close();
try {
apitest();
} catch (Exception ex) {
throw new BuildException(ex);
}
return;
}
String c1 = "com/sun/tdk/signaturetest/Setup.class";
if (zip.getEntry(c1) != null) {
log("Using " + c1 + " found in " + sigtestJar, Project.MSG_DEBUG);
zip.close();
tdk();
return;
}
zip.close();
throw new BuildException("Cannot find " + c1 + " nor " + c2 + " in " + sigtestJar);
} catch (IOException ex) {
throw new BuildException(ex);
}
}
private void tdk() {
Java java = new Java();
java.setProject(getProject());
Path sigtestPath = new Path(getProject());
sigtestPath.setLocation(sigtestJar);
java.setClasspath(sigtestPath);
String a = null;
if ("strictcheck".equals(action.getValue())) { // NOI18N
a = "SignatureTest"; // NOI18N
}
if ("generate".equals(action.getValue())) { // NOI18N
a = "Setup"; // NOI18N
}
if (a == null) {
throw new BuildException("Unsupported action " + action + " use: strictcheck or generate");
}
java.setClassname("com.sun.tdk.signaturetest." + a);
Commandline.Argument arg;
arg = java.createArg();
arg.setValue("-FileName");
arg = java.createArg();
arg.setValue(fileName.getAbsolutePath());
arg = java.createArg();
arg.setValue("-Classpath");
arg = java.createArg();
{
Path extracp = new Path(getProject());
extracp.add(classpath);
FileSet jdk = new FileSet();
jdk.setDir(new File(new File(System.getProperty("java.home")), "lib"));
jdk.setIncludes("*.jar");
extracp.addFileset(jdk);
arg.setPath(extracp);
}
File outputFile = null;
String s = getProject().getProperty("sigtest.output.dir");
if (s != null) {
File dir = getProject().resolveFile(s);
dir.mkdirs();
outputFile = new File(dir, fileName.getName().replace(".sig", "").replace("-", "."));
log(outputFile.toString());
String email = getProject().getProperty("sigtest.mail");
if (email != null) {
try {
try (FileWriter w = new FileWriter(outputFile)) {
w.write("email: ");
w.write(email);
w.write("\n");
}
} catch (IOException ex) {
throw new BuildException(ex);
}
}
java.setAppend(true);
java.setOutput(outputFile);
java.setFork(true);
}
arg = java.createArg();
arg.setLine("-static");
log("Packages: " + packages);
StringTokenizer packagesTokenizer = new StringTokenizer(packages,",");
while (packagesTokenizer.hasMoreTokens()) {
String p = packagesTokenizer.nextToken().trim();
String prefix = "-PackageWithoutSubpackages "; // NOI18N
//Strip the ending ".*"
int idx = p.lastIndexOf(".*");
if (idx > 0) {
p = p.substring(0, idx);
} else {
idx = p.lastIndexOf(".**");
if (idx > 0) {
prefix = "-Package "; // NOI18N
p = p.substring(0, idx);
}
}
arg = java.createArg();
arg.setLine(prefix + p);
}
int returnCode = java.executeJava();
if (returnCode != 95) {
if (failOnError && outputFile == null) {
throw new BuildException("Signature tests return code is wrong (" + returnCode + "), check the messages above. For more info see http://wiki.netbeans.org/wiki/view/SignatureTest", getLocation());
}
else {
log("Signature tests return code is wrong (" + returnCode + "), check the messages above");
}
} else {
if (outputFile != null) {
outputFile.delete();
}
}
}
private <T> void setM(Task task, String name, Class<? extends T> type, T value) throws Exception {
log("Delegating " + name + " value: " + value, Project.MSG_DEBUG);
task.getClass().getMethod(name, type).invoke(task, value);
}
private <T> void setM(Task task, String string, T instance) throws Exception {
setM(task, string, instance.getClass(), instance);
}
private <T> T getM(Task task, String name, Class<T> type) throws Exception {
return type.cast(task.getClass().getMethod(name).invoke(task));
}
private void apitest() throws Exception {
URLClassLoader url = new URLClassLoader(new URL[] { sigtestJar.toURI().toURL() }, Sigtest.class.getClassLoader());
Class<?> clazz = url.loadClass("org.netbeans.apitest.Sigtest");
Task task = (Task) clazz.getConstructor().newInstance();
task.setProject(getProject());
task.setTaskName(getTaskName());
setM(task, "setFailOnError", boolean.class, failOnError);
setM(task, "setFileName", File.class, fileName);
setM(task, "setReport", File.class, report);
setM(task, "setPackages", String.class, packages);
setM(task, "setVersion", String.class, version);
setM(task, "setRelease", String.class, release);
Class<? extends EnumeratedAttribute> actionType = url.loadClass("org.netbeans.apitest.Sigtest$ActionType").asSubclass(EnumeratedAttribute.class);
setM(task, "setAction", EnumeratedAttribute.getInstance(actionType, action.getValue()));
Path path = getM(task, "createClasspath", Path.class);
path.add(classpath);
File outputFile = null;
String s = getProject().getProperty("sigtest.output.dir");
if (s != null) {
File dir = getProject().resolveFile(s);
dir.mkdirs();
outputFile = new File(dir, fileName.getName().replace(".sig", "").replace("-", "."));
log(outputFile.toString());
// java.setOutput(outputFile);
}
task.execute();
if (outputFile != null) {
outputFile.delete();
}
}
public static final class ActionType extends EnumeratedAttribute {
public String[] getValues () {
return new String[] {
"generate",
"check",
"strictcheck",
"binarycheck",
"versioncheck"
};
}
}
}