diff --git a/jstudy.iml b/jstudy.iml
index cb9b265..82289b2 100644
--- a/jstudy.iml
+++ b/jstudy.iml
@@ -5,13 +5,15 @@
-
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 1493ac1..82d9fc4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,7 +14,7 @@
jstudy
- http://maven.apache.org
+ http://gitlab.com/kauron/jstudy
junit
@@ -27,8 +27,24 @@
jfoenix
8.0.9
+
+ org.json
+ json
+ 20190722
+ bundle
+
+
+
+ src/main/resources
+ false
+
+
+ src/main/resources-filtered
+ true
+
+
maven-compiler-plugin
diff --git a/src/main/java/es/kauron/jstudy/controller/Controller.java b/src/main/java/es/kauron/jstudy/controller/Controller.java
index 7487d31..d695568 100644
--- a/src/main/java/es/kauron/jstudy/controller/Controller.java
+++ b/src/main/java/es/kauron/jstudy/controller/Controller.java
@@ -24,16 +24,25 @@ import javafx.scene.layout.BorderPane;
import javafx.stage.FileChooser;
import javafx.stage.Window;
import javafx.stage.WindowEvent;
+import org.json.JSONArray;
+import org.json.JSONObject;
import java.awt.*;
-import java.io.File;
-import java.io.IOException;
+import java.io.*;
+import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
import java.util.List;
import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
public class Controller implements Initializable {
+ private static final String PROJECT_URL = "https://gitlab.com/kauron/jstudy";
+
@FXML
private TabPane tabPane;
@@ -45,6 +54,7 @@ public class Controller implements Initializable {
private final BooleanProperty tabIsTable = new SimpleBooleanProperty(false);
private final Map tabMap = new HashMap<>();
+ private String updateURL, updateFileName;
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
@@ -65,6 +75,75 @@ public class Controller implements Initializable {
}
})
);
+ new Thread(this::checkUpdate).start();
+ }
+
+ private void checkUpdate() {
+ // Check new version via gitlab's REST API
+ String newVersion;
+ File jarFile;
+ BufferedReader br;
+ try {
+ URL apiUrl = new URL("https://gitlab.com/api/v4/projects/9264549/releases");
+ HttpURLConnection connection = (HttpURLConnection) apiUrl.openConnection();
+ connection.setRequestMethod("GET");
+ connection.setRequestProperty("Accept", "application/json");
+ if (connection.getResponseCode() != 200) {
+ System.err.println("Error connecting to Gitlab API");
+ }
+ br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+ } catch (IOException e) {
+ return;
+ }
+ String output = br.lines().collect(Collectors.joining());
+ JSONArray tags = new JSONArray(output);
+ JSONObject latest = tags.getJSONObject(0);
+ newVersion = latest.getString("tag_name").substring(1);
+ if (!isNewVersion(AppPrefs.getVersion(), newVersion))
+ return;
+ String desc = latest.getString("description");
+ Matcher matcher = Pattern.compile("\\[(.*\\.jar)]" +
+ "\\((/uploads/.*/.*\\.jar)\\)").matcher(desc);
+ if (!matcher.find())
+ return;
+ updateURL = matcher.group(2);
+ updateFileName = matcher.group(1);
+ // Ask user whether to update or not.
+ Platform.runLater(this::onUpdate);
+ }
+
+ private void onUpdate() {
+ Optional res = new Alert(Alert.AlertType.INFORMATION,
+ "There is an update ready. Would you like to download it and open it?",
+ ButtonType.YES, ButtonType.NO).showAndWait();
+ if (!res.isPresent() || !res.get().equals(ButtonType.YES))
+ return;
+ try (InputStream inputStream = new URL(PROJECT_URL + updateURL).openStream();
+ ReadableByteChannel readableByteChannel = Channels.newChannel(inputStream);
+ FileOutputStream fileOutputStream = new FileOutputStream(updateFileName)) {
+ fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
+ } catch (IOException e) {
+ return;
+ }
+ // Launch new version
+ try {
+ new ProcessBuilder("java", "-jar", updateFileName).start();
+ } catch (IOException e) {
+ return;
+ }
+ onQuit(null);
+ }
+
+ private boolean isNewVersion(String version, String newVersion) {
+ String[] o = version.split("\\.");
+ String[] n = newVersion.split("\\.");
+ for (int i = 0; i < o.length; i++) {
+ int a = Integer.parseInt(n[i]);
+ int b = Integer.parseInt(o[i]);
+ if (a != b)
+ return a > b;
+ }
+ return false;
}
@FXML
@@ -248,7 +327,7 @@ public class Controller implements Initializable {
protected void onAboutAction(ActionEvent event) {
if (Desktop.isDesktopSupported()) {
try {
- Desktop.getDesktop().browse(URI.create("https://gitlab.com/kauron/jstudy"));
+ Desktop.getDesktop().browse(URI.create(PROJECT_URL));
} catch (Exception e) {
e.printStackTrace();
}
diff --git a/src/main/java/es/kauron/jstudy/model/AppPrefs.java b/src/main/java/es/kauron/jstudy/model/AppPrefs.java
index 81f909c..96670eb 100644
--- a/src/main/java/es/kauron/jstudy/model/AppPrefs.java
+++ b/src/main/java/es/kauron/jstudy/model/AppPrefs.java
@@ -4,6 +4,7 @@ import es.kauron.jstudy.Main;
import javafx.beans.property.SimpleBooleanProperty;
import java.io.File;
+import java.util.Scanner;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
@@ -33,6 +34,12 @@ public class AppPrefs {
flushPrefs();
}
+ public static String getVersion() {
+ String v = new Scanner(AppPrefs.class.getResourceAsStream("/version.txt")).nextLine();
+ assert v.matches("\\d\\.\\d\\.\\d");
+ return v;
+ }
+
public static class BooleanPref extends SimpleBooleanProperty {
private final String name;
diff --git a/src/main/main.iml b/src/main/main.iml
index a9e9bd0..7533b96 100644
--- a/src/main/main.iml
+++ b/src/main/main.iml
@@ -9,5 +9,6 @@
+
\ No newline at end of file
diff --git a/src/main/resources-filtered/version.txt b/src/main/resources-filtered/version.txt
new file mode 100644
index 0000000..e78e522
--- /dev/null
+++ b/src/main/resources-filtered/version.txt
@@ -0,0 +1 @@
+${version}
\ No newline at end of file
diff --git a/version b/version
deleted file mode 100644
index 0bfccb0..0000000
--- a/version
+++ /dev/null
@@ -1 +0,0 @@
-0.4.5