PageRenderTime 41ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/src/net/java/sip/communicator/launcher/SIPCommunicator.java

https://github.com/beewang/jitsi
Java | 333 lines | 174 code | 37 blank | 122 comment | 51 complexity | 977c6bde34056be27e47e531170e2a16 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause
  1. /*
  2. * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
  3. *
  4. * Distributable under LGPL license.
  5. * See terms of license at gnu.org.
  6. */
  7. package net.java.sip.communicator.launcher;
  8. import java.awt.*;
  9. import java.io.*;
  10. import net.java.sip.communicator.util.*;
  11. import net.java.sip.communicator.util.launchutils.*;
  12. import org.apache.felix.main.*;
  13. /**
  14. * Starts the SIP Communicator.
  15. *
  16. * @author Yana Stamcheva
  17. * @author Lyubomir Marinov
  18. * @author Emil Ivov
  19. * @author Sebastien Vincent
  20. */
  21. public class SIPCommunicator
  22. {
  23. /**
  24. * The name of the property that stores our home dir location.
  25. */
  26. public static final String PNAME_SC_HOME_DIR_LOCATION =
  27. "net.java.sip.communicator.SC_HOME_DIR_LOCATION";
  28. /**
  29. * The name of the property that stores our home dir name.
  30. */
  31. public static final String PNAME_SC_HOME_DIR_NAME =
  32. "net.java.sip.communicator.SC_HOME_DIR_NAME";
  33. /**
  34. * The currently active name.
  35. */
  36. private static String overridableDirName = "Jitsi";
  37. /**
  38. * Legacy home directory names that we can use if current dir name
  39. * is the currently active name (overridableDirName).
  40. */
  41. private static String[] legacyDirNames =
  42. {".sip-communicator", "SIP Communicator"};
  43. /**
  44. * Name of the possible configuration file names (used under macosx).
  45. */
  46. private static String[] legacyConfigurationFileNames =
  47. {"sip-communicator.properties", "jitsi.properties",
  48. "sip-communicator.xml", "jitsi.xml"};
  49. /**
  50. * Starts the SIP Communicator.
  51. *
  52. * @param args command line args if any
  53. *
  54. * @throws Exception whenever it makes sense.
  55. */
  56. public static void main(String[] args)
  57. throws Exception
  58. {
  59. String version = System.getProperty("java.version");
  60. String vmVendor = System.getProperty("java.vendor");
  61. String osName = System.getProperty("os.name");
  62. setSystemProperties(osName);
  63. /*
  64. * SC_HOME_DIR_* are specific to the OS so make sure they're configured
  65. * accordingly before any other application-specific logic depending on
  66. * them starts (e.g. Felix).
  67. */
  68. setScHomeDir(osName);
  69. // this needs to be set before any DNS lookup is run
  70. File f = new File(System.getProperty(PNAME_SC_HOME_DIR_LOCATION),
  71. System.getProperty(PNAME_SC_HOME_DIR_NAME)
  72. + File.separator + ".usednsjava");
  73. if(f.exists())
  74. System.setProperty(
  75. "sun.net.spi.nameservice.provider.1", "dns,dnsjava");
  76. if (version.startsWith("1.4") || vmVendor.startsWith("Gnu") ||
  77. vmVendor.startsWith("Free"))
  78. {
  79. String os = "";
  80. if (osName.startsWith("Mac"))
  81. os = ChangeJVMFrame.MAC_OSX;
  82. else if (osName.startsWith("Linux"))
  83. os = ChangeJVMFrame.LINUX;
  84. else if (osName.startsWith("Windows"))
  85. os = ChangeJVMFrame.WINDOWS;
  86. ChangeJVMFrame changeJVMFrame = new ChangeJVMFrame(os);
  87. Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
  88. changeJVMFrame.setLocation(
  89. screenSize.width/2 - changeJVMFrame.getWidth()/2,
  90. screenSize.height/2 - changeJVMFrame.getHeight()/2);
  91. changeJVMFrame.setVisible(true);
  92. return;
  93. }
  94. //first - pass the arguments to our arg handler
  95. LaunchArgHandler argHandler = LaunchArgHandler.getInstance();
  96. int argHandlerRes = argHandler.handleArgs(args);
  97. if ( argHandlerRes == LaunchArgHandler.ACTION_EXIT
  98. || argHandlerRes == LaunchArgHandler.ACTION_ERROR)
  99. {
  100. System.exit(argHandler.getErrorCode());
  101. }
  102. //lock our config dir so that we would only have a single instance of
  103. //sip communicator, no matter how many times we start it (use mainly
  104. //for handling sip: uris after starting the application)
  105. if ( argHandlerRes != LaunchArgHandler.ACTION_CONTINUE_LOCK_DISABLED )
  106. {
  107. switch (new SipCommunicatorLock().tryLock(args))
  108. {
  109. case SipCommunicatorLock.LOCK_ERROR:
  110. System.err.println("Failed to lock SIP Communicator's "
  111. +"configuration directory.\n"
  112. +"Try launching with the --multiple param.");
  113. System.exit(SipCommunicatorLock.LOCK_ERROR);
  114. break;
  115. case SipCommunicatorLock.ALREADY_STARTED:
  116. System.out.println(
  117. "SIP Communicator is already running and will "
  118. +"handle your parameters (if any).\n"
  119. +"Launch with the --multiple param to override this "
  120. +"behaviour.");
  121. //we exit with success because for the user that's what it is.
  122. System.exit(SipCommunicatorLock.SUCCESS);
  123. break;
  124. case SipCommunicatorLock.SUCCESS:
  125. //Successfully locked, continue as normal.
  126. break;
  127. }
  128. }
  129. //there was no error, continue;
  130. System.setOut(new ScStdOut(System.out));
  131. Main.main(new String[0]);
  132. }
  133. /**
  134. * Sets the system properties net.java.sip.communicator.SC_HOME_DIR_LOCATION
  135. * and net.java.sip.communicator.SC_HOME_DIR_NAME (if they aren't already
  136. * set) in accord with the OS conventions specified by the name of the OS.
  137. *
  138. * Please leave the access modifier as package (default) to allow launch-
  139. * wrappers to call it.
  140. *
  141. * @param osName the name of the OS according to which the SC_HOME_DIR_*
  142. * properties are to be set
  143. */
  144. static void setScHomeDir(String osName)
  145. {
  146. /*
  147. * Though we'll be setting the SC_HOME_DIR_* property values depending
  148. * on the OS running the application, we have to make sure we are
  149. * compatible with earlier releases i.e. use
  150. * ${user.home}/.sip-communicator if it exists (and the new path isn't
  151. * already in use).
  152. */
  153. String location = System.getProperty(PNAME_SC_HOME_DIR_LOCATION);
  154. String name = System.getProperty(PNAME_SC_HOME_DIR_NAME);
  155. boolean isHomeDirnameForced = name != null;
  156. if ((location == null) || (name == null))
  157. {
  158. String defaultLocation = System.getProperty("user.home");
  159. String defaultName = ".jitsi";
  160. // Whether we should check legacy names
  161. // 1) when such name is not forced we check
  162. // 2) if such is forced and is the overridableDirName check it
  163. // (the later is the case with name transition SIP Communicator
  164. // -> Jitsi, check them only for Jitsi)
  165. boolean chekLegacyDirNames = (name == null) ||
  166. name.equals(overridableDirName);
  167. if (osName.startsWith("Mac"))
  168. {
  169. if (location == null)
  170. location =
  171. System.getProperty("user.home") + File.separator
  172. + "Library" + File.separator
  173. + "Application Support";
  174. if (name == null)
  175. name = "Jitsi";
  176. }
  177. else if (osName.startsWith("Windows"))
  178. {
  179. /*
  180. * Primarily important on Vista because Windows Explorer opens
  181. * in %USERPROFILE% so .sip-communicator is always visible. But
  182. * it may be a good idea to follow the OS recommendations and
  183. * use APPDATA on pre-Vista systems as well.
  184. */
  185. if (location == null)
  186. location = System.getenv("APPDATA");
  187. if (name == null)
  188. name = "Jitsi";
  189. }
  190. /* If there're no OS specifics, use the defaults. */
  191. if (location == null)
  192. location = defaultLocation;
  193. if (name == null)
  194. name = defaultName;
  195. /*
  196. * As it was noted earlier, make sure we're compatible with previous
  197. * releases. If the home dir name is forced (set as system property)
  198. * doesn't look for the default dir.
  199. */
  200. if (!isHomeDirnameForced
  201. && (new File(location, name).isDirectory() == false)
  202. && new File(defaultLocation, defaultName).isDirectory())
  203. {
  204. location = defaultLocation;
  205. name = defaultName;
  206. }
  207. // if we need to check legacy names and there is no
  208. // current home dir already created
  209. if(chekLegacyDirNames
  210. && !checkHomeFolderExist(location, name, osName))
  211. {
  212. // now check whether some of the legacy dir names
  213. // exists, and use it if exist
  214. for(int i = 0; i < legacyDirNames.length; i++)
  215. {
  216. // check the platform specific directory
  217. if(checkHomeFolderExist(
  218. location, legacyDirNames[i], osName))
  219. {
  220. name = legacyDirNames[i];
  221. break;
  222. }
  223. // now check it and in the default location
  224. if(checkHomeFolderExist(
  225. defaultLocation, legacyDirNames[i], osName))
  226. {
  227. name = legacyDirNames[i];
  228. location = defaultLocation;
  229. break;
  230. }
  231. }
  232. }
  233. System.setProperty(PNAME_SC_HOME_DIR_LOCATION, location);
  234. System.setProperty(PNAME_SC_HOME_DIR_NAME, name);
  235. }
  236. // when we end up with the home dirs, make sure we have log dir
  237. new File(location, name + File.separator + "log").mkdirs();
  238. }
  239. /**
  240. * Checks whether home folder exists.
  241. * Special situation checked under macosx, due to created folder
  242. * of the new version of the updater we may end up with our
  243. * settings in 'SIP Communicator' folder and having 'Jitsi' folder
  244. * created by the updater(its download location).
  245. * So we check not only the folder exist but whether it contains
  246. * any of the known configuration files in it.
  247. *
  248. * @param parent the parent folder
  249. * @param name the folder name to check.
  250. * @param osName OS name
  251. * @return whether folder exists.
  252. */
  253. static boolean checkHomeFolderExist(
  254. String parent, String name, String osName)
  255. {
  256. if(osName.startsWith("Mac"))
  257. {
  258. for(int i = 0; i < legacyConfigurationFileNames.length; i++)
  259. {
  260. if(new File(new File(parent, name)
  261. , legacyConfigurationFileNames[i]).exists())
  262. return true;
  263. }
  264. return false;
  265. }
  266. return new File(parent, name).isDirectory();
  267. }
  268. /**
  269. * Sets some system properties specific to the OS that needs to be set at
  270. * the very beginning of a program (typically for UI related properties,
  271. * before AWT is launched).
  272. *
  273. * @param osName OS name
  274. */
  275. private static void setSystemProperties(String osName)
  276. {
  277. // setup here all system properties that need to be initialized at
  278. // the very beginning of an application
  279. if(osName.startsWith("Windows"))
  280. {
  281. // disable Direct 3D pipeline (used for fullscreen) before
  282. // displaying anything (frame, ...)
  283. System.setProperty("sun.java2d.d3d", "false");
  284. }
  285. else if(osName.startsWith("Mac"))
  286. {
  287. // On Mac OS X when switch in fullscreen, all the monitors goes
  288. // fullscreen (turns black) and only one monitors has images
  289. // displayed. So disable this behavior because somebody may want
  290. // to use one monitor to do other stuff while having other ones with
  291. // fullscreen stuff.
  292. System.setProperty("apple.awt.fullscreencapturealldisplays",
  293. "false");
  294. }
  295. }
  296. }