KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > awt > Desktop


1 /*
2  * @(#)Desktop.java 1.4 06/08/24
3  *
4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.awt;
9
10 import java.io.File JavaDoc;
11 import java.io.IOException JavaDoc;
12 import java.net.URISyntaxException JavaDoc;
13 import java.net.URI JavaDoc;
14 import java.net.URL JavaDoc;
15 import java.net.MalformedURLException JavaDoc;
16 import java.awt.AWTPermission JavaDoc;
17 import java.awt.GraphicsEnvironment JavaDoc;
18 import java.awt.HeadlessException JavaDoc;
19 import java.awt.peer.DesktopPeer;
20 import sun.awt.SunToolkit;
21 import sun.awt.HeadlessToolkit;
22 import java.io.FilePermission JavaDoc;
23 import sun.security.util.SecurityConstants;
24
25 /**
26  * The {@code Desktop} class allows a Java application to launch
27  * associated applications registered on the native desktop to handle
28  * a {@link java.net.URI} or a file.
29  *
30  * <p> Supported operations include:
31  * <ul>
32  * <li>launching the user-default browser to show a specified
33  * URI;</li>
34  * <li>launching the user-default mail client with an optional
35  * {@code mailto} URI;</li>
36  * <li>launching a registered application to open, edit or print a
37  * specified file.</li>
38  * </ul>
39  *
40  * <p> This class provides methods corresponding to these
41  * operations. The methods look for the associated application
42  * registered on the current platform, and launch it to handle a URI
43  * or file. If there is no associated application or the associated
44  * application fails to be launched, an exception is thrown.
45  *
46  * <p> An application is registered to a URI or file type; for
47  * example, the {@code "sxi"} file extension is typically registered
48  * to StarOffice. The mechanism of registereing, accessing, and
49  * launching the associated application is platform-dependent.
50  *
51  * <p> Each operation is an action type represented by the {@link
52  * Desktop.Action} class.
53  *
54  * <p> Note: when some action is invoked and the associated
55  * application is executed, it will be executed on the same system as
56  * the one on which the Java application was launched.
57  *
58  * @since 1.6
59  * @author Armin Chen
60  * @author George Zhang
61  */

