# HG changeset patch # User pchelko # Date 1390999822 -14400 # Node ID 986c81d8805b68af0b61fa7d240bd995ccc469df # Parent 0e0103e73d3ccddd7434336086ca31c1ae8f3dcf 8031964: [macosx] Dragging images from the browser does not work Reviewed-by: anthony, serb diff -r 0e0103e73d3c -r 986c81d8805b jdk/src/macosx/classes/sun/lwawt/macosx/CDataTransferer.java --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CDataTransferer.java Wed Jan 29 16:35:42 2014 +0400 +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CDataTransferer.java Wed Jan 29 16:50:22 2014 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,11 +56,11 @@ }; static { - Map nameMap = new HashMap(predefinedClipboardNames.length, 1.0f); - Map formatMap = new HashMap(predefinedClipboardNames.length, 1.0f); + Map nameMap = new HashMap<>(predefinedClipboardNames.length, 1.0f); + Map formatMap = new HashMap<>(predefinedClipboardNames.length, 1.0f); for (int i = 1; i < predefinedClipboardNames.length; i++) { - nameMap.put(predefinedClipboardNames[i], new Long(i)); - formatMap.put(new Long(i), predefinedClipboardNames[i]); + nameMap.put(predefinedClipboardNames[i], (long) i); + formatMap.put((long) i, predefinedClipboardNames[i]); } predefinedClipboardNameMap = Collections.synchronizedMap(nameMap); predefinedClipboardFormatMap = Collections.synchronizedMap(formatMap); @@ -77,14 +77,6 @@ public static final int CF_PNG = 10; public static final int CF_JPEG = 11; - public static final Long L_CF_TIFF = predefinedClipboardNameMap.get(predefinedClipboardNames[CF_TIFF]); - - // Image file formats with java.awt.Image representation: - private static final Long[] imageFormats = new Long[] { - L_CF_TIFF - }; - - private CDataTransferer() {} private static CDataTransferer fTransferer; @@ -97,18 +89,22 @@ return fTransferer; } + @Override public String getDefaultUnicodeEncoding() { return "utf-16le"; } + @Override public boolean isLocaleDependentTextFormat(long format) { return format == CF_STRING; } + @Override public boolean isFileFormat(long format) { return format == CF_FILE; } + @Override public boolean isImageFormat(long format) { int ifmt = (int)format; switch(ifmt) { @@ -122,43 +118,12 @@ } } - protected Long[] getImageFormatsAsLongArray() { - return imageFormats; - } - - public byte[] translateTransferable(Transferable contents, DataFlavor flavor, long format) throws IOException - { - byte[] bytes = super.translateTransferable(contents, flavor, format); - - // 9-12-02 VL: we may need to do something like Windows here. - //if (format == CF_HTML) { - // bytes = HTMLSupport.convertToHTMLFormat(bytes); - //} - - return bytes; - } - - protected Object translateBytesOrStream(InputStream stream, byte[] bytes, DataFlavor flavor, long format, - Transferable transferable) throws IOException - { - // 5-28-03 VL: [Radar 3266030] - // We need to do like Windows does here. - if (format == CF_HTML && flavor.isFlavorTextType()) { - if (stream == null) { - stream = new ByteArrayInputStream(bytes); - bytes = null; - } - - stream = new HTMLDecodingInputStream(stream); - } + @Override + public Object translateBytes(byte[] bytes, DataFlavor flavor, + long format, Transferable transferable) throws IOException { if (format == CF_URL && URL.class.equals(flavor.getRepresentationClass())) { - if (bytes == null) { - bytes = inputStreamToByteArray(stream); - stream = null; - } - String charset = getDefaultTextCharset(); if (transferable != null && transferable.isDataFlavorSupported(javaTextEncodingFlavor)) { try { @@ -175,9 +140,9 @@ } return super.translateBytes(bytes, flavor, format, transferable); - } + } - + @Override synchronized protected Long getFormatForNativeAsLong(String str) { Long format = predefinedClipboardNameMap.get(str); @@ -202,6 +167,7 @@ // Get registered native format string for an index, return null if unknown: private native String formatForIndex(long index); + @Override protected String getNativeForFormat(long format) { String returnValue = null; @@ -209,7 +175,7 @@ if (format >= 0 && format < predefinedClipboardNames.length) { returnValue = predefinedClipboardNames[(int) format]; } else { - Long formatObj = new Long(format); + Long formatObj = format; returnValue = predefinedClipboardFormatMap.get(formatObj); // predefinedClipboardFormatMap may not know this format: @@ -233,10 +199,13 @@ private final ToolkitThreadBlockedHandler handler = new CToolkitThreadBlockedHandler(); + @Override public ToolkitThreadBlockedHandler getToolkitThreadBlockedHandler() { return handler; } + private native byte[] imageDataToPlatformImageBytes(int[] rData, int nW, int nH); + @Override protected byte[] imageToPlatformBytes(Image image, long format) { int w = image.getWidth(null); int h = image.getHeight(null); @@ -252,32 +221,28 @@ } private static native String[] nativeDragQueryFile(final byte[] bytes); + @Override protected String[] dragQueryFile(final byte[] bytes) { if (bytes == null) return null; if (new String(bytes).startsWith("Unsupported type")) return null; return nativeDragQueryFile(bytes); } - private native byte[] imageDataToPlatformImageBytes(int[] rData, int nW, int nH); - + private native Image getImageForByteStream(byte[] bytes); /** * Translates a byte array which contains * platform-specific image data in the given format into an Image. */ - protected Image platformImageBytesToImage(byte[] bytes, long format) - throws IOException - { + @Override + protected Image platformImageBytesToImage(byte[] bytes, long format) throws IOException { return getImageForByteStream(bytes); } - private native Image getImageForByteStream(byte[] bytes); - @Override protected ByteArrayOutputStream convertFileListToBytes(ArrayList fileList) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); - for (int i = 0; i < fileList.size(); i++) - { - byte[] bytes = fileList.get(i).getBytes(); + for (String file : fileList) { + byte[] bytes = file.getBytes(); bos.write(bytes, 0, bytes.length); bos.write(0); } @@ -303,246 +268,3 @@ } -// ---- Code borrowed from WDataTransferer: ---- -// This will come handy for supporting HTML data. - -final class HTMLSupport { - public static final String ENCODING = "UTF-8"; - - public static final String VERSION = "Version:"; - public static final String START_HTML = "StartHTML:"; - public static final String END_HTML = "EndHTML:"; - public static final String START_FRAGMENT = "StartFragment:"; - public static final String END_FRAGMENT = "EndFragment:"; - public static final String START_FRAGMENT_CMT = ""; - public static final String END_FRAGMENT_CMT = ""; - public static final String EOLN = "\r\n"; - - private static final String VERSION_NUM = "0.9"; - private static final String HTML_START_END = "-1"; - - private static final int PADDED_WIDTH = 10; - - private static final int HEADER_LEN = - VERSION.length() + VERSION_NUM.length() + EOLN.length() + - START_HTML.length() + HTML_START_END.length() + EOLN.length() + - END_HTML.length() + HTML_START_END.length() + EOLN.length() + - START_FRAGMENT.length() + PADDED_WIDTH + EOLN.length() + - END_FRAGMENT.length() + PADDED_WIDTH + EOLN.length() + - START_FRAGMENT_CMT.length() + EOLN.length(); - private static final String HEADER_LEN_STR = - toPaddedString(HEADER_LEN, PADDED_WIDTH); - - private static final String TRAILER = END_FRAGMENT_CMT + EOLN + '\0'; - - private static String toPaddedString(int n, int width) { - String string = "" + n; - int len = string.length(); - if (n >= 0 && len < width) { - char[] array = new char[width - len]; - Arrays.fill(array, '0'); - StringBuffer buffer = new StringBuffer(); - buffer.append(array); - buffer.append(string); - string = buffer.toString(); - } - return string; - } - - public static byte[] convertToHTMLFormat(byte[] bytes) { - StringBuffer header = new StringBuffer(HEADER_LEN); - header.append(VERSION); - header.append(VERSION_NUM); - header.append(EOLN); - header.append(START_HTML); - header.append(HTML_START_END); - header.append(EOLN); - header.append(END_HTML); - header.append(HTML_START_END); - header.append(EOLN); - header.append(START_FRAGMENT); - header.append(HEADER_LEN_STR); - header.append(EOLN); - header.append(END_FRAGMENT); - // Strip terminating NUL byte from array - header.append(toPaddedString(HEADER_LEN + bytes.length - 1, - PADDED_WIDTH)); - header.append(EOLN); - header.append(START_FRAGMENT_CMT); - header.append(EOLN); - - byte[] headerBytes = null, trailerBytes = null; - - try { - headerBytes = new String(header).getBytes(ENCODING); - trailerBytes = TRAILER.getBytes(ENCODING); - } catch (UnsupportedEncodingException cannotHappen) { - } - - byte[] retval = new byte[headerBytes.length + bytes.length - 1 + - trailerBytes.length]; - - System.arraycopy(headerBytes, 0, retval, 0, headerBytes.length); - System.arraycopy(bytes, 0, retval, headerBytes.length, - bytes.length - 1); - System.arraycopy(trailerBytes, 0, retval, - headerBytes.length + bytes.length - 1, - trailerBytes.length); - - return retval; - } -} - -/** -* This stream takes an InputStream which provides data in CF_HTML format, - * strips off the description and context to extract the original HTML data. - */ -class HTMLDecodingInputStream extends InputStream { - - private final BufferedInputStream bufferedStream; - private boolean descriptionParsed = false; - private boolean closed = false; - private int index; - private int end; - - // InputStreamReader uses an 8K buffer. The size is not customizable. - public static final int BYTE_BUFFER_LEN = 8192; - - // CharToByteUTF8.getMaxBytesPerChar returns 3, so we should not buffer - // more chars than 3 times the number of bytes we can buffer. - public static final int CHAR_BUFFER_LEN = BYTE_BUFFER_LEN / 3; - - private static final String FAILURE_MSG = - "Unable to parse HTML description: "; - private static final String INVALID_MSG = " invalid"; - - public HTMLDecodingInputStream(InputStream bytestream) throws IOException { - bufferedStream = new BufferedInputStream(bytestream, BYTE_BUFFER_LEN); - } - - private void parseDescription() throws IOException { - bufferedStream.mark(BYTE_BUFFER_LEN); - - BufferedReader bufferedReader = new BufferedReader - (new InputStreamReader(bufferedStream, HTMLSupport.ENCODING), - CHAR_BUFFER_LEN); - String version = bufferedReader.readLine().trim(); - if (version == null || !version.startsWith(HTMLSupport.VERSION)) { - // Not MS-compliant HTML text. Return raw text from read(). - index = 0; - end = -1; - bufferedStream.reset(); - return; - } - - String input; - boolean startHTML, endHTML, startFragment, endFragment; - startHTML = endHTML = startFragment = endFragment = false; - - try { - do { - input = bufferedReader.readLine().trim(); - if (input == null) { - close(); - throw new IOException(FAILURE_MSG); - } else if (input.startsWith(HTMLSupport.START_HTML)) { - int val = Integer.parseInt - (input.substring(HTMLSupport.START_HTML.length(), - input.length()).trim()); - if (val >= 0) { - index = val; - startHTML = true; - } else if (val != -1) { - close(); - throw new IOException(FAILURE_MSG + - HTMLSupport.START_HTML + - INVALID_MSG); - } - } else if (input.startsWith(HTMLSupport.END_HTML)) { - int val = Integer.parseInt - (input.substring(HTMLSupport.END_HTML.length(), - input.length()).trim()); - if (val >= 0) { - end = val; - endHTML = true; - } else if (val != -1) { - close(); - throw new IOException(FAILURE_MSG + - HTMLSupport.END_HTML + - INVALID_MSG); - } - } else if (!startHTML && !endHTML && - input.startsWith(HTMLSupport.START_FRAGMENT)) { - index = Integer.parseInt - (input.substring(HTMLSupport.START_FRAGMENT.length(), - input.length()).trim()); - if (index < 0) { - close(); - throw new IOException(FAILURE_MSG + - HTMLSupport.START_FRAGMENT + - INVALID_MSG); - } - startFragment = true; - } else if (!startHTML && !endHTML && - input.startsWith(HTMLSupport.END_FRAGMENT)) { - end = Integer.parseInt - (input.substring(HTMLSupport.END_FRAGMENT.length(), - input.length()).trim()); - if (end < 0) { - close(); - throw new IOException(FAILURE_MSG + - HTMLSupport.END_FRAGMENT + - INVALID_MSG); - } - endFragment = true; - } - } while (!((startHTML && endHTML) || - (startFragment && endFragment))); - } catch (NumberFormatException e) { - close(); - throw new IOException(FAILURE_MSG + e); - } - - bufferedStream.reset(); - - for (int i = 0; i < index; i++) { - if (bufferedStream.read() == -1) { - close(); - throw new IOException(FAILURE_MSG + - "Byte stream ends in description."); - } - } - } - - public int read() throws IOException { - if (closed) { - throw new IOException("Stream closed"); - } - - if (!descriptionParsed) { - parseDescription(); // initializes 'index' and 'end' - descriptionParsed = true; - } - - if (end != -1 && index >= end) { - return -1; - } - - int retval = bufferedStream.read(); - if (retval == -1) { - index = end = 0; // so future read() calls will fail quickly - return -1; - } - - index++; - // System.out.print((char)retval); - return retval; - } - - public void close() throws IOException { - if (!closed) { - closed = true; - bufferedStream.close(); - } - } -} diff -r 0e0103e73d3c -r 986c81d8805b jdk/src/macosx/lib/flavormap.properties --- a/jdk/src/macosx/lib/flavormap.properties Wed Jan 29 16:35:42 2014 +0400 +++ b/jdk/src/macosx/lib/flavormap.properties Wed Jan 29 16:50:22 2014 +0400 @@ -79,3 +79,5 @@ TIFF=image/x-java-image;class=java.awt.Image RICH_TEXT=text/rtf HTML=text/html;charset=utf-8;eoln="\r\n";terminators=1 +URL=application/x-java-url;class=java.net.URL +URL=text/uri-list;eoln="\r\n";terminators=1 diff -r 0e0103e73d3c -r 986c81d8805b jdk/test/java/awt/dnd/URLDragTest/URLDragTest.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/dnd/URLDragTest/URLDragTest.html Wed Jan 29 16:50:22 2014 +0400 @@ -0,0 +1,45 @@ + + + + + + DnD of URL across JVM + + + +

