Skip to content
16 changes: 11 additions & 5 deletions ant/project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,22 @@ javac.target=11
java.download=https://bell-sw.com/pages/downloads/#/java-11-lts

# Java vendor to bundle into software (e.g. "*BellSoft|Adoptium|Microsoft|Amazon|IBM")
jlink.java.vendor="BellSoft"
jlink.java.vendor=BellSoft
# Java vendor to bundle into software (e.g. "11.0.17+7")
jlink.java.version="11.0.30+9"
jlink.java.version=11.0.30+9
# Java garbage collector flavor to use (e.g. "hotspot|openj9")
jlink.java.gc="hotspot"
jlink.java.gc=hotspot
# Java garbage collector version to use (e.g. openj9: "0.35.0", zulu: "11.62.17")
jlink.java.gc.version="gc-ver-is-empty"
jlink.java.gc.version=gc-ver-is-empty
# Bundle a locally built copy of Java instead
# jlink.java.target=/path/to/custom/jdk-x.x.x

# Fetch a copy of the JDK from BellSoft's support portal
jlink.api.enabled=false
jlink.api.url=https://api.bell-sw.com/v1/liberica/releases
# jlink.api.token=
# jlink.api.exact=false <-- false: use latest found version; true: match jlink.java.version exactly

# Skip bundling the java runtime
# jre.skip=true

Expand All @@ -60,4 +66,4 @@ provision.dir=${dist.dir}/provision
java.mask.tray=true

# Workaround to delay expansion of $${foo} (e.g. shell scripts)
dollar=$
dollar=$
4 changes: 4 additions & 0 deletions build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,10 @@

<echo level="info">Downloading and bundling the jre for ${target.os}</echo>
<java jar="${dist.dir}/${project.filename}.jar" fork="true" failonerror="true">
<syspropertyset>
<!-- Expose all jlink properties to the environment -->
<propertyref prefix="jlink."/>
</syspropertyset>
<arg value="jlink"/>
<arg line="--platform ${target.os}"/>
<arg line="--arch ${target.arch}"/>
Expand Down
99 changes: 71 additions & 28 deletions src/qz/build/Fetcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Map;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

Expand All @@ -23,9 +29,10 @@ public class Fetcher {
public enum Format {
ZIP(".zip"),
TARBALL(".tar.gz"),
JSON(".json"),
UNKNOWN(null);

String suffix;
final String suffix;
Format(String suffix) {
this.suffix = suffix;
}
Expand All @@ -35,8 +42,12 @@ public String getSuffix() {
}

public static Format parse(String url) {
if(url.contains("?")) {
url = url.substring(0, url.lastIndexOf("?"));
log.debug("Stripped parameters from URL to help detecting file type: '{}'", url);
}
for(Format format : Format.values()) {
if (url.endsWith(format.getSuffix())) {
if (format.getSuffix() != null && url.endsWith(format.getSuffix())) {
return format;
}
}
Expand All @@ -50,55 +61,87 @@ public static void main(String ... args) throws IOException {
new Fetcher("jlink/qz-tray-src_x.x.x", "https://github.com/qzind/tray/archive/master.tar.gz").fetch().uncompress();
}

String resourceName;
String url;
Format format;
Path rootDir;
File tempArchive;
final String resourceName;
final String url;
final Format format;
final Path rootDir;
final Map<String, String> headers;

File tempFile;
File tempExtracted;
File extracted;

public Fetcher(String resourceName, String url) {
this.url = url;
this.resourceName = resourceName;
this.format = Format.parse(url);
// Try to calculate out/
this.rootDir = SystemUtilities.getJarParentPath().getParent();
}

@SuppressWarnings("unused")
public Fetcher(String resourceName, String url, Format format, String rootDir) {
public Fetcher(String resourceName, String url, Format format, Path rootDir, Map<String, String> headers) {
this.resourceName = resourceName;
this.url = url;
this.format = format;
this.rootDir = Paths.get(rootDir);
this.rootDir = rootDir;
this.headers = headers;
}

public Fetcher(String resourceName, String url, Format format, Map<String, String> headers) {
this(resourceName, url, format, SystemUtilities.getJarParentPath().getParent(), headers);
}

public Fetcher(String resourceName, String url, Map<String, String> headers) {
this(resourceName, url, Format.parse(url), headers);
}

public Fetcher(String resourceName, String url) {
this(resourceName, url, null);
}

public Fetcher fetch() throws IOException {
extracted = new File(rootDir.toString(), resourceName);
if(extracted.isDirectory() && extracted.exists()) {
if(extracted.isDirectory() && extracted.exists() && Objects.requireNonNull(extracted.listFiles()).length > 0) {
log.info("Resource '{}' from [{}] has already been downloaded and extracted. Using: [{}]", resourceName, url, extracted);
} else {
tempExtracted = new File(rootDir.toString(), resourceName + "~tmp");
if(tempExtracted.exists()) {
FileUtils.deleteDirectory(tempExtracted);
}
// temp directory to thwart partial extraction
tempExtracted.mkdirs();
tempArchive = File.createTempFile(resourceName, ".zip");
log.info("Fetching '{}' from [{}] and saving to [{}]", resourceName, url, tempArchive);
FileUtils.copyURLToFile(new URL(url), tempArchive);
if(tempExtracted.mkdirs()) {
tempFile = File.createTempFile(resourceName, format == Format.JSON ? ".json" : ".zip");
log.info("Fetching '{}' from [{}] and saving to [{}]", resourceName, url, tempFile);
copyUrlToFile(new URL(url), tempFile.toPath(), headers);
} else {
throw new IOException(String.format("Unable to create directory for jdk extraction '%s'", tempExtracted));
}
}
return this;
}

public void copyUrlToFile(URL url, Path targetPath, Map<String, String> headers) throws IOException {
HttpRequest.Builder requestBuilder;
try {
requestBuilder = HttpRequest.newBuilder().uri(url.toURI()).GET();
if(headers != null) {
headers.forEach(requestBuilder::header);
}
HttpRequest request = requestBuilder.build();

// stream response to file
HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofFile(
Comment thread
Vzor- marked this conversation as resolved.
targetPath,
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.WRITE
));
} catch(URISyntaxException e) {
throw new IOException(String.format("Invalid URI specified '%s'", url), e);
} catch(InterruptedException e) {
throw new IOException(String.format("Request interrupted '%s'", url), e);
}
}

public String uncompress() throws IOException {
if(tempArchive != null) {
log.info("Unzipping '{}' from [{}] to [{}]", resourceName, tempArchive, tempExtracted);
if(tempFile != null) {
log.info("Unzipping '{}' from [{}] to [{}]", resourceName, tempFile, tempExtracted);
if(format == Format.ZIP) {
unzip(tempArchive.getAbsolutePath(), tempExtracted);
unzip(tempFile.getAbsolutePath(), tempExtracted);
} else {
untar(tempArchive.getAbsolutePath(), tempExtracted);
untar(tempFile.getAbsolutePath(), tempExtracted);
}
log.info("Moving [{}] to [{}]", tempExtracted, extracted);
tempExtracted.renameTo(extracted);
Expand Down
Loading
Loading