62 public class Desktop {
63
64     /**
65      * Represents an action type. Each platform supports a different
66      * set of actions. You may use the {@link Desktop#isSupported}
67      * method to determine if the given action is supported by the
68      * current platform.
69      * @see java.awt.Desktop#isSupported(java.awt.Desktop.Action)
70      * @since 1.6
71      */

72     public static enum Action {
73         /**
74          * Represents an "open" action.
75          * @see Desktop#open(java.io.File)
76          */

77         OPEN,
78         /**
79          * Represents an "edit" action.
80          * @see Desktop#edit(java.io.File)
81          */

82         EDIT,
83         /**
84          * Represents a "print" action.
85          * @see Desktop#print(java.io.File)
86          */

87         PRINT,
88         /**
89          * Represents a "mail" action.
90          * @see Desktop#mail()
91          * @see Desktop#mail(java.net.URI)
92          */

93         MAIL,
94         /**
95          * Represents a "browse" action.
96          * @see Desktop#browse(java.net.URI)
97          */

98         BROWSE
99     };
100         
101     private DesktopPeer peer;
102     
103     /**
104      * Suppresses default constructor for noninstantiability.
105      */

106     private Desktop() {
107         peer = Toolkit.getDefaultToolkit().createDesktopPeer(this);
108     }
109     
110     /**
111      * Returns the <code>Desktop</code> instance of the current
112      * browser context. On some platforms the Desktop API may not be
113      * supported; use the {@link #isDesktopSupported} method to
114      * determine if the current desktop is supported.
115      * @return the Desktop instance of the current browser context
116      * @throws HeadlessException if {@link
117      * GraphicsEnvironment#isHeadless()} returns {@code true}
118      * @throws UnsupportedOperationException if this class is not
119      * supported on the current platform
120      * @see #isDesktopSupported()
121      * @see java.awt.GraphicsEnvironment#isHeadless
122      */

123     public static synchronized Desktop JavaDoc getDesktop(){
124         if (GraphicsEnvironment.isHeadless()) throw new HeadlessException JavaDoc();
125         if (!Desktop.isDesktopSupported()) {
126             throw new UnsupportedOperationException JavaDoc("Desktop API is not " +
127                                                     "supported on the current platform");
128         }
129
130         sun.awt.AppContext context = sun.awt.AppContext.getAppContext();
131         Desktop JavaDoc desktop = (Desktop JavaDoc)context.get(Desktop JavaDoc.class);
132
133         if (desktop == null) {
134             desktop = new Desktop JavaDoc();
135             context.put(Desktop JavaDoc.class, desktop);
136         }
137         
138         return desktop;
139     }
140     
141     /**
142      * Tests whether this class is supported on the current platform.
143      * If it's supported, use {@link #getDesktop()} to retrieve an
144      * instance.
145      *
146      * @return <code>true</code> if this class is supported on the
147      * current platform; <code>false</code> otherwise
148      * @see #getDesktop()
149      */

150     public static boolean isDesktopSupported(){
151         Toolkit JavaDoc defaultToolkit = Toolkit.getDefaultToolkit();
152         if (defaultToolkit instanceof SunToolkit) {
153             return ((SunToolkit)defaultToolkit).isDesktopSupported();
154         }
155         return false;
156     }
157     
158     /**
159      * Tests whether an action is supported on the current platform.
160      *
161      * <p>Even when the platform supports an action, a file or URI may
162      * not have a registered application for the action. For example,
163      * most of the platforms support the {@link Desktop.Action#OPEN}
164      * action. But for a specific file, there may not be an
165      * application registered to open it. In this case, {@link
166      * #isSupported} may return {@code true}, but the corresponding
167      * action method will throw an {@link IOException}.
168      *
169      * @param action the specified {@link Action}
170      * @return <code>true</code> if the specified action is supported on
171      * the current platform; <code>false</code> otherwise
172      * @see Desktop.Action
173      */

174     public boolean isSupported(Action action) {
175         return peer.isSupported(action);
176     }
177     
178     /**
179      * Checks if the file is a valid file and readable.
180      *
181      * @throws SecurityException If a security manager exists and its
182      * {@link SecurityManager#checkRead(java.lang.String)} method
183      * denies read access to the file
184      * @throws NullPointerException if file is null
185      * @throws IllegalArgumentException if file doesn't exist
186      */

187     private static void checkFileValidation(File JavaDoc file){
188         if (file == null) throw new NullPointerException JavaDoc("File must not be null");
189
190         if (!file.exists()) {
191             throw new IllegalArgumentException JavaDoc("The file: "
192                                                + file.getPath() + " doesn't exist.");
193         }
194         
195         file.canRead();
196     }
197     
198     /**
199      * Checks if the action type is supported.
200      *
201      * @param actionType the action type in question
202      * @throws UnsupportedOperationException if the specified action type is not
203      * supported on the current platform
204      */

205     private void checkActionSupport(Action actionType){
206         if (!isSupported(actionType)) {
207             throw new UnsupportedOperationException JavaDoc("The " + actionType.name()
208                                                     + " action is not supported on the current platform!");
209         }
210     }
211
212     
213     /**
214      * Calls to the security manager's <code>checkPermission</code> method with
215      * an <code>AWTPermission("showWindowWithoutWarningBanner")</code>
216      * permission.
217      */

218     private void checkAWTPermission(){
219         SecurityManager JavaDoc sm = System.getSecurityManager();
220         if (sm != null) {
221             sm.checkPermission(new AWTPermission JavaDoc(
222                                    "showWindowWithoutWarningBanner"));
223         }
224     }
225
226     /**
227      * Launches the associated application to open the file.
228      *
229      * <p> If the specified file is a directory, the file manager of
230      * the current platform is launched to open it.
231      *
232      * @param file the file to be opened with the associated application
233      * @throws NullPointerException if {@code file} is {@code null}
234      * @throws IllegalArgumentException if the specified file dosen't
235      * exist
236      * @throws UnsupportedOperationException if the current platform
237      * does not support the {@link Desktop.Action#OPEN} action
238      * @throws IOException if the specified file has no associated
239      * application or the associated application fails to be launched
240      * @throws SecurityException if a security manager exists and its
241      * {@link java.lang.SecurityManager#checkRead(java.lang.String)}
242      * method denies read access to the file, or it denies the
243      * <code>AWTPermission("showWindowWithoutWarningBanner")</code>
244      * permission, or the calling thread is not allowed to create a
245      * subprocess
246      * @see java.awt.AWTPermission
247      */

248     public void open(File JavaDoc file) throws IOException JavaDoc {
249         checkAWTPermission();
250         checkExec();
251         checkActionSupport(Action.OPEN);
252         checkFileValidation(file);
253         
254         peer.open(file);
255     }
256    
257     /**
258      * Launches the associated editor application and opens a file for
259      * editing.
260      *
261      * @param file the file to be opened for editing
262      * @throws NullPointerException if the specified file is {@code null}
263      * @throws IllegalArgumentException if the specified file doesn't
264      * exist
265      * @throws UnsupportedOperationException if the current platform
266      * does not support the {@link Desktop.Action#EDIT} action
267      * @throws IOException if the specified file has no associated
268      * editor, or the associated application fails to be launched
269      * @throws SecurityException if a security manager exists and its
270      * {@link java.lang.SecurityManager#checkRead(java.lang.String)}
271      * method denies read access to the file, or {@link
272      * java.lang.SecurityManager#checkWrite(java.lang.String)} method
273      * denies write access to the file, or it denies the
274      * <code>AWTPermission("showWindowWithoutWarningBanner")</code>
275      * permission, or the calling thread is not allowed to create a
276      * subprocess
277      * @see java.awt.AWTPermission
278      */

279     public void edit(File JavaDoc file) throws IOException JavaDoc {
280         checkAWTPermission();
281         checkExec();
282         checkActionSupport(Action.EDIT);
283         file.canWrite();
284         checkFileValidation(file);
285         
286         peer.edit(file);
287     }
288
289     /**
290      * Prints a file with the native desktop printing facility, using
291      * the associated application's print command.
292      *
293      * @param file the file to be printed
294      * @throws NullPointerException if the specified file is {@code
295      * null}
296      * @throws IllegalArgumentException if the specified file doesn't
297      * exist
298      * @throws UnsupportedOperationException if the current platform
299      * does not support the {@link Desktop.Action#PRINT} action
300      * @throws IOException if the specified file has no associated
301      * application that can be used to print it
302      * @throws SecurityException if a security manager exists and its
303      * {@link java.lang.SecurityManager#checkRead(java.lang.String)}
304      * method denies read access to the file, or its {@link
305      * java.lang.SecurityManager#checkPrintJobAccess()} method denies
306      * the permission to print the file, or the calling thread is not
307      * allowed to create a subprocess
308      */

309     public void print(File JavaDoc file) throws IOException JavaDoc {
310         checkExec();
311         SecurityManager JavaDoc sm = System.getSecurityManager();
312         if (sm != null) {
313             sm.checkPrintJobAccess();
314         }
315         checkActionSupport(Action.PRINT);
316         checkFileValidation(file);
317
318         peer.print(file);
319     }
320   
321     /**
322      * Launches the default browser to display a {@code URI}.
323      * If the default browser is not able to handle the specified
324      * {@code URI}, the application registered for handling
325      * {@code URIs} of the specified type is invoked. The application
326      * is determined from the protocol and path of the {@code URI}, as
327      * defined by the {@code URI} class.
328      * <p>
329      * If the calling thread does not have the necessary permissions,
330      * and this is invoked from within an applet,
331      * {@code AppletContext.showDocument()} is used. Similarly, if the calling
332      * does not have the necessary permissions, and this is invoked from within
333      * a Java Web Started application, {@code BasicService.showDocument()}
334      * is used.
335      *
336      * @param uri the URI to be displayed in the user default browser
337      * @throws NullPointerException if {@code uri} is {@code null}
338      * @throws UnsupportedOperationException if the current platform
339      * does not support the {@link Desktop.Action#BROWSE} action
340      * @throws IOException if the user default browser is not found,
341      * or it fails to be launched, or the default handler application
342      * failed to be launched
343      * @throws SecurityException if a security manager exists and it
344      * denies the
345      * <code>AWTPermission("showWindowWithoutWarningBanner")</code>
346      * permission, or the calling thread is not allowed to create a
347      * subprocess; and not invoked from within an applet or Java Web Started
348      * application
349      * @throws IllegalArgumentException if the necessary permissions
350      * are not available and the URI can not be converted to a {@code URL}
351      * @see java.net.URI
352      * @see java.awt.AWTPermission
353      * @see java.applet.AppletContext
354      */

355     public void browse(URI JavaDoc uri) throws IOException JavaDoc {
356         SecurityException JavaDoc securityException = null;
357         try {
358             checkAWTPermission();
359             checkExec();
360         } catch (SecurityException JavaDoc e) {
361             securityException = e;
362         }
363         checkActionSupport(Action.BROWSE);
364         if (uri == null) {
365             throw new NullPointerException JavaDoc();
366         }
367         if (securityException == null) {
368             peer.browse(uri);
369             return;
370         }
371
372         // Calling thread doesn't have necessary priviledges.
373
// Delegate to DesktopBrowse so that it can work in
374
// applet/webstart.
375
URL JavaDoc url = null;
376         try {
377             url = uri.toURL();
378         } catch (MalformedURLException JavaDoc e) {
379             throw new IllegalArgumentException JavaDoc("Unable to convert URI to URL", e);
380         }
381         sun.awt.DesktopBrowse db = sun.awt.DesktopBrowse.getInstance();
382         if (db == null) {
383             // Not in webstart/applet, throw the exception.
384
throw securityException;
385         }
386         db.browse(url);
387     }
388
389     /**
390      * Launches the mail composing window of the user default mail
391      * client.
392      *
393      * @throws UnsupportedOperationException if the current platform
394      * does not support the {@link Desktop.Action#MAIL} action
395      * @throws IOException if the user default mail client is not
396      * found, or it fails to be launched
397      * @throws SecurityException if a security manager exists and it
398      * denies the
399      * <code>AWTPermission("showWindowWithoutWarningBanner")</code>
400      * permission, or the calling thread is not allowed to create a
401      * subprocess
402      * @see java.awt.AWTPermission
403      */

404     public void mail() throws IOException JavaDoc {
405         checkAWTPermission();
406         checkExec();
407         checkActionSupport(Action.MAIL);
408         URI JavaDoc mailtoURI = null;
409         try{
410             mailtoURI = new URI JavaDoc("mailto:?");
411             peer.mail(mailtoURI);
412         } catch (URISyntaxException JavaDoc e){
413             // won't reach here.
414
}
415     }
416
417     /**
418      * Launches the mail composing window of the user default mail
419      * client, filling the message fields specified by a {@code
420      * mailto:} URI.
421      *
422      * <p> A <code>mailto:</code> URI can specify message fields
423      * including <i>"to"</i>, <i>"cc"</i>, <i>"subject"</i>,
424      * <i>"body"</i>, etc. See <a
425      * HREF="http://www.ietf.org/rfc/rfc2368.txt">The mailto URL
426      * scheme (RFC 2368)</a> for the {@code mailto:} URI specification
427      * details.
428      *
429      * @param mailtoURI the specified {@code mailto:} URI
430      * @throws NullPointerException if the specified URI is {@code
431      * null}
432      * @throws IllegalArgumentException if the URI scheme is not
433      * <code>"mailto"</code>
434      * @throws UnsupportedOperationException if the current platform
435      * does not support the {@link Desktop.Action#MAIL} action
436      * @throws IOException if the user default mail client is not
437      * found or fails to be launched
438      * @throws SecurityException if a security manager exists and it
439      * denies the
440      * <code>AWTPermission("showWindowWithoutWarningBanner")</code>
441      * permission, or the calling thread is not allowed to create a
442      * subprocess
443      * @see java.net.URI
444      * @see java.awt.AWTPermission
445      */

446     public void mail(URI JavaDoc mailtoURI) throws IOException JavaDoc {
447         checkAWTPermission();
448         checkExec();
449         checkActionSupport(Action.MAIL);
450         if (mailtoURI == null) throw new NullPointerException JavaDoc();
451
452         if (!"mailto".equalsIgnoreCase(mailtoURI.getScheme())) {
453             throw new IllegalArgumentException JavaDoc("URI scheme is not \"mailto\"");
454         }
455         
456         peer.mail(mailtoURI);
457     }
458
459     private void checkExec() throws SecurityException JavaDoc {
460         SecurityManager JavaDoc sm = System.getSecurityManager();
461         if (sm != null) {
462             sm.checkPermission(new FilePermission JavaDoc("<<ALL FILES>>",
463                                                   SecurityConstants.FILE_EXECUTE_ACTION));
464         }
465     }
466 }
467
Popular Tags