From ac2612d59e05480110b6dc9d62abb8297934c5fc Mon Sep 17 00:00:00 2001 From: rusefi Date: Wed, 17 Jun 2020 01:14:45 -0400 Subject: [PATCH] TS plugin --- .../src/com/rusefi/ts_plugin/PluginEntry.java | 23 ++++++ java_tools/ts_plugin_launcher/.gitignore | 1 + .../com/rusefi/ts_plugin/TsPluginBody.java | 2 + .../rusefi/ts_plugin/TsPluginLauncher.java | 3 +- .../src/com/rusefi/ts_plugin/Updater.java | 75 +++++++++++++++---- 5 files changed, 86 insertions(+), 18 deletions(-) create mode 100644 java_tools/ts_plugin_launcher/.gitignore diff --git a/java_tools/ts_plugin/src/com/rusefi/ts_plugin/PluginEntry.java b/java_tools/ts_plugin/src/com/rusefi/ts_plugin/PluginEntry.java index f714b5dda9..8863017cbe 100644 --- a/java_tools/ts_plugin/src/com/rusefi/ts_plugin/PluginEntry.java +++ b/java_tools/ts_plugin/src/com/rusefi/ts_plugin/PluginEntry.java @@ -15,8 +15,11 @@ import javax.swing.*; import javax.xml.bind.JAXBException; import java.awt.event.ActionEvent; import java.io.IOException; +import java.io.InputStream; import java.util.Map; import java.util.TreeMap; +import java.util.jar.Attributes; +import java.util.jar.Manifest; /** * TsPlugin launcher creates an instance of this class via reflection. @@ -132,4 +135,24 @@ public class PluginEntry implements TsPluginBody { return null; } } + + /** + * this method is invoked by refection + * + * @see TsPluginBody#GET_VERSION + */ + @SuppressWarnings("unused") + public static String getVersion() { + try { + InputStream stream = PluginEntry.class.getResourceAsStream("/META-INF/MANIFEST.MF"); + Manifest manifest = new Manifest(stream); + + Attributes attributes = manifest.getMainAttributes(); + + String result = attributes.getValue("Built-Date"); + return result == null ? "Unknown version" : result; + } catch (IOException e) { + return "Unknown version"; + } + } } diff --git a/java_tools/ts_plugin_launcher/.gitignore b/java_tools/ts_plugin_launcher/.gitignore new file mode 100644 index 0000000000..f23b9489f9 --- /dev/null +++ b/java_tools/ts_plugin_launcher/.gitignore @@ -0,0 +1 @@ +*.jar \ No newline at end of file diff --git a/java_tools/ts_plugin_launcher/src/com/rusefi/ts_plugin/TsPluginBody.java b/java_tools/ts_plugin_launcher/src/com/rusefi/ts_plugin/TsPluginBody.java index 9d16ed1e0c..7a48b3d074 100644 --- a/java_tools/ts_plugin_launcher/src/com/rusefi/ts_plugin/TsPluginBody.java +++ b/java_tools/ts_plugin_launcher/src/com/rusefi/ts_plugin/TsPluginBody.java @@ -3,6 +3,8 @@ package com.rusefi.ts_plugin; import javax.swing.*; public interface TsPluginBody { + String GET_VERSION = "getVersion"; + JComponent getContent(); void close(); diff --git a/java_tools/ts_plugin_launcher/src/com/rusefi/ts_plugin/TsPluginLauncher.java b/java_tools/ts_plugin_launcher/src/com/rusefi/ts_plugin/TsPluginLauncher.java index e0bb31a135..2c9ab5318a 100644 --- a/java_tools/ts_plugin_launcher/src/com/rusefi/ts_plugin/TsPluginLauncher.java +++ b/java_tools/ts_plugin_launcher/src/com/rusefi/ts_plugin/TsPluginLauncher.java @@ -10,12 +10,11 @@ import javax.swing.*; * by the way TS installs stuff into %user%\.efianalytics\TunerStudio\plugins folder */ public class TsPluginLauncher implements ApplicationPlugin { + static final String VERSION = "alpha2020"; - public static final String VERSION = "alpha2020"; private final JPanel content = new JPanel(new VerticalFlowLayout()); public TsPluginLauncher() { - content.add(new JLabel("" + VERSION)); content.add(new Updater().getContent()); } diff --git a/java_tools/ts_plugin_launcher/src/com/rusefi/ts_plugin/Updater.java b/java_tools/ts_plugin_launcher/src/com/rusefi/ts_plugin/Updater.java index ce42374577..a5cb14cc70 100644 --- a/java_tools/ts_plugin_launcher/src/com/rusefi/ts_plugin/Updater.java +++ b/java_tools/ts_plugin_launcher/src/com/rusefi/ts_plugin/Updater.java @@ -1,33 +1,70 @@ package com.rusefi.ts_plugin; import com.rusefi.autoupdate.AutoupdateUtil; +import org.putgemin.VerticalFlowLayout; import javax.swing.*; import java.awt.event.ActionEvent; +import java.io.File; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.MalformedURLException; import java.net.URLClassLoader; +import static com.rusefi.ts_plugin.TsPluginLauncher.VERSION; + public class Updater { private static final String PLUGIN_BODY_JAR = "rusefi_plugin_body.jar"; - private static final String TITLE = "rusEFI plugin installer " + TsPluginLauncher.VERSION; + private static final String TITLE = "rusEFI plugin installer " + VERSION; - private final JPanel content = new JPanel(); + private final JPanel content = new JPanel(new VerticalFlowLayout()); public Updater() { - JButton download = new JButton("Download"); + content.add(new JLabel("" + VERSION)); + + String version = null; + if (new File(PLUGIN_BODY_JAR).exists()) { + version = getVersion(); + } + + JButton download = new JButton("Download latest"); + if (version != null) { + JButton run = new JButton("Run " + version); + run.addActionListener(new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + try { + startPlugin(); + } catch (IllegalAccessException | MalformedURLException | ClassNotFoundException | InstantiationException ex) { + run.setText(e.toString()); + } + } + }); + + content.add(run); + } download.addActionListener(new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { new Thread(() -> startDownload(download)).start(); - - } }); content.add(download); } + private String getVersion() { + try { + Class clazz = getPluginClass(); + Method method = clazz.getMethod(TsPluginBody.GET_VERSION); + return (String) method.invoke(null); + } catch (NoSuchMethodException | MalformedURLException | ClassNotFoundException | IllegalAccessException | InvocationTargetException e) { + return null; + } + } + private void startDownload(JButton download) { SwingUtilities.invokeLater(new Runnable() { @Override @@ -42,27 +79,33 @@ public class Updater { AutoupdateUtil.downloadAutoupdateFile(PLUGIN_BODY_JAR, connectionAndMeta.getHttpConnection(), connectionAndMeta.getCompleteFileSize(), TITLE); - URLClassLoader jarClassLoader = AutoupdateUtil.getClassLoaderByJar(PLUGIN_BODY_JAR); - - Class clazz = Class.forName("com.rusefi.ts_plugin.PluginEntry", true, jarClassLoader); - TsPluginBody instance = (TsPluginBody) clazz.newInstance(); - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - replaceWith(instance); - } - }); + startPlugin(); } catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException e) { download.setEnabled(true); - } + } + private void startPlugin() throws MalformedURLException, ClassNotFoundException, InstantiationException, IllegalAccessException { + Class clazz = getPluginClass(); + TsPluginBody instance = (TsPluginBody) clazz.newInstance(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + replaceWith(instance); + } + }); + } + + private static Class getPluginClass() throws MalformedURLException, ClassNotFoundException { + URLClassLoader jarClassLoader = AutoupdateUtil.getClassLoaderByJar(PLUGIN_BODY_JAR); + return Class.forName("com.rusefi.ts_plugin.PluginEntry", true, jarClassLoader); } private void replaceWith(TsPluginBody instance) { content.removeAll(); content.add(instance.getContent()); + AutoupdateUtil.trueLayout(content.getParent()); } public JPanel getContent() {