src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java

Print this page



   1 /*
   2  * Copyright (c) 2011, 2014, 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 sun.lwawt.macosx;
  27 
  28 import java.awt.*;
  29 
  30 import java.io.*;


  31 import java.net.URL;
  32 import java.nio.charset.Charset;
  33 import java.text.Normalizer;
  34 import java.text.Normalizer.Form;
  35 import java.util.*;
  36 import java.util.regex.*;
  37 
  38 import java.awt.datatransfer.*;
  39 import sun.awt.datatransfer.*;
  40 
  41 public class CDataTransferer extends DataTransferer {
  42     private static final Map<String, Long> predefinedClipboardNameMap;
  43     private static final Map<Long, String> predefinedClipboardFormatMap;
  44 
  45     // See SystemFlavorMap, or the flavormap.properties file:
  46     // We should define a few more types in flavormap.properties, it's rather slim now.
  47     private static final String[] predefinedClipboardNames = {
  48         "",
  49         "STRING",
  50         "FILE_NAME",
  51         "TIFF",
  52         "RICH_TEXT",
  53         "HTML",
  54         "PDF",
  55         "URL",
  56         "PNG",


 108 
 109     @Override
 110     public boolean isImageFormat(long format) {
 111         int ifmt = (int)format;
 112         switch(ifmt) {
 113             case CF_TIFF:
 114             case CF_PDF:
 115             case CF_PNG:
 116             case CF_JPEG:
 117                 return true;
 118             default:
 119                 return false;
 120         }
 121     }
 122 
 123     @Override
 124     public Object translateBytes(byte[] bytes, DataFlavor flavor,
 125                                  long format, Transferable transferable) throws IOException {
 126 
 127         if (format == CF_URL && URL.class.equals(flavor.getRepresentationClass())) {
 128             String charset = Charset.defaultCharset().name();
 129             if (transferable != null && transferable.isDataFlavorSupported(javaTextEncodingFlavor)) {
 130                 try {
 131                     charset = new String((byte[]) transferable.getTransferData(javaTextEncodingFlavor), "UTF-8");
 132                 } catch (UnsupportedFlavorException cannotHappen) {
 133                 }
 134             }
 135             String xml = new String(bytes, charset);
 136             // macosx pasteboard returns a property list that consists of one URL
 137             // let's extract it.
 138             return new URL(extractURL(xml));
 139         }
 140 
 141         if (format == CF_STRING) {












 142             bytes = Normalizer.normalize(new String(bytes, "UTF8"), Form.NFC).getBytes("UTF8");
 143         }
 144 
 145         return super.translateBytes(bytes, flavor, format, transferable);
 146     }
 147 
 148     /**
 149      * Macosx pasteboard returns xml document that contains one URL, for exmple:
 150      * <pre>
 151      *     {@code
 152      * <?xml version=\"1.0\" encoding=\"UTF-8\"?>
 153      * <!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
 154      * <plist version=\"1.0\">
 155      *      <array>
 156      *          <string>file:///path_to_file</string>
 157      *          <string></string>
 158      *      </array>
 159      * </plist>
 160      *     }
 161      * </pre>
 162      */
 163     private String extractURL(String xml) {
 164         Pattern urlExtractorPattern = Pattern.compile("<string>(.*)</string>");
 165         Matcher matcher = urlExtractorPattern.matcher(xml);
 166         if (matcher.find()) {
 167             return matcher.group(1);
 168         } else {
 169             return null;
 170         }
 171     }
 172 
 173     @Override
 174     synchronized protected Long getFormatForNativeAsLong(String str) {
 175         Long format = predefinedClipboardNameMap.get(str);
 176 
 177         if (format == null) {
 178             if (java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance()) {
 179                 // Do not try to access native system for the unknown format
 180                 return -1L;
 181             }
 182             format = registerFormatWithPasteboard(str);
 183             predefinedClipboardNameMap.put(str, format);
 184             predefinedClipboardFormatMap.put(format, str);
 185         }
 186 
 187         return format;
 188     }
 189 
 190     /*
 191      * Adds type to native mapping NSDictionary.
 192      */


 228     private final ToolkitThreadBlockedHandler handler = new CToolkitThreadBlockedHandler();
 229 
 230     @Override
 231     public ToolkitThreadBlockedHandler getToolkitThreadBlockedHandler() {
 232         return handler;
 233     }
 234 
 235     @Override
 236     protected byte[] imageToPlatformBytes(Image image, long format) {
 237         return CImage.getCreator().getPlatformImageBytes(image);
 238     }
 239 
 240     private static native String[] nativeDragQueryFile(final byte[] bytes);
 241     @Override
 242     protected String[] dragQueryFile(final byte[] bytes) {
 243         if (bytes == null) return null;
 244         if (new String(bytes).startsWith("Unsupported type")) return null;
 245         return nativeDragQueryFile(bytes);
 246     }
 247 

 248     @Override
 249     protected Image platformImageBytesToImage(byte[] bytes, long format) throws IOException {
 250         return CImage.getCreator().createImageFromPlatformImageBytes(bytes);
 251     }
 252 
 253     @Override
 254     protected ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList) throws IOException {
 255         ByteArrayOutputStream bos = new ByteArrayOutputStream();
 256         for (String file : fileList) {
 257             byte[] bytes = file.getBytes();
 258             bos.write(bytes, 0, bytes.length);
 259             bos.write(0);
 260         }
 261         return bos;
 262     }
 263 
 264     @Override
 265     protected boolean isURIListFormat(long format) {
 266         String nat = getNativeForFormat(format);
 267         if (nat == null) {
 268             return false;
 269         }
 270         try {
 271             DataFlavor df = new DataFlavor(nat);
 272             if (df.getPrimaryType().equals("text") && df.getSubType().equals("uri-list")) {
 273                 return true;
 274             }
 275         } catch (Exception e) {
 276             // Not a MIME format.
 277         }
 278         return false;
 279     }







 280 }
   1 
   2 /*
   3  * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.  Oracle designates this
   9  * particular file as subject to the "Classpath" exception as provided
  10  * by Oracle in the LICENSE file that accompanied this code.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  23  * or visit www.oracle.com if you need additional information or have any
  24  * questions.
  25  */
  26 
  27 package sun.lwawt.macosx;
  28 
  29 import java.awt.*;
  30 
  31 import java.io.*;
  32 import java.net.URI;
  33 import java.net.URISyntaxException;
  34 import java.net.URL;
  35 import java.nio.charset.Charset;
  36 import java.text.Normalizer;
  37 import java.text.Normalizer.Form;
  38 import java.util.*;

  39 
  40 import java.awt.datatransfer.*;
  41 import sun.awt.datatransfer.*;
  42 
  43 public class CDataTransferer extends DataTransferer {
  44     private static final Map<String, Long> predefinedClipboardNameMap;
  45     private static final Map<Long, String> predefinedClipboardFormatMap;
  46 
  47     // See SystemFlavorMap, or the flavormap.properties file:
  48     // We should define a few more types in flavormap.properties, it's rather slim now.
  49     private static final String[] predefinedClipboardNames = {
  50         "",
  51         "STRING",
  52         "FILE_NAME",
  53         "TIFF",
  54         "RICH_TEXT",
  55         "HTML",
  56         "PDF",
  57         "URL",
  58         "PNG",


 110 
 111     @Override
 112     public boolean isImageFormat(long format) {
 113         int ifmt = (int)format;
 114         switch(ifmt) {
 115             case CF_TIFF:
 116             case CF_PDF:
 117             case CF_PNG:
 118             case CF_JPEG:
 119                 return true;
 120             default:
 121                 return false;
 122         }
 123     }
 124 
 125     @Override
 126     public Object translateBytes(byte[] bytes, DataFlavor flavor,
 127                                  long format, Transferable transferable) throws IOException {
 128 
 129         if (format == CF_URL && URL.class.equals(flavor.getRepresentationClass())) {
 130            String[] strings = dragQueryFile(bytes);
 131             if(strings.length == 0) {
 132                 return null;








 133             }
 134             return new URL(strings[0]);
 135         } else if(isUriListFlavor(flavor)) {
 136             // dragQueryFile works fine with files and url,
 137             // it parses and extracts values from property list.
 138             // maxosx always returens property list for
 139             // CF_URL and CF_FILE
 140             String[] strings = dragQueryFile(bytes);
 141             bytes = String.join(System.getProperty("line.separator"),
 142                     strings).getBytes();
 143             // now we extracted uri from xml, now we should treat it as
 144             // regular string that allows to translate data to target represantation
 145             // class by base method
 146             format = CF_STRING;
 147         } else if (format == CF_STRING) {
 148             bytes = Normalizer.normalize(new String(bytes, "UTF8"), Form.NFC).getBytes("UTF8");
 149         }
 150 
 151         return super.translateBytes(bytes, flavor, format, transferable);
 152     }
 153 

























 154     @Override
 155     synchronized protected Long getFormatForNativeAsLong(String str) {
 156         Long format = predefinedClipboardNameMap.get(str);
 157 
 158         if (format == null) {
 159             if (java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance()) {
 160                 // Do not try to access native system for the unknown format
 161                 return -1L;
 162             }
 163             format = registerFormatWithPasteboard(str);
 164             predefinedClipboardNameMap.put(str, format);
 165             predefinedClipboardFormatMap.put(format, str);
 166         }
 167 
 168         return format;
 169     }
 170 
 171     /*
 172      * Adds type to native mapping NSDictionary.
 173      */


 209     private final ToolkitThreadBlockedHandler handler = new CToolkitThreadBlockedHandler();
 210 
 211     @Override
 212     public ToolkitThreadBlockedHandler getToolkitThreadBlockedHandler() {
 213         return handler;
 214     }
 215 
 216     @Override
 217     protected byte[] imageToPlatformBytes(Image image, long format) {
 218         return CImage.getCreator().getPlatformImageBytes(image);
 219     }
 220 
 221     private static native String[] nativeDragQueryFile(final byte[] bytes);
 222     @Override
 223     protected String[] dragQueryFile(final byte[] bytes) {
 224         if (bytes == null) return null;
 225         if (new String(bytes).startsWith("Unsupported type")) return null;
 226         return nativeDragQueryFile(bytes);
 227     }
 228 
 229 
 230     @Override
 231     protected Image platformImageBytesToImage(byte[] bytes, long format) throws IOException {
 232         return CImage.getCreator().createImageFromPlatformImageBytes(bytes);
 233     }
 234 
 235     @Override
 236     protected ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList) throws IOException {
 237         ByteArrayOutputStream bos = new ByteArrayOutputStream();
 238         for (String file : fileList) {
 239             byte[] bytes = file.getBytes();
 240             bos.write(bytes, 0, bytes.length);
 241             bos.write(0);
 242         }
 243         return bos;
 244     }
 245 
 246     @Override
 247     protected boolean isURIListFormat(long format) {
 248         String nat = getNativeForFormat(format);
 249         if (nat == null) {
 250             return false;
 251         }
 252         try {
 253             DataFlavor df = new DataFlavor(nat);
 254             if (isUriListFlavor(df)) {
 255                 return true;
 256             }
 257         } catch (Exception e) {
 258             // Not a MIME format.
 259         }
 260         return false;
 261     }
 262 
 263     private boolean isUriListFlavor(DataFlavor df) {
 264         if (df.getPrimaryType().equals("text") && df.getSubType().equals("uri-list")) {
 265             return true;
 266         }
 267         return false;
 268     }
 269 }