X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fde%2Ftodesbaum%2Fjsite%2Fgui%2FUpdateChecker.java;h=44be635ae9ea5c7595192ee0b7f3d7f3cffa5a56;hb=a7d90795bb3f97633bdeb0ccc5b060f39f14eb54;hp=9f5ebf4ecaabf2e170e7fa9d480b50070de61d44;hpb=ad548a5cd100faf20905658ea389ad1f680807f8;p=jSite.git diff --git a/src/de/todesbaum/jsite/gui/UpdateChecker.java b/src/de/todesbaum/jsite/gui/UpdateChecker.java index 9f5ebf4..44be635 100644 --- a/src/de/todesbaum/jsite/gui/UpdateChecker.java +++ b/src/de/todesbaum/jsite/gui/UpdateChecker.java @@ -19,146 +19,263 @@ package de.todesbaum.jsite.gui; -import java.awt.BorderLayout; -import java.awt.event.ActionEvent; - -import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JProgressBar; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; import de.todesbaum.jsite.application.Freenet7Interface; -import de.todesbaum.jsite.i18n.I18n; -import de.todesbaum.jsite.i18n.I18nContainer; +import de.todesbaum.jsite.main.Main; +import de.todesbaum.jsite.main.Version; +import de.todesbaum.util.freenet.fcp2.Client; +import de.todesbaum.util.freenet.fcp2.ClientGet; +import de.todesbaum.util.freenet.fcp2.Connection; +import de.todesbaum.util.freenet.fcp2.Message; +import de.todesbaum.util.freenet.fcp2.Persistence; +import de.todesbaum.util.freenet.fcp2.ReturnType; +import de.todesbaum.util.freenet.fcp2.Verbosity; +import de.todesbaum.util.io.Closer; /** * Checks for newer versions of jSite. * * @author David ‘Bombe’ Roden <bombe@freenetproject.org> */ -public class UpdateChecker { +public class UpdateChecker implements Runnable { + + /** Counter for connection names. */ + private static int counter = 0; + + /** The edition for the update check URL. */ + private static final int UPDATE_EDITION = 0; /** The URL for update checks. */ - @SuppressWarnings("unused") - private static final String UPDATE_KEY = "USK@e3myoFyp5avg6WYN16ImHri6J7Nj8980Fm~aQe4EX1U,QvbWT0ImE0TwLODTl7EoJx2NBnwDxTbLTE6zkB-eGPs,AQACAAE/jSite/0/currentVersion.txt"; + private static final String UPDATE_KEY = "USK@e3myoFyp5avg6WYN16ImHri6J7Nj8980Fm~aQe4EX1U,QvbWT0ImE0TwLODTl7EoJx2NBnwDxTbLTE6zkB-eGPs,AQACAAE"; + + /** Object used for synchronization. */ + private final Object syncObject = new Object(); + + /** Update listeners. */ + private final List updateListeners = new ArrayList(); - /** The parent of the dialog. */ - @SuppressWarnings("unused") - private final JFrame parent; + /** Whether the main thread should stop. */ + private boolean shouldStop = false; + + /** Current last found edition of update key. */ + private int lastUpdateEdition = UPDATE_EDITION; + + /** Last found version. */ + private Version lastVersion = Main.getVersion(); /** The freenet interface. */ - @SuppressWarnings("unused") private final Freenet7Interface freenetInterface; - /** The cancel action. */ - @SuppressWarnings("unused") - private Action cancelAction; - /** * Creates a new update checker that uses the given frame as its parent and * communications via the given freenet interface. * - * @param parent - * The parent of the dialog * @param freenetInterface * The freenet interface */ - public UpdateChecker(JFrame parent, Freenet7Interface freenetInterface) { - this.parent = parent; + public UpdateChecker(Freenet7Interface freenetInterface) { this.freenetInterface = freenetInterface; - initActions(); } // - // ACTIONS + // EVENT LISTENER MANAGEMENT // /** - * Checks for updates, showing a dialog with an indeterminate progress bar. + * Adds an update listener to the list of registered listeners. + * + * @param updateListener + * The update listener to add + */ + public void addUpdateListener(UpdateListener updateListener) { + updateListeners.add(updateListener); + } + + /** + * Removes the given listener from the list of registered listeners. + * + * @param updateListener + * The update listener to remove */ - public void checkForUpdates() { - showBusyDialog(); + public void removeUpdateListener(UpdateListener updateListener) { + updateListeners.remove(updateListener); + } + + /** + * Notifies all listeners that a version was found. + * + * @param foundVersion + * The version that was found + * @param versionTimestamp + * The timestamp of the version + */ + protected void fireUpdateFound(Version foundVersion, long versionTimestamp) { + for (UpdateListener updateListener : updateListeners) { + updateListener.foundUpdateData(foundVersion, versionTimestamp); + } } // - // PRIVATE METHODS + // ACCESSORS // /** - * Initializes all actions. + * Returns the latest version that was found. + * + * @return The latest found version */ - private void initActions() { - cancelAction = new AbstractAction(I18n.getMessage("")) { - - /** - * {@inheritDoc} - */ - public void actionPerformed(ActionEvent actionEvent) { - /* TODO */ - } - }; + public Version getLatestVersion() { + return lastVersion; + } + + // + // ACTIONS + // + + /** + * Starts the update checker. + */ + public void start() { + new Thread(this).start(); } /** - * Shows a “please wait” dialog. + * Stops the update checker. */ - private void showBusyDialog() { - new Thread(new Runnable() { - - @SuppressWarnings("synthetic-access") - public void run() { - BusyPanel busyPanel = new BusyPanel(); - JButton cancelButton = new JButton(cancelAction); - JOptionPane.showOptionDialog(parent, busyPanel, I18n.getMessage(""), 0, JOptionPane.INFORMATION_MESSAGE, null, new Object[] { cancelButton }, cancelButton); - } - }).start(); + public void stop() { + synchronized (syncObject) { + shouldStop = true; + syncObject.notifyAll(); + } } + // + // PRIVATE METHODS + // + /** - * A panel that shows a busy progress bar and a “please wait” message. + * Returns whether the update checker should stop. * - * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @return true if the update checker should stop, + * false otherwise */ - private class BusyPanel extends JPanel { - - /** - * Creates a new busy panel. - */ - public BusyPanel() { - super(new BorderLayout(12, 12)); - initComponents(); + private boolean shouldStop() { + synchronized (syncObject) { + return shouldStop; } + } - // - // PRIVATE METHODS - // - - /** - * Initializes all components of this panel. - */ - private void initComponents() { - final JLabel label = new JLabel(I18n.getMessage("")); /* TODO */ - JProgressBar progressBar = new JProgressBar(); - progressBar.setIndeterminate(true); + /** + * Creates the URI of the update file for the given edition. + * + * @param edition + * The edition number + * @return The URI for the update file for the given edition + */ + private String constructUpdateKey(int edition) { + return UPDATE_KEY + "/jSite/" + edition + "/jSite.properties"; + } - add(label, BorderLayout.PAGE_START); - add(progressBar, BorderLayout.PAGE_END); + // + // INTERFACE Runnable + // - I18nContainer.getInstance().registerRunnable(new Runnable() { + /** + * {@inheritDoc} + */ + public void run() { + Connection connection = freenetInterface.getConnection("jSite-" + ++counter + "-UpdateChecker"); + try { + connection.connect(); + } catch (IOException e1) { + e1.printStackTrace(); + } + Client client = new Client(connection); + boolean checkNow = false; + int currentEdition = lastUpdateEdition; + while (!shouldStop()) { + checkNow = false; + System.out.println("Trying " + constructUpdateKey(currentEdition)); + ClientGet clientGet = new ClientGet("get-update-key"); + clientGet.setUri(constructUpdateKey(currentEdition)); + clientGet.setPersistence(Persistence.CONNECTION); + clientGet.setReturnType(ReturnType.direct); + clientGet.setVerbosity(Verbosity.ALL); + try { + client.execute(clientGet); + boolean stop = false; + while (!stop) { + Message message = client.readMessage(); + System.out.println(message); + if ("GetFailed".equals(message.getName())) { + if ("27".equals(message.get("code"))) { + String editionString = message.get("redirecturi").split("/")[2]; + int editionNumber = -1; + try { + editionNumber = Integer.parseInt(editionString); + } catch (NumberFormatException nfe1) { + /* ignore. */ + } + if (editionNumber != -1) { + System.out.println("Found new edition " + editionNumber); + currentEdition = editionNumber; + lastUpdateEdition = editionNumber; + checkNow = true; + break; + } + } + } + if ("AllData".equals(message.getName())) { + System.out.println("Update data found."); + InputStream dataInputStream = null; + Properties properties = new Properties(); + try { + dataInputStream = message.getPayloadInputStream(); + properties.load(dataInputStream); + } finally { + Closer.close(dataInputStream); + } - /** - * {@inheritDoc} - */ - public void run() { - label.setText(I18n.getMessage("")); /* TODO */ + String foundVersionString = properties.getProperty("jSite.Version"); + if (foundVersionString != null) { + Version foundVersion = Version.parse(foundVersionString); + if (foundVersion != null) { + lastVersion = foundVersion; + String versionTimestampString = properties.getProperty("jSite.Date"); + System.out.println(versionTimestampString); + long versionTimestamp = -1; + try { + versionTimestamp = Long.parseLong(versionTimestampString); + } catch (NumberFormatException nfe1) { + /* ignore. */ + } + fireUpdateFound(foundVersion, versionTimestamp); + stop = true; + checkNow = true; + ++currentEdition; + } + } + } + } + } catch (IOException e) { + System.out.println("Got IOException: " + e.getMessage()); + e.printStackTrace(); + } + if (!checkNow && !shouldStop()) { + synchronized (syncObject) { + try { + syncObject.wait(15 * 60 * 1000); + } catch (InterruptedException ie1) { + /* ignore. */ + } } - }); + } } - } }