2 * jSite-remote - UpdateChecker.java -
3 * Copyright © 2008 David Roden
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 package de.todesbaum.jsite.gui;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.Properties;
28 import javax.swing.JFrame;
30 import de.todesbaum.jsite.application.Freenet7Interface;
31 import de.todesbaum.jsite.main.Main;
32 import de.todesbaum.jsite.main.Version;
33 import de.todesbaum.util.freenet.fcp2.Client;
34 import de.todesbaum.util.freenet.fcp2.ClientGet;
35 import de.todesbaum.util.freenet.fcp2.Connection;
36 import de.todesbaum.util.freenet.fcp2.Message;
37 import de.todesbaum.util.freenet.fcp2.Persistence;
38 import de.todesbaum.util.freenet.fcp2.ReturnType;
39 import de.todesbaum.util.freenet.fcp2.Verbosity;
40 import de.todesbaum.util.io.Closer;
43 * Checks for newer versions of jSite.
45 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
47 public class UpdateChecker implements Runnable {
49 /** Counter for connection names. */
50 private static int counter = 0;
52 /** The edition for the update check URL. */
53 private static final int UPDATE_EDITION = 0;
55 /** The URL for update checks. */
56 private static final String UPDATE_KEY = "USK@e3myoFyp5avg6WYN16ImHri6J7Nj8980Fm~aQe4EX1U,QvbWT0ImE0TwLODTl7EoJx2NBnwDxTbLTE6zkB-eGPs,AQACAAE";
58 /** Object used for synchronization. */
59 private final Object syncObject = new Object();
61 /** Update listeners. */
62 private final List<UpdateListener> updateListeners = new ArrayList<UpdateListener>();
64 /** Whether the main thread should stop. */
65 private boolean shouldStop = false;
67 /** Current last found edition of update key. */
68 private int lastUpdateEdition = UPDATE_EDITION;
70 /** Last found version. */
71 private Version lastVersion = Main.getVersion();
73 /** The parent of the dialog. */
74 private final JFrame parent;
76 /** The freenet interface. */
77 private final Freenet7Interface freenetInterface;
80 * Creates a new update checker that uses the given frame as its parent and
81 * communications via the given freenet interface.
84 * The parent of the dialog
85 * @param freenetInterface
86 * The freenet interface
88 public UpdateChecker(JFrame parent, Freenet7Interface freenetInterface) {
90 this.freenetInterface = freenetInterface;
94 // EVENT LISTENER MANAGEMENT
97 public void addUpdateListener(UpdateListener updateListener) {
98 updateListeners.add(updateListener);
101 public void removeUpdateListener(UpdateListener updateListener) {
102 updateListeners.remove(updateListener);
105 protected void fireUpdateFound(Version foundVersion, long versionTimestamp) {
106 for (UpdateListener updateListener : updateListeners) {
107 updateListener.foundUpdateData(foundVersion, versionTimestamp);
115 public void start() {
116 new Thread(this).start();
120 synchronized (syncObject) {
122 syncObject.notifyAll();
130 private boolean shouldStop() {
131 synchronized (syncObject) {
136 private String constructUpdateKey(int edition) {
137 return UPDATE_KEY + "/jSite/" + edition + "/jSite.properties";
141 // INTERFACE Runnable
145 Connection connection = freenetInterface.getConnection("jSite-" + ++counter + "-UpdateChecker");
147 connection.connect();
148 } catch (IOException e1) {
149 e1.printStackTrace();
151 Client client = new Client(connection);
152 boolean checkNow = false;
153 int currentEdition = lastUpdateEdition;
154 while (!shouldStop()) {
156 System.out.println("Trying " + constructUpdateKey(currentEdition));
157 ClientGet clientGet = new ClientGet("get-update-key");
158 clientGet.setUri(constructUpdateKey(currentEdition));
159 clientGet.setPersistence(Persistence.CONNECTION);
160 clientGet.setReturnType(ReturnType.direct);
161 clientGet.setVerbosity(Verbosity.ALL);
163 client.execute(clientGet);
164 boolean stop = false;
166 Message message = client.readMessage();
167 System.out.println(message);
168 if ("GetFailed".equals(message.getName())) {
169 if ("27".equals(message.get("code"))) {
170 String editionString = message.get("redirecturi").split("/")[2];
171 int editionNumber = -1;
173 editionNumber = Integer.parseInt(editionString);
174 } catch (NumberFormatException nfe1) {
177 if (editionNumber != -1) {
178 System.out.println("Found new edition " + editionNumber);
179 currentEdition = editionNumber;
180 lastUpdateEdition = editionNumber;
186 if ("AllData".equals(message.getName())) {
187 System.out.println("Update data found.");
188 InputStream dataInputStream = null;
189 Properties properties = new Properties();
191 dataInputStream = message.getPayloadInputStream();
192 properties.load(dataInputStream);
194 Closer.close(dataInputStream);
197 String foundVersionString = properties.getProperty("jSite.Version");
198 if (foundVersionString != null) {
199 Version foundVersion = Version.parse(foundVersionString);
200 if (foundVersion != null) {
201 lastVersion = foundVersion;
202 String versionTimestampString = properties.getProperty("jSite.Date");
203 System.out.println(versionTimestampString);
204 long versionTimestamp = -1;
206 versionTimestamp = Long.parseLong(versionTimestampString);
207 } catch (NumberFormatException nfe1) {
210 fireUpdateFound(foundVersion, versionTimestamp);
218 } catch (IOException e) {
219 System.out.println("Got IOException: " + e.getMessage());
222 if (!checkNow && !shouldStop()) {
223 synchronized (syncObject) {
225 syncObject.wait(15 * 60 * 1000);
226 } catch (InterruptedException ie1) {