import java.io.*;
import java.net.*;
import java.util.*;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
/**
* Ant Task for downloading the latest JRE or JDK from Oracle.
*/
public class Downloader extends Task {
static final String COOKIE =
"oraclelicense=accept-securebackup-cookie";
private int version; // Java 8
private int update; // Update 131
private int build; // Build 11
// https://gist.github.com/P7h/9741922
// http://stackoverflow.com/q/10268583
private String hash; // d54c1d3a095b4ff2b6607d096fa80163
private boolean jdk; // false if JRE
private String flavor;
private String path; // target path
public Downloader() { }
public void setVersion(int version) {
this.version = version;
}
public void setUpdate(int update) {
this.update = update;
}
public void setBuild(int build) {
this.build = build;
}
public void setHash(String hash) {
this.hash = hash;
}
public void setJDK(boolean jdk) {
this.jdk = jdk;
}
public void setFlavor(String flavor) {
this.flavor = flavor;
}
public void setPath(String path) {
this.path = path;
}
public void execute() throws BuildException {
if (version == 0) {
throw new BuildException("Version (i.e. 7 or 8) must be set");
}
if (build == 0) {
throw new BuildException("Build number must be set");
}
if (flavor == null) {
throw new BuildException("You've gotta choose a flavor (macosx-x64.dmg, windows-x64.exe...)");
}
if (update >= 121 && hash == null) {
throw new BuildException("Starting with 8u121, a hash is required, see https://gist.github.com/P7h/9741922");
}
//download(path, jdk, platform, bits, version, update, build);
try {
download();
} catch (IOException e) {
throw new BuildException(e);
}
}
void download() throws IOException {
String filename = (jdk ? "jdk" : "jre") +
(update == 0 ?
String.format("-%d-%s", version, flavor) :
String.format("-%du%d-%s", version, update, flavor));
if (path == null) {
path = filename;
}
String url = "http://download.oracle.com/otn-pub/java/jdk/" +
(update == 0 ?
String.format("%d-b%02d/", version, build) :
String.format("%du%d-b%02d/", version, update, build));
// URL format changed starting with 8u121
if (update >= 121) {
url += hash + "/";
}
// Finally, add the filename to the end
url += filename;
HttpURLConnection conn =
(HttpURLConnection) new URL(url).openConnection();
conn.setRequestProperty("Cookie", COOKIE);
//printHeaders(conn);
//conn.connect();
while (conn.getResponseCode() == 302) {
Map<String, List<String>> headers = conn.getHeaderFields();
List<String> location = headers.get("Location");
if (location.size() == 1) {
url = location.get(0);
System.out.println("Redirecting to " + url);
} else {
throw new BuildException("Got " + location.size() + " locations.");
}
List<String> cookies = headers.get("Set-Cookie");
conn = (HttpURLConnection) new URL(url).openConnection();
if (cookies != null) {
for (String cookie : cookies) {
conn.setRequestProperty("Cookie", cookie);
}
}
conn.setRequestProperty("Cookie", COOKIE);
conn.connect();
}
if (conn.getResponseCode() == 200) {
InputStream input = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(input);
File outputFile = new File(path); //folder, filename);
System.out.format("Downloading %s from %s%n", outputFile.getAbsolutePath(), url);
// Write to a temp file so that we don't have an incomplete download
// masquerading as a good archive.
File tempFile = File.createTempFile("download", "", outputFile.getParentFile());
BufferedOutputStream output =
new BufferedOutputStream(new FileOutputStream(tempFile));
int c = bis.read();
while (c != -1) {
output.write(c);
c = bis.read();
}
bis.close();
output.flush();
output.close();
if (outputFile.exists()) {
if (!outputFile.delete()) {
throw new BuildException("Could not delete old download: " + outputFile.getAbsolutePath());
}
}
if (!tempFile.renameTo(outputFile)) {
throw new BuildException(String.format("Could not rename %s to %s",
tempFile.getAbsolutePath(),
outputFile.getAbsolutePath()));
}
} else {
printHeaders(conn);
System.exit(1);
}
}
static void printHeaders(URLConnection conn) {
Map<String, List<String>> headers = conn.getHeaderFields();
Set<Map.Entry<String, List<String>>> entrySet = headers.entrySet();
for (Map.Entry<String, List<String>> entry : entrySet) {
String headerName = entry.getKey();
System.out.println("Header Name:" + headerName);
List<String> headerValues = entry.getValue();
for (String value : headerValues) {
System.out.print("Header value:" + value);
}
System.out.println();
System.out.println();
}
}
}