Skip to content

Commit fc8b1a7

Browse files
committed
Added Update Checking...
1 parent 4045e7f commit fc8b1a7

7 files changed

Lines changed: 135 additions & 26 deletions

File tree

src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
module org.mangorage.installer {
22
requires com.google.gson;
33
requires jopt.simple;
4+
requires java.xml;
45
}

src/main/java/org/mangorage/installer/Installer.java

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import joptsimple.OptionSet;
77
import joptsimple.OptionSpec;
88
import joptsimple.util.PathConverter;
9+
import org.mangorage.installer.core.UpdateChecker;
910
import org.mangorage.installer.core.data.*;
1011
import java.io.*;
1112
import java.lang.reflect.Method;
@@ -29,23 +30,31 @@ public class Installer {
2930
private static final Path LIBRARIES_PATH = Path.of("libraries/").toAbsolutePath();
3031

3132
public static void main(String[] args) {
32-
System.out.println("Starting Installer...");
33-
System.out.println("Arguments Supplied: " + Arrays.toString(args));
33+
org.mangorage.installer.core.LogUtil.println("Starting Installer...");
34+
org.mangorage.installer.core.LogUtil.println("Arguments Supplied: " + Arrays.toString(args));
3435

3536
OptionParser parser = new OptionParser();
3637

37-
OptionSpec<Void> launchArg = parser
38+
final OptionSpec<Void> launchArg = parser
3839
.accepts("launch", "Whether or not to launch the program that will be installed/updated");
3940

40-
OptionSpec<Path> manualJar = parser
41+
final OptionSpec<Path> manualJar = parser
4142
.accepts("manualJar", "Provide a path to the jar")
4243
.withRequiredArg()
4344
.withValuesSeparatedBy(";")
4445
.withValuesConvertedBy(new PathConverter());
4546

47+
final OptionSpec<Integer> checkUpdates = parser
48+
.accepts("checkUpdates", "Automatically check for updates for packages which want to be checked")
49+
.withRequiredArg()
50+
.ofType(Integer.TYPE);
51+
4652
var options = parser.parse(args);
4753

48-
List<File> jars = options.has("manualJar") ? getManualJars(options, manualJar) : processPackages();
54+
List<File> jars = options.has("manualJar") ? getManualJars(options, manualJar) : processPackages(
55+
options.has(checkUpdates) && options.has("launch"),
56+
options.has(checkUpdates) ? options.valueOf(checkUpdates) : 0
57+
);
4958

5059
if (jars.isEmpty()) {
5160
throw new IllegalStateException("No JARs found to process!");
@@ -55,10 +64,10 @@ public static void main(String[] args) {
5564
handleDependencies(dependencies);
5665

5766
if (options.has("launch")) {
58-
System.out.println("Finished running installer...");
67+
org.mangorage.installer.core.LogUtil.println("Finished running installer...");
5968
launchJar(jars, args);
6069
} else {
61-
System.out.println("Finished running installer...");
70+
org.mangorage.installer.core.LogUtil.println("Finished running installer...");
6271
System.exit(0);
6372
}
6473
}
@@ -70,8 +79,8 @@ private static List<File> getManualJars(OptionSet options, OptionSpec<Path> manu
7079
.toList();
7180
}
7281

73-
private static List<File> processPackages() {
74-
System.out.println("Processing installer/packages.json");
82+
private static List<File> processPackages(final boolean checkUpdates, final int updateFreq) {
83+
org.mangorage.installer.core.LogUtil.println("Processing installer/packages.json");
7584
File file = new File("installer/packages.json");
7685
if (!file.exists()) throw new IllegalStateException("packages.json not found!");
7786

@@ -80,6 +89,7 @@ private static List<File> processPackages() {
8089

8190
try (var reader = new FileReader(file)) {
8291
Packages packages = GSON.fromJson(reader, Packages.class);
92+
if (checkUpdates) UpdateChecker.startChecker(packages, updateFreq);
8393
Map<String, String> newVersions = new HashMap<>();
8494

8595
for (Dependency dependency : packages.packages()) {
@@ -125,7 +135,7 @@ private static File handleDependency(Dependency dependency, Map<String, String>
125135
return new File(destination, dependency.target());
126136
}
127137

128-
System.out.println("Installing/updating " + dependency.target());
138+
org.mangorage.installer.core.LogUtil.println("Installing/updating " + dependency.target());
129139
return Util.downloadTo(maven, latestVersion, destination + "/" + dependency.target());
130140
}
131141

@@ -134,13 +144,13 @@ private static String fetchLatestVersion(Maven maven, String defaultVersion) {
134144
try {
135145
return Util.parseLatestVersion(future.get(10, TimeUnit.SECONDS), defaultVersion);
136146
} catch (Exception e) {
137-
System.out.println("Failed to get metadata, using default version: " + defaultVersion);
147+
org.mangorage.installer.core.LogUtil.println("Failed to get metadata, using default version: " + defaultVersion);
138148
return defaultVersion;
139149
}
140150
}
141151

142152
private static List<Dependency> extractDependencies(List<File> jars) {
143-
System.out.println("Extracting dependencies from JARs");
153+
org.mangorage.installer.core.LogUtil.println("Extracting dependencies from JARs");
144154
List<Dependency> dependencies = new ArrayList<>();
145155

146156
for (File jar : jars) {
@@ -150,7 +160,7 @@ private static List<Dependency> extractDependencies(List<File> jars) {
150160
try (var reader = new InputStreamReader(jarFile.getInputStream(entry))) {
151161
List<Dependency> extracted = GSON.fromJson(reader, Dependencies.class).dependencies();
152162
dependencies.addAll(extracted);
153-
extracted.forEach(dep -> System.out.println("Found dependency: " + dep));
163+
extracted.forEach(dep -> org.mangorage.installer.core.LogUtil.println("Found dependency: " + dep));
154164
}
155165
}
156166
} catch (IOException e) {
@@ -161,8 +171,8 @@ private static List<Dependency> extractDependencies(List<File> jars) {
161171
}
162172

163173
private static void handleDependencies(List<Dependency> dependencies) {
164-
System.out.println("Handling dependencies...");
165-
System.out.println("Skipping dependencies already present...");
174+
org.mangorage.installer.core.LogUtil.println("Handling dependencies...");
175+
org.mangorage.installer.core.LogUtil.println("Skipping dependencies already present...");
166176
Set<String> installedJars = new HashSet<>();
167177
List<File> existingJars = getExistingLibraryJars();
168178

@@ -171,7 +181,7 @@ private static void handleDependencies(List<Dependency> dependencies) {
171181
if (!existingJars.contains(new File(LIBRARIES_PATH.toString(), dep.target()))) {
172182
Util.installUrl(dep.getDownloadURL(), LIBRARIES_PATH.toString(), true);
173183
} else {
174-
System.out.println("Skipped -> " + dep.target());
184+
org.mangorage.installer.core.LogUtil.println("Skipped -> " + dep.target());
175185
}
176186
}
177187

@@ -186,7 +196,7 @@ private static List<File> getExistingLibraryJars() {
186196
private static void deleteUnusedDependencies(List<File> existingJars, Set<String> installedJars) {
187197
existingJars.forEach(file -> {
188198
if (!installedJars.contains(file.getName())) {
189-
System.out.println("Deleting unused dependency: " + file.getName());
199+
org.mangorage.installer.core.LogUtil.println("Deleting unused dependency: " + file.getName());
190200
file.delete();
191201
}
192202
});
@@ -201,7 +211,7 @@ public static String findMainClass(List<File> files) {
201211
ZipEntry entry;
202212
while ((entry = zis.getNextEntry()) != null) {
203213
if (SERVICE_PATH.equals(entry.getName())) {
204-
System.out.println("Found " + SERVICE_PATH + " in " + file.getName());
214+
org.mangorage.installer.core.LogUtil.println("Found " + SERVICE_PATH + " in " + file.getName());
205215
return reader.lines().collect(Collectors.joining("\n"));
206216
}
207217
}
@@ -213,10 +223,10 @@ public static String findMainClass(List<File> files) {
213223
}
214224

215225
public static void launchJar(List<File> jars, String[] args) {
216-
System.out.println("Attempting to launch....");
226+
org.mangorage.installer.core.LogUtil.println("Attempting to launch....");
217227
String mainClass = findMainClass(jars).strip();
218228
if (mainClass.isEmpty()) {
219-
System.out.println("Could not find Valid Launch File from List of Jars...");
229+
org.mangorage.installer.core.LogUtil.println("Could not find Valid Launch File from List of Jars...");
220230
return;
221231
}
222232

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.mangorage.installer.core;
2+
3+
public final class LogUtil {
4+
public static void println(final String msg) {
5+
System.out.println("[INSTALLER] " + msg);
6+
}
7+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package org.mangorage.installer.core;
2+
3+
import org.mangorage.installer.core.data.Dependency;
4+
import org.mangorage.installer.core.data.Packages;
5+
import org.mangorage.installer.core.data.Util;
6+
import java.util.HashMap;
7+
import java.util.Map;
8+
import java.util.Timer;
9+
import java.util.TimerTask;
10+
import java.util.concurrent.Executors;
11+
12+
public final class UpdateChecker extends TimerTask {
13+
public static void startChecker(final Packages packages, final int freq) {
14+
org.mangorage.installer.core.LogUtil.println("Starting Update Checker... Checks every " + freq + "ms");
15+
new UpdateChecker(packages, freq);
16+
}
17+
18+
private final Map<String, String> lastUpdated = new HashMap<>();
19+
20+
private final Packages packages;
21+
private final Timer timer = new Timer();
22+
23+
UpdateChecker(final Packages packages, final int freq) {
24+
this.packages = packages;
25+
Executors.newSingleThreadExecutor().execute(() -> start(freq));
26+
}
27+
28+
void start(final int freq) {
29+
org.mangorage.installer.core.LogUtil.println("Started Update Checker.");
30+
packages
31+
.packages()
32+
.stream()
33+
.filter(Dependency::checkUpdate)
34+
.forEach(dependency -> {
35+
final var metadata = Util.downloadMetadata(dependency.getMaven());
36+
final var lastUpdatedTime = Util.getLastUpdated(metadata);
37+
lastUpdated.put(dependency.target(), lastUpdatedTime);
38+
});
39+
40+
timer.scheduleAtFixedRate(this, freq, freq);
41+
}
42+
43+
@Override
44+
public void run() {
45+
packages
46+
.packages()
47+
.stream()
48+
.filter(Dependency::checkUpdate)
49+
.forEach(dependency -> {
50+
final var metadata = Util.downloadMetadata(dependency.getMaven());
51+
final var lastUpdatedTime = Util.getLastUpdated(metadata);
52+
final var lastCheckedUpdatedTime = lastUpdated.get(dependency.target());
53+
if (lastCheckedUpdatedTime != null) {
54+
if (!lastCheckedUpdatedTime.matches(lastUpdatedTime)) {
55+
org.mangorage.installer.core.LogUtil.println("Exiting... Found update for " + dependency.target());
56+
System.exit(0);
57+
}
58+
}
59+
});
60+
}
61+
}

src/main/java/org/mangorage/installer/core/data/Dependency.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,14 @@
2222

2323
package org.mangorage.installer.core.data;
2424

25-
public record Dependency(String url, String group, String artifact, String version, String target) {
25+
public record Dependency(
26+
String url,
27+
String group,
28+
String artifact,
29+
String version,
30+
String target,
31+
boolean checkUpdate
32+
) {
2633
public static String fix(String value) {
2734
if (value.endsWith("/")) {
2835
return value.substring(0, value.length() - 1);
@@ -34,6 +41,14 @@ public static String fixDot(String value) {
3441
return value.replaceAll("\\.", "/");
3542
}
3643

44+
public Maven getMaven() {
45+
return new Maven(
46+
url,
47+
group,
48+
artifact
49+
);
50+
}
51+
3752
public String getDownloadURL() {
3853
return "%s/%s/%s/%s/%s".formatted(fix(url), fixDot(group), artifact, version, target);
3954
}

src/main/java/org/mangorage/installer/core/data/Util.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
import java.nio.file.StandardCopyOption;
3535
import java.util.stream.Collectors;
3636

37-
public class Util {
37+
public final class Util {
3838

3939
public static File downloadTo(Maven maven, String version, String path) {
4040
String URL = "%s/%s/%s/%s/%s-%s.jar".formatted(
@@ -54,9 +54,24 @@ public static File downloadTo(Maven maven, String version, String path) {
5454
return new File(path);
5555
}
5656

57+
public static String getLastUpdated(String xmlContent) {
58+
String tag = "<lastUpdated>";
59+
String endTag = "</lastUpdated>";
60+
61+
int start = xmlContent.indexOf(tag);
62+
int end = xmlContent.indexOf(endTag);
63+
64+
if (start == -1 || end == -1 || start > end) {
65+
throw new IllegalStateException("Can't find your precious <lastUpdated> tag, genius.");
66+
}
67+
68+
start += tag.length();
69+
return xmlContent.substring(start, end).trim();
70+
}
71+
5772
public static String downloadMetadata(Maven maven) {
5873
String url = maven.repository() + "/" + maven.groupId().replace(".", "/") + "/" + maven.artifactId() + "/maven-metadata.xml";
59-
System.out.println("Downloading Metadata from %s".formatted(url));
74+
org.mangorage.installer.core.LogUtil.println("Downloading Metadata from %s".formatted(url));
6075
try {
6176
return convertInputStreamToString(new URL(url).openStream());
6277
} catch (IOException e) {
@@ -102,13 +117,13 @@ public static void installUrl(String url, String destinationPath, boolean resolv
102117
if (!Files.exists(destination.getParent())) Files.createDirectories(destination.getParent());
103118
Files.copy(inputStream, destination, StandardCopyOption.REPLACE_EXISTING);
104119

105-
System.out.println("Installation complete. File saved to: " + destination);
120+
org.mangorage.installer.core.LogUtil.println("[INSTALLER] Installation complete. File saved to: " + destination);
106121
} catch (URISyntaxException e) {
107122
throw new RuntimeException(e);
108123
}
109124

110125
} catch (IOException e) {
111-
System.out.println(url);
126+
org.mangorage.installer.core.LogUtil.println(url);
112127
throw new IllegalStateException(e);
113128
}
114129
}

src/main/java/org/mangorage/installer/core/data/Version.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import java.util.regex.Matcher;
66
import java.util.regex.Pattern;
77

8-
public class Version implements Comparable<Version> {
8+
public final class Version implements Comparable<Version> {
99

1010
public static List<Version> parseMetadata(String metadata) {
1111
return Version.parseVersions(metadata).stream().map(a -> {

0 commit comments

Comments
 (0)