From 7753d05b61ed80578022c6f295e4fa1241228304 Mon Sep 17 00:00:00 2001 From: zzz Date: Mon, 5 Jan 2015 12:42:39 +0000 Subject: [PATCH] UrlLauncher: - Configure browser with routerconsole.browser (ticket #1159) - Convert to ClientApp interface --- .../src/net/i2p/apps/systray/SysTray.java | 6 +- .../src/net/i2p/apps/systray/UrlLauncher.java | 156 ++++++++++++++++-- history.txt | 10 ++ .../src/net/i2p/router/RouterVersion.java | 2 +- 4 files changed, 152 insertions(+), 22 deletions(-) diff --git a/apps/systray/java/src/net/i2p/apps/systray/SysTray.java b/apps/systray/java/src/net/i2p/apps/systray/SysTray.java index a6b608d90..21f6f45f7 100644 --- a/apps/systray/java/src/net/i2p/apps/systray/SysTray.java +++ b/apps/systray/java/src/net/i2p/apps/systray/SysTray.java @@ -37,7 +37,6 @@ public class SysTray implements SysTrayMenuListener { private static SysTray _instance; private static String _portString; private static boolean _showIcon; - private static UrlLauncher _urlLauncher = new UrlLauncher(); private static final boolean _is64 = SystemVersion.is64Bit(); static { @@ -84,17 +83,18 @@ public class SysTray implements SysTrayMenuListener { private static void openRouterConsole(String url) { String browser = null; + UrlLauncher urlLauncher = new UrlLauncher(); if (_browserString == null || _browserString.equals("default")) { try { - if (_urlLauncher.openUrl(url)) + if (urlLauncher.openUrl(url)) return; } catch (Exception ex) { // Fall through. } } else { try { - if (_urlLauncher.openUrl(url, _browserString)) + if (urlLauncher.openUrl(url, _browserString)) return; } catch (Exception ex) { // Fall through. diff --git a/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java b/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java index aeb159aa3..7604169b0 100644 --- a/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java +++ b/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java @@ -22,6 +22,9 @@ import java.net.URL; import java.util.Locale; import net.i2p.I2PAppContext; +import net.i2p.app.*; +import static net.i2p.app.ClientAppState.*; +import net.i2p.util.I2PAppThread; import net.i2p.util.ShellCommand; import net.i2p.util.SystemVersion; @@ -35,13 +38,19 @@ import net.i2p.util.SystemVersion; * * @author hypercubus */ -public class UrlLauncher { +public class UrlLauncher implements ClientApp { - ShellCommand _shellCommand = new ShellCommand(); + private final ShellCommand _shellCommand; + private volatile ClientAppState _state; + private final I2PAppContext _context; + private final ClientAppManager _mgr; + private final String[] _args; private static final int WAIT_TIME = 5*1000; private static final int MAX_WAIT_TIME = 5*60*1000; private static final int MAX_TRIES = 99; + private static final String REGISTERED_NAME = "UrlLauncher"; + private static final String PROP_BROWSER = "routerconsole.browser"; /** * Browsers to try IN-ORDER @@ -69,12 +78,43 @@ public class UrlLauncher { "lynx" }; + /** + * ClientApp constructor used from clients.config + * + * @since 0.9.18 + */ + public UrlLauncher(I2PAppContext context, ClientAppManager mgr, String[] args) { + _state = UNINITIALIZED; + _context = context; + _mgr = mgr; + if (args == null || args.length <= 0) + args = new String[] {"http://127.0.0.1:7657/index.jsp"}; + _args = args; + _shellCommand = new ShellCommand(); + _state = INITIALIZED; + } + + /** + * Constructor from SysTray + * + * @since 0.9.18 + */ + public UrlLauncher() { + _state = UNINITIALIZED; + _context = I2PAppContext.getGlobalContext(); + _mgr = null; + _args = null; + _shellCommand = new ShellCommand(); + _state = INITIALIZED; + } + /** * Prevent bad user experience by waiting for the server to be there * before launching the browser. + * * @return success */ - public boolean waitForServer(String urlString) { + private static boolean waitForServer(String urlString) { URL url; try { url = new URL(urlString); @@ -126,6 +166,8 @@ public class UrlLauncher { * unsuccessful, an attempt is made to launch the URL using the most common * browsers. * + * BLOCKING + * * @param url The URL to open. * @return true if the operation was successful, otherwise * false. @@ -133,12 +175,14 @@ public class UrlLauncher { * @throws Exception */ public boolean openUrl(String url) throws Exception { - - String osName = System.getProperty("os.name"); - waitForServer(url); if (validateUrlFormat(url)) { - if (osName.toLowerCase(Locale.US).indexOf("mac") > -1) { + String cbrowser = _context.getProperty(PROP_BROWSER); + if (cbrowser != null) { + return openUrl(url, cbrowser); + } + if (SystemVersion.isMac()) { + String osName = System.getProperty("os.name"); if (osName.toLowerCase(Locale.US).startsWith("mac os x")) { if (_shellCommand.executeSilentAndWaitTimed("open " + url, 5)) @@ -150,13 +194,11 @@ public class UrlLauncher { if (_shellCommand.executeSilentAndWaitTimed("iexplore " + url, 5)) return true; - } else if (SystemVersion.isWindows()) { - String browserString = "\"C:\\Program Files\\Internet Explorer\\iexplore.exe\" -nohome"; BufferedReader bufferedReader = null; - File foo = new File(I2PAppContext.getGlobalContext().getTempDir(), "browser.reg"); + File foo = new File(_context.getTempDir(), "browser.reg"); _shellCommand.executeSilentAndWait("regedit /E \"" + foo.getAbsolutePath() + "\" \"HKEY_CLASSES_ROOT\\http\\shell\\open\\command\""); try { @@ -184,12 +226,9 @@ public class UrlLauncher { } if (_shellCommand.executeSilentAndWaitTimed(browserString + ' ' + url, 5)) return true; - } else { - // fall through } - for (int i = 0; i < BROWSERS.length; i++) { if (_shellCommand.executeSilentAndWaitTimed(BROWSERS[i] + ' ' + url, 5)) return true; @@ -201,6 +240,8 @@ public class UrlLauncher { /** * Opens the given URL with the given browser. * + * BLOCKING + * * @param url The URL to open. * @param browser The browser to use. * @return true if the operation was successful, @@ -209,17 +250,16 @@ public class UrlLauncher { * @throws Exception */ public boolean openUrl(String url, String browser) throws Exception { - waitForServer(url); - if (validateUrlFormat(url)) + if (validateUrlFormat(url)) { if (_shellCommand.executeSilentAndWaitTimed(browser + " " + url, 5)) return true; - + } return false; } - private boolean validateUrlFormat(String urlString) { - try { + private static boolean validateUrlFormat(String urlString) { + try { // just to check validity new URL(urlString); } catch (MalformedURLException e) { @@ -228,6 +268,86 @@ public class UrlLauncher { return true; } + /** + * ClientApp interface + * @since 0.9.18 + */ + public void startup() { + String url = _args[0]; + if (!validateUrlFormat(url)) { + changeState(START_FAILED, new MalformedURLException("Bad url: " + url)); + return; + } + changeState(STARTING); + Thread t = new I2PAppThread(new Runner(), "UrlLauncher", true); + t.start(); + } + + private class Runner implements Runnable { + public void run() { + changeState(RUNNING); + try { + String url = _args[0]; + openUrl(url); + changeState(STOPPED); + } catch (Exception e) { + changeState(CRASHED, e); + } + } + } + + /** + * ClientApp interface + * @since 0.9.18 + */ + public ClientAppState getState() { + return _state; + } + + /** + * ClientApp interface + * @since 0.9.18 + */ + public String getName() { + return REGISTERED_NAME; + } + + /** + * ClientApp interface + * @since 0.9.18 + */ + public String getDisplayName() { + return REGISTERED_NAME + " \"" + _args[0] + '"'; + } + + /** + * @since 0.9.18 + */ + private void changeState(ClientAppState state) { + changeState(state, null); + } + + /** + * @since 0.9.18 + */ + private synchronized void changeState(ClientAppState state, Exception e) { + _state = state; + if (_mgr != null) + _mgr.notify(this, state, null, e); + } + + /** + * ClientApp interface + * @since 0.9.18 + */ + public void shutdown(String[] args) { + // doesn't really do anything + changeState(STOPPED); + } + + /** + * Obsolete, now uses ClientApp interface + */ public static void main(String args[]) { UrlLauncher launcher = new UrlLauncher(); try { diff --git a/history.txt b/history.txt index 99244811d..266630398 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,13 @@ +2015-01-05 zzz + * Blocklist: + - Rewrite to read and merge multiple files + - Include in update, use version in base dir too + - Increase limits + - Bug fixes + * UrlLauncher: + - Configure browser with routerconsole.browser (ticket #1159) + - Convert to ClientApp interface + 2015-01-03 zzz * I2CP: Use configured leaseset keys if available * I2PTunnel: Persist leaseset keys diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index f6e6df3a5..4e28a2c8d 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 4; + public final static long BUILD = 5; /** for example "-test" */ public final static String EXTRA = "";