1 /* 2 * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.javafx.application; 27 28 import java.io.File; 29 import java.lang.reflect.Method; 30 import java.net.URI; 31 import java.security.AccessController; 32 import java.security.PrivilegedActionException; 33 import java.security.PrivilegedExceptionAction; 34 import javafx.application.Application; 35 import netscape.javascript.JSObject; 36 37 38 public abstract class HostServicesDelegate { 39 40 private static Method getInstanceMeth = null; 41 42 public static HostServicesDelegate getInstance(final Application app) { 43 // Call into the deploy code to get the delegate class 44 HostServicesDelegate instance = null; 45 try { 46 instance = AccessController.doPrivileged( 47 (PrivilegedExceptionAction<HostServicesDelegate>) () -> { 48 if (getInstanceMeth == null) { 49 try { 50 final String factoryClassName = 51 "com.sun.deploy.uitoolkit.impl.fx.HostServicesFactory"; 52 53 Class factoryClass = Class.forName(factoryClassName, 54 true, 55 HostServicesDelegate.class.getClassLoader()); 56 getInstanceMeth = factoryClass.getMethod( 57 "getInstance", Application.class); 58 } catch (Exception ex) { 59 return null; 60 } 61 } 62 return (HostServicesDelegate) 63 getInstanceMeth.invoke(null, app); 64 } 65 ); 66 } catch (PrivilegedActionException pae) { 67 System.err.println(pae.getException().toString()); 68 return null; 69 } 70 if (instance == null) { 71 // in this case we are in standalone mode 72 instance = StandaloneHostService.getInstance(app); 73 } 74 return instance; 75 } 76 77 protected HostServicesDelegate() { 78 } 79 80 public abstract String getCodeBase(); 81 82 public abstract String getDocumentBase(); 83 84 public abstract void showDocument(String uri); 85 86 public abstract JSObject getWebContext(); 87 88 // StandaloneHostService implementation 89 private static class StandaloneHostService extends HostServicesDelegate { 90 91 private static HostServicesDelegate instance = null; 92 93 private Class appClass = null; 94 95 public static HostServicesDelegate getInstance(Application app) { 96 synchronized (StandaloneHostService.class) { 97 if (instance == null) { 98 instance = new StandaloneHostService(app); 99 } 100 return instance; 101 } 102 } 103 104 private StandaloneHostService(Application app) { 105 appClass = app.getClass(); 106 } 107 108 @Override 109 public String getCodeBase() { 110 // If the application was launched in standalone mode, this method 111 // returns the directory containing the application jar file. 112 // If the application is not packaged in a jar file, this method 113 // returns the empty string. 114 String theClassFile = appClass.getName(); 115 int idx = theClassFile.lastIndexOf("."); 116 if (idx >= 0) { 117 // Strip off package name prefix in class name if exists 118 // getResoruce will automatically add in package name during 119 // lookup; see Class.getResource javadoc for more details 120 theClassFile = theClassFile.substring(idx + 1); 121 } 122 theClassFile = theClassFile + ".class"; 123 124 String classUrlString = appClass.getResource(theClassFile).toString(); 125 if (!classUrlString.startsWith("jar:file:") || 126 classUrlString.indexOf("!") == -1) { 127 return ""; 128 } 129 // Strip out the "jar:" and everything after and including the "!" 130 String urlString = classUrlString.substring(4, 131 classUrlString.lastIndexOf("!")); 132 File jarFile = null; 133 try { 134 jarFile = new File(new URI(urlString).getPath()); 135 } catch (Exception e) { 136 // should not happen 137 } 138 if (jarFile != null) { 139 String codebase = jarFile.getParent(); 140 if (codebase != null) { 141 return toURIString(codebase); 142 } 143 } 144 145 return ""; 146 } 147 148 private String toURIString(String filePath) { 149 try { 150 return new File(filePath).toURI().toString(); 151 } catch (Exception e) { 152 // should not happen 153 // dump stack for debug purpose 154 e.printStackTrace(); 155 } 156 return ""; 157 } 158 159 @Override public String getDocumentBase() { 160 // If the application was launched in standalone mode, 161 // this method returns the URI of the current directory. 162 return toURIString(System.getProperty("user.dir")); 163 } 164 165 static final String[] browsers = {"google-chrome", "firefox", "opera", 166 "konqueror", "mozilla"}; 167 168 @Override 169 public void showDocument(final String uri) { 170 String osName = System.getProperty("os.name"); 171 try { 172 if (osName.startsWith("Mac OS")) { 173 Class.forName("com.apple.eio.FileManager").getDeclaredMethod( 174 "openURL", new Class[]{String.class}).invoke(null, 175 new Object[]{uri}); 176 } else if (osName.startsWith("Windows")) { 177 Runtime.getRuntime().exec( 178 "rundll32 url.dll,FileProtocolHandler " + uri); 179 } else { //assume Unix or Linux 180 String browser = null; 181 for (String b : browsers) { 182 if (browser == null && Runtime.getRuntime().exec( 183 new String[]{"which", b}).getInputStream().read() != -1) { 184 Runtime.getRuntime().exec(new String[]{browser = b, uri}); 185 } 186 } 187 if (browser == null) { 188 throw new Exception("No web browser found"); 189 } 190 } 191 } catch (Exception e) { 192 // should not happen 193 // dump stack for debug purpose 194 e.printStackTrace(); 195 } 196 } 197 198 @Override public JSObject getWebContext() { 199 return null; 200 } 201 } 202 }