Loading build.gradle +1 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ dependencies { compile 'ch.qos.logback:logback-core:1.2.3' compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.30' compile 'org.yaml:snakeyaml:1.26' compile 'org.json:json:20240303' testCompile 'junit:junit:4.12' //compile 'org.slf4j:slf4j-log4j1:1.7.5' Loading src/main/java/ecorp/easy/installer/tasks/DownloadTask.java +127 −9 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; Loading @@ -44,6 +45,10 @@ import java.util.Scanner; import javafx.concurrent.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javafx.util.Pair; import org.json.JSONArray; import org.json.JSONObject; import org.json.JSONException; /** * this class verify the checksum of a file and download it Loading Loading @@ -73,7 +78,7 @@ public class DownloadTask extends Task<Boolean>{ final private ResourceBundle i18n; final private String targetUrl; final private String fileName; private String fileName; /** * COnstruction of the download task Loading @@ -93,16 +98,15 @@ public class DownloadTask extends Task<Boolean>{ */ @Override protected Boolean call() throws Exception { final String latestBuildFilename = fetchLatestBuildFilename(targetUrl); //build local filePath final String localFilePath = AppConstants.getSourcesFolderPath() + fileName; //Check if already exist and integrity final String checksumFilePath = localFilePath + checkSumExtension; if(isCancelled()) return false; this.updateTitle("Downloading "+fileName+checkSumExtension); this.updateTitle("Downloading " + latestBuildFilename + checkSumExtension); File checksumLmdFile = new File(AppConstants.getSourcesFolderPath()+"lmd."+fileName+checkSumExtension); Loading @@ -123,7 +127,7 @@ public class DownloadTask extends Task<Boolean>{ if(isCancelled()) return false; this.updateTitle("Downloading "+fileName); this.updateTitle("Downloading "+ latestBuildFilename); final String tmpFilePath = AppConstants.getSourcesFolderPath()+"tmp."+fileName; Loading Loading @@ -178,6 +182,120 @@ public class DownloadTask extends Task<Boolean>{ } } private String fetchLatestBuildFilename(String archiveUrl) { // Extract codeName and codeType from the archiveUrl Pair<String, String> codeInfo = getCodeNameFromUrl(archiveUrl); if (codeInfo == null) { logger.error("Failed to fetch latest build filename: codeName or codeType is null."); return null; } String codeName = codeInfo.getKey(); String codeType = codeInfo.getValue(); // Construct API URL using codeName and codeType HttpURLConnection apiConnection = getApiConnection(codeName, codeType); if (apiConnection == null) { logger.error("Failed to fetch latest build filename: API connection is null."); return null; } try { String latestBuildFilename = processApiResponse(apiConnection); return latestBuildFilename; } catch (IOException e) { logger.error("Error processing API response: {}", e.getMessage()); return null; } finally { if (apiConnection != null) { apiConnection.disconnect(); } } } private Pair<String, String> getCodeNameFromUrl(String archiveUrl) { try { URL url = new URL(archiveUrl); String[] urlParts = url.getPath().split("/"); for (int i = 0; i < urlParts.length; i++) { if (urlParts[i].equals("stable") || urlParts[i].equals("dev")) { if (i + 1 < urlParts.length) { String codeType = urlParts[i]; String codeName = urlParts[i + 1]; logger.debug("CodeName extracted from URL: {}", codeName); logger.debug("CodeType extracted from URL: {}", codeType); return new Pair<>(codeName, codeType); } } } logger.error("Invalid URL: Can't find codeName or codeType in: {}", archiveUrl); } catch (MalformedURLException e) { logger.error("Invalid URL: {}", e.getMessage()); } return null; } private HttpURLConnection getApiConnection(String codeName, String codeType) { try { URL apiUrl = new URL("https://ota.ecloud.global/api/v1/" + codeName + "/" + codeType + "?format=json"); HttpURLConnection apiConnection = (HttpURLConnection) apiUrl.openConnection(); apiConnection.setRequestMethod("GET"); apiConnection.setRequestProperty("User-Agent", "null eOS v3"); return apiConnection; } catch (IOException e) { logger.error("Error establishing API connection: {}", e.getMessage()); } return null; } private String processApiResponse(HttpURLConnection apiConnection) throws IOException { try { int responseCode = apiConnection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { String responseString = inputStreamToString(apiConnection.getInputStream()); // Try parsing the response as JSON new JSONObject(responseString); JSONObject responseJson = new JSONObject(responseString); JSONArray responses = responseJson.getJSONArray("response"); JSONObject responseObject = responses.getJSONObject(0); String filename = responseObject.getString("filename"); return filename; } else { logger.error("Error fetching latest build filename: HTTP response code {}", responseCode); } } catch (JSONException e) { logger.warn("API response appears to be invalid JSON. Ignoring..."); return null; } catch (IOException e) { logger.error("Error processing API response: {}", e.getMessage()); } finally { if (apiConnection != null) { apiConnection.disconnect(); } } return null; } private String inputStreamToString(InputStream inputStream) throws IOException { StringBuilder responseString = new StringBuilder(); Scanner scanner = new Scanner(inputStream); while (scanner.hasNextLine()) { responseString.append(scanner.nextLine()); responseString.append("\n"); } scanner.close(); return responseString.toString(); } /** * Perform the downloading of the specified file * If a part is already downloaded, then the download resume from previous state Loading src/main/java/module-info.java +1 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ module ecorp.easy.installer { requires org.yaml.snakeyaml; requires org.slf4j; requires logback.classic; requires org.json; opens ecorp.easy.installer to javafx.fxml; opens ecorp.easy.installer.controllers to javafx.fxml; opens ecorp.easy.installer.controllers.subcontrollers to javafx.fxml; Loading Loading
build.gradle +1 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ dependencies { compile 'ch.qos.logback:logback-core:1.2.3' compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.30' compile 'org.yaml:snakeyaml:1.26' compile 'org.json:json:20240303' testCompile 'junit:junit:4.12' //compile 'org.slf4j:slf4j-log4j1:1.7.5' Loading
src/main/java/ecorp/easy/installer/tasks/DownloadTask.java +127 −9 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; Loading @@ -44,6 +45,10 @@ import java.util.Scanner; import javafx.concurrent.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javafx.util.Pair; import org.json.JSONArray; import org.json.JSONObject; import org.json.JSONException; /** * this class verify the checksum of a file and download it Loading Loading @@ -73,7 +78,7 @@ public class DownloadTask extends Task<Boolean>{ final private ResourceBundle i18n; final private String targetUrl; final private String fileName; private String fileName; /** * COnstruction of the download task Loading @@ -93,16 +98,15 @@ public class DownloadTask extends Task<Boolean>{ */ @Override protected Boolean call() throws Exception { final String latestBuildFilename = fetchLatestBuildFilename(targetUrl); //build local filePath final String localFilePath = AppConstants.getSourcesFolderPath() + fileName; //Check if already exist and integrity final String checksumFilePath = localFilePath + checkSumExtension; if(isCancelled()) return false; this.updateTitle("Downloading "+fileName+checkSumExtension); this.updateTitle("Downloading " + latestBuildFilename + checkSumExtension); File checksumLmdFile = new File(AppConstants.getSourcesFolderPath()+"lmd."+fileName+checkSumExtension); Loading @@ -123,7 +127,7 @@ public class DownloadTask extends Task<Boolean>{ if(isCancelled()) return false; this.updateTitle("Downloading "+fileName); this.updateTitle("Downloading "+ latestBuildFilename); final String tmpFilePath = AppConstants.getSourcesFolderPath()+"tmp."+fileName; Loading Loading @@ -178,6 +182,120 @@ public class DownloadTask extends Task<Boolean>{ } } private String fetchLatestBuildFilename(String archiveUrl) { // Extract codeName and codeType from the archiveUrl Pair<String, String> codeInfo = getCodeNameFromUrl(archiveUrl); if (codeInfo == null) { logger.error("Failed to fetch latest build filename: codeName or codeType is null."); return null; } String codeName = codeInfo.getKey(); String codeType = codeInfo.getValue(); // Construct API URL using codeName and codeType HttpURLConnection apiConnection = getApiConnection(codeName, codeType); if (apiConnection == null) { logger.error("Failed to fetch latest build filename: API connection is null."); return null; } try { String latestBuildFilename = processApiResponse(apiConnection); return latestBuildFilename; } catch (IOException e) { logger.error("Error processing API response: {}", e.getMessage()); return null; } finally { if (apiConnection != null) { apiConnection.disconnect(); } } } private Pair<String, String> getCodeNameFromUrl(String archiveUrl) { try { URL url = new URL(archiveUrl); String[] urlParts = url.getPath().split("/"); for (int i = 0; i < urlParts.length; i++) { if (urlParts[i].equals("stable") || urlParts[i].equals("dev")) { if (i + 1 < urlParts.length) { String codeType = urlParts[i]; String codeName = urlParts[i + 1]; logger.debug("CodeName extracted from URL: {}", codeName); logger.debug("CodeType extracted from URL: {}", codeType); return new Pair<>(codeName, codeType); } } } logger.error("Invalid URL: Can't find codeName or codeType in: {}", archiveUrl); } catch (MalformedURLException e) { logger.error("Invalid URL: {}", e.getMessage()); } return null; } private HttpURLConnection getApiConnection(String codeName, String codeType) { try { URL apiUrl = new URL("https://ota.ecloud.global/api/v1/" + codeName + "/" + codeType + "?format=json"); HttpURLConnection apiConnection = (HttpURLConnection) apiUrl.openConnection(); apiConnection.setRequestMethod("GET"); apiConnection.setRequestProperty("User-Agent", "null eOS v3"); return apiConnection; } catch (IOException e) { logger.error("Error establishing API connection: {}", e.getMessage()); } return null; } private String processApiResponse(HttpURLConnection apiConnection) throws IOException { try { int responseCode = apiConnection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { String responseString = inputStreamToString(apiConnection.getInputStream()); // Try parsing the response as JSON new JSONObject(responseString); JSONObject responseJson = new JSONObject(responseString); JSONArray responses = responseJson.getJSONArray("response"); JSONObject responseObject = responses.getJSONObject(0); String filename = responseObject.getString("filename"); return filename; } else { logger.error("Error fetching latest build filename: HTTP response code {}", responseCode); } } catch (JSONException e) { logger.warn("API response appears to be invalid JSON. Ignoring..."); return null; } catch (IOException e) { logger.error("Error processing API response: {}", e.getMessage()); } finally { if (apiConnection != null) { apiConnection.disconnect(); } } return null; } private String inputStreamToString(InputStream inputStream) throws IOException { StringBuilder responseString = new StringBuilder(); Scanner scanner = new Scanner(inputStream); while (scanner.hasNextLine()) { responseString.append(scanner.nextLine()); responseString.append("\n"); } scanner.close(); return responseString.toString(); } /** * Perform the downloading of the specified file * If a part is already downloaded, then the download resume from previous state Loading
src/main/java/module-info.java +1 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ module ecorp.easy.installer { requires org.yaml.snakeyaml; requires org.slf4j; requires logback.classic; requires org.json; opens ecorp.easy.installer to javafx.fxml; opens ecorp.easy.installer.controllers to javafx.fxml; opens ecorp.easy.installer.controllers.subcontrollers to javafx.fxml; Loading