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}