mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-14 09:37:36 -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:
13
build.gradle
13
build.gradle
@@ -51,7 +51,6 @@ dependencies {
|
|||||||
implementation 'com.github.DSheirer.jmbe:jmbe-api:1.0.0'
|
implementation 'com.github.DSheirer.jmbe:jmbe-api:1.0.0'
|
||||||
|
|
||||||
//mavenCentral/jcenter imports
|
//mavenCentral/jcenter imports
|
||||||
implementation 'org.apache.commons:commons-math3:3.6.1'
|
|
||||||
implementation 'ch.qos.logback:logback-core:1.2.3'
|
implementation 'ch.qos.logback:logback-core:1.2.3'
|
||||||
implementation 'ch.qos.logback:logback-classic:1.2.3'
|
implementation 'ch.qos.logback:logback-classic:1.2.3'
|
||||||
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.9.8'
|
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.9.8'
|
||||||
@@ -60,6 +59,7 @@ dependencies {
|
|||||||
implementation 'com.github.jiconfont:jiconfont-javafx:1.0.0'
|
implementation 'com.github.jiconfont:jiconfont-javafx:1.0.0'
|
||||||
implementation 'com.github.jiconfont:jiconfont-swing:1.0.1'
|
implementation 'com.github.jiconfont:jiconfont-swing:1.0.1'
|
||||||
implementation 'com.github.wendykierp:JTransforms:3.1'
|
implementation 'com.github.wendykierp:JTransforms:3.1'
|
||||||
|
implementation 'com.google.code.gson:gson:2.8.6'
|
||||||
implementation 'com.google.guava:guava:27.0.1-jre'
|
implementation 'com.google.guava:guava:27.0.1-jre'
|
||||||
implementation 'com.jidesoft:jide-oss:3.6.18'
|
implementation 'com.jidesoft:jide-oss:3.6.18'
|
||||||
implementation 'com.miglayout:miglayout-swing:5.2'
|
implementation 'com.miglayout:miglayout-swing:5.2'
|
||||||
@@ -68,18 +68,22 @@ dependencies {
|
|||||||
implementation 'io.github.dsheirer:radio-reference-api:15.1.4'
|
implementation 'io.github.dsheirer:radio-reference-api:15.1.4'
|
||||||
implementation 'javax.usb:usb-api:1.0.2'
|
implementation 'javax.usb:usb-api:1.0.2'
|
||||||
implementation 'net.coderazzi:tablefilter-swing:5.4.0'
|
implementation 'net.coderazzi:tablefilter-swing:5.4.0'
|
||||||
|
implementation 'org.apache.commons:commons-compress:1.20'
|
||||||
|
implementation 'commons-io:commons-io:2.7'
|
||||||
implementation 'org.apache.commons:commons-lang3:3.8.1'
|
implementation 'org.apache.commons:commons-lang3:3.8.1'
|
||||||
implementation 'org.apache.commons:commons-io:1.3.2'
|
implementation 'org.apache.commons:commons-math3:3.6.1'
|
||||||
implementation 'org.apache.mina:mina-core:2.1.3'
|
implementation 'org.apache.mina:mina-core:2.1.3'
|
||||||
implementation 'org.apache.mina:mina-http:2.1.3'
|
implementation 'org.apache.mina:mina-http:2.1.3'
|
||||||
implementation 'org.controlsfx:controlsfx:11.0.1'
|
implementation 'org.controlsfx:controlsfx:11.0.1'
|
||||||
|
implementation 'org.rauschig:jarchivelib:1.0.0'
|
||||||
|
|
||||||
implementation 'org.slf4j:slf4j-api:1.7.25'
|
implementation 'org.slf4j:slf4j-api:1.7.25'
|
||||||
implementation 'org.usb4java:libusb4java:1.3.0'
|
implementation 'org.usb4java:libusb4java:1.3.0'
|
||||||
implementation 'org.usb4java:usb4java:1.3.0'
|
implementation 'org.usb4java:usb4java:1.3.0'
|
||||||
implementation 'org.usb4java:usb4java-javax:1.3.0'
|
implementation 'org.usb4java:usb4java-javax:1.3.0'
|
||||||
implementation 'pl.edu.icm:JLargeArrays:1.6'
|
implementation 'pl.edu.icm:JLargeArrays:1.6'
|
||||||
|
|
||||||
//The must remain as compile options to ensure they are included in the build to produce multi-OS images
|
//These must remain as compile options to ensure they are included in the build to produce multi-OS images
|
||||||
compile "org.openjfx:javafx-base:13:win"
|
compile "org.openjfx:javafx-base:13:win"
|
||||||
compile "org.openjfx:javafx-base:13:linux"
|
compile "org.openjfx:javafx-base:13:linux"
|
||||||
compile "org.openjfx:javafx-base:13:mac"
|
compile "org.openjfx:javafx-base:13:mac"
|
||||||
@@ -174,7 +178,8 @@ runtime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
|
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
|
||||||
modules = ['java.desktop', 'java.naming', 'jdk.unsupported', 'jdk.unsupported.desktop', 'java.net.http', 'java.sql']
|
modules = ['java.desktop', 'java.naming', 'jdk.unsupported', 'jdk.unsupported.desktop', 'java.net.http',
|
||||||
|
'java.sql', 'jdk.crypto.ec']
|
||||||
imageZip = hasTargetJdk ? file("$buildDir/image/sdr-trunk.zip") : file("$buildDir/image/sdr-trunk-" + version + ".zip")
|
imageZip = hasTargetJdk ? file("$buildDir/image/sdr-trunk.zip") : file("$buildDir/image/sdr-trunk-" + version + ".zip")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ import io.github.dsheirer.gui.preference.PreferenceEditorType;
|
|||||||
import io.github.dsheirer.gui.preference.UserPreferencesEditor;
|
import io.github.dsheirer.gui.preference.UserPreferencesEditor;
|
||||||
import io.github.dsheirer.gui.preference.ViewUserPreferenceEditorRequest;
|
import io.github.dsheirer.gui.preference.ViewUserPreferenceEditorRequest;
|
||||||
import io.github.dsheirer.icon.IconModel;
|
import io.github.dsheirer.icon.IconModel;
|
||||||
|
import io.github.dsheirer.jmbe.JmbeEditor;
|
||||||
|
import io.github.dsheirer.jmbe.JmbeEditorRequest;
|
||||||
import io.github.dsheirer.module.log.EventLogManager;
|
import io.github.dsheirer.module.log.EventLogManager;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
import io.github.dsheirer.preference.UserPreferences;
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
@@ -68,12 +70,14 @@ public class JavaFxWindowManager extends Application
|
|||||||
public static final String USER_PREFERENCES_EDITOR = "preferences";
|
public static final String USER_PREFERENCES_EDITOR = "preferences";
|
||||||
public static final String STAGE_MONITOR_KEY_CHANNEL_MAP_EDITOR = "channel.map";
|
public static final String STAGE_MONITOR_KEY_CHANNEL_MAP_EDITOR = "channel.map";
|
||||||
public static final String STAGE_MONITOR_KEY_ICON_MANAGER_EDITOR = "icon.manager";
|
public static final String STAGE_MONITOR_KEY_ICON_MANAGER_EDITOR = "icon.manager";
|
||||||
|
public static final String STAGE_MONITOR_KEY_JMBE_EDITOR = "jmbe.editor";
|
||||||
public static final String STAGE_MONITOR_KEY_PLAYLIST_EDITOR = "playlist";
|
public static final String STAGE_MONITOR_KEY_PLAYLIST_EDITOR = "playlist";
|
||||||
public static final String STAGE_MONITOR_KEY_USER_PREFERENCES_EDITOR = "user.preferences";
|
public static final String STAGE_MONITOR_KEY_USER_PREFERENCES_EDITOR = "user.preferences";
|
||||||
|
|
||||||
private JFXPanel mJFXPanel;
|
private JFXPanel mJFXPanel;
|
||||||
private ChannelMapEditor mChannelMapEditor;
|
private ChannelMapEditor mChannelMapEditor;
|
||||||
private IconManager mIconManager;
|
private IconManager mIconManager;
|
||||||
|
private JmbeEditor mJmbeEditor;
|
||||||
private PlaylistEditor mPlaylistEditor;
|
private PlaylistEditor mPlaylistEditor;
|
||||||
private PlaylistManager mPlaylistManager;
|
private PlaylistManager mPlaylistManager;
|
||||||
private UserPreferences mUserPreferences;
|
private UserPreferences mUserPreferences;
|
||||||
@@ -81,6 +85,7 @@ public class JavaFxWindowManager extends Application
|
|||||||
|
|
||||||
private Stage mChannelMapStage;
|
private Stage mChannelMapStage;
|
||||||
private Stage mIconManagerStage;
|
private Stage mIconManagerStage;
|
||||||
|
private Stage mJmbeEditorStage;
|
||||||
private Stage mPlaylistStage;
|
private Stage mPlaylistStage;
|
||||||
private Stage mUserPreferencesStage;
|
private Stage mUserPreferencesStage;
|
||||||
|
|
||||||
@@ -205,6 +210,56 @@ public class JavaFxWindowManager extends Application
|
|||||||
return mIconManager;
|
return mIconManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes a JMBE s editor request
|
||||||
|
*/
|
||||||
|
@Subscribe
|
||||||
|
public void process(final JmbeEditorRequest request)
|
||||||
|
{
|
||||||
|
if(request.isCloseEditorRequest())
|
||||||
|
{
|
||||||
|
execute(() -> {
|
||||||
|
getJmbeEditorStage().hide();
|
||||||
|
mJmbeEditorStage = null;
|
||||||
|
mJmbeEditor = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
execute(() -> {
|
||||||
|
getJmbeEditorStage().show();
|
||||||
|
getJmbeEditorStage().requestFocus();
|
||||||
|
getJmbeEditorStage().toFront();
|
||||||
|
getJmbeEditor().process(request);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stage getJmbeEditorStage()
|
||||||
|
{
|
||||||
|
if(mJmbeEditorStage == null)
|
||||||
|
{
|
||||||
|
createJFXPanel();
|
||||||
|
Scene scene = new Scene(getJmbeEditor(), 650, 650);
|
||||||
|
mJmbeEditorStage = new Stage();
|
||||||
|
mJmbeEditorStage.setTitle("sdrtrunk - JMBE Library Updater");
|
||||||
|
mJmbeEditorStage.setScene(scene);
|
||||||
|
mUserPreferences.getJavaFxPreferences().monitor(mJmbeEditorStage, STAGE_MONITOR_KEY_JMBE_EDITOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mJmbeEditorStage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JmbeEditor getJmbeEditor()
|
||||||
|
{
|
||||||
|
if(mJmbeEditor == null)
|
||||||
|
{
|
||||||
|
mJmbeEditor = new JmbeEditor(mUserPreferences);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mJmbeEditor;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lazy construct and access the playlist editor
|
* Lazy construct and access the playlist editor
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ public class PlaylistEditor extends BorderPane
|
|||||||
{
|
{
|
||||||
if(mChannelEditor == null)
|
if(mChannelEditor == null)
|
||||||
{
|
{
|
||||||
mChannelEditor = new ChannelEditor(mPlaylistManager);
|
mChannelEditor = new ChannelEditor(mPlaylistManager, mUserPreferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mChannelEditor;
|
return mChannelEditor;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import io.github.dsheirer.module.decode.config.AuxDecodeConfiguration;
|
|||||||
import io.github.dsheirer.module.decode.config.DecodeConfiguration;
|
import io.github.dsheirer.module.decode.config.DecodeConfiguration;
|
||||||
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.record.RecorderType;
|
import io.github.dsheirer.record.RecorderType;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
@@ -60,9 +61,9 @@ public class AMConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager
|
* @param playlistManager
|
||||||
*/
|
*/
|
||||||
public AMConfigurationEditor(PlaylistManager playlistManager)
|
public AMConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager);
|
super(playlistManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
getTitledPanesBox().getChildren().add(getRecordPane());
|
getTitledPanesBox().getChildren().add(getRecordPane());
|
||||||
|
|||||||
@@ -25,13 +25,17 @@ package io.github.dsheirer.gui.playlist.channel;
|
|||||||
import io.github.dsheirer.alias.AliasModel;
|
import io.github.dsheirer.alias.AliasModel;
|
||||||
import io.github.dsheirer.controller.channel.Channel;
|
import io.github.dsheirer.controller.channel.Channel;
|
||||||
import io.github.dsheirer.controller.channel.ChannelException;
|
import io.github.dsheirer.controller.channel.ChannelException;
|
||||||
|
import io.github.dsheirer.eventbus.MyEventBus;
|
||||||
import io.github.dsheirer.gui.control.MaxLengthUnaryOperator;
|
import io.github.dsheirer.gui.control.MaxLengthUnaryOperator;
|
||||||
import io.github.dsheirer.gui.playlist.Editor;
|
import io.github.dsheirer.gui.playlist.Editor;
|
||||||
|
import io.github.dsheirer.gui.preference.PreferenceEditorType;
|
||||||
|
import io.github.dsheirer.gui.preference.ViewUserPreferenceEditorRequest;
|
||||||
import io.github.dsheirer.module.decode.DecoderType;
|
import io.github.dsheirer.module.decode.DecoderType;
|
||||||
import io.github.dsheirer.module.decode.config.AuxDecodeConfiguration;
|
import io.github.dsheirer.module.decode.config.AuxDecodeConfiguration;
|
||||||
import io.github.dsheirer.module.decode.config.DecodeConfiguration;
|
import io.github.dsheirer.module.decode.config.DecodeConfiguration;
|
||||||
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfigTuner;
|
import io.github.dsheirer.source.config.SourceConfigTuner;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
@@ -48,6 +52,7 @@ import javafx.geometry.Insets;
|
|||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.ButtonType;
|
import javafx.scene.control.ButtonType;
|
||||||
|
import javafx.scene.control.CheckBox;
|
||||||
import javafx.scene.control.ComboBox;
|
import javafx.scene.control.ComboBox;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.ScrollPane;
|
import javafx.scene.control.ScrollPane;
|
||||||
@@ -78,6 +83,7 @@ public abstract class ChannelConfigurationEditor extends Editor<Channel>
|
|||||||
private final static Logger mLog = LoggerFactory.getLogger(ChannelConfigurationEditor.class);
|
private final static Logger mLog = LoggerFactory.getLogger(ChannelConfigurationEditor.class);
|
||||||
|
|
||||||
private PlaylistManager mPlaylistManager;
|
private PlaylistManager mPlaylistManager;
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
protected EditorModificationListener mEditorModificationListener = new EditorModificationListener();
|
protected EditorModificationListener mEditorModificationListener = new EditorModificationListener();
|
||||||
private Button mPlayButton;
|
private Button mPlayButton;
|
||||||
private TextField mSystemField;
|
private TextField mSystemField;
|
||||||
@@ -97,9 +103,10 @@ public abstract class ChannelConfigurationEditor extends Editor<Channel>
|
|||||||
private IconNode mStopGraphicNode;
|
private IconNode mStopGraphicNode;
|
||||||
private ChannelProcessingMonitor mChannelProcessingMonitor = new ChannelProcessingMonitor();
|
private ChannelProcessingMonitor mChannelProcessingMonitor = new ChannelProcessingMonitor();
|
||||||
|
|
||||||
public ChannelConfigurationEditor(PlaylistManager playlistManager)
|
public ChannelConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
mPlaylistManager = playlistManager;
|
mPlaylistManager = playlistManager;
|
||||||
|
mUserPreferences = userPreferences;
|
||||||
|
|
||||||
setMaxWidth(Double.MAX_VALUE);
|
setMaxWidth(Double.MAX_VALUE);
|
||||||
|
|
||||||
@@ -317,6 +324,45 @@ public abstract class ChannelConfigurationEditor extends Editor<Channel>
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(requiresJmbeLibrarySetup() &&
|
||||||
|
mUserPreferences.getJmbeLibraryPreference().getAlertIfMissingLibraryRequired() &&
|
||||||
|
!getItem().processingProperty().get())
|
||||||
|
{
|
||||||
|
String content = "The decoder for this channel configuration requires the (optional) JMBE " +
|
||||||
|
"library to produce audio and the JMBE library is not currently setup. Do you want to " +
|
||||||
|
"setup the JMBE library?";
|
||||||
|
|
||||||
|
Alert alert = new Alert(Alert.AlertType.CONFIRMATION, content, ButtonType.YES, ButtonType.NO);
|
||||||
|
alert.setTitle("JMBE Library");
|
||||||
|
alert.setHeaderText("Setup JMBE Library?");
|
||||||
|
|
||||||
|
Label label = new Label(content);
|
||||||
|
label.setMaxWidth(Double.MAX_VALUE);
|
||||||
|
label.setMaxHeight(Double.MAX_VALUE);
|
||||||
|
label.getStyleClass().add("content");
|
||||||
|
label.setWrapText(true);
|
||||||
|
|
||||||
|
CheckBox checkBox = new CheckBox("Don't Show This Again");
|
||||||
|
checkBox.setOnAction(event1 -> {
|
||||||
|
boolean dontShowAgain = checkBox.isSelected();
|
||||||
|
mUserPreferences.getJmbeLibraryPreference().setAlertIfMissingLibraryRequired(!dontShowAgain);
|
||||||
|
});
|
||||||
|
|
||||||
|
VBox contentBox = new VBox();
|
||||||
|
contentBox.setPrefWidth(360);
|
||||||
|
contentBox.setSpacing(10);
|
||||||
|
contentBox.getChildren().addAll(label, checkBox);
|
||||||
|
alert.getDialogPane().setContent(contentBox);
|
||||||
|
alert.initOwner(getPlayButton().getScene().getWindow());
|
||||||
|
Optional<ButtonType> optionalButtonType = alert.showAndWait();
|
||||||
|
|
||||||
|
if(optionalButtonType.isPresent() && optionalButtonType.get() == ButtonType.YES)
|
||||||
|
{
|
||||||
|
MyEventBus.getEventBus().post(new ViewUserPreferenceEditorRequest(PreferenceEditorType.JMBE_LIBRARY));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!getItem().processingProperty().get())
|
if(!getItem().processingProperty().get())
|
||||||
{
|
{
|
||||||
ThreadPool.SCHEDULED.execute(() -> {
|
ThreadPool.SCHEDULED.execute(() -> {
|
||||||
@@ -366,6 +412,17 @@ public abstract class ChannelConfigurationEditor extends Editor<Channel>
|
|||||||
return mPlayButton;
|
return mPlayButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the decoder type for the channel configuration requires the JMBE library and if the
|
||||||
|
* application is not currently setup for the JMBE library.
|
||||||
|
*/
|
||||||
|
private boolean requiresJmbeLibrarySetup()
|
||||||
|
{
|
||||||
|
return getItem() != null &&
|
||||||
|
getItem().getDecodeConfiguration().getDecoderType().providesMBEAudioFrames() &&
|
||||||
|
!mUserPreferences.getJmbeLibraryPreference().hasJmbeLibraryPath();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggles the text and graphic of the channel play button to reflect the playing state of the channel
|
* Toggles the text and graphic of the channel play button to reflect the playing state of the channel
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ package io.github.dsheirer.gui.playlist.channel;
|
|||||||
|
|
||||||
import io.github.dsheirer.module.decode.DecoderType;
|
import io.github.dsheirer.module.decode.DecoderType;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -44,26 +45,27 @@ public class ChannelConfigurationEditorFactory
|
|||||||
* @param playlistManager for the editor
|
* @param playlistManager for the editor
|
||||||
* @return constructed editor
|
* @return constructed editor
|
||||||
*/
|
*/
|
||||||
public static ChannelConfigurationEditor getEditor(DecoderType decoderType, PlaylistManager playlistManager)
|
public static ChannelConfigurationEditor getEditor(DecoderType decoderType, PlaylistManager playlistManager,
|
||||||
|
UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
switch(decoderType)
|
switch(decoderType)
|
||||||
{
|
{
|
||||||
case AM:
|
case AM:
|
||||||
return new AMConfigurationEditor(playlistManager);
|
return new AMConfigurationEditor(playlistManager, userPreferences);
|
||||||
case NBFM:
|
case NBFM:
|
||||||
return new NBFMConfigurationEditor(playlistManager);
|
return new NBFMConfigurationEditor(playlistManager, userPreferences);
|
||||||
case LTR_NET:
|
case LTR_NET:
|
||||||
return new LTRNetConfigurationEditor(playlistManager);
|
return new LTRNetConfigurationEditor(playlistManager, userPreferences);
|
||||||
case LTR:
|
case LTR:
|
||||||
return new LTRConfigurationEditor(playlistManager);
|
return new LTRConfigurationEditor(playlistManager, userPreferences);
|
||||||
case MPT1327:
|
case MPT1327:
|
||||||
return new MPT1327ConfigurationEditor(playlistManager);
|
return new MPT1327ConfigurationEditor(playlistManager, userPreferences);
|
||||||
case PASSPORT:
|
case PASSPORT:
|
||||||
return new PassportConfigurationEditor(playlistManager);
|
return new PassportConfigurationEditor(playlistManager, userPreferences);
|
||||||
case P25_PHASE1:
|
case P25_PHASE1:
|
||||||
return new P25P1ConfigurationEditor(playlistManager);
|
return new P25P1ConfigurationEditor(playlistManager, userPreferences);
|
||||||
case P25_PHASE2:
|
case P25_PHASE2:
|
||||||
return new P25P2ConfigurationEditor(playlistManager);
|
return new P25P2ConfigurationEditor(playlistManager, userPreferences);
|
||||||
default:
|
default:
|
||||||
if(decoderType != null && !mLoggedUnrecognizedTypes.contains(decoderType))
|
if(decoderType != null && !mLoggedUnrecognizedTypes.contains(decoderType))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import io.github.dsheirer.controller.channel.Channel;
|
|||||||
import io.github.dsheirer.module.decode.DecoderFactory;
|
import io.github.dsheirer.module.decode.DecoderFactory;
|
||||||
import io.github.dsheirer.module.decode.DecoderType;
|
import io.github.dsheirer.module.decode.DecoderType;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.source.config.SourceConfigTuner;
|
import io.github.dsheirer.source.config.SourceConfigTuner;
|
||||||
import io.github.dsheirer.source.config.SourceConfigTunerMultipleFrequency;
|
import io.github.dsheirer.source.config.SourceConfigTunerMultipleFrequency;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
@@ -79,6 +80,7 @@ public class ChannelEditor extends SplitPane
|
|||||||
{
|
{
|
||||||
private final static Logger mLog = LoggerFactory.getLogger(ChannelEditor.class);
|
private final static Logger mLog = LoggerFactory.getLogger(ChannelEditor.class);
|
||||||
private PlaylistManager mPlaylistManager;
|
private PlaylistManager mPlaylistManager;
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
private TableView<Channel> mChannelTableView;
|
private TableView<Channel> mChannelTableView;
|
||||||
private Label mPlaceholderLabel;
|
private Label mPlaceholderLabel;
|
||||||
private MenuButton mNewButton;
|
private MenuButton mNewButton;
|
||||||
@@ -101,10 +103,11 @@ public class ChannelEditor extends SplitPane
|
|||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager containing playlists and channel configurations
|
* @param playlistManager containing playlists and channel configurations
|
||||||
*/
|
*/
|
||||||
public ChannelEditor(PlaylistManager playlistManager)
|
public ChannelEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
mPlaylistManager = playlistManager;
|
mPlaylistManager = playlistManager;
|
||||||
mUnknownConfigurationEditor = new UnknownConfigurationEditor(mPlaylistManager);
|
mUserPreferences = userPreferences;
|
||||||
|
mUnknownConfigurationEditor = new UnknownConfigurationEditor(mPlaylistManager, userPreferences);
|
||||||
|
|
||||||
HBox channelsBox = new HBox();
|
HBox channelsBox = new HBox();
|
||||||
channelsBox.setSpacing(10.0);
|
channelsBox.setSpacing(10.0);
|
||||||
@@ -200,7 +203,8 @@ public class ChannelEditor extends SplitPane
|
|||||||
|
|
||||||
if(editor == null)
|
if(editor == null)
|
||||||
{
|
{
|
||||||
editor = ChannelConfigurationEditorFactory.getEditor(channelDecoderType, mPlaylistManager);
|
editor = ChannelConfigurationEditorFactory.getEditor(channelDecoderType, mPlaylistManager,
|
||||||
|
mUserPreferences);
|
||||||
|
|
||||||
if(editor != null)
|
if(editor != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import io.github.dsheirer.module.decode.ltrstandard.DecodeConfigLTRStandard;
|
|||||||
import io.github.dsheirer.module.log.EventLogType;
|
import io.github.dsheirer.module.log.EventLogType;
|
||||||
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.record.RecorderType;
|
import io.github.dsheirer.record.RecorderType;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
@@ -74,10 +75,11 @@ public class LTRConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
/**
|
/**
|
||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager
|
* @param playlistManager
|
||||||
|
* @param userPreferences
|
||||||
*/
|
*/
|
||||||
public LTRConfigurationEditor(PlaylistManager playlistManager)
|
public LTRConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager);
|
super(playlistManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import io.github.dsheirer.module.decode.ltrnet.DecodeConfigLTRNet;
|
|||||||
import io.github.dsheirer.module.log.EventLogType;
|
import io.github.dsheirer.module.log.EventLogType;
|
||||||
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.record.RecorderType;
|
import io.github.dsheirer.record.RecorderType;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
@@ -74,10 +75,11 @@ public class LTRNetConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
/**
|
/**
|
||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager
|
* @param playlistManager
|
||||||
|
* @param userPreferences
|
||||||
*/
|
*/
|
||||||
public LTRNetConfigurationEditor(PlaylistManager playlistManager)
|
public LTRNetConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager);
|
super(playlistManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import io.github.dsheirer.module.decode.mpt1327.DecodeConfigMPT1327;
|
|||||||
import io.github.dsheirer.module.log.EventLogType;
|
import io.github.dsheirer.module.log.EventLogType;
|
||||||
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.record.RecorderType;
|
import io.github.dsheirer.record.RecorderType;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
@@ -84,10 +85,11 @@ public class MPT1327ConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
/**
|
/**
|
||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager
|
* @param playlistManager
|
||||||
|
* @param userPreferences
|
||||||
*/
|
*/
|
||||||
public MPT1327ConfigurationEditor(PlaylistManager playlistManager)
|
public MPT1327ConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager);
|
super(playlistManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
getTitledPanesBox().getChildren().add(getEventLogPane());
|
getTitledPanesBox().getChildren().add(getEventLogPane());
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import io.github.dsheirer.module.decode.nbfm.DecodeConfigNBFM;
|
|||||||
import io.github.dsheirer.module.log.EventLogType;
|
import io.github.dsheirer.module.log.EventLogType;
|
||||||
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.record.RecorderType;
|
import io.github.dsheirer.record.RecorderType;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
@@ -73,10 +74,11 @@ public class NBFMConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
/**
|
/**
|
||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager
|
* @param playlistManager
|
||||||
|
* @param userPreferences
|
||||||
*/
|
*/
|
||||||
public NBFMConfigurationEditor(PlaylistManager playlistManager)
|
public NBFMConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager);
|
super(playlistManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import io.github.dsheirer.module.decode.p25.phase1.P25P1Decoder;
|
|||||||
import io.github.dsheirer.module.log.EventLogType;
|
import io.github.dsheirer.module.log.EventLogType;
|
||||||
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.record.RecorderType;
|
import io.github.dsheirer.record.RecorderType;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
@@ -80,10 +81,11 @@ public class P25P1ConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
/**
|
/**
|
||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager
|
* @param playlistManager
|
||||||
|
* @param userPreferences
|
||||||
*/
|
*/
|
||||||
public P25P1ConfigurationEditor(PlaylistManager playlistManager)
|
public P25P1ConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager);
|
super(playlistManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
getTitledPanesBox().getChildren().add(getEventLogPane());
|
getTitledPanesBox().getChildren().add(getEventLogPane());
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import io.github.dsheirer.module.decode.p25.phase2.enumeration.ScrambleParameter
|
|||||||
import io.github.dsheirer.module.log.EventLogType;
|
import io.github.dsheirer.module.log.EventLogType;
|
||||||
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.record.RecorderType;
|
import io.github.dsheirer.record.RecorderType;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
@@ -70,10 +71,11 @@ public class P25P2ConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
/**
|
/**
|
||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager
|
* @param playlistManager
|
||||||
|
* @param userPreferences
|
||||||
*/
|
*/
|
||||||
public P25P2ConfigurationEditor(PlaylistManager playlistManager)
|
public P25P2ConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager);
|
super(playlistManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
getTitledPanesBox().getChildren().add(getEventLogPane());
|
getTitledPanesBox().getChildren().add(getEventLogPane());
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import io.github.dsheirer.module.decode.passport.DecodeConfigPassport;
|
|||||||
import io.github.dsheirer.module.log.EventLogType;
|
import io.github.dsheirer.module.log.EventLogType;
|
||||||
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.record.RecorderType;
|
import io.github.dsheirer.record.RecorderType;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
@@ -66,10 +67,11 @@ public class PassportConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
/**
|
/**
|
||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager
|
* @param playlistManager
|
||||||
|
* @param userPreferences
|
||||||
*/
|
*/
|
||||||
public PassportConfigurationEditor(PlaylistManager playlistManager)
|
public PassportConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager);
|
super(playlistManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import io.github.dsheirer.module.decode.config.AuxDecodeConfiguration;
|
|||||||
import io.github.dsheirer.module.decode.config.DecodeConfiguration;
|
import io.github.dsheirer.module.decode.config.DecodeConfiguration;
|
||||||
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
import io.github.dsheirer.module.log.config.EventLogConfiguration;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
import javafx.scene.control.TitledPane;
|
import javafx.scene.control.TitledPane;
|
||||||
@@ -45,9 +46,9 @@ public class UnknownConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param aliasModel
|
* @param aliasModel
|
||||||
*/
|
*/
|
||||||
public UnknownConfigurationEditor(PlaylistManager playlistManager)
|
public UnknownConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager);
|
super(playlistManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,17 +22,28 @@ package io.github.dsheirer.gui.preference.decoder;
|
|||||||
|
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import io.github.dsheirer.eventbus.MyEventBus;
|
import io.github.dsheirer.eventbus.MyEventBus;
|
||||||
|
import io.github.dsheirer.jmbe.JmbeCreator;
|
||||||
|
import io.github.dsheirer.jmbe.JmbeEditorRequest;
|
||||||
|
import io.github.dsheirer.jmbe.github.GitHub;
|
||||||
|
import io.github.dsheirer.jmbe.github.Release;
|
||||||
|
import io.github.dsheirer.jmbe.github.Version;
|
||||||
import io.github.dsheirer.preference.PreferenceType;
|
import io.github.dsheirer.preference.PreferenceType;
|
||||||
import io.github.dsheirer.preference.UserPreferences;
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.preference.decoder.JmbeLibraryPreference;
|
import io.github.dsheirer.util.ThreadPool;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
|
import javafx.geometry.HPos;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.ButtonType;
|
||||||
|
import javafx.scene.control.CheckBox;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.Priority;
|
import javafx.scene.layout.Region;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -45,27 +56,64 @@ import java.nio.file.Path;
|
|||||||
/**
|
/**
|
||||||
* Preference settings for decoders
|
* Preference settings for decoders
|
||||||
*/
|
*/
|
||||||
public class JmbeLibraryPreferenceEditor extends HBox
|
public class JmbeLibraryPreferenceEditor extends VBox
|
||||||
{
|
{
|
||||||
private final static Logger mLog = LoggerFactory.getLogger(JmbeLibraryPreferenceEditor.class);
|
private final static Logger mLog = LoggerFactory.getLogger(JmbeLibraryPreferenceEditor.class);
|
||||||
|
|
||||||
private static final String PATH_NOT_SET = "(not set)";
|
private static final String PATH_NOT_SET = "(not set)";
|
||||||
private JmbeLibraryPreference mJmbeLibraryPreference;
|
private static final String CREATE_LIBRARY = "Create Library";
|
||||||
|
private static final String CHECK_FOR_UPDATE = "Check For Library Update";
|
||||||
|
private static final String LIBRARY_NOT_SETUP = "None. Click Select or Create Library button to setup.";
|
||||||
|
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
private GridPane mEditorPane;
|
private GridPane mEditorPane;
|
||||||
private Label mJmbeLibraryLabel;
|
private Label mJmbeLibraryLabel;
|
||||||
private Button mPathToJmbeLibraryButton;
|
private Label mJmbeVersionLabel;
|
||||||
private Button mPathToJmbeLibraryResetButton;
|
|
||||||
private Label mPathToJmbeLibraryLabel;
|
private Label mPathToJmbeLibraryLabel;
|
||||||
|
private Button mSelectButton;
|
||||||
|
private Button mResetButton;
|
||||||
|
private Button mCreateButton;
|
||||||
|
private HBox mButtonsBox;
|
||||||
|
private CheckBox mAlertUserWhenMissingCheckBox;
|
||||||
|
|
||||||
public JmbeLibraryPreferenceEditor(UserPreferences userPreferences)
|
public JmbeLibraryPreferenceEditor(UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
mJmbeLibraryPreference = userPreferences.getJmbeLibraryPreference();
|
mUserPreferences = userPreferences;
|
||||||
|
|
||||||
//Register to receive directory preference update notifications so we can update the path labels
|
//Register to receive directory preference update notifications so we can update the path labels
|
||||||
MyEventBus.getEventBus().register(this);
|
MyEventBus.getEventBus().register(this);
|
||||||
|
|
||||||
HBox.setHgrow(getEditorPane(), Priority.ALWAYS);
|
setPadding(new Insets(10,10,10,10));
|
||||||
getChildren().add(getEditorPane());
|
setSpacing(10);
|
||||||
|
getChildren().addAll(getEditorPane(), getButtonsBox(), getAlertUserWhenMissingCheckBox());
|
||||||
|
}
|
||||||
|
|
||||||
|
private CheckBox getAlertUserWhenMissingCheckBox()
|
||||||
|
{
|
||||||
|
if(mAlertUserWhenMissingCheckBox == null)
|
||||||
|
{
|
||||||
|
mAlertUserWhenMissingCheckBox = new CheckBox("Alert when decoder requires missing JMBE library");
|
||||||
|
mAlertUserWhenMissingCheckBox.setSelected(mUserPreferences.getJmbeLibraryPreference()
|
||||||
|
.getAlertIfMissingLibraryRequired());
|
||||||
|
mAlertUserWhenMissingCheckBox.setOnAction(event -> {
|
||||||
|
boolean alert = mAlertUserWhenMissingCheckBox.isSelected();
|
||||||
|
mUserPreferences.getJmbeLibraryPreference().setAlertIfMissingLibraryRequired(alert);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return mAlertUserWhenMissingCheckBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
private HBox getButtonsBox()
|
||||||
|
{
|
||||||
|
if(mButtonsBox == null)
|
||||||
|
{
|
||||||
|
mButtonsBox = new HBox();
|
||||||
|
mButtonsBox.setSpacing(10);
|
||||||
|
mButtonsBox.getChildren().addAll(getCreateButton(), getSelectButton(), getResetButton());
|
||||||
|
}
|
||||||
|
|
||||||
|
return mButtonsBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GridPane getEditorPane()
|
private GridPane getEditorPane()
|
||||||
@@ -73,85 +121,206 @@ public class JmbeLibraryPreferenceEditor extends HBox
|
|||||||
if(mEditorPane == null)
|
if(mEditorPane == null)
|
||||||
{
|
{
|
||||||
mEditorPane = new GridPane();
|
mEditorPane = new GridPane();
|
||||||
mEditorPane.setPadding(new Insets(10, 10, 10, 10));
|
mEditorPane.setVgap(10);
|
||||||
|
mEditorPane.setHgap(10);
|
||||||
|
|
||||||
int row = 0;
|
int row = 0;
|
||||||
|
|
||||||
GridPane.setMargin(getJmbeLibraryLabel(), new Insets(0, 10, 0, 0));
|
mEditorPane.add(getJmbeLibraryLabel(), 0, row, 2, 1);
|
||||||
mEditorPane.add(getJmbeLibraryLabel(), 0, row);
|
|
||||||
|
Label versionLabel = new Label("Current Version:");
|
||||||
|
GridPane.setHalignment(versionLabel, HPos.RIGHT);
|
||||||
|
mEditorPane.add(versionLabel, 0, ++row);
|
||||||
|
|
||||||
|
mEditorPane.add(getJmbeVersionLabel(), 1, row);
|
||||||
|
|
||||||
|
Label fileLabel = new Label("File:");
|
||||||
|
GridPane.setHalignment(fileLabel, HPos.RIGHT);
|
||||||
|
mEditorPane.add(fileLabel, 0, ++row);
|
||||||
|
|
||||||
GridPane.setMargin(getPathToJmbeLibraryLabel(), new Insets(0, 10, 0, 0));
|
|
||||||
mEditorPane.add(getPathToJmbeLibraryLabel(), 1, row);
|
mEditorPane.add(getPathToJmbeLibraryLabel(), 1, row);
|
||||||
|
|
||||||
GridPane.setMargin(getPathToJmbeLibraryButton(), new Insets(2, 10, 2, 0));
|
|
||||||
mEditorPane.add(getPathToJmbeLibraryButton(), 2, row);
|
|
||||||
|
|
||||||
GridPane.setMargin(getPathToJmbeLibraryResetButton(), new Insets(2, 0, 2, 0));
|
|
||||||
mEditorPane.add(getPathToJmbeLibraryResetButton(), 3, row++);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mEditorPane;
|
return mEditorPane;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Button getCreateButton()
|
||||||
|
{
|
||||||
|
if(mCreateButton == null)
|
||||||
|
{
|
||||||
|
mCreateButton = new Button();
|
||||||
|
mCreateButton.setText(mUserPreferences.getJmbeLibraryPreference()
|
||||||
|
.getPathJmbeLibrary() != null ? CHECK_FOR_UPDATE : CREATE_LIBRARY);
|
||||||
|
mCreateButton.setOnAction(event -> checkForUpdatedLibrary());
|
||||||
|
}
|
||||||
|
|
||||||
|
return mCreateButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for availability of an updated JMBE library
|
||||||
|
*/
|
||||||
|
private void checkForUpdatedLibrary()
|
||||||
|
{
|
||||||
|
ThreadPool.SCHEDULED.execute(() -> {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Version current = mUserPreferences.getJmbeLibraryPreference().getCurrentVersion();
|
||||||
|
final Release release = GitHub.getLatestRelease(JmbeCreator.GITHUB_JMBE_RELEASES_URL);
|
||||||
|
|
||||||
|
mLog.info("Checking for JMBE Library Updates ...");
|
||||||
|
mLog.info("Current: " + (current != null ? current.toString() : "empty"));
|
||||||
|
|
||||||
|
final boolean canUpdate = (release != null) && ((current == null) ||
|
||||||
|
(release.getVersion().compareTo(current) > 0));
|
||||||
|
|
||||||
|
if(release != null)
|
||||||
|
{
|
||||||
|
mLog.info("Available: " + release.getVersion().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(canUpdate)
|
||||||
|
{
|
||||||
|
mLog.info("JMBE Library update is available");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mLog.info("No JMBE library update is available at this time");
|
||||||
|
}
|
||||||
|
|
||||||
|
Platform.runLater(new Runnable()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if(canUpdate)
|
||||||
|
{
|
||||||
|
String content = "JMBE library version " + release.getVersion().toString() +
|
||||||
|
" is available. Would you like to download the latest source code and " +
|
||||||
|
"create an updated JMBE library?";
|
||||||
|
Alert alert = new Alert(Alert.AlertType.INFORMATION, content, ButtonType.YES, ButtonType.NO);
|
||||||
|
alert.setResizable(true);
|
||||||
|
|
||||||
|
//Workaroud for dialog sizing issue on Windows
|
||||||
|
alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE);
|
||||||
|
|
||||||
|
alert.setTitle("JMBE Library Update Check");
|
||||||
|
alert.setHeaderText("Update is available");
|
||||||
|
alert.initOwner(getCreateButton().getScene().getWindow());
|
||||||
|
alert.showAndWait().ifPresent(buttonType -> {
|
||||||
|
if(buttonType == ButtonType.YES)
|
||||||
|
{
|
||||||
|
mLog.info("Posting JMBE editor request to event bus");
|
||||||
|
MyEventBus.getEventBus().post(new JmbeEditorRequest(release));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Alert alert = new Alert(Alert.AlertType.INFORMATION,
|
||||||
|
"No JMBE library update is available.", ButtonType.OK);
|
||||||
|
alert.setTitle("JMBE Library Update Check");
|
||||||
|
if(release != null)
|
||||||
|
{
|
||||||
|
alert.setHeaderText("No update available");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
alert.setHeaderText("Unable to determine latest release version. Check network connection");
|
||||||
|
}
|
||||||
|
alert.initOwner(getCreateButton().getScene().getWindow());
|
||||||
|
alert.showAndWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Throwable t)
|
||||||
|
{
|
||||||
|
mLog.error("Error during JavaFX portion of create library");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch(Throwable t)
|
||||||
|
{
|
||||||
|
mLog.error("Error during create library", t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private Label getJmbeLibraryLabel()
|
private Label getJmbeLibraryLabel()
|
||||||
{
|
{
|
||||||
if(mJmbeLibraryLabel == null)
|
if(mJmbeLibraryLabel == null)
|
||||||
{
|
{
|
||||||
mJmbeLibraryLabel = new Label("JMBE Audio Library:");
|
mJmbeLibraryLabel = new Label("JMBE Audio Library");
|
||||||
}
|
}
|
||||||
|
|
||||||
return mJmbeLibraryLabel;
|
return mJmbeLibraryLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Button getPathToJmbeLibraryButton()
|
private Label getJmbeVersionLabel()
|
||||||
{
|
{
|
||||||
if(mPathToJmbeLibraryButton == null)
|
if(mJmbeVersionLabel == null)
|
||||||
{
|
{
|
||||||
mPathToJmbeLibraryButton = new Button("Change...");
|
mJmbeVersionLabel = new Label();
|
||||||
mPathToJmbeLibraryButton.setOnAction(new EventHandler<ActionEvent>()
|
Version version = mUserPreferences.getJmbeLibraryPreference().getCurrentVersion();
|
||||||
|
|
||||||
|
if(version != null)
|
||||||
|
{
|
||||||
|
mJmbeVersionLabel.setText(version.toString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mJmbeVersionLabel.setText(LIBRARY_NOT_SETUP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mJmbeVersionLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Button getSelectButton()
|
||||||
|
{
|
||||||
|
if(mSelectButton == null)
|
||||||
|
{
|
||||||
|
mSelectButton = new Button("Select...");
|
||||||
|
mSelectButton.setOnAction(new EventHandler<ActionEvent>()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void handle(ActionEvent event)
|
public void handle(ActionEvent event)
|
||||||
{
|
{
|
||||||
FileChooser fileChooser = new FileChooser();
|
FileChooser fileChooser = new FileChooser();
|
||||||
fileChooser.setTitle("Select JMBE Audio Library Location");
|
fileChooser.setTitle("Select JMBE Audio Library Location");
|
||||||
Stage stage = (Stage)getPathToJmbeLibraryButton().getScene().getWindow();
|
fileChooser.setInitialDirectory(mUserPreferences.getDirectoryPreference().getDefaultJmbeDirectory().toFile());
|
||||||
|
Stage stage = (Stage)getSelectButton().getScene().getWindow();
|
||||||
File selected = fileChooser.showOpenDialog(stage);
|
File selected = fileChooser.showOpenDialog(stage);
|
||||||
|
|
||||||
if(selected != null)
|
if(selected != null)
|
||||||
{
|
{
|
||||||
mJmbeLibraryPreference.setPathJmbeLibrary(selected.toPath());
|
mUserPreferences.getJmbeLibraryPreference().setPathJmbeLibrary(selected.toPath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return mPathToJmbeLibraryButton;
|
return mSelectButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Button getPathToJmbeLibraryResetButton()
|
private Button getResetButton()
|
||||||
{
|
{
|
||||||
if(mPathToJmbeLibraryResetButton == null)
|
if(mResetButton == null)
|
||||||
{
|
{
|
||||||
mPathToJmbeLibraryResetButton = new Button("Reset");
|
mResetButton = new Button("Reset");
|
||||||
mPathToJmbeLibraryResetButton.setOnAction(new EventHandler<ActionEvent>()
|
mResetButton.setOnAction(event -> mUserPreferences.getJmbeLibraryPreference().resetPathJmbeLibrary());
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void handle(ActionEvent event)
|
|
||||||
{
|
|
||||||
mJmbeLibraryPreference.resetPathJmbeLibrary();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mPathToJmbeLibraryResetButton;
|
return mResetButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Label getPathToJmbeLibraryLabel()
|
private Label getPathToJmbeLibraryLabel()
|
||||||
{
|
{
|
||||||
if(mPathToJmbeLibraryLabel == null)
|
if(mPathToJmbeLibraryLabel == null)
|
||||||
{
|
{
|
||||||
Path path = mJmbeLibraryPreference.getPathJmbeLibrary();
|
Path path = mUserPreferences.getJmbeLibraryPreference().getPathJmbeLibrary();
|
||||||
mPathToJmbeLibraryLabel = new Label(path != null ? path.toString() : PATH_NOT_SET);
|
mPathToJmbeLibraryLabel = new Label(path != null ? path.toString() : PATH_NOT_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,8 +332,14 @@ public class JmbeLibraryPreferenceEditor extends HBox
|
|||||||
{
|
{
|
||||||
if(preferenceType != null && preferenceType == PreferenceType.JMBE_LIBRARY)
|
if(preferenceType != null && preferenceType == PreferenceType.JMBE_LIBRARY)
|
||||||
{
|
{
|
||||||
Path path = mJmbeLibraryPreference.getPathJmbeLibrary();
|
Path path = mUserPreferences.getJmbeLibraryPreference().getPathJmbeLibrary();
|
||||||
getPathToJmbeLibraryLabel().setText(path != null ? path.toString() : PATH_NOT_SET);
|
getPathToJmbeLibraryLabel().setText(path != null ? path.toString() : PATH_NOT_SET);
|
||||||
|
Version version = mUserPreferences.getJmbeLibraryPreference().getCurrentVersion();
|
||||||
|
getJmbeVersionLabel().setText(version != null ? version.toString() : LIBRARY_NOT_SETUP);
|
||||||
|
getCreateButton().setText(mUserPreferences.getJmbeLibraryPreference()
|
||||||
|
.getPathJmbeLibrary() != null ? CHECK_FOR_UPDATE : CREATE_LIBRARY);
|
||||||
|
getAlertUserWhenMissingCheckBox().setSelected(mUserPreferences.getJmbeLibraryPreference()
|
||||||
|
.getAlertIfMissingLibraryRequired());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,6 +68,11 @@ public class DirectoryPreferenceEditor extends HBox
|
|||||||
private Button mResetEventLogsButton;
|
private Button mResetEventLogsButton;
|
||||||
private Label mEventLogsPathLabel;
|
private Label mEventLogsPathLabel;
|
||||||
|
|
||||||
|
private Label mJmbeLabel;
|
||||||
|
private Button mChangeJmbeButton;
|
||||||
|
private Button mResetJmbeButton;
|
||||||
|
private Label mJmbePathLabel;
|
||||||
|
|
||||||
private Label mPlaylistLabel;
|
private Label mPlaylistLabel;
|
||||||
private Button mChangePlaylistButton;
|
private Button mChangePlaylistButton;
|
||||||
private Button mResetPlaylistButton;
|
private Button mResetPlaylistButton;
|
||||||
@@ -157,6 +162,19 @@ public class DirectoryPreferenceEditor extends HBox
|
|||||||
mEditorPane.add(getResetEventLogsButton(), 3, row++);
|
mEditorPane.add(getResetEventLogsButton(), 3, row++);
|
||||||
|
|
||||||
|
|
||||||
|
GridPane.setMargin(getJmbeLabel(), new Insets(0, 10, 0, 0));
|
||||||
|
mEditorPane.add(getJmbeLabel(), 0, row);
|
||||||
|
|
||||||
|
GridPane.setMargin(getJmbePathLabel(), new Insets(0, 10, 0, 0));
|
||||||
|
mEditorPane.add(getJmbePathLabel(), 1, row);
|
||||||
|
|
||||||
|
GridPane.setMargin(getChangeJmbeButton(), new Insets(2, 10, 2, 0));
|
||||||
|
mEditorPane.add(getChangeJmbeButton(), 2, row);
|
||||||
|
|
||||||
|
GridPane.setMargin(getResetJmbeButton(), new Insets(2, 0, 2, 0));
|
||||||
|
mEditorPane.add(getResetJmbeButton(), 3, row++);
|
||||||
|
|
||||||
|
|
||||||
GridPane.setMargin(getPlaylistLabel(), new Insets(0, 10, 0, 0));
|
GridPane.setMargin(getPlaylistLabel(), new Insets(0, 10, 0, 0));
|
||||||
mEditorPane.add(getPlaylistLabel(), 0, row);
|
mEditorPane.add(getPlaylistLabel(), 0, row);
|
||||||
|
|
||||||
@@ -407,6 +425,71 @@ public class DirectoryPreferenceEditor extends HBox
|
|||||||
return mEventLogsPathLabel;
|
return mEventLogsPathLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Label getJmbeLabel()
|
||||||
|
{
|
||||||
|
if(mJmbeLabel == null)
|
||||||
|
{
|
||||||
|
mJmbeLabel = new Label("JMBE Libraries");
|
||||||
|
}
|
||||||
|
|
||||||
|
return mJmbeLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Button getChangeJmbeButton()
|
||||||
|
{
|
||||||
|
if(mChangeJmbeButton == null)
|
||||||
|
{
|
||||||
|
mChangeJmbeButton = new Button("Change...");
|
||||||
|
mChangeJmbeButton.setOnAction(new EventHandler<ActionEvent>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void handle(ActionEvent event)
|
||||||
|
{
|
||||||
|
DirectoryChooser directoryChooser = new DirectoryChooser();
|
||||||
|
directoryChooser.setTitle("Select JMBE Folder");
|
||||||
|
directoryChooser.setInitialDirectory(mDirectoryPreference.getDirectoryJmbe().toFile());
|
||||||
|
Stage stage = (Stage)getChangeJmbeButton().getScene().getWindow();
|
||||||
|
File selected = directoryChooser.showDialog(stage);
|
||||||
|
|
||||||
|
if(selected != null)
|
||||||
|
{
|
||||||
|
mDirectoryPreference.setDirectoryJmbe(selected.toPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return mChangeJmbeButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Button getResetJmbeButton()
|
||||||
|
{
|
||||||
|
if(mResetJmbeButton == null)
|
||||||
|
{
|
||||||
|
mResetJmbeButton = new Button("Reset");
|
||||||
|
mResetJmbeButton.setOnAction(new EventHandler<ActionEvent>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void handle(ActionEvent event)
|
||||||
|
{
|
||||||
|
mDirectoryPreference.resetDirectoryJmbe();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return mResetJmbeButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Label getJmbePathLabel()
|
||||||
|
{
|
||||||
|
if(mJmbePathLabel == null)
|
||||||
|
{
|
||||||
|
mJmbePathLabel = new Label(mDirectoryPreference.getDirectoryJmbe().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return mJmbePathLabel;
|
||||||
|
}
|
||||||
|
|
||||||
private Label getPlaylistLabel()
|
private Label getPlaylistLabel()
|
||||||
{
|
{
|
||||||
if(mPlaylistLabel == null)
|
if(mPlaylistLabel == null)
|
||||||
|
|||||||
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
package io.github.dsheirer.preference.decoder;
|
package io.github.dsheirer.preference.decoder;
|
||||||
|
|
||||||
|
import io.github.dsheirer.jmbe.github.Version;
|
||||||
import io.github.dsheirer.preference.Preference;
|
import io.github.dsheirer.preference.Preference;
|
||||||
import io.github.dsheirer.preference.PreferenceType;
|
import io.github.dsheirer.preference.PreferenceType;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
@@ -32,6 +33,8 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.prefs.Preferences;
|
import java.util.prefs.Preferences;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decoder preferences
|
* Decoder preferences
|
||||||
@@ -42,7 +45,10 @@ public class JmbeLibraryPreference extends Preference
|
|||||||
private Preferences mPreferences = Preferences.userNodeForPackage(JmbeLibraryPreference.class);
|
private Preferences mPreferences = Preferences.userNodeForPackage(JmbeLibraryPreference.class);
|
||||||
|
|
||||||
private static final String PREFERENCE_KEY_PATH_JMBE_LIBRARY = "path.jmbe.library.1.0.0";
|
private static final String PREFERENCE_KEY_PATH_JMBE_LIBRARY = "path.jmbe.library.1.0.0";
|
||||||
|
private static final String PREFERENCE_KEY_PATH_ALERT_LIBRARY_REQUIRED = "alert.jmbe.required";
|
||||||
|
private final Pattern VERSION_PATTERN = Pattern.compile(".*jmbe-(\\d{1,5}.\\d{1,5}.\\d{1,5}\\w*)\\.jar");
|
||||||
private Path mPathJmbeLibrary;
|
private Path mPathJmbeLibrary;
|
||||||
|
private Boolean mAlertIfMissingLibraryRequired;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs this preference with an update listener
|
* Constructs this preference with an update listener
|
||||||
@@ -60,6 +66,23 @@ public class JmbeLibraryPreference extends Preference
|
|||||||
return PreferenceType.JMBE_LIBRARY;
|
return PreferenceType.JMBE_LIBRARY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Version getCurrentVersion()
|
||||||
|
{
|
||||||
|
Path path = getPathJmbeLibrary();
|
||||||
|
|
||||||
|
if(path != null)
|
||||||
|
{
|
||||||
|
Matcher m = VERSION_PATTERN.matcher(path.toString());
|
||||||
|
|
||||||
|
if(m.matches())
|
||||||
|
{
|
||||||
|
return Version.fromString(m.group(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Path to the JMBE audio codec library
|
* Path to the JMBE audio codec library
|
||||||
*/
|
*/
|
||||||
@@ -73,6 +96,14 @@ public class JmbeLibraryPreference extends Preference
|
|||||||
return mPathJmbeLibrary;
|
return mPathJmbeLibrary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if a path to a JMBE library is setup (ie non-null).
|
||||||
|
*/
|
||||||
|
public boolean hasJmbeLibraryPath()
|
||||||
|
{
|
||||||
|
return getPathJmbeLibrary() != null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the path to the JMBE library
|
* Sets the path to the JMBE library
|
||||||
*/
|
*/
|
||||||
@@ -93,6 +124,30 @@ public class JmbeLibraryPreference extends Preference
|
|||||||
notifyPreferenceUpdated();
|
notifyPreferenceUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the user should be alerted when the JMBE library is not setup, but required for decoding.
|
||||||
|
*/
|
||||||
|
public boolean getAlertIfMissingLibraryRequired()
|
||||||
|
{
|
||||||
|
if(mAlertIfMissingLibraryRequired == null)
|
||||||
|
{
|
||||||
|
mAlertIfMissingLibraryRequired = mPreferences.getBoolean(PREFERENCE_KEY_PATH_ALERT_LIBRARY_REQUIRED, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mAlertIfMissingLibraryRequired;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value for alerting when the library is required for decoding but the library is not currently setup.
|
||||||
|
* @param alert true if the user should be alerted when the library is not setup, but required for decoding.
|
||||||
|
*/
|
||||||
|
public void setAlertIfMissingLibraryRequired(boolean alert)
|
||||||
|
{
|
||||||
|
mAlertIfMissingLibraryRequired = alert;
|
||||||
|
mPreferences.putBoolean(PREFERENCE_KEY_PATH_ALERT_LIBRARY_REQUIRED, mAlertIfMissingLibraryRequired);
|
||||||
|
notifyPreferenceUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the path stored in preferences and referenced by the key argument if it exists, otherwise returns the
|
* Returns the path stored in preferences and referenced by the key argument if it exists, otherwise returns the
|
||||||
* default path.
|
* default path.
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ public class DirectoryPreference extends Preference
|
|||||||
private static final String DIRECTORY_APPLICATION_ROOT = "SDRTrunk";
|
private static final String DIRECTORY_APPLICATION_ROOT = "SDRTrunk";
|
||||||
private static final String DIRECTORY_APPLICATION_LOG = "logs";
|
private static final String DIRECTORY_APPLICATION_LOG = "logs";
|
||||||
private static final String DIRECTORY_EVENT_LOG = "event_logs";
|
private static final String DIRECTORY_EVENT_LOG = "event_logs";
|
||||||
|
private static final String DIRECTORY_JMBE = "jmbe";
|
||||||
private static final String DIRECTORY_PLAYLIST = "playlist";
|
private static final String DIRECTORY_PLAYLIST = "playlist";
|
||||||
private static final String DIRECTORY_RECORDING = "recordings";
|
private static final String DIRECTORY_RECORDING = "recordings";
|
||||||
private static final String DIRECTORY_SCREEN_CAPTURE = "screen_captures";
|
private static final String DIRECTORY_SCREEN_CAPTURE = "screen_captures";
|
||||||
@@ -50,6 +51,7 @@ public class DirectoryPreference extends Preference
|
|||||||
private static final String PREFERENCE_KEY_DIRECTORY_APPLICATION_ROOT = "directory.application.root";
|
private static final String PREFERENCE_KEY_DIRECTORY_APPLICATION_ROOT = "directory.application.root";
|
||||||
private static final String PREFERENCE_KEY_DIRECTORY_APPLICATION_LOGS = "directory.application.logs";
|
private static final String PREFERENCE_KEY_DIRECTORY_APPLICATION_LOGS = "directory.application.logs";
|
||||||
private static final String PREFERENCE_KEY_DIRECTORY_EVENT_LOGS = "directory.event.logs";
|
private static final String PREFERENCE_KEY_DIRECTORY_EVENT_LOGS = "directory.event.logs";
|
||||||
|
private static final String PREFERENCE_KEY_DIRECTORY_JMBE = "directory.jmbe";
|
||||||
private static final String PREFERENCE_KEY_DIRECTORY_PLAYLIST = "directory.playlist";
|
private static final String PREFERENCE_KEY_DIRECTORY_PLAYLIST = "directory.playlist";
|
||||||
private static final String PREFERENCE_KEY_DIRECTORY_RECORDING = "directory.recording";
|
private static final String PREFERENCE_KEY_DIRECTORY_RECORDING = "directory.recording";
|
||||||
private static final String PREFERENCE_KEY_DIRECTORY_SCREEN_CAPTURE = "directory.screen.capture";
|
private static final String PREFERENCE_KEY_DIRECTORY_SCREEN_CAPTURE = "directory.screen.capture";
|
||||||
@@ -58,6 +60,7 @@ public class DirectoryPreference extends Preference
|
|||||||
private Path mDirectoryApplicationRoot;
|
private Path mDirectoryApplicationRoot;
|
||||||
private Path mDirectoryApplicationLogs;
|
private Path mDirectoryApplicationLogs;
|
||||||
private Path mDirectoryEventLogs;
|
private Path mDirectoryEventLogs;
|
||||||
|
private Path mDirectoryJmbe;
|
||||||
private Path mDirectoryPlaylist;
|
private Path mDirectoryPlaylist;
|
||||||
private Path mDirectoryRecording;
|
private Path mDirectoryRecording;
|
||||||
private Path mDirectoryScreenCapture;
|
private Path mDirectoryScreenCapture;
|
||||||
@@ -115,6 +118,7 @@ public class DirectoryPreference extends Preference
|
|||||||
{
|
{
|
||||||
mDirectoryApplicationLogs = null;
|
mDirectoryApplicationLogs = null;
|
||||||
mDirectoryEventLogs = null;
|
mDirectoryEventLogs = null;
|
||||||
|
mDirectoryJmbe = null;
|
||||||
mDirectoryPlaylist = null;
|
mDirectoryPlaylist = null;
|
||||||
mDirectoryRecording = null;
|
mDirectoryRecording = null;
|
||||||
mDirectoryScreenCapture = null;
|
mDirectoryScreenCapture = null;
|
||||||
@@ -204,6 +208,40 @@ public class DirectoryPreference extends Preference
|
|||||||
notifyPreferenceUpdated();
|
notifyPreferenceUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path to the folder for storing the JMBE audio library
|
||||||
|
*/
|
||||||
|
public Path getDirectoryJmbe()
|
||||||
|
{
|
||||||
|
if(mDirectoryJmbe == null)
|
||||||
|
{
|
||||||
|
mDirectoryJmbe = getPath(PREFERENCE_KEY_DIRECTORY_JMBE, getDefaultJmbeDirectory());
|
||||||
|
createDirectory(mDirectoryJmbe);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mDirectoryJmbe;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the path to the JMBE folder
|
||||||
|
*/
|
||||||
|
public void setDirectoryJmbe(Path path)
|
||||||
|
{
|
||||||
|
mDirectoryJmbe = path;
|
||||||
|
mPreferences.put(PREFERENCE_KEY_DIRECTORY_JMBE, path.toString());
|
||||||
|
notifyPreferenceUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a stored playlist directory preference so that the default path can be used again
|
||||||
|
*/
|
||||||
|
public void resetDirectoryJmbe()
|
||||||
|
{
|
||||||
|
mPreferences.remove(PREFERENCE_KEY_DIRECTORY_JMBE);
|
||||||
|
mDirectoryJmbe = null;
|
||||||
|
notifyPreferenceUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Path to the folder for storing playlist
|
* Path to the folder for storing playlist
|
||||||
*/
|
*/
|
||||||
@@ -364,6 +402,14 @@ public class DirectoryPreference extends Preference
|
|||||||
return getDirectoryApplicationRoot().resolve(DIRECTORY_EVENT_LOG);
|
return getDirectoryApplicationRoot().resolve(DIRECTORY_EVENT_LOG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default JMBE directory
|
||||||
|
*/
|
||||||
|
public Path getDefaultJmbeDirectory()
|
||||||
|
{
|
||||||
|
return getDirectoryApplicationRoot().resolve(DIRECTORY_JMBE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default playlist directory
|
* Default playlist directory
|
||||||
*/
|
*/
|
||||||
|
|||||||
76
src/main/java/io/github/dsheirer/util/FileUtil.java
Normal file
76
src/main/java/io/github/dsheirer/util/FileUtil.java
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.DirectoryStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File Utilities
|
||||||
|
*/
|
||||||
|
public class FileUtil
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Recursively searches for the named file starting in the specified directory.
|
||||||
|
* @param directory to search for the file
|
||||||
|
* @return path to the file or null if the file can't be found
|
||||||
|
* @throws IOException if there is a file system error or if the file is not found
|
||||||
|
*/
|
||||||
|
public static Path findFile(Path directory, String name) throws IOException
|
||||||
|
{
|
||||||
|
if(Files.isDirectory(directory))
|
||||||
|
{
|
||||||
|
DirectoryStream<Path> stream = Files.newDirectoryStream(directory);
|
||||||
|
Iterator<Path> it = stream.iterator();
|
||||||
|
Path path = null;
|
||||||
|
while(it.hasNext())
|
||||||
|
{
|
||||||
|
path = it.next();
|
||||||
|
|
||||||
|
if(Files.isDirectory(path))
|
||||||
|
{
|
||||||
|
Path candidate = findFile(path, name);
|
||||||
|
|
||||||
|
if(candidate != null)
|
||||||
|
{
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(path.endsWith(name))
|
||||||
|
{
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IOException("A directory required for this method [" +
|
||||||
|
(directory != null ? directory.toString() : "null") + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
101
src/main/java/io/github/dsheirer/util/OSType.java
Normal file
101
src/main/java/io/github/dsheirer/util/OSType.java
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public enum OSType
|
||||||
|
{
|
||||||
|
LINUX_32,
|
||||||
|
LINUX_64,
|
||||||
|
OSX_32,
|
||||||
|
OSX_64,
|
||||||
|
WINDOWS_32,
|
||||||
|
WINDOWS_64,
|
||||||
|
UNKNOWN;
|
||||||
|
|
||||||
|
public static EnumSet<OSType> WINDOWS_TYPES = EnumSet.of(WINDOWS_32, WINDOWS_64);
|
||||||
|
public static EnumSet<OSType> LINUX_TYPES = EnumSet.of(LINUX_32, LINUX_64, OSX_32, OSX_64);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this enumeration entry is a Windows type
|
||||||
|
*/
|
||||||
|
public boolean isWindows()
|
||||||
|
{
|
||||||
|
return WINDOWS_TYPES.contains(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this enumeration entry is a Linux type
|
||||||
|
*/
|
||||||
|
public boolean isLinux()
|
||||||
|
{
|
||||||
|
return LINUX_TYPES.contains(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detects the current host operating system and architecture
|
||||||
|
*/
|
||||||
|
public static OSType getCurrentOSType()
|
||||||
|
{
|
||||||
|
String os = System.getProperty("os.name", "unknown").toLowerCase(Locale.ENGLISH);
|
||||||
|
String arch = System.getProperty("os.arch");
|
||||||
|
|
||||||
|
if(os.contains("win"))
|
||||||
|
{
|
||||||
|
if(arch.contains("64"))
|
||||||
|
{
|
||||||
|
return OSType.WINDOWS_64;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return OSType.WINDOWS_32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(os.contains("mac") || os.contains("darwin"))
|
||||||
|
{
|
||||||
|
if(arch.contains("64"))
|
||||||
|
{
|
||||||
|
return OSType.OSX_64;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return OSType.OSX_32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(os.contains("nux") || os.contains("nix") || os.contains("aix"))
|
||||||
|
{
|
||||||
|
if(arch.contains("64"))
|
||||||
|
{
|
||||||
|
return OSType.LINUX_64;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return OSType.LINUX_32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OSType.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
158
src/main/java/io/github/dsheirer/util/ZipUtility.java
Normal file
158
src/main/java/io/github/dsheirer/util/ZipUtility.java
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
package io.github.dsheirer.util;
|
||||||
|
|
||||||
|
import org.rauschig.jarchivelib.ArchiveFormat;
|
||||||
|
import org.rauschig.jarchivelib.Archiver;
|
||||||
|
import org.rauschig.jarchivelib.ArchiverFactory;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This utility compresses a list of files to standard ZIP format file.
|
||||||
|
* It is able to compress all sub files and sub directories, recursively.
|
||||||
|
*
|
||||||
|
* @author www.codejava.net
|
||||||
|
*/
|
||||||
|
public class ZipUtility
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A constants for buffer size used to read/write data
|
||||||
|
*/
|
||||||
|
private static final int BUFFER_SIZE = 4096;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compresses a list of files to a destination zip file
|
||||||
|
*
|
||||||
|
* @param listFiles A collection of files and directories
|
||||||
|
* @param destZipFile The path of the destination zip file
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void zip(List<File> listFiles, String destZipFile) throws FileNotFoundException,
|
||||||
|
IOException
|
||||||
|
{
|
||||||
|
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(destZipFile));
|
||||||
|
for(File file : listFiles)
|
||||||
|
{
|
||||||
|
if(file.isDirectory())
|
||||||
|
{
|
||||||
|
zipDirectory(file, file.getName(), zos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zipFile(file, zos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zos.flush();
|
||||||
|
zos.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compresses files represented in an array of paths
|
||||||
|
*
|
||||||
|
* @param files a String array containing file paths
|
||||||
|
* @param destZipFile The path of the destination zip file
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void zip(String[] files, String destZipFile) throws FileNotFoundException, IOException
|
||||||
|
{
|
||||||
|
List<File> listFiles = new ArrayList<File>();
|
||||||
|
|
||||||
|
for(int i = 0; i < files.length; i++)
|
||||||
|
{
|
||||||
|
listFiles.add(new File(files[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
zip(listFiles, destZipFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a directory to the current zip output stream
|
||||||
|
*
|
||||||
|
* @param folder the directory to be added
|
||||||
|
* @param parentFolder the path of parent directory
|
||||||
|
* @param zos the current zip output stream
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void zipDirectory(File folder, String parentFolder, ZipOutputStream zos) throws
|
||||||
|
FileNotFoundException, IOException
|
||||||
|
{
|
||||||
|
if(folder == null || folder.listFiles() == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(File file : folder.listFiles())
|
||||||
|
{
|
||||||
|
if(file.exists())
|
||||||
|
{
|
||||||
|
if(file.isDirectory())
|
||||||
|
{
|
||||||
|
zipDirectory(file, parentFolder + "/" + file.getName(), zos);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
zos.putNextEntry(new ZipEntry(parentFolder + "/" + file.getName()));
|
||||||
|
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
|
||||||
|
long bytesRead = 0;
|
||||||
|
byte[] bytesIn = new byte[BUFFER_SIZE];
|
||||||
|
int read = 0;
|
||||||
|
while((read = bis.read(bytesIn)) != -1)
|
||||||
|
{
|
||||||
|
zos.write(bytesIn, 0, read);
|
||||||
|
bytesRead += read;
|
||||||
|
}
|
||||||
|
zos.closeEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a file to the current zip output stream
|
||||||
|
*
|
||||||
|
* @param file the file to be added
|
||||||
|
* @param zos the current zip output stream
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void zipFile(File file, ZipOutputStream zos) throws FileNotFoundException, IOException
|
||||||
|
{
|
||||||
|
zos.putNextEntry(new ZipEntry(file.getName()));
|
||||||
|
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
|
||||||
|
long bytesRead = 0;
|
||||||
|
byte[] bytesIn = new byte[BUFFER_SIZE];
|
||||||
|
int read = 0;
|
||||||
|
while((read = bis.read(bytesIn)) != -1)
|
||||||
|
{
|
||||||
|
zos.write(bytesIn, 0, read);
|
||||||
|
bytesRead += read;
|
||||||
|
}
|
||||||
|
zos.closeEntry();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unzips the specified file into the directory where it's located
|
||||||
|
*
|
||||||
|
* @param zipFile to unzip
|
||||||
|
* @return path to where the file was unzipped.
|
||||||
|
* @throws IOException if there are errors unzipping
|
||||||
|
*/
|
||||||
|
public static Path unzip(Path zipFile) throws IOException
|
||||||
|
{
|
||||||
|
Path parent = zipFile.getParent();
|
||||||
|
Archiver archiver = ArchiverFactory.createArchiver(ArchiveFormat.ZIP);
|
||||||
|
archiver.extract(zipFile.toFile(), parent.toFile());
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user