From c3e344e1d37e19cf03e22265cd19249145785502 Mon Sep 17 00:00:00 2001 From: Nicolas Roduit Date: Mon, 30 May 2022 13:49:16 +0200 Subject: [PATCH] Show message when a new release is available #278 --- annotations/idea/java/lang/annotations.xml | 3 + weasis-base/weasis-base-ui/pom.xml | 5 + .../org/weasis/base/ui/gui/WeasisWin.java | 114 ++++++++++++++++++ .../core/api/gui/util/AppProperties.java | 11 ++ .../java/org/weasis/dicom/qr/RsQuery.java | 15 ++- .../main/java/org/weasis/dicom/sr/SRView.java | 3 +- weasis-launcher/conf/ext-config.properties | 2 + .../org/weasis/launcher/WeasisLauncher.java | 2 + 8 files changed, 145 insertions(+), 10 deletions(-) diff --git a/annotations/idea/java/lang/annotations.xml b/annotations/idea/java/lang/annotations.xml index 484821018..3170cefa6 100644 --- a/annotations/idea/java/lang/annotations.xml +++ b/annotations/idea/java/lang/annotations.xml @@ -5,6 +5,9 @@ + + + diff --git a/weasis-base/weasis-base-ui/pom.xml b/weasis-base/weasis-base-ui/pom.xml index 2b1dfa3a5..5037e7a21 100644 --- a/weasis-base/weasis-base-ui/pom.xml +++ b/weasis-base/weasis-base-ui/pom.xml @@ -44,5 +44,10 @@ ${weasis.core.img.version} provided + + org.glassfish + jakarta.json + provided + diff --git a/weasis-base/weasis-base-ui/src/main/java/org/weasis/base/ui/gui/WeasisWin.java b/weasis-base/weasis-base-ui/src/main/java/org/weasis/base/ui/gui/WeasisWin.java index 48d23d995..6e16d29ab 100644 --- a/weasis-base/weasis-base-ui/src/main/java/org/weasis/base/ui/gui/WeasisWin.java +++ b/weasis-base/weasis-base-ui/src/main/java/org/weasis/base/ui/gui/WeasisWin.java @@ -9,6 +9,8 @@ */ package org.weasis.base.ui.gui; +import static java.time.temporal.ChronoUnit.SECONDS; + import bibliothek.extension.gui.dock.theme.EclipseTheme; import bibliothek.extension.gui.dock.theme.eclipse.EclipseTabDockActionLocation; import bibliothek.extension.gui.dock.theme.eclipse.EclipseTabStateInfo; @@ -52,26 +54,41 @@ import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; +import java.io.IOException; import java.io.PrintStream; +import java.io.StringReader; import java.lang.management.ManagementFactory; import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpResponse.BodyHandlers; +import java.time.Duration; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Optional; +import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; +import javax.json.Json; +import javax.json.JsonObject; +import javax.json.JsonReader; import javax.management.InstanceNotFoundException; import javax.management.JMException; import javax.management.MBeanServer; import javax.management.ObjectName; import javax.swing.Action; import javax.swing.Icon; +import javax.swing.JCheckBox; import javax.swing.JCheckBoxMenuItem; import javax.swing.JComponent; import javax.swing.JFrame; +import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; @@ -84,6 +101,7 @@ import javax.swing.TransferHandler; import javax.swing.TransferHandler.DropLocation; import javax.swing.WindowConstants; +import org.osgi.framework.Version; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.weasis.base.ui.Messages; @@ -313,6 +331,14 @@ public void createMainPanel() { UIManager.MAIN_AREA.getComponent().setTransferHandler(new SequenceHandler()); UIManager.MAIN_AREA.setLocation(CLocation.base().normalRectangle(0, 0, 1, 1)); UIManager.MAIN_AREA.setVisible(true); + + boolean updateRelease = + BundleTools.SYSTEM_PREFERENCES.getBooleanProperty("weasis.update.release", true); + boolean showDownloadRelease = + BundleTools.SYSTEM_PREFERENCES.getBooleanProperty("weasis.show.update.next.release", true); + if (updateRelease && showDownloadRelease) { + CompletableFuture.runAsync(() -> checkReleaseUpdate(frame)); + } } HashMap>> getSeriesByEntry( @@ -712,6 +738,37 @@ private JMenuBar createMenuBar() { openBrowser( websiteMenuItem, BundleTools.SYSTEM_PREFERENCES.getProperty("weasis.help.online"))); helpMenuItem.add(websiteMenuItem); + helpMenuItem.add(new JSeparator()); + + final JMenuItem updateMenuItem = new JMenuItem("Check for Updates..."); + updateMenuItem.addActionListener( + e -> { + JsonObject object = getLastRelease(); + if (object != null) { + Version vOld = AppProperties.getVersion(AppProperties.WEASIS_VERSION); + Version vNew = AppProperties.getVersion(object.getString("version")); + if (vNew.compareTo(vOld) > 0) { + openBrowser(updateMenuItem, object.getString("url")); + } else { + GuiExecutor.instance() + .execute( + () -> + JOptionPane.showMessageDialog( + updateMenuItem, + "The current release is already the latest release available.", + "Update", + JOptionPane.INFORMATION_MESSAGE)); + } + } + }); + helpMenuItem.add(updateMenuItem); + + final JMenuItem reportMenuItem = new JMenuItem("Submit a Bug Report"); + reportMenuItem.addActionListener( + e -> openBrowser(reportMenuItem, "https://github.com/nroduit/Weasis/issues")); + helpMenuItem.add(reportMenuItem); + helpMenuItem.add(new JSeparator()); + final JMenuItem aboutMenuItem = new JMenuItem( String.format(Messages.getString("WeasisAboutBox.about"), AppProperties.WEASIS_NAME)); @@ -726,6 +783,63 @@ private JMenuBar createMenuBar() { return menuBar; } + private JsonObject getLastRelease() { + try { + HttpRequest request = + HttpRequest.newBuilder() + .uri(new URI("https://nroduit.github.io/en/api/release/api.json")) + .timeout(Duration.of(10, SECONDS)) + .GET() + .build(); + + HttpResponse response = + HttpClient.newBuilder() + .followRedirects(HttpClient.Redirect.ALWAYS) + .build() + .send(request, BodyHandlers.ofString()); + + try (JsonReader jsonReader = Json.createReader(new StringReader(response.body()))) { + return jsonReader.readObject(); + } + } catch (IOException | URISyntaxException ex) { + LOGGER.error("Cannot check release update", ex); + } catch (InterruptedException ex2) { + Thread.currentThread().interrupt(); + } + return null; + } + + private void checkReleaseUpdate(Component parent) { + JsonObject object = getLastRelease(); + if (object != null) { + Version vOld = AppProperties.getVersion(AppProperties.WEASIS_VERSION); + // Version vNew = AppProperties.getVersion(object.getString("version")); + Version vNew = AppProperties.getVersion("4.0.2"); + if (vNew.compareTo(vOld) > 0) { + GuiExecutor.instance() + .execute( + () -> { + JLabel label = + new JLabel("A new release is available. Do you want to download it?"); + label.setAlignmentX(JLabel.RIGHT_ALIGNMENT); + JCheckBox dontAskMeAgain = new JCheckBox("Don't ask me again"); + dontAskMeAgain.setAlignmentX(JLabel.RIGHT_ALIGNMENT); + JPanel panel = GuiUtils.getVerticalBoxLayoutPanel(label, dontAskMeAgain); + int confirm = + JOptionPane.showConfirmDialog( + parent, panel, "Update", JOptionPane.YES_NO_OPTION); + if (confirm == 0) { + openBrowser(parent, object.getString("url")); + } + if (dontAskMeAgain.isSelected()) { + BundleTools.SYSTEM_PREFERENCES.putBooleanProperty( + "weasis.show.update.next.release", false); + } + }); + } + } + } + private void openBrowser(Component c, String ref) { try { URL url = new URL(ref); diff --git a/weasis-core/weasis-core-api/src/main/java/org/weasis/core/api/gui/util/AppProperties.java b/weasis-core/weasis-core-api/src/main/java/org/weasis/core/api/gui/util/AppProperties.java index e177f7ce9..d9d8887dd 100644 --- a/weasis-core/weasis-core-api/src/main/java/org/weasis/core/api/gui/util/AppProperties.java +++ b/weasis-core/weasis-core-api/src/main/java/org/weasis/core/api/gui/util/AppProperties.java @@ -14,6 +14,7 @@ import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceReference; +import org.osgi.framework.Version; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.weasis.core.util.FileUtil; @@ -129,4 +130,14 @@ public static File buildAccessibleTempDirectory(String... subFolderName) { } return AppProperties.APP_TEMP_DIR; } + + public static Version getVersion(String version) { + String v = ""; + if (version != null) { + int start = version.startsWith("v") ? 1 : 0; + int end = version.indexOf('-'); + v = end > 0 ? version.substring(start, end) : version; + } + return new Version(v); + } } diff --git a/weasis-dicom/weasis-dicom-qr/src/main/java/org/weasis/dicom/qr/RsQuery.java b/weasis-dicom/weasis-dicom-qr/src/main/java/org/weasis/dicom/qr/RsQuery.java index 2a62d175c..06a835f76 100644 --- a/weasis-dicom/weasis-dicom-qr/src/main/java/org/weasis/dicom/qr/RsQuery.java +++ b/weasis-dicom/weasis-dicom-qr/src/main/java/org/weasis/dicom/qr/RsQuery.java @@ -170,14 +170,13 @@ static void populateDicomModel(DicomModel dicomModel, Attributes item) { TagW.PatientPseudoUID, patientPseudoUID, DicomModel.patient.tagView()) { @Override public String toString() { - StringBuilder buf = new StringBuilder(getDisplayValue(this, Tag.PatientName)); - buf.append(" ["); - buf.append(getDisplayValue(this, Tag.PatientID)); - buf.append("] "); - buf.append(getDisplayValue(this, Tag.PatientBirthDate)); - buf.append(" "); - buf.append(getDisplayValue(this, Tag.PatientSex)); - return buf.toString(); + return getDisplayValue(this, Tag.PatientName) + + " [" + + getDisplayValue(this, Tag.PatientID) + + "] " + + getDisplayValue(this, Tag.PatientBirthDate) + + " " + + getDisplayValue(this, Tag.PatientSex); } }; DicomMediaUtils.writeMetaData(patient, item); diff --git a/weasis-dicom/weasis-dicom-sr/src/main/java/org/weasis/dicom/sr/SRView.java b/weasis-dicom/weasis-dicom-sr/src/main/java/org/weasis/dicom/sr/SRView.java index 856e8d299..787df965c 100644 --- a/weasis-dicom/weasis-dicom-sr/src/main/java/org/weasis/dicom/sr/SRView.java +++ b/weasis-dicom/weasis-dicom-sr/src/main/java/org/weasis/dicom/sr/SRView.java @@ -23,7 +23,6 @@ import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextPane; -import javax.swing.border.EmptyBorder; import javax.swing.event.HyperlinkEvent; import org.dcm4che3.data.Attributes; import org.dcm4che3.data.Tag; @@ -82,7 +81,7 @@ public SRView(Series series) { JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - htmlPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); + htmlPanel.setBorder(GuiUtils.getEmptyBorder(5, 5, 5, 5)); htmlPanel.setContentType("text/html"); htmlPanel.setEditable(false); htmlPanel.addHyperlinkListener( diff --git a/weasis-launcher/conf/ext-config.properties b/weasis-launcher/conf/ext-config.properties index d32aa6b40..2142c8f7e 100644 --- a/weasis-launcher/conf/ext-config.properties +++ b/weasis-launcher/conf/ext-config.properties @@ -61,6 +61,8 @@ org.apache.sling.commons.log.stack.limit=-1 weasis.show.disclaimer=false ##### Show a message when the release has changed weasis.show.release=false +##### Show a message when a new release is available +weasis.update.release=true ##### Allows exporting DICOM files. Default value is true. #weasis.export.dicom=false ##### Allows DICOM send. Is always false when weasis.export.dicom=false. diff --git a/weasis-launcher/src/main/java/org/weasis/launcher/WeasisLauncher.java b/weasis-launcher/src/main/java/org/weasis/launcher/WeasisLauncher.java index 2d48c16a7..43792b52e 100644 --- a/weasis-launcher/src/main/java/org/weasis/launcher/WeasisLauncher.java +++ b/weasis-launcher/src/main/java/org/weasis/launcher/WeasisLauncher.java @@ -996,6 +996,8 @@ else if (cleanCache && versionNew != null && !versionNew.equals(versionOld)) { if (update) { FileUtil.storeProperties(sourceIDProps, localSourceProp, null); + // Reset message when deploying a new release + currentProps.setProperty("weasis.show.update.next.release", Boolean.TRUE.toString()); } // Transmit weasis.properties