mirror of
https://github.com/packwiz/packwiz-installer.git
synced 2025-04-19 13:06:30 +02:00
Thanks IntelliJ. ThintelliJ.
This commit is contained in:
parent
794b817eff
commit
bd95bc15ad
2
.idea/.gitignore
generated
vendored
Normal file
2
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Default ignored files
|
||||
/workspace.xml
|
18
.idea/gradle.xml
generated
Normal file
18
.idea/gradle.xml
generated
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="11" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="useQualifiedModuleNames" value="true" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
5
.idea/misc.xml
generated
Normal file
5
.idea/misc.xml
generated
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK" />
|
||||
</project>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,5 @@
|
||||
package link.infra.packwiz.installer;
|
||||
|
||||
class DownloadTask {
|
||||
|
||||
}
|
@ -1,22 +1,14 @@
|
||||
package link.infra.packwiz.installer;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.DefaultParser;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
|
||||
import link.infra.packwiz.installer.ui.CLIHandler;
|
||||
import link.infra.packwiz.installer.ui.IUserInterface;
|
||||
import link.infra.packwiz.installer.ui.InstallWindow;
|
||||
import org.apache.commons.cli.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
public class Main {
|
||||
|
||||
@ -28,13 +20,11 @@ public class Main {
|
||||
this.startup(args);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
JOptionPane.showMessageDialog(null,
|
||||
"A fatal error occurred: \n" + e.getClass().getCanonicalName() + ": " + e.getMessage(),
|
||||
"packwiz-installer", JOptionPane.ERROR_MESSAGE);
|
||||
System.exit(1);
|
||||
}
|
||||
EventQueue.invokeLater(() -> {
|
||||
JOptionPane.showMessageDialog(null,
|
||||
"A fatal error occurred: \n" + e.getClass().getCanonicalName() + ": " + e.getMessage(),
|
||||
"packwiz-installer", JOptionPane.ERROR_MESSAGE);
|
||||
System.exit(1);
|
||||
});
|
||||
// In case the eventqueue is broken, exit after 1 minute
|
||||
try {
|
||||
@ -127,14 +117,12 @@ public class Main {
|
||||
} catch (Exception e) {
|
||||
// TODO: better error message?
|
||||
ui.handleExceptionAndExit(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
// TODO: better error message?
|
||||
ui.handleExceptionAndExit(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,8 @@
|
||||
package link.infra.packwiz.installer;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
public class RequiresBootstrap {
|
||||
|
||||
public static void main(String[] args) {
|
||||
@ -15,10 +13,10 @@ public class RequiresBootstrap {
|
||||
if (Arrays.stream(args).map(str -> {
|
||||
if (str == null) return "";
|
||||
if (str.startsWith("--")) {
|
||||
return str.substring(2, str.length());
|
||||
return str.substring(2);
|
||||
}
|
||||
if (str.startsWith("-")) {
|
||||
return str.substring(1, str.length());
|
||||
return str.substring(1);
|
||||
}
|
||||
return "";
|
||||
}).anyMatch(str -> str.equals("g") || str.equals("no-gui"))) {
|
||||
|
@ -1,36 +1,11 @@
|
||||
package link.infra.packwiz.installer;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletionService;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorCompletionService;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonIOException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.moandjiezana.toml.Toml;
|
||||
|
||||
import link.infra.packwiz.installer.metadata.IndexFile;
|
||||
import link.infra.packwiz.installer.metadata.ManifestFile;
|
||||
import link.infra.packwiz.installer.metadata.PackFile;
|
||||
@ -44,6 +19,16 @@ import okio.Buffer;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class UpdateManager {
|
||||
|
||||
public final Options opts;
|
||||
@ -84,8 +69,8 @@ public class UpdateManager {
|
||||
return true;
|
||||
}
|
||||
if (this.depSides != null) {
|
||||
for (int i = 0; i < this.depSides.length; i++) {
|
||||
if (this.depSides[i].equals(tSide)) {
|
||||
for (Side depSide : this.depSides) {
|
||||
if (depSide.equals(tSide)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -96,7 +81,7 @@ public class UpdateManager {
|
||||
public static Side from(String name) {
|
||||
String lowerName = name.toLowerCase();
|
||||
for (Side side : Side.values()) {
|
||||
if (side.sideName == lowerName) {
|
||||
if (side.sideName.equals(lowerName)) {
|
||||
return side;
|
||||
}
|
||||
}
|
||||
@ -150,9 +135,7 @@ public class UpdateManager {
|
||||
|
||||
List<URI> invalidatedUris = new ArrayList<>();
|
||||
if (manifest.cachedFiles != null) {
|
||||
Iterator<Map.Entry<URI, ManifestFile.File>> it = manifest.cachedFiles.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<URI, ManifestFile.File> entry = it.next();
|
||||
for (Map.Entry<URI, ManifestFile.File> entry : manifest.cachedFiles.entrySet()) {
|
||||
if (entry.getValue().cachedLocation != null) {
|
||||
if (!Files.exists(Paths.get(opts.packFolder, entry.getValue().cachedLocation))) {
|
||||
URI fileUri = entry.getKey();
|
||||
@ -225,7 +208,7 @@ public class UpdateManager {
|
||||
}
|
||||
|
||||
if (manifest.cachedFiles == null) {
|
||||
manifest.cachedFiles = new HashMap<URI, ManifestFile.File>();
|
||||
manifest.cachedFiles = new HashMap<>();
|
||||
}
|
||||
|
||||
ui.submitProgress(new InstallProgress("Checking local files..."));
|
||||
@ -233,7 +216,7 @@ public class UpdateManager {
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<URI, ManifestFile.File> entry = it.next();
|
||||
if (entry.getValue().cachedLocation != null) {
|
||||
if (!indexFile.files.stream().anyMatch(f -> f.file.equals(entry.getKey()))) {
|
||||
if (indexFile.files.stream().noneMatch(f -> f.file.equals(entry.getKey()))) {
|
||||
// File has been removed from the index
|
||||
try {
|
||||
Files.deleteIfExists(Paths.get(opts.packFolder, entry.getValue().cachedLocation));
|
||||
@ -248,12 +231,11 @@ public class UpdateManager {
|
||||
ui.submitProgress(new InstallProgress("Comparing new files..."));
|
||||
|
||||
// TODO: progress bar
|
||||
ConcurrentLinkedQueue<Exception> exceptionQueue = new ConcurrentLinkedQueue<Exception>();
|
||||
List<IndexFile.File> newFiles = indexFile.files.stream().map(f -> {
|
||||
ConcurrentLinkedQueue<Exception> exceptionQueue = new ConcurrentLinkedQueue<>();
|
||||
List<IndexFile.File> newFiles = indexFile.files.stream().peek(f -> {
|
||||
if (f.hashFormat == null || f.hashFormat.length() == 0) {
|
||||
f.hashFormat = indexFile.hashFormat;
|
||||
}
|
||||
return f;
|
||||
}).filter(f -> {
|
||||
if (invalidatedUris.contains(f.file)) {
|
||||
return true;
|
||||
@ -267,13 +249,12 @@ public class UpdateManager {
|
||||
return false;
|
||||
}
|
||||
return cachedFile == null || !newHash.equals(cachedFile.hash);
|
||||
}).parallel().map(f -> {
|
||||
}).parallel().peek(f -> {
|
||||
try {
|
||||
f.downloadMeta(indexFile, indexUri);
|
||||
} catch (Exception e) {
|
||||
exceptionQueue.add(e);
|
||||
}
|
||||
return f;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
for (Exception e : exceptionQueue) {
|
||||
@ -284,81 +265,78 @@ public class UpdateManager {
|
||||
// TODO: present options
|
||||
// TODO: all options should be presented, not just new files!!!!!!!
|
||||
// and options should be readded to newFiles after option -> true
|
||||
newFiles.stream().filter(f -> f.linkedFile != null).filter(f -> f.linkedFile.option != null).map(f -> {
|
||||
return "option: " + (f.linkedFile.option.description == null ? "null" : f.linkedFile.option.description);
|
||||
}).forEachOrdered(desc -> {
|
||||
newFiles.stream().filter(f -> f.linkedFile != null).filter(f -> f.linkedFile.option != null).map(f ->
|
||||
"option: " + (f.linkedFile.option.description == null ? "null" : f.linkedFile.option.description)
|
||||
).forEachOrdered(desc -> {
|
||||
System.out.println(desc);
|
||||
});
|
||||
|
||||
// TODO: different thread pool type?
|
||||
ExecutorService threadPool = Executors.newFixedThreadPool(10);
|
||||
CompletionService<DownloadCompletion> completionService = new ExecutorCompletionService<DownloadCompletion>(
|
||||
threadPool);
|
||||
CompletionService<DownloadCompletion> completionService = new ExecutorCompletionService<>(threadPool);
|
||||
|
||||
for (IndexFile.File f : newFiles) {
|
||||
ManifestFile.File cachedFile = manifest.cachedFiles.get(f.file);
|
||||
completionService.submit(new Callable<DownloadCompletion>() {
|
||||
public DownloadCompletion call() {
|
||||
DownloadCompletion dc = new DownloadCompletion();
|
||||
dc.file = f;
|
||||
completionService.submit(() -> {
|
||||
DownloadCompletion dc = new DownloadCompletion();
|
||||
dc.file = f;
|
||||
|
||||
if (cachedFile != null && cachedFile.linkedFileHash != null && f.linkedFile != null) {
|
||||
try {
|
||||
if (cachedFile.linkedFileHash.equals(f.linkedFile.getHash())) {
|
||||
// Do nothing, the file didn't change
|
||||
// TODO: but if the hash of the metafile changed, what did change?????
|
||||
// should this be checked somehow??
|
||||
return dc;
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
Path destPath = Paths.get(opts.packFolder, f.getDestURI().toString());
|
||||
|
||||
// Don't update files marked with preserve if they already exist on disk
|
||||
if (f.preserve) {
|
||||
if (Files.exists(destPath)) {
|
||||
if (cachedFile != null && cachedFile.linkedFileHash != null && f.linkedFile != null) {
|
||||
try {
|
||||
if (cachedFile.linkedFileHash.equals(f.linkedFile.getHash())) {
|
||||
// Do nothing, the file didn't change
|
||||
// TODO: but if the hash of the metafile changed, what did change?????
|
||||
// should this be checked somehow??
|
||||
return dc;
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
try {
|
||||
Hash hash;
|
||||
String fileHashFormat;
|
||||
if (f.linkedFile != null) {
|
||||
hash = f.linkedFile.getHash();
|
||||
fileHashFormat = f.linkedFile.download.hashFormat;
|
||||
} else {
|
||||
hash = f.getHash();
|
||||
fileHashFormat = f.hashFormat;
|
||||
}
|
||||
Path destPath = Paths.get(opts.packFolder, f.getDestURI().toString());
|
||||
|
||||
Source src = f.getSource(indexUri);
|
||||
GeneralHashingSource fileSource = HashUtils.getHasher(fileHashFormat).getHashingSource(src);
|
||||
Buffer data = new Buffer();
|
||||
Okio.buffer(fileSource).readAll(data);
|
||||
|
||||
if (fileSource.hashIsEqual(hash)) {
|
||||
Files.createDirectories(destPath.getParent());
|
||||
Files.copy(data.inputStream(), destPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
} else {
|
||||
System.out.println("Invalid hash for " + f.getDestURI().toString());
|
||||
System.out.println("Calculated: " + fileSource.getHash());
|
||||
System.out.println("Expected: " + hash);
|
||||
dc.err = new Exception("Hash invalid!");
|
||||
}
|
||||
|
||||
if (cachedFile != null && !destPath.equals(Paths.get(opts.packFolder, cachedFile.cachedLocation))) {
|
||||
// Delete old file if location changes
|
||||
Files.delete(Paths.get(opts.packFolder, cachedFile.cachedLocation));
|
||||
}
|
||||
|
||||
return dc;
|
||||
} catch (Exception e) {
|
||||
dc.err = e;
|
||||
// Don't update files marked with preserve if they already exist on disk
|
||||
if (f.preserve) {
|
||||
if (Files.exists(destPath)) {
|
||||
return dc;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Hash hash;
|
||||
String fileHashFormat;
|
||||
if (f.linkedFile != null) {
|
||||
hash = f.linkedFile.getHash();
|
||||
fileHashFormat = f.linkedFile.download.hashFormat;
|
||||
} else {
|
||||
hash = f.getHash();
|
||||
fileHashFormat = f.hashFormat;
|
||||
}
|
||||
|
||||
Source src = f.getSource(indexUri);
|
||||
GeneralHashingSource fileSource = HashUtils.getHasher(fileHashFormat).getHashingSource(src);
|
||||
Buffer data = new Buffer();
|
||||
Okio.buffer(fileSource).readAll(data);
|
||||
|
||||
if (fileSource.hashIsEqual(hash)) {
|
||||
Files.createDirectories(destPath.getParent());
|
||||
Files.copy(data.inputStream(), destPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
} else {
|
||||
System.out.println("Invalid hash for " + f.getDestURI().toString());
|
||||
System.out.println("Calculated: " + fileSource.getHash());
|
||||
System.out.println("Expected: " + hash);
|
||||
dc.err = new Exception("Hash invalid!");
|
||||
}
|
||||
|
||||
if (cachedFile != null && !destPath.equals(Paths.get(opts.packFolder, cachedFile.cachedLocation))) {
|
||||
// Delete old file if location changes
|
||||
Files.delete(Paths.get(opts.packFolder, cachedFile.cachedLocation));
|
||||
}
|
||||
|
||||
return dc;
|
||||
} catch (Exception e) {
|
||||
dc.err = e;
|
||||
return dc;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,8 @@
|
||||
package link.infra.packwiz.installer.metadata;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.annotations.JsonAdapter;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.moandjiezana.toml.Toml;
|
||||
|
||||
import link.infra.packwiz.installer.metadata.hash.GeneralHashingSource;
|
||||
import link.infra.packwiz.installer.metadata.hash.Hash;
|
||||
import link.infra.packwiz.installer.metadata.hash.HashUtils;
|
||||
@ -15,6 +10,10 @@ import link.infra.packwiz.installer.request.HandlerManager;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
public class IndexFile {
|
||||
@SerializedName("hash-format")
|
||||
public String hashFormat;
|
||||
@ -69,6 +68,7 @@ public class IndexFile {
|
||||
|
||||
public Hash getHash() throws Exception {
|
||||
if (hash == null) {
|
||||
// TODO: should these be more specific exceptions (e.g. IndexFileException?!)
|
||||
throw new Exception("Index file doesn't have a hash");
|
||||
}
|
||||
if (hashFormat == null) {
|
||||
@ -90,7 +90,8 @@ public class IndexFile {
|
||||
if (file != null) {
|
||||
return Paths.get(file.getPath()).getFileName().toString();
|
||||
}
|
||||
return file.getPath();
|
||||
// TODO: throw some kind of exception?
|
||||
return "Invalid file";
|
||||
}
|
||||
|
||||
public URI getDestURI() {
|
||||
|
@ -48,7 +48,7 @@ public class HashingSourceHasher implements IHasher {
|
||||
if (value != null) {
|
||||
return value.equals(objHash.value);
|
||||
} else {
|
||||
return objHash.value == null ? true : false;
|
||||
return objHash.value == null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
package link.infra.packwiz.installer.metadata.hash;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import okio.Buffer;
|
||||
import okio.Source;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class Murmur2Hasher implements IHasher {
|
||||
private class Murmur2GeneralHashingSource extends GeneralHashingSource {
|
||||
Murmur2Hash value;
|
||||
@ -40,8 +40,7 @@ public class Murmur2Hasher implements IHasher {
|
||||
private byte[] computeNormalizedArray(byte[] input) {
|
||||
byte[] output = new byte[input.length];
|
||||
int num = 0;
|
||||
for (int i = 0; i < input.length; i++) {
|
||||
byte b = input[i];
|
||||
for (byte b : input) {
|
||||
if (!(b == 9 || b == 10 || b == 13 || b == 32)) {
|
||||
output[num] = b;
|
||||
num++;
|
||||
@ -54,7 +53,7 @@ public class Murmur2Hasher implements IHasher {
|
||||
|
||||
}
|
||||
|
||||
private class Murmur2Hash extends Hash {
|
||||
private static class Murmur2Hash extends Hash {
|
||||
int value;
|
||||
private Murmur2Hash(String value) {
|
||||
// Parsing as long then casting to int converts values gt int max value but lt uint max value
|
||||
|
@ -1,17 +1,17 @@
|
||||
package link.infra.packwiz.installer.request;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import okio.Source;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* IRequestHandler handles requests for locations specified in modpack metadata.
|
||||
*/
|
||||
public interface IRequestHandler {
|
||||
|
||||
public boolean matchesHandler(URI loc);
|
||||
boolean matchesHandler(URI loc);
|
||||
|
||||
public default URI getNewLoc(URI loc) {
|
||||
default URI getNewLoc(URI loc) {
|
||||
return loc;
|
||||
}
|
||||
|
||||
@ -22,6 +22,6 @@ public interface IRequestHandler {
|
||||
* @return The Source containing the data of the file
|
||||
* @throws Exception
|
||||
*/
|
||||
public Source getFileSource(URI loc) throws Exception;
|
||||
Source getFileSource(URI loc) throws Exception;
|
||||
|
||||
}
|
||||
|
@ -19,14 +19,17 @@ public class RequestHandlerGithub extends RequestHandlerZip {
|
||||
}
|
||||
|
||||
// TODO: is caching really needed, if HTTPURLConnection follows redirects correctly?
|
||||
private Map<String, URI> zipUriMap = new HashMap<String, URI>();
|
||||
final ReentrantReadWriteLock zipUriLock = new ReentrantReadWriteLock();
|
||||
private Map<String, URI> zipUriMap = new HashMap<>();
|
||||
private final ReentrantReadWriteLock zipUriLock = new ReentrantReadWriteLock();
|
||||
private static Pattern repoMatcherPattern = Pattern.compile("/([\\w.-]+/[\\w.-]+).*");
|
||||
|
||||
private String getRepoName(URI loc) {
|
||||
Matcher matcher = repoMatcherPattern.matcher(loc.getPath());
|
||||
matcher.matches();
|
||||
return matcher.group(1);
|
||||
if (matcher.matches()) {
|
||||
return matcher.group(1);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -57,8 +60,11 @@ public class RequestHandlerGithub extends RequestHandlerZip {
|
||||
|
||||
private String getBranch(URI loc) {
|
||||
Matcher matcher = branchMatcherPattern.matcher(loc.getPath());
|
||||
matcher.matches();
|
||||
return matcher.group(1);
|
||||
if (matcher.matches()) {
|
||||
return matcher.group(1);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,10 @@
|
||||
package link.infra.packwiz.installer.request.handlers;
|
||||
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSource;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
@ -11,14 +16,9 @@ import java.util.function.Predicate;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSource;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
||||
|
||||
protected final boolean modeHasFolder;
|
||||
private final boolean modeHasFolder;
|
||||
|
||||
public RequestHandlerZip(boolean modeHasFolder) {
|
||||
this.modeHasFolder = modeHasFolder;
|
||||
@ -35,14 +35,14 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
||||
private class ZipReader {
|
||||
|
||||
private final ZipInputStream zis;
|
||||
private final Map<URI, Buffer> readFiles = new HashMap<URI, Buffer>();
|
||||
private final Map<URI, Buffer> readFiles = new HashMap<>();
|
||||
// Write lock implies access to ZipInputStream - only 1 thread must read at a time!
|
||||
final ReentrantLock filesLock = new ReentrantLock();
|
||||
private ZipEntry entry;
|
||||
|
||||
private final BufferedSource zipSource;
|
||||
|
||||
public ZipReader(Source zip) {
|
||||
ZipReader(Source zip) {
|
||||
zis = new ZipInputStream(Okio.buffer(zip).inputStream());
|
||||
zipSource = Okio.buffer(Okio.source(zis));
|
||||
}
|
||||
@ -71,7 +71,7 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
||||
}
|
||||
}
|
||||
|
||||
public Source getFileSource(URI loc) throws Exception {
|
||||
Source getFileSource(URI loc) throws Exception {
|
||||
filesLock.lock();
|
||||
// Assume files are only read once, allow GC by removing
|
||||
Buffer file = readFiles.remove(loc);
|
||||
@ -82,13 +82,10 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
||||
|
||||
file = findFile(loc);
|
||||
filesLock.unlock();
|
||||
if (file != null) {
|
||||
return file;
|
||||
}
|
||||
return null;
|
||||
return file;
|
||||
}
|
||||
|
||||
public URI findInZip(Predicate<URI> matches) throws Exception {
|
||||
URI findInZip(Predicate<URI> matches) throws Exception {
|
||||
filesLock.lock();
|
||||
for (URI file : readFiles.keySet()) {
|
||||
if (matches.test(file)) {
|
||||
@ -115,8 +112,8 @@ public abstract class RequestHandlerZip extends RequestHandlerHTTP {
|
||||
|
||||
}
|
||||
|
||||
private final Map<URI, ZipReader> cache = new HashMap<URI, ZipReader>();
|
||||
final ReentrantReadWriteLock cacheLock = new ReentrantReadWriteLock();
|
||||
private final Map<URI, ZipReader> cache = new HashMap<>();
|
||||
private final ReentrantReadWriteLock cacheLock = new ReentrantReadWriteLock();
|
||||
|
||||
protected abstract URI getZipUri(URI loc) throws Exception;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user