1 | package net.i2p.launchers.osx |
---|
2 | |
---|
3 | import java.awt.SystemTray |
---|
4 | import java.io.File |
---|
5 | |
---|
6 | import net.i2p.launchers.{CompleteDeployment, OSXDefaults} |
---|
7 | |
---|
8 | import scala.concurrent.{Await, Future} |
---|
9 | import scala.concurrent.ExecutionContext.Implicits.global |
---|
10 | import scala.concurrent.duration._ |
---|
11 | import scala.sys.process.Process |
---|
12 | import scala.util.{Failure, Success} |
---|
13 | |
---|
14 | /** |
---|
15 | * |
---|
16 | * For java developers: |
---|
17 | * A scala object is like an instance of a class. |
---|
18 | * If you define a method inside an object, it's equals to |
---|
19 | * java's static methods. |
---|
20 | * |
---|
21 | * Also, in scala, the body of a class/object is executed as it's |
---|
22 | * constructor. |
---|
23 | * |
---|
24 | * Also noteworthy; |
---|
25 | * val is immutable |
---|
26 | * var is mutable |
---|
27 | * |
---|
28 | * |
---|
29 | * The i2p base directory in the build should be in a relative path from |
---|
30 | * the launcher, which would be ../Resources/i2pbase - this directory would |
---|
31 | * need to be copied out to a "writable" area, since we're in a signed "immutable" |
---|
32 | * bundle. First this launcher will check if i2pbase is already deployed to a |
---|
33 | * writable area, if it's not, it deploys, if the i2pbase directory has an older |
---|
34 | * version than the one in the bundle, it upgrades. It does nothing if versions |
---|
35 | * matches. |
---|
36 | * |
---|
37 | * |
---|
38 | * @author Meeh |
---|
39 | * @version 0.0.1 |
---|
40 | * @since 0.9.35 |
---|
41 | */ |
---|
42 | object LauncherAppMain extends App { |
---|
43 | |
---|
44 | val i2pBaseDir = OSXDefaults.getOSXBaseDirectory |
---|
45 | |
---|
46 | val selfDirPath = new File(getClass().getProtectionDomain().getCodeSource().getLocation().getPath).getParentFile |
---|
47 | |
---|
48 | // Tricky to get around, but feels hard to use a "var" which means mutable.. |
---|
49 | // It's like cursing in the church... Worse. |
---|
50 | var sysTray: Option[SystemTrayManager] = None |
---|
51 | |
---|
52 | val deployment = new CompleteDeployment(new File(selfDirPath.getPath, "../Resources/i2pbase.zip"), i2pBaseDir) |
---|
53 | |
---|
54 | val depProc = deployment.makeDeployment |
---|
55 | // Change directory to base dir |
---|
56 | System.setProperty("user.dir", i2pBaseDir.getAbsolutePath) |
---|
57 | |
---|
58 | // System shutdown hook |
---|
59 | sys.ShutdownHookThread { |
---|
60 | println("exiting launcher process") |
---|
61 | } |
---|
62 | |
---|
63 | Await.ready(depProc, 60000 millis) |
---|
64 | |
---|
65 | println("I2P Base Directory Extracted.") |
---|
66 | |
---|
67 | try { |
---|
68 | val routerProcess: Future[Process] = MacOSXRouterLauncher.runRouter(i2pBaseDir, args) |
---|
69 | |
---|
70 | if (SystemTray.isSupported) { |
---|
71 | sysTray = Some(new SystemTrayManager) |
---|
72 | } |
---|
73 | |
---|
74 | routerProcess onComplete { |
---|
75 | case Success(forkResult) => { |
---|
76 | println(s"Router started successfully!") |
---|
77 | try { |
---|
78 | val routerPID = MacOSXRouterLauncher.pid(forkResult) |
---|
79 | println(s"PID is ${routerPID}") |
---|
80 | } catch { |
---|
81 | case ex:java.lang.RuntimeException => println(s"Minor error: ${ex.getMessage}") |
---|
82 | } |
---|
83 | if (!sysTray.isEmpty) sysTray.get.setRunning(true) |
---|
84 | } |
---|
85 | case Failure(fail) => { |
---|
86 | println(s"Router failed to start, error is: ${fail.toString}") |
---|
87 | } |
---|
88 | } |
---|
89 | |
---|
90 | } finally { |
---|
91 | System.out.println("Exit?") |
---|
92 | } |
---|
93 | } |
---|