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