History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/awt/Desktop.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/awt/Desktop.java+484−0
@@ -0,0 +1,484 @@
1+/*
2+ * Copyright (c) 2005, 2006, 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 java.awt;
27+
28+import java.io.File;
29+import java.io.IOException;
30+import java.net.URISyntaxException;
31+import java.net.URI;
32+import java.net.URL;
33+import java.net.MalformedURLException;
34+import java.awt.AWTPermission;
35+import java.awt.GraphicsEnvironment;
36+import java.awt.HeadlessException;
37+import java.awt.peer.DesktopPeer;
38+import sun.awt.SunToolkit;
39+import sun.awt.HeadlessToolkit;
40+import java.io.FilePermission;
41+import sun.security.util.SecurityConstants;
42+
43+/**
44+ * The {@code Desktop} class allows a Java application to launch
45+ * associated applications registered on the native desktop to handle
46+ * a {@link java.net.URI} or a file.
47+ *
48+ * <p> Supported operations include:
49+ * <ul>
50+ * <li>launching the user-default browser to show a specified
51+ * URI;</li>
52+ * <li>launching the user-default mail client with an optional
53+ * {@code mailto} URI;</li>
54+ * <li>launching a registered application to open, edit or print a
55+ * specified file.</li>
56+ * </ul>
57+ *
58+ * <p> This class provides methods corresponding to these
59+ * operations. The methods look for the associated application
60+ * registered on the current platform, and launch it to handle a URI
61+ * or file. If there is no associated application or the associated
62+ * application fails to be launched, an exception is thrown.
63+ *
64+ * <p> An application is registered to a URI or file type; for
65+ * example, the {@code "sxi"} file extension is typically registered
66+ * to StarOffice. The mechanism of registering, accessing, and
67+ * launching the associated application is platform-dependent.
68+ *
69+ * <p> Each operation is an action type represented by the {@link
70+ * Desktop.Action} class.
71+ *
72+ * <p> Note: when some action is invoked and the associated
73+ * application is executed, it will be executed on the same system as
74+ * the one on which the Java application was launched.
75+ *
76+ * @since 1.6
77+ * @author Armin Chen
78+ * @author George Zhang
79+ */
80+public class Desktop {
81+
82+ /**
83+ * Represents an action type. Each platform supports a different
84+ * set of actions. You may use the {@link Desktop#isSupported}
85+ * method to determine if the given action is supported by the
86+ * current platform.
87+ * @see java.awt.Desktop#isSupported(java.awt.Desktop.Action)
88+ * @since 1.6
89+ */
90+ public static enum Action {
91+ /**
92+ * Represents an "open" action.
93+ * @see Desktop#open(java.io.File)
94+ */
95+ OPEN,
96+ /**
97+ * Represents an "edit" action.
98+ * @see Desktop#edit(java.io.File)
99+ */
100+ EDIT,
101+ /**
102+ * Represents a "print" action.
103+ * @see Desktop#print(java.io.File)
104+ */
105+ PRINT,
106+ /**
107+ * Represents a "mail" action.
108+ * @see Desktop#mail()
109+ * @see Desktop#mail(java.net.URI)
110+ */
111+ MAIL,
112+ /**
113+ * Represents a "browse" action.
114+ * @see Desktop#browse(java.net.URI)
115+ */
116+ BROWSE
117+ };
118+
119+ private DesktopPeer peer;
120+
121+ /**
122+ * Suppresses default constructor for noninstantiability.
123+ */
124+ private Desktop() {
125+ peer = Toolkit.getDefaultToolkit().createDesktopPeer(this);
126+ }
127+
128+ /**
129+ * Returns the <code>Desktop</code> instance of the current
130+ * browser context. On some platforms the Desktop API may not be
131+ * supported; use the {@link #isDesktopSupported} method to
132+ * determine if the current desktop is supported.
133+ * @return the Desktop instance of the current browser context
134+ * @throws HeadlessException if {@link
135+ * GraphicsEnvironment#isHeadless()} returns {@code true}
136+ * @throws UnsupportedOperationException if this class is not
137+ * supported on the current platform
138+ * @see #isDesktopSupported()
139+ * @see java.awt.GraphicsEnvironment#isHeadless
140+ */
141+ public static synchronized Desktop getDesktop(){
142+ if (GraphicsEnvironment.isHeadless()) throw new HeadlessException();
143+ if (!Desktop.isDesktopSupported()) {
144+ throw new UnsupportedOperationException("Desktop API is not " +
145+ "supported on the current platform");
146+ }
147+
148+ sun.awt.AppContext context = sun.awt.AppContext.getAppContext();
149+ Desktop desktop = (Desktop)context.get(Desktop.class);
150+
151+ if (desktop == null) {
152+ desktop = new Desktop();
153+ context.put(Desktop.class, desktop);
154+ }
155+
156+ return desktop;
157+ }
158+
159+ /**
160+ * Tests whether this class is supported on the current platform.
161+ * If it's supported, use {@link #getDesktop()} to retrieve an
162+ * instance.
163+ *
164+ * @return <code>true</code> if this class is supported on the
165+ * current platform; <code>false</code> otherwise
166+ * @see #getDesktop()
167+ */
168+ public static boolean isDesktopSupported(){
169+ Toolkit defaultToolkit = Toolkit.getDefaultToolkit();
170+ if (defaultToolkit instanceof SunToolkit) {
171+ return ((SunToolkit)defaultToolkit).isDesktopSupported();
172+ }
173+ return false;
174+ }
175+
176+ /**
177+ * Tests whether an action is supported on the current platform.
178+ *
179+ * <p>Even when the platform supports an action, a file or URI may
180+ * not have a registered application for the action. For example,
181+ * most of the platforms support the {@link Desktop.Action#OPEN}
182+ * action. But for a specific file, there may not be an
183+ * application registered to open it. In this case, {@link
184+ * #isSupported} may return {@code true}, but the corresponding
185+ * action method will throw an {@link IOException}.
186+ *
187+ * @param action the specified {@link Action}
188+ * @return <code>true</code> if the specified action is supported on
189+ * the current platform; <code>false</code> otherwise
190+ * @see Desktop.Action
191+ */
192+ public boolean isSupported(Action action) {
193+ return peer.isSupported(action);
194+ }
195+
196+ /**
197+ * Checks if the file is a valid file and readable.
198+ *
199+ * @throws SecurityException If a security manager exists and its
200+ * {@link SecurityManager#checkRead(java.lang.String)} method
201+ * denies read access to the file
202+ * @throws NullPointerException if file is null
203+ * @throws IllegalArgumentException if file doesn't exist
204+ */
205+ private static void checkFileValidation(File file){
206+ if (file == null) throw new NullPointerException("File must not be null");
207+
208+ if (!file.exists()) {
209+ throw new IllegalArgumentException("The file: "
210+ + file.getPath() + " doesn't exist.");
211+ }
212+
213+ file.canRead();
214+ }
215+
216+ /**
217+ * Checks if the action type is supported.
218+ *
219+ * @param actionType the action type in question
220+ * @throws UnsupportedOperationException if the specified action type is not
221+ * supported on the current platform
222+ */
223+ private void checkActionSupport(Action actionType){
224+ if (!isSupported(actionType)) {
225+ throw new UnsupportedOperationException("The " + actionType.name()
226+ + " action is not supported on the current platform!");
227+ }
228+ }
229+
230+
231+ /**
232+ * Calls to the security manager's <code>checkPermission</code> method with
233+ * an <code>AWTPermission("showWindowWithoutWarningBanner")</code>
234+ * permission.
235+ */
236+ private void checkAWTPermission(){
237+ SecurityManager sm = System.getSecurityManager();
238+ if (sm != null) {
239+ sm.checkPermission(new AWTPermission(
240+ "showWindowWithoutWarningBanner"));
241+ }
242+ }
243+
244+ /**
245+ * Launches the associated application to open the file.
246+ *
247+ * <p> If the specified file is a directory, the file manager of
248+ * the current platform is launched to open it.
249+ *
250+ * @param file the file to be opened with the associated application
251+ * @throws NullPointerException if {@code file} is {@code null}
252+ * @throws IllegalArgumentException if the specified file doesn't
253+ * exist
254+ * @throws UnsupportedOperationException if the current platform
255+ * does not support the {@link Desktop.Action#OPEN} action
256+ * @throws IOException if the specified file has no associated
257+ * application or the associated application fails to be launched
258+ * @throws SecurityException if a security manager exists and its
259+ * {@link java.lang.SecurityManager#checkRead(java.lang.String)}
260+ * method denies read access to the file, or it denies the
261+ * <code>AWTPermission("showWindowWithoutWarningBanner")</code>
262+ * permission, or the calling thread is not allowed to create a
263+ * subprocess
264+ * @see java.awt.AWTPermission
265+ */
266+ public void open(File file) throws IOException {
267+ checkAWTPermission();
268+ checkExec();
269+ checkActionSupport(Action.OPEN);
270+ checkFileValidation(file);
271+
272+ peer.open(file);
273+ }
274+
275+ /**
276+ * Launches the associated editor application and opens a file for
277+ * editing.
278+ *
279+ * @param file the file to be opened for editing
280+ * @throws NullPointerException if the specified file is {@code null}
281+ * @throws IllegalArgumentException if the specified file doesn't
282+ * exist
283+ * @throws UnsupportedOperationException if the current platform
284+ * does not support the {@link Desktop.Action#EDIT} action
285+ * @throws IOException if the specified file has no associated
286+ * editor, or the associated application fails to be launched
287+ * @throws SecurityException if a security manager exists and its
288+ * {@link java.lang.SecurityManager#checkRead(java.lang.String)}
289+ * method denies read access to the file, or {@link
290+ * java.lang.SecurityManager#checkWrite(java.lang.String)} method
291+ * denies write access to the file, or it denies the
292+ * <code>AWTPermission("showWindowWithoutWarningBanner")</code>
293+ * permission, or the calling thread is not allowed to create a
294+ * subprocess
295+ * @see java.awt.AWTPermission
296+ */
297+ public void edit(File file) throws IOException {
298+ checkAWTPermission();
299+ checkExec();
300+ checkActionSupport(Action.EDIT);
301+ file.canWrite();
302+ checkFileValidation(file);
303+
304+ peer.edit(file);
305+ }
306+
307+ /**
308+ * Prints a file with the native desktop printing facility, using
309+ * the associated application's print command.
310+ *
311+ * @param file the file to be printed
312+ * @throws NullPointerException if the specified file is {@code
313+ * null}
314+ * @throws IllegalArgumentException if the specified file doesn't
315+ * exist
316+ * @throws UnsupportedOperationException if the current platform
317+ * does not support the {@link Desktop.Action#PRINT} action
318+ * @throws IOException if the specified file has no associated
319+ * application that can be used to print it
320+ * @throws SecurityException if a security manager exists and its
321+ * {@link java.lang.SecurityManager#checkRead(java.lang.String)}
322+ * method denies read access to the file, or its {@link
323+ * java.lang.SecurityManager#checkPrintJobAccess()} method denies
324+ * the permission to print the file, or the calling thread is not
325+ * allowed to create a subprocess
326+ */
327+ public void print(File file) throws IOException {
328+ checkExec();
329+ SecurityManager sm = System.getSecurityManager();
330+ if (sm != null) {
331+ sm.checkPrintJobAccess();
332+ }
333+ checkActionSupport(Action.PRINT);
334+ checkFileValidation(file);
335+
336+ peer.print(file);
337+ }
338+
339+ /**
340+ * Launches the default browser to display a {@code URI}.
341+ * If the default browser is not able to handle the specified
342+ * {@code URI}, the application registered for handling
343+ * {@code URIs} of the specified type is invoked. The application
344+ * is determined from the protocol and path of the {@code URI}, as
345+ * defined by the {@code URI} class.
346+ * <p>
347+ * If the calling thread does not have the necessary permissions,
348+ * and this is invoked from within an applet,
349+ * {@code AppletContext.showDocument()} is used. Similarly, if the calling
350+ * does not have the necessary permissions, and this is invoked from within
351+ * a Java Web Started application, {@code BasicService.showDocument()}
352+ * is used.
353+ *
354+ * @param uri the URI to be displayed in the user default browser
355+ * @throws NullPointerException if {@code uri} is {@code null}
356+ * @throws UnsupportedOperationException if the current platform
357+ * does not support the {@link Desktop.Action#BROWSE} action
358+ * @throws IOException if the user default browser is not found,
359+ * or it fails to be launched, or the default handler application
360+ * failed to be launched
361+ * @throws SecurityException if a security manager exists and it
362+ * denies the
363+ * <code>AWTPermission("showWindowWithoutWarningBanner")</code>
364+ * permission, or the calling thread is not allowed to create a
365+ * subprocess; and not invoked from within an applet or Java Web Started
366+ * application
367+ * @throws IllegalArgumentException if the necessary permissions
368+ * are not available and the URI can not be converted to a {@code URL}
369+ * @see java.net.URI
370+ * @see java.awt.AWTPermission
371+ * @see java.applet.AppletContext
372+ */
373+ public void browse(URI uri) throws IOException {
374+ SecurityException securityException = null;
375+ try {
376+ checkAWTPermission();
377+ checkExec();
378+ } catch (SecurityException e) {
379+ securityException = e;
380+ }
381+ checkActionSupport(Action.BROWSE);
382+ if (uri == null) {
383+ throw new NullPointerException();
384+ }
385+ if (securityException == null) {
386+ peer.browse(uri);
387+ return;
388+ }
389+
390+ // Calling thread doesn't have necessary priviledges.
391+ // Delegate to DesktopBrowse so that it can work in
392+ // applet/webstart.
393+ URL url = null;
394+ try {
395+ url = uri.toURL();
396+ } catch (MalformedURLException e) {
397+ throw new IllegalArgumentException("Unable to convert URI to URL", e);
398+ }
399+ sun.awt.DesktopBrowse db = sun.awt.DesktopBrowse.getInstance();
400+ if (db == null) {
401+ // Not in webstart/applet, throw the exception.
402+ throw securityException;
403+ }
404+ db.browse(url);
405+ }
406+
407+ /**
408+ * Launches the mail composing window of the user default mail
409+ * client.
410+ *
411+ * @throws UnsupportedOperationException if the current platform
412+ * does not support the {@link Desktop.Action#MAIL} action
413+ * @throws IOException if the user default mail client is not
414+ * found, or it fails to be launched
415+ * @throws SecurityException if a security manager exists and it
416+ * denies the
417+ * <code>AWTPermission("showWindowWithoutWarningBanner")</code>
418+ * permission, or the calling thread is not allowed to create a
419+ * subprocess
420+ * @see java.awt.AWTPermission
421+ */
422+ public void mail() throws IOException {
423+ checkAWTPermission();
424+ checkExec();
425+ checkActionSupport(Action.MAIL);
426+ URI mailtoURI = null;
427+ try{
428+ mailtoURI = new URI("mailto:?");
429+ peer.mail(mailtoURI);
430+ } catch (URISyntaxException e){
431+ // won't reach here.
432+ }
433+ }
434+
435+ /**
436+ * Launches the mail composing window of the user default mail
437+ * client, filling the message fields specified by a {@code
438+ * mailto:} URI.
439+ *
440+ * <p> A <code>mailto:</code> URI can specify message fields
441+ * including <i>"to"</i>, <i>"cc"</i>, <i>"subject"</i>,
442+ * <i>"body"</i>, etc. See <a
443+ * href="http://www.ietf.org/rfc/rfc2368.txt">The mailto URL
444+ * scheme (RFC 2368)</a> for the {@code mailto:} URI specification
445+ * details.
446+ *
447+ * @param mailtoURI the specified {@code mailto:} URI
448+ * @throws NullPointerException if the specified URI is {@code
449+ * null}
450+ * @throws IllegalArgumentException if the URI scheme is not
451+ * <code>"mailto"</code>
452+ * @throws UnsupportedOperationException if the current platform
453+ * does not support the {@link Desktop.Action#MAIL} action
454+ * @throws IOException if the user default mail client is not
455+ * found or fails to be launched
456+ * @throws SecurityException if a security manager exists and it
457+ * denies the
458+ * <code>AWTPermission("showWindowWithoutWarningBanner")</code>
459+ * permission, or the calling thread is not allowed to create a
460+ * subprocess
461+ * @see java.net.URI
462+ * @see java.awt.AWTPermission
463+ */
464+ public void mail(URI mailtoURI) throws IOException {
465+ checkAWTPermission();
466+ checkExec();
467+ checkActionSupport(Action.MAIL);
468+ if (mailtoURI == null) throw new NullPointerException();
469+
470+ if (!"mailto".equalsIgnoreCase(mailtoURI.getScheme())) {
471+ throw new IllegalArgumentException("URI scheme is not \"mailto\"");
472+ }
473+
474+ peer.mail(mailtoURI);
475+ }
476+
477+ private void checkExec() throws SecurityException {
478+ SecurityManager sm = System.getSecurityManager();
479+ if (sm != null) {
480+ sm.checkPermission(new FilePermission("<<ALL FILES>>",
481+ SecurityConstants.FILE_EXECUTE_ACTION));
482+ }
483+ }
484+}