PageRenderTime 40ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/aqmon/lib/j2ssh/src/com/sshtools/common/util/BrowserLauncher.java

http://ece01sd.googlecode.com/
Java | 442 lines | 310 code | 83 blank | 49 comment | 26 complexity | 9484b4a5cf42599c324c47cdd0498848 MD5 | raw file
Possible License(s): IPL-1.0, GPL-3.0, GPL-2.0, JSON
  1. /*
  2. * SSHTools - Java SSH2 API
  3. *
  4. * Copyright (C) 2002-2003 Lee David Painter and Contributors.
  5. *
  6. * Contributions made by:
  7. *
  8. * Brett Smith
  9. * Richard Pernavas
  10. * Erwin Bolwidt
  11. *
  12. * This program is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU General Public License
  14. * as published by the Free Software Foundation; either version 2
  15. * of the License, or (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  25. */
  26. package com.sshtools.common.util;
  27. import java.io.*;
  28. import java.lang.reflect.*;
  29. /**
  30. *
  31. *
  32. * @author $author$
  33. * @version $Revision: 1.14 $
  34. */
  35. public class BrowserLauncher {
  36. private static int jvm;
  37. private static Object browser;
  38. private static boolean loadedWithoutErrors;
  39. private static Class mrjFileUtilsClass;
  40. private static Class mrjOSTypeClass;
  41. private static Class macOSErrorClass;
  42. private static Class aeDescClass;
  43. private static Constructor aeTargetConstructor;
  44. private static Constructor appleEventConstructor;
  45. private static Constructor aeDescConstructor;
  46. private static Method findFolder;
  47. private static Method getFileType;
  48. private static Method makeOSType;
  49. private static Method putParameter;
  50. private static Method sendNoReply;
  51. private static Object kSystemFolderType;
  52. private static Integer keyDirectObject;
  53. private static Integer kAutoGenerateReturnID;
  54. private static Integer kAnyTransactionID;
  55. private static final int MRJ_2_0 = 0;
  56. private static final int MRJ_2_1 = 1;
  57. private static final int WINDOWS_NT = 2;
  58. private static final int WINDOWS_9x = 3;
  59. private static final int OTHER = -1;
  60. private static final String FINDER_TYPE = "FNDR";
  61. private static final String FINDER_CREATOR = "MACS";
  62. private static final String GURL_EVENT = "GURL";
  63. private static final String FIRST_WINDOWS_PARAMETER = "/c";
  64. private static final String SECOND_WINDOWS_PARAMETER = "start";
  65. private static final String NETSCAPE_OPEN_PARAMETER_START = " -remote 'openURL(";
  66. private static final String NETSCAPE_OPEN_PARAMETER_END = ")'";
  67. private static String errorMessage;
  68. static {
  69. loadedWithoutErrors = true;
  70. String osName = System.getProperty("os.name");
  71. if ("Mac OS".equals(osName)) {
  72. String mrjVersion = System.getProperty("mrj.version");
  73. String majorMRJVersion = mrjVersion.substring(0, 3);
  74. try {
  75. double version = Double.valueOf(majorMRJVersion).doubleValue();
  76. if (version == 2) {
  77. jvm = MRJ_2_0;
  78. } else if (version >= 2.1) {
  79. // For the time being, assume that all post-2.0 versions of MRJ work the same
  80. jvm = MRJ_2_1;
  81. } else {
  82. loadedWithoutErrors = false;
  83. errorMessage = "Unsupported MRJ version: " + version;
  84. }
  85. } catch (NumberFormatException nfe) {
  86. loadedWithoutErrors = false;
  87. errorMessage = "Invalid MRJ version: " + mrjVersion;
  88. }
  89. } else if (osName.startsWith("Windows")) {
  90. if (osName.indexOf("9") != -1) {
  91. jvm = WINDOWS_9x;
  92. } else {
  93. jvm = WINDOWS_NT;
  94. }
  95. } else {
  96. jvm = OTHER;
  97. }
  98. if (loadedWithoutErrors) { // if we haven't hit any errors yet
  99. loadedWithoutErrors = loadClasses();
  100. }
  101. }
  102. private BrowserLauncher() {
  103. }
  104. private static boolean loadClasses() {
  105. switch (jvm) {
  106. case MRJ_2_0:
  107. try {
  108. Class aeTargetClass = Class.forName("com.apple.MacOS.AETarget");
  109. macOSErrorClass = Class.forName("com.apple.MacOS.MacOSError");
  110. Class osUtilsClass = Class.forName("com.apple.MacOS.OSUtils");
  111. Class appleEventClass = Class.forName(
  112. "com.apple.MacOS.AppleEvent");
  113. Class aeClass = Class.forName("com.apple.MacOS.ae");
  114. aeDescClass = Class.forName("com.apple.MacOS.AEDesc");
  115. aeTargetConstructor = aeTargetClass.getDeclaredConstructor(new Class[] {
  116. int.class
  117. });
  118. appleEventConstructor = appleEventClass.getDeclaredConstructor(new Class[] {
  119. int.class, int.class, aeTargetClass, int.class,
  120. int.class
  121. });
  122. aeDescConstructor = aeDescClass.getDeclaredConstructor(new Class[] {
  123. String.class
  124. });
  125. makeOSType = osUtilsClass.getDeclaredMethod("makeOSType",
  126. new Class[] { String.class });
  127. putParameter = appleEventClass.getDeclaredMethod("putParameter",
  128. new Class[] { int.class, aeDescClass });
  129. sendNoReply = appleEventClass.getDeclaredMethod("sendNoReply",
  130. new Class[] { });
  131. Field keyDirectObjectField = aeClass.getDeclaredField(
  132. "keyDirectObject");
  133. keyDirectObject = (Integer) keyDirectObjectField.get(null);
  134. Field autoGenerateReturnIDField = appleEventClass.getDeclaredField(
  135. "kAutoGenerateReturnID");
  136. kAutoGenerateReturnID = (Integer) autoGenerateReturnIDField.get(null);
  137. Field anyTransactionIDField = appleEventClass.getDeclaredField(
  138. "kAnyTransactionID");
  139. kAnyTransactionID = (Integer) anyTransactionIDField.get(null);
  140. } catch (ClassNotFoundException cnfe) {
  141. errorMessage = cnfe.getMessage();
  142. return false;
  143. } catch (NoSuchMethodException nsme) {
  144. errorMessage = nsme.getMessage();
  145. return false;
  146. } catch (NoSuchFieldException nsfe) {
  147. errorMessage = nsfe.getMessage();
  148. return false;
  149. } catch (IllegalAccessException iae) {
  150. errorMessage = iae.getMessage();
  151. return false;
  152. }
  153. break;
  154. case MRJ_2_1:
  155. try {
  156. mrjFileUtilsClass = Class.forName("com.apple.mrj.MRJFileUtils");
  157. mrjOSTypeClass = Class.forName("com.apple.mrj.MRJOSType");
  158. Field systemFolderField = mrjFileUtilsClass.getDeclaredField(
  159. "kSystemFolderType");
  160. kSystemFolderType = systemFolderField.get(null);
  161. findFolder = mrjFileUtilsClass.getDeclaredMethod("findFolder",
  162. new Class[] { mrjOSTypeClass });
  163. getFileType = mrjFileUtilsClass.getDeclaredMethod("getFileType",
  164. new Class[] { File.class });
  165. } catch (ClassNotFoundException cnfe) {
  166. errorMessage = cnfe.getMessage();
  167. return false;
  168. } catch (NoSuchFieldException nsfe) {
  169. errorMessage = nsfe.getMessage();
  170. return false;
  171. } catch (NoSuchMethodException nsme) {
  172. errorMessage = nsme.getMessage();
  173. return false;
  174. } catch (SecurityException se) {
  175. errorMessage = se.getMessage();
  176. return false;
  177. } catch (IllegalAccessException iae) {
  178. errorMessage = iae.getMessage();
  179. return false;
  180. }
  181. break;
  182. }
  183. return true;
  184. }
  185. private static Object locateBrowser() {
  186. if (browser != null) {
  187. return browser;
  188. }
  189. switch (jvm) {
  190. case MRJ_2_0:
  191. try {
  192. Integer finderCreatorCode = (Integer) makeOSType.invoke(null,
  193. new Object[] { FINDER_CREATOR });
  194. Object aeTarget = aeTargetConstructor.newInstance(new Object[] {
  195. finderCreatorCode
  196. });
  197. Integer gurlType = (Integer) makeOSType.invoke(null,
  198. new Object[] { GURL_EVENT });
  199. Object appleEvent = appleEventConstructor.newInstance(new Object[] {
  200. gurlType, gurlType, aeTarget, kAutoGenerateReturnID,
  201. kAnyTransactionID
  202. });
  203. // Don't set browser = appleEvent because then the next time we call
  204. // locateBrowser(), we'll get the same AppleEvent, to which we'll already have
  205. // added the relevant parameter. Instead, regenerate the AppleEvent every time.
  206. // There's probably a way to do this better; if any has any ideas, please let
  207. // me know.
  208. return appleEvent;
  209. } catch (IllegalAccessException iae) {
  210. browser = null;
  211. errorMessage = iae.getMessage();
  212. return browser;
  213. } catch (InstantiationException ie) {
  214. browser = null;
  215. errorMessage = ie.getMessage();
  216. return browser;
  217. } catch (InvocationTargetException ite) {
  218. browser = null;
  219. errorMessage = ite.getMessage();
  220. return browser;
  221. }
  222. case MRJ_2_1:
  223. File systemFolder;
  224. try {
  225. systemFolder = (File) findFolder.invoke(null,
  226. new Object[] { kSystemFolderType });
  227. } catch (IllegalArgumentException iare) {
  228. browser = null;
  229. errorMessage = iare.getMessage();
  230. return browser;
  231. } catch (IllegalAccessException iae) {
  232. browser = null;
  233. errorMessage = iae.getMessage();
  234. return browser;
  235. } catch (InvocationTargetException ite) {
  236. browser = null;
  237. errorMessage = ite.getTargetException().getClass() + ": " +
  238. ite.getTargetException().getMessage();
  239. return browser;
  240. }
  241. String[] systemFolderFiles = systemFolder.list();
  242. // Avoid a FilenameFilter because that can't be stopped mid-list
  243. for (int i = 0; i < systemFolderFiles.length; i++) {
  244. try {
  245. File file = new File(systemFolder, systemFolderFiles[i]);
  246. if (!file.isFile()) {
  247. continue;
  248. }
  249. Object fileType = getFileType.invoke(null,
  250. new Object[] { file });
  251. if (FINDER_TYPE.equals(fileType.toString())) {
  252. browser = file.toString(); // Actually the Finder, but that's OK
  253. return browser;
  254. }
  255. } catch (IllegalArgumentException iare) {
  256. browser = browser;
  257. errorMessage = iare.getMessage();
  258. return null;
  259. } catch (IllegalAccessException iae) {
  260. browser = null;
  261. errorMessage = iae.getMessage();
  262. return browser;
  263. } catch (InvocationTargetException ite) {
  264. browser = null;
  265. errorMessage = ite.getTargetException().getClass() + ": " +
  266. ite.getTargetException().getMessage();
  267. return browser;
  268. }
  269. }
  270. browser = null;
  271. break;
  272. case WINDOWS_NT:
  273. browser = "cmd.exe";
  274. break;
  275. case WINDOWS_9x:
  276. browser = "command.com";
  277. break;
  278. case OTHER:default:
  279. //browser = "netscape"; surely mozilla is the thing these days
  280. browser = "mozilla";
  281. break;
  282. }
  283. return browser;
  284. }
  285. /**
  286. *
  287. *
  288. * @param url
  289. *
  290. * @throws IOException
  291. */
  292. public static void openURL(String url) throws IOException {
  293. if (!loadedWithoutErrors) {
  294. throw new IOException("Exception in finding browser: " +
  295. errorMessage);
  296. }
  297. Object browser = locateBrowser();
  298. if (browser == null) {
  299. throw new IOException("Unable to locate browser: " + errorMessage);
  300. }
  301. switch (jvm) {
  302. case MRJ_2_0:
  303. Object aeDesc = null;
  304. try {
  305. aeDesc = aeDescConstructor.newInstance(new Object[] { url });
  306. putParameter.invoke(browser,
  307. new Object[] { keyDirectObject, aeDesc });
  308. sendNoReply.invoke(browser, new Object[] { });
  309. } catch (InvocationTargetException ite) {
  310. throw new IOException(
  311. "InvocationTargetException while creating AEDesc: " +
  312. ite.getMessage());
  313. } catch (IllegalAccessException iae) {
  314. throw new IOException(
  315. "IllegalAccessException while building AppleEvent: " +
  316. iae.getMessage());
  317. } catch (InstantiationException ie) {
  318. throw new IOException(
  319. "InstantiationException while creating AEDesc: " +
  320. ie.getMessage());
  321. } finally {
  322. aeDesc = null; // Encourage it to get disposed if it was created
  323. browser = null; // Ditto
  324. }
  325. break;
  326. case MRJ_2_1:
  327. Runtime.getRuntime().exec(new String[] { (String) browser, url });
  328. break;
  329. case WINDOWS_NT:
  330. case WINDOWS_9x:
  331. Runtime.getRuntime().exec(new String[] {
  332. (String) browser, FIRST_WINDOWS_PARAMETER,
  333. SECOND_WINDOWS_PARAMETER, url
  334. });
  335. break;
  336. case OTHER:
  337. // Assume that we're on Unix and that Netscape is installed
  338. // First, attempt to open the URL in a currently running session of Netscape
  339. Process process = Runtime.getRuntime().exec((String) browser +
  340. NETSCAPE_OPEN_PARAMETER_START + url +
  341. NETSCAPE_OPEN_PARAMETER_END);
  342. try {
  343. int exitCode = process.waitFor();
  344. if (exitCode != 0) { // if Netscape was not open
  345. Runtime.getRuntime().exec(new String[] { (String) browser, url });
  346. }
  347. } catch (InterruptedException ie) {
  348. throw new IOException(
  349. "InterruptedException while launching browser: " +
  350. ie.getMessage());
  351. }
  352. break;
  353. default:
  354. // This should never occur, but if it does, we'll try the simplest thing possible
  355. Runtime.getRuntime().exec(new String[] { (String) browser, url });
  356. break;
  357. }
  358. }
  359. }