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.awt.Desktop; 29 import java.io.File; 30 import java.lang.reflect.Method; 31 import java.net.URI; 32 import java.security.AccessController; 33 import java.security.PrivilegedActionException; 34 import java.security.PrivilegedExceptionAction; 35 import javafx.application.Application; 36 import netscape.javascript.JSObject; 37 38 39 public abstract class HostServicesDelegate { 40 41 private static Method getInstanceMeth = null; 42 43 public static HostServicesDelegate getInstance(final Application app) { 44 // Call into the deploy code to get the delegate class 45 HostServicesDelegate instance = null; 46 try { 47 instance = AccessController.doPrivileged( 48 (PrivilegedExceptionAction<HostServicesDelegate>) () -> { 49 if (getInstanceMeth == null) { 50 try { 51 final String factoryClassName = 52 "com.sun.deploy.uitoolkit.impl.fx.HostServicesFactory"; 53 54 Class factoryClass = Class.forName(factoryClassName, 55 true, 56 HostServicesDelegate.class.getClassLoader()); 57 getInstanceMeth = factoryClass.getMethod( 58 "getInstance", Application.class); 59 } catch (Exception ex) { 60 return null; 61 } 62 } 63 return (HostServicesDelegate) 64 getInstanceMeth.invoke(null, app); 65 } 66 ); 67 } catch (PrivilegedActionException pae) { 68 System.err.println(pae.getException().toString()); 69 return null; 70 } 71 if (instance == null) { 72 // in this case we are in standalone mode 73 instance = StandaloneHostService.getInstance(app); 74 } 75 return instance; 76 } 77 78 protected HostServicesDelegate() { 79 } 80 81 public abstract String getCodeBase(); 82 83 public abstract String getDocumentBase(); 84 85 public abstract void showDocument(String uri); 86 87 public abstract JSObject getWebContext(); 88 89 // StandaloneHostService implementation 90 private static class StandaloneHostService extends HostServicesDelegate { 91 92 private static HostServicesDelegate instance = null; 93 94 private Class appClass = null; 95 96 public static HostServicesDelegate getInstance(Application app) { 97 synchronized (StandaloneHostService.class) { 98 if (instance == null) { 99 instance = new StandaloneHostService(app); 100 } 101 return instance; 102 } 103 } 104 105 private StandaloneHostService(Application app) { 106 appClass = app.getClass(); 107 } 108 109 @Override 110 public String getCodeBase() { 111 // If the application was launched in standalone mode, this method 112 // returns the directory containing the application jar file. 113 // If the application is not packaged in a jar file, this method 114 // returns the empty string. 115 String theClassFile = appClass.getName(); 116 int idx = theClassFile.lastIndexOf("."); 117 if (idx >= 0) { 118 // Strip off package name prefix in class name if exists 119 // getResoruce will automatically add in package name during 120 // lookup; see Class.getResource javadoc for more details 121 theClassFile = theClassFile.substring(idx + 1); 122 } 123 theClassFile = theClassFile + ".class"; 124 125 String classUrlString = appClass.getResource(theClassFile).toString(); 126 if (!classUrlString.startsWith("jar:file:") || 127 classUrlString.indexOf("!") == -1) { 128 return ""; 129 } 130 // Strip out the "jar:" and everything after and including the "!" 131 String urlString = classUrlString.substring(4, 132 classUrlString.lastIndexOf("!")); 133 File jarFile = null; 134 try { 135 jarFile = new File(new URI(urlString).getPath()); 136 } catch (Exception e) { 137 // should not happen 138 } 139 if (jarFile != null) { 140 String codebase = jarFile.getParent(); 141 if (codebase != null) { 142 return toURIString(codebase); 143 } 144 } 145 146 return ""; 147 } 148 149 private String toURIString(String filePath) { 150 try { 151 return new File(filePath).toURI().toString(); 152 } catch (Exception e) { 153 // should not happen 154 // dump stack for debug purpose 155 e.printStackTrace(); 156 } 157 return ""; 158 } 159 160 @Override public String getDocumentBase() { 161 // If the application was launched in standalone mode, 162 // this method returns the URI of the current directory. 163 return toURIString(System.getProperty("user.dir")); 164 } 165 166 static final String[] browsers = {"google-chrome", "firefox", "opera", 167 "konqueror", "mozilla"}; 168 169 @Override 170 public void showDocument(final String uri) { 171 String osName = System.getProperty("os.name"); 172 try { 173 if (osName.startsWith("Mac OS")) { 174 Desktop.getDesktop().browse(URI.create(uri)); 175 } else if (osName.startsWith("Windows")) { 176 Runtime.getRuntime().exec( 177 "rundll32 url.dll,FileProtocolHandler " + uri); 178 } else { //assume Unix or Linux 179 String browser = null; 180 for (String b : browsers) { 181 if (browser == null && Runtime.getRuntime().exec( 182 new String[]{"which", b}).getInputStream().read() != -1) { 183 Runtime.getRuntime().exec(new String[]{browser = b, uri}); 184 } 185 } 186 if (browser == null) { 187 throw new Exception("No web browser found"); 188 } 189 } 190 } catch (Exception e) { 191 // should not happen 192 // dump stack for debug purpose 193 e.printStackTrace(); 194 } 195 } 196 197 @Override public JSObject getWebContext() { 198 return null; 199 } 200 } 201 }