KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > loaders > LoaderTransfer


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.openide.loaders;
21
22
23 import java.awt.datatransfer.*;
24 import java.awt.dnd.DnDConstants JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.text.MessageFormat JavaDoc;
27 import java.util.logging.Level JavaDoc;
28 import java.util.logging.Logger JavaDoc;
29 import org.openide.util.datatransfer.*;
30
31 /** Class that contains specific datatransfer flavors and methods to work with
32  * transfered DataObjects. There are flavors to allow a DataObject
33  * to be copied or cut into clipboard, and to retrieve them from clipboard
34  * when implementing paste operation.
35  * <p>This is a dummy utility class--no instances are possible.
36  *
37  * @author Vita Stejskal
38  * @since 1.21
39  */

40 public abstract class LoaderTransfer {
41
42     /** Creates new LoaderTransfer */
43     private LoaderTransfer () {}
44     
45     /** Constants for drag-n-drop operations.
46     * Are exactly the same as constants
47     * in {@link DnDConstants}.
48     */

49     public static final int DND_NONE = DnDConstants.ACTION_NONE;
50     public static final int DND_COPY = DnDConstants.ACTION_COPY;
51     public static final int DND_MOVE = DnDConstants.ACTION_MOVE;
52     public static final int DND_COPY_OR_MOVE = DnDConstants.ACTION_COPY | DnDConstants.ACTION_MOVE;
53     public static final int DND_LINK = DnDConstants.ACTION_LINK;
54     public static final int DND_REFERENCE = DnDConstants.ACTION_LINK;
55
56     /** Constant indicating copying to the clipboard.
57     * Equal to {@link #DND_COPY}, because
58     * copy to clipboard and d'n'd copy should be the same.
59     */

60     public static final int CLIPBOARD_COPY = DND_COPY;
61
62     /** Constant indicating cutting to the clipboard.
63     */

64     public static final int CLIPBOARD_CUT = 0x04;
65
66     /** Generic mask for copying DataObjects (do not destroy the original).
67     * Equal to {@link #CLIPBOARD_COPY} or {@link #DND_COPY}.
68     */

69     public static final int COPY = CLIPBOARD_COPY | DND_COPY;
70
71     /** Generic mask for moving DataObjects (destroy the original).
72     * Equal to {@link #CLIPBOARD_CUT} or {@link #DND_MOVE}.
73     */

74     public static final int MOVE = CLIPBOARD_CUT | DND_MOVE;
75     
76
77     /** message format to create and parse the mimetype
78     */

79     private static MessageFormat JavaDoc dndMimeType = new MessageFormat JavaDoc (
80                 "application/x-java-openide-dataobjectdnd;class=org.openide.loaders.DataObject;mask={0}" // NOI18N
81
);
82     
83     /** Creates transferable that represents an operation, such as cut-to-clipboard.
84     * The transferable will be recognizable by {@link #getDataObject} and {@link #getDataObjects}.
85     *
86     * @param d the DataObject to create a transferable for
87     * @param actions the action performed on the DataObject's node
88     * @return the transferable
89     */

90     public static ExTransferable.Single transferable (final DataObject d, int actions) {
91         return new ExTransferable.Single (createDndFlavor (actions)) {
92                    public Object JavaDoc getData () {
93                        return d;
94                    }
95                };
96     }
97     
98     /** Obtain a DataObject from a transferable.
99     * Probes the transferable in case it includes a flavor corresponding
100     * to a DataObject's node operation (which you must specify a mask for).
101     *
102     * @param t transferable
103     * @param action one of the <code>DND_*</code> or <code>CLIPBOARD_*</code> constants
104     * @return the DataObject or <code>null</code>
105     */

106     public static DataObject getDataObject (Transferable t, int action) {
107         DataFlavor[] flavors = t.getTransferDataFlavors ();
108         if (flavors == null) {
109             return null;
110         }
111         int len = flavors.length;
112
113         String JavaDoc subtype = "x-java-openide-dataobjectdnd"; // NOI18N
114
String JavaDoc primary = "application"; // NOI18N
115
String JavaDoc mask = "mask"; // NOI18N
116

117         for (int i = 0; i < len; i++) {
118             DataFlavor df = flavors[i];
119             
120             if (
121                 df.getSubType ().equals (subtype) &&
122                 df.getPrimaryType ().equals (primary)
123             ) {
124                 try {
125                     int m = Integer.valueOf (df.getParameter (mask)).intValue ();
126                     if ((m & action) != 0) {
127                         // found the node
128
DataObject o = (DataObject)t.getTransferData(df);
129                         if (o.isValid()) {
130                             return o;
131                         } else {
132                             // #14344
133
return null;
134                         }
135                     }
136                 } catch (NumberFormatException JavaDoc nfe) {
137                     maybeReportException (nfe);
138                 } catch (ClassCastException JavaDoc cce) {
139                     maybeReportException (cce);
140                 } catch (IOException JavaDoc ioe) {
141                     // #32206 - this exception is thrown when underlying fileobject
142
// does not exist and DataObject cannot be found for it. It happens when
143
// user copy a DataObject into clipboard, close NB, delete the file,
144
// restart the NB. During the startup the clipboard content is checked and
145
// this exception is thrown. It would be better to catch just FileStateInvalidException,
146
// but it gets wrapped into IOException in sun.awt.datatransfer.DataTransferer.
147
// Logging this exception as informative is too confusing.
148
// There is usually several exceptions logged for one clipboard object
149
// and users file it repeatedly as bug. Just log some explanation message instead.
150
DataObject.LOG.fine(
151                         "Object in clipboard refers to a non existing file. "+ ioe.toString()); //NOI18N
152
} catch (UnsupportedFlavorException ufe) {
153                     maybeReportException (ufe);
154                 }
155             }
156         }
157
158         return null;
159     }
160     
161     /** Obtain a list of DataObjects from a transferable.
162     * If there is only a single DataObject in the transferable, this will just return a singleton
163     * array like {@link #getDataObject}.
164     * If there is a {@link ExTransferable#multiFlavor multiple transfer} (of at least one element),
165     * each element of which
166     * contains a DataObject, then an array of these will be returned.
167     * If neither of these things is true, <code>null</code> will be returned.
168     * <p>This is a convenience method intended for those who wish to specially support pastes
169     * of multiple DataObjects at once.
170     * @param t the transferable to probe
171     * @param action a DnD or clipboard constant
172     * @return a non-empty array of nodes, or <code>null</code>
173     */

174     public static DataObject[] getDataObjects (Transferable t, int action) {
175         try {
176             if (t.isDataFlavorSupported (ExTransferable.multiFlavor)) {
177                 MultiTransferObject mto = (MultiTransferObject) t.getTransferData (ExTransferable.multiFlavor);
178                 int count = mto.getCount ();
179                 DataObject[] datas = new DataObject[count];
180                 boolean ok = true;
181                 for (int i = 0; i < count; i++) {
182                     DataObject d = getDataObject (mto.getTransferableAt (i), action);
183                     if (d == null) {
184                         ok = false;
185                         break;
186                     } else {
187                         datas[i] = d;
188                     }
189                 }
190                 if (ok && count > 0) return datas;
191             } else {
192                 DataObject d = getDataObject (t, action);
193                 if (d != null) return new DataObject[] { d };
194             }
195         } catch (ClassCastException JavaDoc cce) {
196             maybeReportException (cce);
197         } catch (IOException JavaDoc ioe) {
198             maybeReportException (ioe);
199         } catch (UnsupportedFlavorException ufe) {
200             maybeReportException (ufe);
201         }
202         return null;
203     }
204     
205     /** Creates data flavor for given mask of dnd actions.
206     * @param actions any mask of dnd constants DND_* and CLIPBOARD_*
207     */

208     private static DataFlavor createDndFlavor (int actions) {
209         try {
210             return new DataFlavor(dndMimeType.format(new Object JavaDoc[] {new Integer JavaDoc(actions)}), null, DataObject.class.getClassLoader());
211         } catch (ClassNotFoundException JavaDoc ex) {
212             throw new AssertionError JavaDoc(ex);
213         }
214     }
215
216     /** Print a stack trace if debugging is on.
217     * Used for exceptions that could occur when probing transferables,
218     * which should not interrupt the probing with an error, but
219     * indicate a bug elsewhere and should be reported somehow.
220     * @param e the exception
221     */

222     private static void maybeReportException (Exception JavaDoc e) {
223         Logger.getLogger(LoaderTransfer.class.getName()).log(Level.WARNING, null, e);
224     }
225 }
226
Popular Tags