001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.openfile;
043:
044: import java.awt.datatransfer.DataFlavor;
045: import java.awt.datatransfer.Transferable;
046: import java.awt.datatransfer.UnsupportedFlavorException;
047: import java.awt.dnd.DropTargetDragEvent;
048: import java.awt.dnd.DropTargetDropEvent;
049: import java.io.File;
050: import java.io.IOException;
051: import java.net.URI;
052: import java.util.ArrayList;
053: import java.util.List;
054: import java.util.StringTokenizer;
055: import java.util.logging.Level;
056: import java.util.logging.Logger;
057: import javax.swing.Box;
058: import javax.swing.BoxLayout;
059: import javax.swing.JComponent;
060: import javax.swing.JLabel;
061: import javax.swing.JPanel;
062: import org.openide.DialogDisplayer;
063: import org.openide.ErrorManager;
064: import org.openide.NotifyDescriptor;
065: import org.openide.filesystems.FileObject;
066: import org.openide.filesystems.FileUtil;
067: import org.openide.util.NbBundle;
068: import org.openide.windows.ExternalDropHandler;
069:
070: /**
071: *
072: * @author S. Aubrecht
073: */
074: public class DefaultExternalDropHandler extends ExternalDropHandler {
075:
076: public boolean canDrop(DropTargetDragEvent e) {
077: return canDrop(e.getCurrentDataFlavors());
078: }
079:
080: public boolean canDrop(DropTargetDropEvent e) {
081: return canDrop(e.getCurrentDataFlavors());
082: }
083:
084: boolean canDrop(DataFlavor[] flavors) {
085: for (int i = 0; null != flavors && i < flavors.length; i++) {
086: if (DataFlavor.javaFileListFlavor.equals(flavors[i])
087: || getUriListDataFlavor().equals(flavors[i])) {
088:
089: return true;
090: }
091: }
092: return false;
093: }
094:
095: public boolean handleDrop(DropTargetDropEvent e) {
096: Transferable t = e.getTransferable();
097: if (null == t)
098: return false;
099: List<File> fileList = getFileList(t);
100: if ((fileList == null) || fileList.isEmpty()) {
101: return false;
102: }
103:
104: //TODO - remove the code below once issue #46813 is resolved
105: //#46813 - NetBeans does not support UNC paths
106: Object errMsg = null;
107: if (fileList.size() == 1) {
108: errMsg = openFile(fileList.get(0));
109: } else {
110: boolean hasSomeSuccess = false;
111: boolean failureNonUNC = false;
112: List<String> fileErrs = null;
113: for (File file : fileList) {
114: String fileErr = openFile(file);
115: if (fileErr == null) {
116: hasSomeSuccess = true;
117: } else {
118: if (!OpenFile.isSpecifiedByUNCPath(file)) {
119: failureNonUNC = true;
120: }
121: if (fileErrs == null) {
122: fileErrs = new ArrayList<String>(fileList
123: .size());
124: }
125: fileErrs.add(fileErr);
126: }
127: }
128: if (fileErrs != null) { //some file could not be opened
129: String mainMsgKey;
130: if (!hasSomeSuccess && !failureNonUNC) {
131: /* all of the files were specified by UNC paths */
132: mainMsgKey = "MSG_could_not_open_any_file_all_UNC"; //NOI18N
133: fileErrs = null;
134: } else if (hasSomeSuccess) {
135: mainMsgKey = "MSG_could_not_open_some_files"; //NOI18N
136: } else {
137: mainMsgKey = "MSG_could_not_open_any_file"; //NOI18N
138: }
139: String mainMsg = NbBundle.getMessage(OpenFile.class,
140: mainMsgKey);
141: if (fileErrs == null) {
142: errMsg = mainMsg;
143: } else {
144: JComponent msgPanel = new JPanel();
145: msgPanel.setLayout(new BoxLayout(msgPanel,
146: BoxLayout.PAGE_AXIS));
147: msgPanel.add(new JLabel(mainMsg));
148: msgPanel.add(Box.createVerticalStrut(12));
149: for (String fileErr : fileErrs) {
150: msgPanel.add(new JLabel(fileErr));
151: }
152: errMsg = msgPanel;
153: }
154: }
155: }
156: if (errMsg != null) {
157: DialogDisplayer.getDefault().notify(
158: new NotifyDescriptor.Message(errMsg,
159: NotifyDescriptor.WARNING_MESSAGE));
160: return false;
161: }
162: return true;
163: }
164:
165: List<File> getFileList(Transferable t) {
166: try {
167: if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
168: //windows & mac
169: return (List<File>) t
170: .getTransferData(DataFlavor.javaFileListFlavor);
171: } else if (t.isDataFlavorSupported(getUriListDataFlavor())) {
172: //linux
173: String uriList = (String) t
174: .getTransferData(getUriListDataFlavor());
175: return textURIListToFileList(uriList);
176: }
177: } catch (UnsupportedFlavorException ex) {
178: ErrorManager.getDefault().notify(
179: ErrorManager.INFORMATIONAL, ex);
180: } catch (IOException ex) {
181: // Ignore. Can be just "Owner timed out" from sun.awt.X11.XSelection.getData.
182: Logger
183: .getLogger(
184: DefaultExternalDropHandler.class.getName())
185: .log(Level.FINE, null, ex);
186: }
187: return null;
188: }
189:
190: /**
191: * Opens the given file.
192: * @param file file to be opened
193: * @return {@code null} if the file was successfully opened;
194: * or a localized error message in case of failure
195: */
196: String openFile(File file) {
197: FileObject fo = FileUtil.toFileObject(FileUtil
198: .normalizeFile(file));
199: if (fo == null) {
200: //TODO - remove once issue #46813 is resolved
201: //#46813 - NetBeans does not support UNC paths
202: String msgKey;
203: if (OpenFile.isSpecifiedByUNCPath(file)) {
204: msgKey = "MSG_UncNotSupported"; //NOI18N
205: } else {
206: msgKey = "MSG_FilePathTypeNotSupported"; //NOI18N
207: }
208: return NbBundle.getMessage(OpenFile.class, msgKey, file
209: .toString());
210: }
211: return OpenFile.open(fo, -1);
212: }
213:
214: private static DataFlavor uriListDataFlavor;
215:
216: DataFlavor getUriListDataFlavor() {
217: if (null == uriListDataFlavor) {
218: try {
219: uriListDataFlavor = new DataFlavor(
220: "text/uri-list;class=java.lang.String");
221: } catch (ClassNotFoundException cnfE) {
222: //cannot happen
223: throw new AssertionError(cnfE);
224: }
225: }
226: return uriListDataFlavor;
227: }
228:
229: List<File> textURIListToFileList(String data) {
230: List<File> list = new ArrayList<File>(1);
231: for (StringTokenizer st = new StringTokenizer(data, "\r\n"); st
232: .hasMoreTokens();) {
233: String s = st.nextToken();
234: if (s.startsWith("#")) {
235: // the line is a comment (as per the RFC 2483)
236: continue;
237: }
238: try {
239: URI uri = new URI(s);
240: File file = new File(uri);
241: list.add(file);
242: } catch (java.net.URISyntaxException e) {
243: // malformed URI
244: } catch (IllegalArgumentException e) {
245: // the URI is not a valid 'file:' URI
246: }
247: }
248: return list;
249: }
250: }
|