URLDragTest
Bug ID: 8031964

+ +

This is an AUTOMATIC test, simply wait for completion

+ + + + diff -r 0e0103e73d3c -r 986c81d8805b jdk/test/java/awt/dnd/URLDragTest/URLDragTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/dnd/URLDragTest/URLDragTest.java Wed Jan 29 16:50:22 2014 +0400 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + test + @bug 8031964 + @summary Dragging images from the browser does not work + @author Petr Pchelko : area=dnd + @library ../../regtesthelpers + @build Sysout + @run applet/manual=yesno URLDragTest.html +*/ + +import test.java.awt.regtesthelpers.Sysout; + +import java.applet.Applet; +import java.awt.*; +import java.awt.datatransfer.DataFlavor; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; + +public class URLDragTest extends Applet { + + + @Override + public void init() { + setBackground(Color.red); + setDropTarget(new DropTarget(this, + DnDConstants.ACTION_COPY, + new DropTargetAdapter() { + @Override + public void dragEnter(DropTargetDragEvent dtde) { + dtde.acceptDrag(DnDConstants.ACTION_COPY); + } + + @Override + public void dragOver(DropTargetDragEvent dtde) { + dtde.acceptDrag(DnDConstants.ACTION_COPY); + } + + @Override + public void drop(DropTargetDropEvent dtde) { + dtde.acceptDrop(DnDConstants.ACTION_COPY); + dtde.getCurrentDataFlavorsAsList() + .stream() + .map(DataFlavor::toString) + .forEach(Sysout::println); + } + })); + + String[] instructions = { + "1) Open the browser.", + "2) Drag any image from the browser page to the red square", + "3) When the image is dropped you should se the list of available DataFlavors", + "4) If you see application/x-java-url and text/uri-list flavors - test PASSED", + "5) Otherwise the test is FAILED"}; + Sysout.createDialogWithInstructions(instructions); + } + + @Override + public void start() { + setSize(200, 200); + setVisible(true); + } +}