package jdk.incubator.jpackage.internal;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static jdk.incubator.jpackage.internal.StandardBundlerParam.RESOURCE_DIR;
import jdk.incubator.jpackage.internal.resources.ResourceLocator;
final class OverridableResource {
OverridableResource(String defaultName) {
this.defaultName = defaultName;
}
OverridableResource setSubstitutionData(Map<String, String> v) {
if (v != null) {
substitutionData = new HashMap<>(v);
} else {
substitutionData = null;
}
return this;
}
OverridableResource setCategory(String v) {
category = v;
return this;
}
OverridableResource setResourceDir(Path v) {
resourceDir = v;
return this;
}
OverridableResource setResourceDir(File v) {
return setResourceDir(toPath(v));
}
OverridableResource setPublicName(Path v) {
publicName = v;
return this;
}
OverridableResource setPublicName(String v) {
return setPublicName(Path.of(v));
}
OverridableResource setExternal(Path v) {
externalPath = v;
return this;
}
OverridableResource setExternal(File v) {
return setExternal(toPath(v));
}
void saveToFile(Path dest) throws IOException {
final String printableCategory;
if (category != null) {
printableCategory = String.format("[%s]", category);
} else {
printableCategory = "";
}
if (externalPath != null && externalPath.toFile().exists()) {
Log.verbose(MessageFormat.format(I18N.getString(
"message.using-custom-resource-from-file"),
printableCategory,
externalPath.toAbsolutePath().normalize()));
try (InputStream in = Files.newInputStream(externalPath)) {
processResourceStream(in, dest);
}
return;
}
final Path resourceName = Optional.ofNullable(publicName).orElse(
dest.getFileName());
if (resourceDir != null) {
final Path customResource = resourceDir.resolve(resourceName);
if (customResource.toFile().exists()) {
Log.verbose(MessageFormat.format(I18N.getString(
"message.using-custom-resource"), printableCategory,
resourceDir.normalize().toAbsolutePath().relativize(
customResource.normalize().toAbsolutePath())));
try (InputStream in = Files.newInputStream(customResource)) {
processResourceStream(in, dest);
}
return;
}
}
if (defaultName != null) {
Log.verbose(MessageFormat.format(
I18N.getString("message.using-default-resource"),
defaultName, printableCategory, resourceName));
try (InputStream in = readDefault(defaultName)) {
processResourceStream(in, dest);
}
}
}
void saveToFile(File dest) throws IOException {
saveToFile(dest.toPath());
}
static InputStream readDefault(String resourceName) {
return ResourceLocator.class.getResourceAsStream(resourceName);
}
static OverridableResource createResource(String defaultName,
Map<String, ? super Object> params) {
return new OverridableResource(defaultName).setResourceDir(
RESOURCE_DIR.fetchFrom(params));
}
private static List<String> substitute(Stream<String> lines,
Map<String, String> substitutionData) {
return lines.map(line -> {
String result = line;
for (var entry : substitutionData.entrySet()) {
result = result.replace(entry.getKey(), Optional.ofNullable(
entry.getValue()).orElse(""));
}
return result;
}).collect(Collectors.toList());
}
private static Path toPath(File v) {
if (v != null) {
return v.toPath();
}
return null;
}
private void processResourceStream(InputStream rawResource, Path dest)