WebInstall.java
/* *******************************************************************
* Copyright (c) 1999-2000 Xerox Corporation.
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v 2.0
* which accompanies this distribution and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
*
* Contributors:
* Xerox/PARC initial implementation
* ******************************************************************/
package org.aspectj.testing.util;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
/**
* Install programmatically using http URL.
* (Very strange that java tool classpath does not accept http URL's.)
*
* Example:
* <p><code>java -classpath aj-testing.jar org.aspectj.testing.util.WebInstall
* https://aspectj.org/download/distribution/aspectj10-tools.jar -text
* install.properties</code>
*
* <p>You can omit the <code>-text install.properties</code> if there is
* a file called "install.properties" in the current directory.
*
* <p>The properties file must define the properties
* <code>output.dir</code> and <code>context.javaPath</code>
* in properties- and platform specifie ways.
* For property values, a backslash must be escaped with another backslash,
* and directory separators should be valid. E.g., on Windows:
* <pre>output.dir=c:\\output\\dir
* context.javaPath=c:\\apps\\jdk1.3.1</pre>
*
* For an installer to complete programmatically,
* the output directory must be empty of colliding files.
* This will fail with a stack trace if anything goes wrong, except for
* simple input errors.
*
* <p>You may also use this as a driver for the known installers
* by specifying the following options (-baseurl must be first):<pre>
* -baseurl {baseurl}
* -version {version}
* -context.javaPath {path to JDK} (properties form)
* -output.dir {path to outDir} (properties form, including trailing /)
* -outdir {path to outDir} (actual form) </pre>
* such that URL=
* <code>{baseurl}<packagePrefix>{version}<packageSuffix>.jar</code>
* and paths to context.javaPath and output.dir are specified in
* properties-compliant format
*
* @see ant script test-product.xml for example of installing from files
* which can be driven from the command-line.
*/
public class WebInstall {
private static final String EOL = "\n"; // todo where is this defined?
public static final String SYNTAX
= "java WebInstall url {args}" + EOL
+ " url - to installer" + EOL
+ " args - normally -text install.properties" + EOL
+ " (if n/a, use install.properties)" + EOL;
/** default arguments assume file <code>install.properties</code>
* is in current directory */
private static final String[] ARGS = new String[]
{ "-text", "install.properties" };
/** @param args the String[] <code>{ "<url>" {, "-text", "<propsPath>" }</code> */
public static void main(String[] args) throws Exception {
if ((null != args) && (args.length > 0)
&& ("-baseurl".equals(args[0]))) {
driver(args);
} else {
try {
new WebInstall().install(args);
} catch (Throwable t) {
System.err.println("Error installing args ");
for (int i = 0; i < args.length; i++) {
System.err.println(" " + i + ": " + args[i]);
}
t.printStackTrace(System.err);
}
}
}
/** known .jar packages {(prefix, suffix}...} */
protected static String[] packages = new String[]
{ "aspectj-tools-", ""
, "aspectj-docs-", ""
};
/**
* Drive install of all jar-based installers.
* @param args the String[] containing<pre>
* -baseurl {baseurl}
* -version {version}
* -context.javaPath {path to JDK} (properties form)
* -output.dir {path to outDir} (properties form, including trailing /)
* -outdir {path to outDir} (actual form) </pre>
* such that URL=
* <code>{baseurl}<packagePrefix>{version}<packageSuffix>.jar</code>
* and paths to context.javaPath and output.dir are specified in
* properties-compliant format
*/
protected static void driver(String[] args) throws Exception {
String baseurl = null;
String version = null;
String outputDir = null;
File outdir = null;
String jdk = null;
for (int i = 0; i < args.length; i++) {
if ("-baseurl".equals(args[i])) {
baseurl = args[++i];
} else if ("-version".equals(args[i])) {
version = args[++i];
} else if ("-context.javaPath".equals(args[i])) {
jdk = args[++i];
} else if ("-output.dir".equals(args[i])) {
outputDir=args[++i];
} else if ("-outdir".equals(args[i])) {
outdir = new File(args[++i]).getCanonicalFile();
if (!outdir.isDirectory()) {
outdir.mkdir();
}
}
}
final File props = File.createTempFile("WebInstall", null);
final String[] ARGS = new String [] {null, "-text", props.getCanonicalPath()};
for (int i = 0; i < packages.length; i++) {
String name = packages[i++] + version + packages[i];
File outDir = new File(outdir, name);
FileWriter fw = null;
try {
if (!outDir.isDirectory()) {
outDir.mkdir();
}
fw = new FileWriter(props);
fw.write("output.dir=" + outputDir + name + "\n");
fw.write("context.javaPath=" + jdk + "\n");
fw.close();
fw = null;
ARGS[0] = baseurl + name + ".jar";
main(ARGS);
} finally {
try { if (null != fw) fw.close(); }
catch (java.io.IOException e) {} // ignore
}
}
if (props.exists()) props.delete();
} // driver
private static boolean printError(String err) {
if (null != err) System.err.println(err);
System.err.println(SYNTAX);
return (null != err);
}
/**
* Create a classloader using the first argument (presumed to be URL for classloader),
* construct the installer, and invoke it using remaining arguments (or default args).
*/
protected void install(String[] args) throws Exception {
if ((null == args) || (args.length < 1)
|| (null == args[0]) || (1 > args[0].length())) {
if (printError("expecting installer URL")) return;
}
URL[] urls = new URL[] { new URL(args[0]) };
//System.err.println("before: " + render(args));
args = getArgs(args);
//System.err.println("after: " + render(args));
URLClassLoader cl = new URLClassLoader(urls);
Class c = cl.loadClass("$installer$.org.aspectj.Main"); // todo: dependency on class name
Method ms = c.getMethod("main", new Class[]{String[].class});
ms.invoke(null, new Object[] { args });
}
public static final String render(String[] args) {
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < args.length; i++) {
if (0 < i) sb.append(", ");
sb.append("" + args[i]);
}
sb.append("]");
return sb.toString();
}
/** @return args less args[0] or default args if less than 3 arguments */
protected String[] getArgs(String[] args) {
if ((null == args) || (args.length < 3)) {
return ARGS;
} else {
String[] result = new String[args.length-1];
System.arraycopy(args, 1, result, 0, result.length);
return result;
}
}
}