001package apps; 002 003import java.awt.Desktop; 004import java.awt.FlowLayout; 005import java.awt.event.ActionEvent; 006 007import java.io.BufferedReader; 008import java.io.FileNotFoundException; 009import java.io.IOException; 010import java.io.InputStream; 011import java.io.InputStreamReader; 012 013import java.net.*; 014 015import javax.annotation.Nonnull; 016import javax.swing.BoxLayout; 017import javax.swing.Icon; 018import javax.swing.JButton; 019import javax.swing.JFrame; 020import javax.swing.JPanel; 021import javax.swing.JTextArea; 022 023import jmri.util.JmriJFrame; 024import jmri.util.swing.JmriPanel; 025import jmri.util.swing.WindowInterface; 026 027/** 028 * Swing action to check for more recent JMRI version. Checks a jmri.org URL for 029 * information. 030 * 031 * @author Bob Jacobsen Copyright (C) 2007, 2014 032 * @author Matt Harris Copyright (C) 2008 033 * 034 */ 035public class CheckForUpdateAction extends jmri.util.swing.JmriAbstractAction { 036 037 public CheckForUpdateAction(@Nonnull String s, @Nonnull WindowInterface wi) { 038 super(s, wi); 039 } 040 041 public CheckForUpdateAction(@Nonnull String s, @Nonnull Icon i, @Nonnull WindowInterface wi) { 042 super(s, i, wi); 043 } 044 045 public CheckForUpdateAction() { 046 super(Bundle.getMessage("TitleUpdate")); 047 } 048 049 @Override 050 public void actionPerformed(ActionEvent ev) { 051 052 final JFrame frame = new JmriJFrame(Bundle.getMessage("TitleUpdate"), false, false); 053 frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS)); 054 055 JTextArea text = new JTextArea(); 056 text.setEditable(false); 057 frame.add(text); 058 059 String productionrelease = ""; 060 String testrelease = ""; 061 062 String urlname = "https://www.jmri.org/releaselist"; 063 String downloadURI = "https://www.jmri.org/download/"; 064 065 URL url; 066 try { 067 url = new URI(urlname).toURL(); 068 } catch (MalformedURLException | URISyntaxException e){ 069 log.error("Unexpected failure in URL parsing", e); 070 return; 071 } 072 073 try ( InputStream in = url.openConnection().getInputStream(); 074 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); ) { 075 076 // search for releases 077 String line; 078 while ((line = reader.readLine()) != null) { 079 if (line.startsWith("production")) { 080 productionrelease = getNumber(reader); 081 } 082 if (line.startsWith("test")) { 083 testrelease = getNumber(reader); 084 } 085 } 086 } catch (FileNotFoundException e) { 087 log.debug("Unable to get version info from web", e); 088 } catch (IOException e) { 089 log.debug("Unexpected failure during reading", e); 090 } 091 092 // add content 093 text.append(Bundle.getMessage("MostRecent", productionrelease) + "\n"); 094 text.append(Bundle.getMessage("MostRecentTest", testrelease) + "\n"); 095 text.append(Bundle.getMessage("YouHaveVersion", jmri.Version.name()) + "\n"); // cleaner form is getCanonicalVersion() 096 097 JPanel p = new JPanel(); 098 p.setLayout(new FlowLayout()); 099 100 JButton go = new JButton(Bundle.getMessage("ButtonDownloadPage")); 101 go.addActionListener((ActionEvent event) -> { 102 try { 103 Desktop.getDesktop().browse(new URI(downloadURI)); 104 } catch (java.net.URISyntaxException e) { 105 log.error("Invalid page requested", e); 106 } catch (java.io.IOException e) { 107 log.error("Could no load page", e); 108 } 109 }); 110 p.add(go); 111 112 JButton close = new JButton(Bundle.getMessage("ButtonClose")); 113 close.addActionListener((ActionEvent event) -> { 114 frame.setVisible(false); 115 frame.dispose(); 116 }); 117 p.add(close); 118 119 frame.add(p); 120 frame.pack(); 121 122 // show 123 frame.setVisible(true); 124 } 125 126 @Nonnull 127 String getNumber(@Nonnull BufferedReader reader) throws java.io.IOException { 128 String line = reader.readLine(); // skip a line 129 log.debug("intentionally skipping line {}", line ); 130 line = reader.readLine(); 131 if (line == null) return ""; 132 return line.substring(0, line.length() - 1); // drop trailing : 133 } 134 135 // never invoked, because we overrode actionPerformed above 136 @Override 137 public JmriPanel makePanel() { 138 throw new IllegalArgumentException("Should not be invoked"); 139 } 140 141 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CheckForUpdateAction.class); 142 143}