1 16 package com.google.gwt.junit.remote; 17 18 import java.io.IOException ; 19 import java.rmi.Naming ; 20 import java.rmi.RemoteException ; 21 import java.rmi.registry.LocateRegistry ; 22 import java.rmi.registry.Registry ; 23 import java.rmi.server.UnicastRemoteObject ; 24 import java.util.HashMap ; 25 import java.util.Map ; 26 import java.util.Timer ; 27 import java.util.TimerTask ; 28 29 60 public class BrowserManagerServer extends UnicastRemoteObject implements 61 BrowserManager { 62 63 67 68 84 private final class ProcessManager { 85 86 90 private final class KillTask extends TimerTask { 91 94 public void run() { 95 synchronized (processByToken) { 96 101 if (killTask == this) { 102 doKill(); 103 } 104 } 105 } 106 } 107 108 112 private Object key; 113 114 118 private KillTask killTask; 119 120 123 private final Process process; 124 125 136 ProcessManager(Object key, Process process, long initKeepAliveMs) { 137 this.process = process; 138 this.key = key; 139 schedule(initKeepAliveMs); 140 processByToken.put(key, this); 141 } 142 143 147 public void doKill() { 148 Object removed = processByToken.remove(key); 149 assert (removed == this); 150 process.destroy(); 151 schedule(0); 152 } 153 154 164 public boolean keepAlive(long keepAliveMs) { 165 try { 166 171 process.exitValue(); 172 } catch (IllegalThreadStateException e) { 173 schedule(keepAliveMs); 175 return true; 176 } 177 178 doKill(); 180 return false; 181 } 182 183 192 private void schedule(long keepAliveMs) { 193 if (killTask != null) { 194 killTask.cancel(); 195 killTask = null; 196 } 197 if (keepAliveMs > 0) { 198 killTask = new KillTask(); 199 timer.schedule(killTask, keepAliveMs); 200 } 201 } 202 } 203 204 208 public static void main(String [] args) throws Exception { 209 if (args.length == 0) { 210 System.err.println("" 211 + "Manages local browser windows for a remote client using RMI.\n" 212 + "\n" 213 + "Pass in an even number of args, at least 2. The first argument\n" 214 + "is a short registration name, and the second argument is the\n" 215 + "executable to run when that name is used; for example,\n" + "\n" 216 + "\tie6 \"C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE\"\n" 217 + "\n" 218 + "would register Internet Explorer to \"rmi://localhost/ie6\".\n" 219 + "The third and fourth arguments make another pair, and so on.\n"); 220 System.exit(1); 221 } 222 223 if (args.length < 2) { 224 throw new IllegalArgumentException ("Need at least 2 arguments"); 225 } 226 227 if (args.length % 2 != 0) { 228 throw new IllegalArgumentException ("Need an even number of arguments"); 229 } 230 231 LocateRegistry.createRegistry(Registry.REGISTRY_PORT); 235 System.out.println("RMI registry ready."); 236 237 for (int i = 0; i < args.length; i += 2) { 238 BrowserManagerServer bms = new BrowserManagerServer(args[i + 1]); 239 Naming.rebind(args[i], bms); 240 System.out.println(args[i] + " started and awaiting connections"); 241 } 242 } 243 244 247 private final String launchCmd; 248 249 253 private int nextToken = 1; 254 255 260 private final Map processByToken = new HashMap (); 261 262 266 private final Timer timer = new Timer (); 267 268 275 public BrowserManagerServer(String launchCmd) throws RemoteException { 276 this.launchCmd = launchCmd; 277 } 278 279 282 public void keepAlive(int token, long keepAliveMs) { 283 284 if (keepAliveMs <= 0) { 285 throw new IllegalArgumentException (); 286 } 287 288 synchronized (processByToken) { 289 if (token < 0 || token >= nextToken) { 291 throw new IllegalArgumentException (); 292 } 293 Integer intTok = new Integer (token); 294 ProcessManager process = (ProcessManager) processByToken.get(intTok); 295 if (process != null) { 296 if (process.keepAlive(keepAliveMs)) { 297 return; 299 } else { 300 } 302 } 303 } 304 305 throw new IllegalStateException ("Process " + token + " already dead"); 306 } 307 308 311 public void killBrowser(int token) { 312 synchronized (processByToken) { 313 if (token < 0 || token >= nextToken) { 315 throw new IllegalArgumentException (); 316 } 317 Integer intTok = new Integer (token); 318 ProcessManager process = (ProcessManager) processByToken.get(intTok); 319 if (process != null) { 320 process.doKill(); 321 } 322 } 323 } 324 325 328 public int launchNewBrowser(String url, long keepAliveMs) { 329 330 if (url == null || keepAliveMs <= 0) { 331 throw new IllegalArgumentException (); 332 } 333 334 try { 335 Process child = Runtime.getRuntime().exec(new String [] {launchCmd, url}); 336 synchronized (processByToken) { 337 int myToken = nextToken++; 338 Integer intTok = new Integer (myToken); 339 new ProcessManager(intTok, child, keepAliveMs); 341 return myToken; 342 } 343 } catch (IOException e) { 344 throw new RuntimeException ("Error launching browser '" + launchCmd 345 + "' for '" + url + "'", e); 346 } 347 } 348 } 349 | Popular Tags |