Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/awt/Desktop.java
38829 views
/*1* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.awt;2627import java.io.File;28import java.io.IOException;29import java.net.URISyntaxException;30import java.net.URI;31import java.net.URL;32import java.net.MalformedURLException;33import java.awt.AWTPermission;34import java.awt.GraphicsEnvironment;35import java.awt.HeadlessException;36import java.awt.peer.DesktopPeer;37import sun.awt.SunToolkit;38import sun.awt.HeadlessToolkit;39import java.io.FilePermission;40import sun.security.util.SecurityConstants;4142/**43* The {@code Desktop} class allows a Java application to launch44* associated applications registered on the native desktop to handle45* a {@link java.net.URI} or a file.46*47* <p> Supported operations include:48* <ul>49* <li>launching the user-default browser to show a specified50* URI;</li>51* <li>launching the user-default mail client with an optional52* {@code mailto} URI;</li>53* <li>launching a registered application to open, edit or print a54* specified file.</li>55* </ul>56*57* <p> This class provides methods corresponding to these58* operations. The methods look for the associated application59* registered on the current platform, and launch it to handle a URI60* or file. If there is no associated application or the associated61* application fails to be launched, an exception is thrown.62*63* <p> An application is registered to a URI or file type; for64* example, the {@code "sxi"} file extension is typically registered65* to StarOffice. The mechanism of registering, accessing, and66* launching the associated application is platform-dependent.67*68* <p> Each operation is an action type represented by the {@link69* Desktop.Action} class.70*71* <p> Note: when some action is invoked and the associated72* application is executed, it will be executed on the same system as73* the one on which the Java application was launched.74*75* @since 1.676* @author Armin Chen77* @author George Zhang78*/79public class Desktop {8081/**82* Represents an action type. Each platform supports a different83* set of actions. You may use the {@link Desktop#isSupported}84* method to determine if the given action is supported by the85* current platform.86* @see java.awt.Desktop#isSupported(java.awt.Desktop.Action)87* @since 1.688*/89public static enum Action {90/**91* Represents an "open" action.92* @see Desktop#open(java.io.File)93*/94OPEN,95/**96* Represents an "edit" action.97* @see Desktop#edit(java.io.File)98*/99EDIT,100/**101* Represents a "print" action.102* @see Desktop#print(java.io.File)103*/104PRINT,105/**106* Represents a "mail" action.107* @see Desktop#mail()108* @see Desktop#mail(java.net.URI)109*/110MAIL,111/**112* Represents a "browse" action.113* @see Desktop#browse(java.net.URI)114*/115BROWSE116};117118private DesktopPeer peer;119120/**121* Suppresses default constructor for noninstantiability.122*/123private Desktop() {124peer = Toolkit.getDefaultToolkit().createDesktopPeer(this);125}126127/**128* Returns the <code>Desktop</code> instance of the current129* browser context. On some platforms the Desktop API may not be130* supported; use the {@link #isDesktopSupported} method to131* determine if the current desktop is supported.132* @return the Desktop instance of the current browser context133* @throws HeadlessException if {@link134* GraphicsEnvironment#isHeadless()} returns {@code true}135* @throws UnsupportedOperationException if this class is not136* supported on the current platform137* @see #isDesktopSupported()138* @see java.awt.GraphicsEnvironment#isHeadless139*/140public static synchronized Desktop getDesktop(){141if (GraphicsEnvironment.isHeadless()) throw new HeadlessException();142if (!Desktop.isDesktopSupported()) {143throw new UnsupportedOperationException("Desktop API is not " +144"supported on the current platform");145}146147sun.awt.AppContext context = sun.awt.AppContext.getAppContext();148Desktop desktop = (Desktop)context.get(Desktop.class);149150if (desktop == null) {151desktop = new Desktop();152context.put(Desktop.class, desktop);153}154155return desktop;156}157158/**159* Tests whether this class is supported on the current platform.160* If it's supported, use {@link #getDesktop()} to retrieve an161* instance.162*163* @return <code>true</code> if this class is supported on the164* current platform; <code>false</code> otherwise165* @see #getDesktop()166*/167public static boolean isDesktopSupported(){168Toolkit defaultToolkit = Toolkit.getDefaultToolkit();169if (defaultToolkit instanceof SunToolkit) {170return ((SunToolkit)defaultToolkit).isDesktopSupported();171}172return false;173}174175/**176* Tests whether an action is supported on the current platform.177*178* <p>Even when the platform supports an action, a file or URI may179* not have a registered application for the action. For example,180* most of the platforms support the {@link Desktop.Action#OPEN}181* action. But for a specific file, there may not be an182* application registered to open it. In this case, {@link183* #isSupported} may return {@code true}, but the corresponding184* action method will throw an {@link IOException}.185*186* @param action the specified {@link Action}187* @return <code>true</code> if the specified action is supported on188* the current platform; <code>false</code> otherwise189* @see Desktop.Action190*/191public boolean isSupported(Action action) {192return peer.isSupported(action);193}194195/**196* Checks if the file is a valid file and readable.197*198* @throws SecurityException If a security manager exists and its199* {@link SecurityManager#checkRead(java.lang.String)} method200* denies read access to the file201* @throws NullPointerException if file is null202* @throws IllegalArgumentException if file doesn't exist203*/204private static void checkFileValidation(File file) {205if (!file.exists()) {206throw new IllegalArgumentException("The file: "207+ file.getPath() + " doesn't exist.");208}209}210211/**212* Checks if the action type is supported.213*214* @param actionType the action type in question215* @throws UnsupportedOperationException if the specified action type is not216* supported on the current platform217*/218private void checkActionSupport(Action actionType){219if (!isSupported(actionType)) {220throw new UnsupportedOperationException("The " + actionType.name()221+ " action is not supported on the current platform!");222}223}224225226/**227* Calls to the security manager's <code>checkPermission</code> method with228* an <code>AWTPermission("showWindowWithoutWarningBanner")</code>229* permission.230*/231private void checkAWTPermission(){232SecurityManager sm = System.getSecurityManager();233if (sm != null) {234sm.checkPermission(new AWTPermission(235"showWindowWithoutWarningBanner"));236}237}238239/**240* Launches the associated application to open the file.241*242* <p> If the specified file is a directory, the file manager of243* the current platform is launched to open it.244*245* @param file the file to be opened with the associated application246* @throws NullPointerException if {@code file} is {@code null}247* @throws IllegalArgumentException if the specified file doesn't248* exist249* @throws UnsupportedOperationException if the current platform250* does not support the {@link Desktop.Action#OPEN} action251* @throws IOException if the specified file has no associated252* application or the associated application fails to be launched253* @throws SecurityException if a security manager exists and its254* {@link java.lang.SecurityManager#checkRead(java.lang.String)}255* method denies read access to the file, or it denies the256* <code>AWTPermission("showWindowWithoutWarningBanner")</code>257* permission, or the calling thread is not allowed to create a258* subprocess259* @see java.awt.AWTPermission260*/261public void open(File file) throws IOException {262file = new File(file.getPath());263checkAWTPermission();264checkExec();265checkActionSupport(Action.OPEN);266checkFileValidation(file);267268peer.open(file);269}270271/**272* Launches the associated editor application and opens a file for273* editing.274*275* @param file the file to be opened for editing276* @throws NullPointerException if the specified file is {@code null}277* @throws IllegalArgumentException if the specified file doesn't278* exist279* @throws UnsupportedOperationException if the current platform280* does not support the {@link Desktop.Action#EDIT} action281* @throws IOException if the specified file has no associated282* editor, or the associated application fails to be launched283* @throws SecurityException if a security manager exists and its284* {@link java.lang.SecurityManager#checkRead(java.lang.String)}285* method denies read access to the file, or {@link286* java.lang.SecurityManager#checkWrite(java.lang.String)} method287* denies write access to the file, or it denies the288* <code>AWTPermission("showWindowWithoutWarningBanner")</code>289* permission, or the calling thread is not allowed to create a290* subprocess291* @see java.awt.AWTPermission292*/293public void edit(File file) throws IOException {294file = new File(file.getPath());295checkAWTPermission();296checkExec();297checkActionSupport(Action.EDIT);298file.canWrite();299checkFileValidation(file);300301peer.edit(file);302}303304/**305* Prints a file with the native desktop printing facility, using306* the associated application's print command.307*308* @param file the file to be printed309* @throws NullPointerException if the specified file is {@code310* null}311* @throws IllegalArgumentException if the specified file doesn't312* exist313* @throws UnsupportedOperationException if the current platform314* does not support the {@link Desktop.Action#PRINT} action315* @throws IOException if the specified file has no associated316* application that can be used to print it317* @throws SecurityException if a security manager exists and its318* {@link java.lang.SecurityManager#checkRead(java.lang.String)}319* method denies read access to the file, or its {@link320* java.lang.SecurityManager#checkPrintJobAccess()} method denies321* the permission to print the file, or the calling thread is not322* allowed to create a subprocess323*/324public void print(File file) throws IOException {325file = new File(file.getPath());326checkExec();327SecurityManager sm = System.getSecurityManager();328if (sm != null) {329sm.checkPrintJobAccess();330}331checkActionSupport(Action.PRINT);332checkFileValidation(file);333334peer.print(file);335}336337/**338* Launches the default browser to display a {@code URI}.339* If the default browser is not able to handle the specified340* {@code URI}, the application registered for handling341* {@code URIs} of the specified type is invoked. The application342* is determined from the protocol and path of the {@code URI}, as343* defined by the {@code URI} class.344* <p>345* If the calling thread does not have the necessary permissions,346* and this is invoked from within an applet,347* {@code AppletContext.showDocument()} is used. Similarly, if the calling348* does not have the necessary permissions, and this is invoked from within349* a Java Web Started application, {@code BasicService.showDocument()}350* is used.351*352* @param uri the URI to be displayed in the user default browser353* @throws NullPointerException if {@code uri} is {@code null}354* @throws UnsupportedOperationException if the current platform355* does not support the {@link Desktop.Action#BROWSE} action356* @throws IOException if the user default browser is not found,357* or it fails to be launched, or the default handler application358* failed to be launched359* @throws SecurityException if a security manager exists and it360* denies the361* <code>AWTPermission("showWindowWithoutWarningBanner")</code>362* permission, or the calling thread is not allowed to create a363* subprocess; and not invoked from within an applet or Java Web Started364* application365* @throws IllegalArgumentException if the necessary permissions366* are not available and the URI can not be converted to a {@code URL}367* @see java.net.URI368* @see java.awt.AWTPermission369* @see java.applet.AppletContext370*/371public void browse(URI uri) throws IOException {372SecurityException securityException = null;373try {374checkAWTPermission();375checkExec();376} catch (SecurityException e) {377securityException = e;378}379checkActionSupport(Action.BROWSE);380if (uri == null) {381throw new NullPointerException();382}383if (securityException == null) {384peer.browse(uri);385return;386}387388// Calling thread doesn't have necessary priviledges.389// Delegate to DesktopBrowse so that it can work in390// applet/webstart.391URL url = null;392try {393url = uri.toURL();394} catch (MalformedURLException e) {395throw new IllegalArgumentException("Unable to convert URI to URL", e);396}397sun.awt.DesktopBrowse db = sun.awt.DesktopBrowse.getInstance();398if (db == null) {399// Not in webstart/applet, throw the exception.400throw securityException;401}402db.browse(url);403}404405/**406* Launches the mail composing window of the user default mail407* client.408*409* @throws UnsupportedOperationException if the current platform410* does not support the {@link Desktop.Action#MAIL} action411* @throws IOException if the user default mail client is not412* found, or it fails to be launched413* @throws SecurityException if a security manager exists and it414* denies the415* <code>AWTPermission("showWindowWithoutWarningBanner")</code>416* permission, or the calling thread is not allowed to create a417* subprocess418* @see java.awt.AWTPermission419*/420public void mail() throws IOException {421checkAWTPermission();422checkExec();423checkActionSupport(Action.MAIL);424URI mailtoURI = null;425try{426mailtoURI = new URI("mailto:?");427peer.mail(mailtoURI);428} catch (URISyntaxException e){429// won't reach here.430}431}432433/**434* Launches the mail composing window of the user default mail435* client, filling the message fields specified by a {@code436* mailto:} URI.437*438* <p> A <code>mailto:</code> URI can specify message fields439* including <i>"to"</i>, <i>"cc"</i>, <i>"subject"</i>,440* <i>"body"</i>, etc. See <a441* href="http://www.ietf.org/rfc/rfc2368.txt">The mailto URL442* scheme (RFC 2368)</a> for the {@code mailto:} URI specification443* details.444*445* @param mailtoURI the specified {@code mailto:} URI446* @throws NullPointerException if the specified URI is {@code447* null}448* @throws IllegalArgumentException if the URI scheme is not449* <code>"mailto"</code>450* @throws UnsupportedOperationException if the current platform451* does not support the {@link Desktop.Action#MAIL} action452* @throws IOException if the user default mail client is not453* found or fails to be launched454* @throws SecurityException if a security manager exists and it455* denies the456* <code>AWTPermission("showWindowWithoutWarningBanner")</code>457* permission, or the calling thread is not allowed to create a458* subprocess459* @see java.net.URI460* @see java.awt.AWTPermission461*/462public void mail(URI mailtoURI) throws IOException {463checkAWTPermission();464checkExec();465checkActionSupport(Action.MAIL);466if (mailtoURI == null) throw new NullPointerException();467468if (!"mailto".equalsIgnoreCase(mailtoURI.getScheme())) {469throw new IllegalArgumentException("URI scheme is not \"mailto\"");470}471472peer.mail(mailtoURI);473}474475private void checkExec() throws SecurityException {476SecurityManager sm = System.getSecurityManager();477if (sm != null) {478sm.checkPermission(new FilePermission("<<ALL FILES>>",479SecurityConstants.FILE_EXECUTE_ACTION));480}481}482}483484485