mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
#829 Integrates JMBE Creator with new user preferences editor for auto-downloading and compiling the JMBE library from within sdrtrunk. (#844)
Co-authored-by: Denny <denny@denny-desktop>
This commit is contained in:
323
src/main/java/io/github/dsheirer/jmbe/JmbeCreator.java
Normal file
323
src/main/java/io/github/dsheirer/jmbe/JmbeCreator.java
Normal file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.jmbe;
|
||||
|
||||
import io.github.dsheirer.jmbe.github.Asset;
|
||||
import io.github.dsheirer.jmbe.github.GitHub;
|
||||
import io.github.dsheirer.jmbe.github.Release;
|
||||
import io.github.dsheirer.util.FileUtil;
|
||||
import io.github.dsheirer.util.OSType;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.rauschig.jarchivelib.ArchiveFormat;
|
||||
import org.rauschig.jarchivelib.Archiver;
|
||||
import org.rauschig.jarchivelib.ArchiverFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* Creates the JMBE library by downloading the JMBE Creator CLI application from GitHub and executing it.
|
||||
*/
|
||||
public class JmbeCreator
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(JmbeCreator.class);
|
||||
public static final String GITHUB_JMBE_RELEASES_URL = "https://api.github.com/repos/dsheirer/jmbe/releases";
|
||||
public static final String CREATOR_SCRIPT_LINUX = "creator";
|
||||
public static final String CREATOR_SCRIPT_WINDOWS = "creator.bat";
|
||||
|
||||
private StringProperty mConsoleOutput = new SimpleStringProperty();
|
||||
private BooleanProperty mCompleteProperty = new SimpleBooleanProperty();
|
||||
private boolean mHasErrors = false;
|
||||
private Release mRelease;
|
||||
private Path mLibraryPath;
|
||||
private StringBuilder mConsoleStringBuilder = new StringBuilder();
|
||||
|
||||
/**
|
||||
* Creates an instance.
|
||||
* @param release for the version to create
|
||||
* @param library path where the library should be created
|
||||
*/
|
||||
public JmbeCreator(Release release, Path library)
|
||||
{
|
||||
mRelease = release;
|
||||
mLibraryPath = library;
|
||||
}
|
||||
|
||||
/**
|
||||
* Path to where the library should be created
|
||||
*/
|
||||
public Path getLibraryPath()
|
||||
{
|
||||
return mLibraryPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Property that indicates if the creation process has finished.
|
||||
*/
|
||||
public BooleanProperty completeProperty()
|
||||
{
|
||||
return mCompleteProperty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Console output from the build process.
|
||||
*/
|
||||
public StringProperty consoleOutputProperty()
|
||||
{
|
||||
return mConsoleOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints (adds) the message text to the console property
|
||||
* @param message to add
|
||||
*/
|
||||
private void printToConsole(String message)
|
||||
{
|
||||
mConsoleStringBuilder.append(message).append("\n");
|
||||
final String console = mConsoleStringBuilder.toString();
|
||||
Platform.runLater(() -> consoleOutputProperty().setValue(console));
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the build process completed successfully (false) or there were errors (true).
|
||||
*/
|
||||
public boolean hasErrors()
|
||||
{
|
||||
return mHasErrors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the build process that downloads the JMBE creator utility, unzips it, and commands the utility
|
||||
* to create the library at the specified library path.
|
||||
*/
|
||||
public void execute()
|
||||
{
|
||||
final Asset asset = getJMBECreatorAsset(mRelease);
|
||||
|
||||
if(asset != null)
|
||||
{
|
||||
ThreadPool.SCHEDULED.execute(() -> {
|
||||
Path tempDirectory = null;
|
||||
try
|
||||
{
|
||||
tempDirectory = Files.createTempDirectory("sdrtrunk-jmbe-creator");
|
||||
printToConsole("Created: Temp Directory [" + tempDirectory.toString() + "]");
|
||||
printToConsole("Downloading: JMBE Creator [" + asset.toString() + "]");
|
||||
printToConsole("Please wait ...");
|
||||
Path creator = GitHub.downloadArtifact(asset.getDownloadUrl(), tempDirectory);
|
||||
|
||||
if(creator != null)
|
||||
{
|
||||
printToConsole("Downloaded: JMBE Creator [" + creator.toString() + "]");
|
||||
Path unzipped = creator.getParent();
|
||||
Archiver archiver = ArchiverFactory.createArchiver(ArchiveFormat.ZIP);
|
||||
archiver.extract(creator.toFile(), unzipped.toFile());
|
||||
printToConsole("Unzipped: [" + unzipped.toString() + "]");
|
||||
|
||||
Path script = null;
|
||||
|
||||
OSType osType = OSType.getCurrentOSType();
|
||||
|
||||
if(osType.isLinux())
|
||||
{
|
||||
script = FileUtil.findFile(unzipped, CREATOR_SCRIPT_LINUX);
|
||||
}
|
||||
else if(osType.isWindows())
|
||||
{
|
||||
script = FileUtil.findFile(unzipped, CREATOR_SCRIPT_WINDOWS);
|
||||
}
|
||||
|
||||
if(script != null)
|
||||
{
|
||||
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||
processBuilder.command(script.toString(), mLibraryPath.toString());
|
||||
|
||||
try
|
||||
{
|
||||
Process process = processBuilder.start();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
String line;
|
||||
while((line = reader.readLine()) != null)
|
||||
{
|
||||
printToConsole(line);
|
||||
}
|
||||
|
||||
int exitCode = process.waitFor();
|
||||
|
||||
if(exitCode == 0)
|
||||
{
|
||||
printToConsole("Library Created Successfully!");
|
||||
Platform.runLater(() -> completeProperty().set(true));
|
||||
}
|
||||
else
|
||||
{
|
||||
terminateWithErrors("Failed: Exit Code [" + exitCode + "]");
|
||||
mLog.error("Script failed with exit code: " + exitCode);
|
||||
}
|
||||
}
|
||||
catch(InterruptedException ie)
|
||||
{
|
||||
terminateWithErrors("Failed: Script Process was interrupted");
|
||||
mLog.error("Interrupted", ie);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
terminateWithErrors("Failed: Unable to find JMBE creator launch script for this OS");
|
||||
mLog.error("Script was null. Unable to find JMBE creator launch script");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Throwable t)
|
||||
{
|
||||
terminateWithErrors("Failed: Unknown Error - " + t.getLocalizedMessage());
|
||||
mLog.error("Failed to create the JMBE library", t);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if(tempDirectory != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
FileUtils.deleteDirectory(tempDirectory.toFile());
|
||||
printToConsole("Deleted: Temporary Directory [" + tempDirectory.toString() + "]");
|
||||
}
|
||||
catch(IOException ioe)
|
||||
{
|
||||
printToConsole("Failed: Deleting Temporary Directory [" + tempDirectory.toString() + "]");
|
||||
mLog.error("Error deleting temporary directory [" + tempDirectory.toString() + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
terminateWithErrors("Failed: Unable to identify correct JMBE creator utility from GitHub " +
|
||||
"repository for this computer's operating system and architecture");
|
||||
mLog.error("Unable to create JMBE library. Can't find JMBE Creator for this OS and architecture");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Terminates the execution and updates flags to indicate error state
|
||||
* @param message to display as console output
|
||||
*/
|
||||
private void terminateWithErrors(String message)
|
||||
{
|
||||
printToConsole(message);
|
||||
printToConsole("Please follow the instructions for manually creating and installing the JMBE library");
|
||||
Platform.runLater(() -> {
|
||||
mHasErrors = true;
|
||||
mCompleteProperty.set(true);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to find the correct JMBE creator for this operating system and architecture for the specified release
|
||||
* @param release to find
|
||||
* @return JMBE creator asset or null.
|
||||
*/
|
||||
public static Asset getJMBECreatorAsset(Release release)
|
||||
{
|
||||
OSType osType = OSType.getCurrentOSType();
|
||||
|
||||
if(release != null)
|
||||
{
|
||||
for(Asset asset: release.getAssets())
|
||||
{
|
||||
if(isCorrectAsset(asset, osType))
|
||||
{
|
||||
return asset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the asset is correct for the host operating system and architecture
|
||||
* @param asset to check
|
||||
* @param osType for the current host (OS & architecture)
|
||||
* @return true if the asset is correct for this host.
|
||||
*/
|
||||
public static boolean isCorrectAsset(Asset asset, OSType osType)
|
||||
{
|
||||
if(isJMBECreator(asset))
|
||||
{
|
||||
String name = asset.getName();
|
||||
|
||||
switch(osType)
|
||||
{
|
||||
case LINUX_32:
|
||||
return name.contains("linux") && name.contains("_32");
|
||||
case LINUX_64:
|
||||
return name.contains("linux") && name.contains("_64");
|
||||
case OSX_64:
|
||||
return name.contains("osx") && name.contains("_64");
|
||||
case WINDOWS_32:
|
||||
return name.contains("windows") && name.contains("_32");
|
||||
case WINDOWS_64:
|
||||
return name.contains("windows") && name.contains("_64");
|
||||
case UNKNOWN:
|
||||
case OSX_32:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the GitHub asset has a non-null asset name and is a JMBE Creator asset
|
||||
*/
|
||||
private static boolean isJMBECreator(Asset asset)
|
||||
{
|
||||
return asset.getName() != null && asset.getName().startsWith("jmbe-creator");
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Release release = GitHub.getLatestRelease(GITHUB_JMBE_RELEASES_URL);
|
||||
Path library = Paths.get("/home/denny/temp/jmbe.jar");
|
||||
JmbeCreator jmbeCreator = new JmbeCreator(release, library);
|
||||
|
||||
jmbeCreator.execute();
|
||||
|
||||
while(true);
|
||||
}
|
||||
}
|
||||
327
src/main/java/io/github/dsheirer/jmbe/JmbeEditor.java
Normal file
327
src/main/java/io/github/dsheirer/jmbe/JmbeEditor.java
Normal file
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.jmbe;
|
||||
|
||||
import io.github.dsheirer.eventbus.MyEventBus;
|
||||
import io.github.dsheirer.jmbe.github.Release;
|
||||
import io.github.dsheirer.jmbe.github.Version;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import javafx.geometry.HPos;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Separator;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Editor pane for JMBE Library creator
|
||||
*/
|
||||
public class JmbeEditor extends VBox
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(JmbeEditor.class);
|
||||
private UserPreferences mUserPreferences;
|
||||
private Release mCurrentRelease;
|
||||
private Label mCurrentVersionLabel;
|
||||
private Label mUpdatedVersionLabel;
|
||||
private Label mLibraryPathLabel;
|
||||
private Button mChangeDirectoryButton;
|
||||
private GridPane mLabelGridPane;
|
||||
private Path mLibraryDirectoryPath;
|
||||
private Button mCreateButton;
|
||||
private TextArea mConsoleTextArea;
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
* @param userPreferences
|
||||
*/
|
||||
public JmbeEditor(UserPreferences userPreferences)
|
||||
{
|
||||
mUserPreferences = userPreferences;
|
||||
setPadding(new Insets(10,10,10,10));
|
||||
setSpacing(10);
|
||||
Separator separator = new Separator();
|
||||
separator.setMaxWidth(Double.MAX_VALUE);
|
||||
VBox.setVgrow(getConsoleTextArea(), Priority.ALWAYS);
|
||||
getChildren().addAll(getLabelGridPane(), separator, getCreateButton(), getConsoleTextArea());
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a request to configure the editor to build the release version specified in the request.
|
||||
* @param request to build a specific release version
|
||||
*/
|
||||
public void process(JmbeEditorRequest request)
|
||||
{
|
||||
if(request != null)
|
||||
{
|
||||
setCurrentRelease(request.getCurrentRelease());
|
||||
}
|
||||
}
|
||||
|
||||
private TextArea getConsoleTextArea()
|
||||
{
|
||||
if(mConsoleTextArea == null)
|
||||
{
|
||||
mConsoleTextArea = new TextArea();
|
||||
mConsoleTextArea.setMaxHeight(Double.MAX_VALUE);
|
||||
mConsoleTextArea.setMaxWidth(Double.MAX_VALUE);
|
||||
}
|
||||
|
||||
return mConsoleTextArea;
|
||||
}
|
||||
|
||||
private Button getCreateButton()
|
||||
{
|
||||
if(mCreateButton == null)
|
||||
{
|
||||
mCreateButton = new Button("Create Library");
|
||||
mCreateButton.setOnAction(event -> {
|
||||
String noticeText = "The JMBE library is available as source code for educational purposes " +
|
||||
"only. It is a written description of how certain voice encoding/decoding algorithms " +
|
||||
"could be implemented. Executable objects compiled or derived from this package may " +
|
||||
"be covered by one or more patents. Users are strongly advised to check for any " +
|
||||
"patent restrictions or licensing requirements before compiling or using this " +
|
||||
"source code.\n\nClicking the YES button indicates that you are requesting to download " +
|
||||
"the JMBE source code and compile the JMBE library.";
|
||||
|
||||
Alert alert = new Alert(Alert.AlertType.WARNING, noticeText, ButtonType.YES, ButtonType.NO);
|
||||
alert.setResizable(true);
|
||||
|
||||
//Workaroud for dialog sizing issue on Windows
|
||||
alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE);
|
||||
|
||||
alert.setTitle("Download and Compile JMBE Library?");
|
||||
alert.setHeaderText("Do you want to continue?");
|
||||
alert.initOwner(getCreateButton().getScene().getWindow());
|
||||
alert.showAndWait().ifPresent(buttonType -> {
|
||||
if(buttonType == ButtonType.YES)
|
||||
{
|
||||
Path library = getLibraryDirectoryPath().resolve(getJarName(mCurrentRelease.getVersion()));
|
||||
getCreateButton().setDisable(true);
|
||||
createJmbeLibrary(library);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return mCreateButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads the JMBE creator and creates the library using the specified path argument.
|
||||
* @param library path
|
||||
*/
|
||||
private void createJmbeLibrary(Path library)
|
||||
{
|
||||
JmbeCreator jmbeCreator = new JmbeCreator(mCurrentRelease, library);
|
||||
getConsoleTextArea().textProperty().bind(jmbeCreator.consoleOutputProperty());
|
||||
jmbeCreator.completeProperty().addListener((observable, oldValue, newValue) -> {
|
||||
getCreateButton().setDisable(false);
|
||||
boolean failed = jmbeCreator.hasErrors();
|
||||
String content = null;
|
||||
if(failed)
|
||||
{
|
||||
content = "JMBE library creation attempt failed. Please update the library manually by " +
|
||||
"downloading the JMBE creator application.";
|
||||
}
|
||||
else
|
||||
{
|
||||
content = "JMBE library successfully created/updated";
|
||||
mUserPreferences.getJmbeLibraryPreference().setPathJmbeLibrary(jmbeCreator.getLibraryPath());
|
||||
getCurrentVersionLabel().setText(mCurrentRelease.getVersion().toString());
|
||||
}
|
||||
Alert alert = new Alert(Alert.AlertType.INFORMATION, content, ButtonType.OK);
|
||||
alert.setTitle("JMBE Library Creator");
|
||||
alert.setHeaderText((failed ? "Attempt failed." : "Success!") + " Please click OK to close this window");
|
||||
alert.initOwner(getCreateButton().getScene().getWindow());
|
||||
alert.showAndWait().ifPresent(buttonType -> {
|
||||
jmbeCreator.completeProperty().unbind();
|
||||
MyEventBus.getEventBus().post(new JmbeEditorRequest(true));
|
||||
});
|
||||
});
|
||||
jmbeCreator.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a jar name for the specified release version
|
||||
* @param version of the GitHub JMBE release
|
||||
* @return JMBE library jar name
|
||||
*/
|
||||
public static String getJarName(Version version)
|
||||
{
|
||||
String name = version.toString();
|
||||
name = name.replace("v", "");
|
||||
return "jmbe-" + name + ".jar";
|
||||
}
|
||||
|
||||
private GridPane getLabelGridPane()
|
||||
{
|
||||
if(mLabelGridPane == null)
|
||||
{
|
||||
mLabelGridPane = new GridPane();
|
||||
mLabelGridPane.setHgap(10);
|
||||
mLabelGridPane.setVgap(10);
|
||||
|
||||
int row = 0;
|
||||
|
||||
Label topLabel = new Label("Create or Update JMBE Library");
|
||||
mLabelGridPane.add(topLabel, 0, row, 2, 1);
|
||||
|
||||
Label currentLabel = new Label("Current Version:");
|
||||
GridPane.setHalignment(currentLabel, HPos.RIGHT);
|
||||
mLabelGridPane.add(currentLabel, 0, ++row);
|
||||
mLabelGridPane.add(getCurrentVersionLabel(), 1, row);
|
||||
|
||||
Label updateLabel = new Label("Updating To Version:");
|
||||
GridPane.setHalignment(updateLabel, HPos.RIGHT);
|
||||
mLabelGridPane.add(updateLabel, 0, ++row);
|
||||
mLabelGridPane.add(getUpdatedVersionLabel(), 1, row);
|
||||
|
||||
Label pathLabel = new Label("Store Library At:");
|
||||
GridPane.setHalignment(pathLabel, HPos.RIGHT);
|
||||
mLabelGridPane.add(pathLabel, 0, ++row);
|
||||
mLabelGridPane.add(getLibraryPathLabel(), 1, row);
|
||||
|
||||
mLabelGridPane.add(getChangeDirectoryButton(), 1, ++row);
|
||||
}
|
||||
|
||||
return mLabelGridPane;
|
||||
}
|
||||
|
||||
private Path getLibraryDirectoryPath()
|
||||
{
|
||||
if(mLibraryDirectoryPath == null)
|
||||
{
|
||||
mLibraryDirectoryPath = mUserPreferences.getDirectoryPreference().getDefaultJmbeDirectory();
|
||||
}
|
||||
|
||||
return mLibraryDirectoryPath;
|
||||
}
|
||||
|
||||
private Button getChangeDirectoryButton()
|
||||
{
|
||||
if(mChangeDirectoryButton == null)
|
||||
{
|
||||
mChangeDirectoryButton = new Button("Change Directory ...");
|
||||
mChangeDirectoryButton.setOnAction(event -> {
|
||||
DirectoryChooser chooser = new DirectoryChooser();
|
||||
chooser.setInitialDirectory(getLibraryDirectoryPath().toFile());
|
||||
chooser.setTitle("JMBE Library Directory");
|
||||
File newDirectory = chooser.showDialog(getChangeDirectoryButton().getScene().getWindow());
|
||||
setLibraryDirectoryPath(newDirectory.toPath());
|
||||
});
|
||||
}
|
||||
|
||||
return mChangeDirectoryButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the library path and updates the display label
|
||||
*/
|
||||
private void setLibraryDirectoryPath(Path path)
|
||||
{
|
||||
if(path != null)
|
||||
{
|
||||
mLibraryDirectoryPath = path;
|
||||
getLibraryPathLabel().setText(mLibraryDirectoryPath.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private Label getLibraryPathLabel()
|
||||
{
|
||||
if(mLibraryPathLabel == null)
|
||||
{
|
||||
mLibraryPathLabel = new Label();
|
||||
|
||||
if(getLibraryDirectoryPath() != null)
|
||||
{
|
||||
mLibraryPathLabel.setText(getLibraryDirectoryPath().toString());
|
||||
}
|
||||
}
|
||||
|
||||
return mLibraryPathLabel;
|
||||
}
|
||||
|
||||
private Label getCurrentVersionLabel()
|
||||
{
|
||||
if(mCurrentVersionLabel == null)
|
||||
{
|
||||
mCurrentVersionLabel = new Label("(empty)");
|
||||
|
||||
Version currentVersion = mUserPreferences.getJmbeLibraryPreference().getCurrentVersion();
|
||||
|
||||
if(currentVersion != null)
|
||||
{
|
||||
mCurrentVersionLabel.setText(currentVersion.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return mCurrentVersionLabel;
|
||||
}
|
||||
|
||||
private Label getUpdatedVersionLabel()
|
||||
{
|
||||
if(mUpdatedVersionLabel == null)
|
||||
{
|
||||
mUpdatedVersionLabel = new Label("(empty)");
|
||||
}
|
||||
|
||||
return mUpdatedVersionLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Current release version available from GitHub.
|
||||
* @return current release or null if the release hasn't been set.
|
||||
*/
|
||||
private Release getCurrentRelease()
|
||||
{
|
||||
return mCurrentRelease;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current release version available from GitHub.
|
||||
* @param release version
|
||||
*/
|
||||
public void setCurrentRelease(Release release)
|
||||
{
|
||||
mCurrentRelease = release;
|
||||
|
||||
if(release != null)
|
||||
{
|
||||
Version updateVersion = release.getVersion();
|
||||
|
||||
if(updateVersion != null)
|
||||
{
|
||||
getUpdatedVersionLabel().setText(updateVersion.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
65
src/main/java/io/github/dsheirer/jmbe/JmbeEditorRequest.java
Normal file
65
src/main/java/io/github/dsheirer/jmbe/JmbeEditorRequest.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.jmbe;
|
||||
|
||||
import io.github.dsheirer.jmbe.github.Release;
|
||||
|
||||
/**
|
||||
* Request to create a JMBE library from the specified GitHub release version
|
||||
*/
|
||||
public class JmbeEditorRequest
|
||||
{
|
||||
private Release mCurrentRelease;
|
||||
private boolean mCloseEditor = false;
|
||||
|
||||
/**
|
||||
* Constructs an instance to request an edit of the specified release
|
||||
* @param release available on GitHub
|
||||
*/
|
||||
public JmbeEditorRequest(Release release)
|
||||
{
|
||||
mCurrentRelease = release;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a request to close and dispose of the editor
|
||||
* @param close
|
||||
*/
|
||||
public JmbeEditorRequest(boolean close)
|
||||
{
|
||||
mCloseEditor = close;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this is a close (and dispose) editor request
|
||||
*/
|
||||
public boolean isCloseEditorRequest()
|
||||
{
|
||||
return mCloseEditor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release version requested
|
||||
*/
|
||||
public Release getCurrentRelease()
|
||||
{
|
||||
return mCurrentRelease;
|
||||
}
|
||||
}
|
||||
75
src/main/java/io/github/dsheirer/jmbe/github/Asset.java
Normal file
75
src/main/java/io/github/dsheirer/jmbe/github/Asset.java
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.jmbe.github;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* GitHub Asset
|
||||
*/
|
||||
public class Asset
|
||||
{
|
||||
private JsonObject mJsonObject;
|
||||
|
||||
public Asset(JsonObject jsonObject)
|
||||
{
|
||||
mJsonObject = jsonObject;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return getTag("name");
|
||||
}
|
||||
|
||||
/**
|
||||
* URL to download this asset
|
||||
*/
|
||||
public String getDownloadUrl()
|
||||
{
|
||||
return getTag("browser_download_url");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Access the string contents of a json tag
|
||||
* @param tagName to access
|
||||
* @return string value or null
|
||||
*/
|
||||
private String getTag(String tagName)
|
||||
{
|
||||
if(mJsonObject != null)
|
||||
{
|
||||
JsonElement element = mJsonObject.get(tagName);
|
||||
|
||||
if(!element.isJsonNull())
|
||||
{
|
||||
return element.toString().replace("\"", "");
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
175
src/main/java/io/github/dsheirer/jmbe/github/GitHub.java
Normal file
175
src/main/java/io/github/dsheirer/jmbe/github/GitHub.java
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* Copyright (C) 2015-2020 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.jmbe.github;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
|
||||
/**
|
||||
* Utilities for accessing GitHub repositories and releases
|
||||
*/
|
||||
public class GitHub
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(GitHub.class);
|
||||
|
||||
private GitHub()
|
||||
{
|
||||
//There's nothing to construct in this class
|
||||
}
|
||||
|
||||
/**
|
||||
* Download an artifact to the specified directory
|
||||
* @param url of the artifact to download
|
||||
* @param directory to store the downloaded file
|
||||
* @return path to the downloaded artifact or null
|
||||
*/
|
||||
public static Path downloadArtifact(String url, Path directory)
|
||||
{
|
||||
HttpClient client = HttpClient.newBuilder()
|
||||
.followRedirects(HttpClient.Redirect.ALWAYS)
|
||||
.build();
|
||||
|
||||
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).build();
|
||||
|
||||
try
|
||||
{
|
||||
HttpResponse<Path> response = client.send(request, HttpResponse.BodyHandlers.ofFileDownload(directory,
|
||||
StandardOpenOption.CREATE, StandardOpenOption.WRITE));
|
||||
|
||||
if(response.statusCode() != 200)
|
||||
{
|
||||
mLog.error("HTTP Download Status Code: " + response.statusCode());
|
||||
}
|
||||
|
||||
return response.body();
|
||||
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
mLog.error("Error downloading source code from GitHub", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the latest release object from the repository.
|
||||
* @param repositoryURL for the GitHub api
|
||||
* @return the latest release or null
|
||||
*/
|
||||
public static Release getLatestRelease(String repositoryURL)
|
||||
{
|
||||
HttpClient httpClient = HttpClient.newHttpClient();
|
||||
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(repositoryURL)).build();
|
||||
|
||||
try
|
||||
{
|
||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
|
||||
if(response.statusCode() == 200)
|
||||
{
|
||||
return parseResponse(response.body());
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.error("Error while fetching latest releases - HTTP:" + response.statusCode());
|
||||
}
|
||||
}
|
||||
catch(IOException | InterruptedException e)
|
||||
{
|
||||
mLog.error("Error while detecting the current release version of JMBE library", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a json string containing an array or GitHub release objects and returns the latest release.
|
||||
* @param json string returned from URL call
|
||||
* @return latest release version
|
||||
*/
|
||||
private static Release parseResponse(String json)
|
||||
{
|
||||
Release release = null;
|
||||
|
||||
if(json != null)
|
||||
{
|
||||
JsonElement element = JsonParser.parseString(json);
|
||||
|
||||
if(element.isJsonArray())
|
||||
{
|
||||
JsonArray array = element.getAsJsonArray();
|
||||
|
||||
for(JsonElement child: array)
|
||||
{
|
||||
if(child.isJsonObject())
|
||||
{
|
||||
JsonObject releaseObject = child.getAsJsonObject();
|
||||
Version version = getVersion(releaseObject);
|
||||
|
||||
if(version != null)
|
||||
{
|
||||
if(release == null || release.getVersion().compareTo(version) < 0)
|
||||
{
|
||||
release = new Release(version, releaseObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return release;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a version object from the tag_name.
|
||||
* @param jsonObject containing a tag_name formatted as: vAAAAA.BBBBB.CCCCx where:
|
||||
* A = major, 0-99999
|
||||
* B = minor, 0-99999
|
||||
* C = release, 0-99999
|
||||
* x = (optional)patch, a-z
|
||||
*
|
||||
* @return version instance or null
|
||||
*/
|
||||
private static Version getVersion(JsonObject jsonObject)
|
||||
{
|
||||
JsonElement tagName = jsonObject.get("tag_name");
|
||||
|
||||
if(tagName != null)
|
||||
{
|
||||
return Version.fromString(tagName.toString());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
159
src/main/java/io/github/dsheirer/jmbe/github/Release.java
Normal file
159
src/main/java/io/github/dsheirer/jmbe/github/Release.java
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.jmbe.github;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* GitHub release
|
||||
*/
|
||||
public class Release
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(Release.class);
|
||||
|
||||
private Version mVersion;
|
||||
private JsonObject mJsonObject;
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
* @param version of the release
|
||||
* @param jsonObject that represents the release
|
||||
*/
|
||||
public Release(Version version, JsonObject jsonObject)
|
||||
{
|
||||
mVersion = version;
|
||||
mJsonObject = jsonObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Version stamp for the release
|
||||
*/
|
||||
public Version getVersion()
|
||||
{
|
||||
return mVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* JsonObject for the release
|
||||
*/
|
||||
public JsonObject getJsonObject()
|
||||
{
|
||||
return mJsonObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the release
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return getTag("name");
|
||||
}
|
||||
|
||||
/**
|
||||
* Assets URL
|
||||
*/
|
||||
public String getAssetsUrl()
|
||||
{
|
||||
return getTag("assets_url");
|
||||
}
|
||||
|
||||
public List<Asset> getAssets()
|
||||
{
|
||||
List<Asset> assets = new ArrayList<>();
|
||||
JsonArray array = mJsonObject.getAsJsonArray("assets");
|
||||
|
||||
if(!array.isJsonNull())
|
||||
{
|
||||
for(JsonElement element: array)
|
||||
{
|
||||
assets.add(new Asset(element.getAsJsonObject()));
|
||||
}
|
||||
}
|
||||
|
||||
return assets;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML URL
|
||||
*/
|
||||
public String getHtmlUrl()
|
||||
{
|
||||
return getTag("html_url");
|
||||
}
|
||||
|
||||
/**
|
||||
* Zip File Download URL
|
||||
*/
|
||||
public String getDownloadUrl()
|
||||
{
|
||||
return getTag("zipball_url");
|
||||
}
|
||||
|
||||
/**
|
||||
* Access the string contents of a json tag
|
||||
* @param tagName to access
|
||||
* @return string value or null
|
||||
*/
|
||||
private String getTag(String tagName)
|
||||
{
|
||||
if(mJsonObject != null)
|
||||
{
|
||||
JsonElement element = mJsonObject.get(tagName);
|
||||
|
||||
if(!element.isJsonNull())
|
||||
{
|
||||
return element.toString().replace("\"", "");
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indicates if the release has a download URL
|
||||
*/
|
||||
public boolean hasDownloadUrl()
|
||||
{
|
||||
return getDownloadUrl() != null;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("\nName:").append(getName());
|
||||
sb.append("\nVersion: ").append(getVersion().toString());
|
||||
sb.append("\nHTML URL:").append(getHtmlUrl());
|
||||
sb.append("\nDownload URL:").append(getDownloadUrl());
|
||||
|
||||
for(Asset asset: getAssets())
|
||||
{
|
||||
sb.append("\nAsset: " + asset.toString());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
226
src/main/java/io/github/dsheirer/jmbe/github/Version.java
Normal file
226
src/main/java/io/github/dsheirer/jmbe/github/Version.java
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.jmbe.github;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Version representation and parsing class
|
||||
*/
|
||||
public class Version implements Comparable<Version>
|
||||
{
|
||||
public final static Pattern VERSION_PATTERN = Pattern.compile("v?(\\d{1,5}).(\\d{1,5}).(\\d{1,5})(\\w*)");
|
||||
|
||||
private Integer mMajor;
|
||||
private Integer mMinor;
|
||||
private Integer mRelease;
|
||||
private Character mPatch;
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
* @param major version
|
||||
* @param minor version
|
||||
* @param release version
|
||||
* @param patch version (optional)
|
||||
*/
|
||||
public Version(int major, int minor, int release, Character patch)
|
||||
{
|
||||
mMajor = major;
|
||||
mMinor = minor;
|
||||
mRelease = release;
|
||||
mPatch = patch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the argument into a version instance.
|
||||
* @param version string (e.g. v1.0.6a)
|
||||
* @return
|
||||
*/
|
||||
public static Version fromString(String version)
|
||||
{
|
||||
if(version != null)
|
||||
{
|
||||
Matcher m = VERSION_PATTERN.matcher(version.replace("\"", ""));
|
||||
|
||||
if(m.matches())
|
||||
{
|
||||
int major = 0;
|
||||
int minor = 0;
|
||||
int release = 0;
|
||||
Character patch = null;
|
||||
|
||||
try
|
||||
{
|
||||
major = Integer.parseInt(m.group(1));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
//Do nothing, we couldn't parse the value
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
minor = Integer.parseInt(m.group(2));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
//Do nothing, we couldn't parse the value
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
release = Integer.parseInt(m.group(3));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
//Do nothing, we couldn't parse the value
|
||||
}
|
||||
|
||||
String rawPatch = m.group(4);
|
||||
|
||||
if(rawPatch != null && rawPatch.length() >= 1)
|
||||
{
|
||||
patch = rawPatch.charAt(0);
|
||||
}
|
||||
|
||||
return new Version(major, minor, release, patch);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Integer getMajor()
|
||||
{
|
||||
return mMajor;
|
||||
}
|
||||
|
||||
public boolean hasMajor()
|
||||
{
|
||||
return mMajor != null;
|
||||
}
|
||||
|
||||
public Integer getMinor()
|
||||
{
|
||||
return mMinor;
|
||||
}
|
||||
|
||||
public boolean hasMinor()
|
||||
{
|
||||
return mMinor != null;
|
||||
}
|
||||
|
||||
public Integer getRelease()
|
||||
{
|
||||
return mRelease;
|
||||
}
|
||||
|
||||
public boolean hasRelease()
|
||||
{
|
||||
return mRelease != null;
|
||||
}
|
||||
|
||||
public char getPatch()
|
||||
{
|
||||
return mPatch;
|
||||
}
|
||||
|
||||
public boolean hasPatch()
|
||||
{
|
||||
return mPatch != null;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(hasMajor() ? getMajor() : "x");
|
||||
sb.append(".").append(hasMinor() ? getMinor() : "x");
|
||||
sb.append(".").append(hasRelease() ? getRelease() : "x");
|
||||
if(hasPatch())
|
||||
{
|
||||
sb.append(mPatch);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Version other)
|
||||
{
|
||||
if(hasMajor() && other.hasMajor())
|
||||
{
|
||||
if(getMajor() != other.getMajor())
|
||||
{
|
||||
return Integer.compare(getMajor(), other.getMajor());
|
||||
}
|
||||
else
|
||||
{
|
||||
if(hasMinor() && other.hasMinor())
|
||||
{
|
||||
if(getMinor() != other.getMinor())
|
||||
{
|
||||
return Integer.compare(getMinor(), other.getMinor());
|
||||
}
|
||||
else
|
||||
{
|
||||
if(hasRelease() && other.hasRelease())
|
||||
{
|
||||
if(getRelease() != other.getRelease())
|
||||
{
|
||||
return Integer.compare(getRelease(), other.getRelease());
|
||||
}
|
||||
else
|
||||
{
|
||||
if(hasPatch() && other.hasPatch())
|
||||
{
|
||||
if(getPatch() != other.getPatch())
|
||||
{
|
||||
return Character.compare(getPatch(), other.getPatch());
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return hasPatch() ? 1 : -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return hasRelease() ? -1 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return hasMinor() ? -1 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return hasMajor() ? -1 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user