提交 4e4eb5d9 编写于 作者: P pchelko

8031964: [macosx] Dragging images from the browser does not work

Reviewed-by: anthony, serb
上级 d06bc486
/* /*
* Copyright (c) 2011, 2013, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -56,11 +56,11 @@ public class CDataTransferer extends DataTransferer { ...@@ -56,11 +56,11 @@ public class CDataTransferer extends DataTransferer {
}; };
static { static {
Map<String, Long> nameMap = new HashMap<String, Long>(predefinedClipboardNames.length, 1.0f); Map<String, Long> nameMap = new HashMap<>(predefinedClipboardNames.length, 1.0f);
Map<Long, String> formatMap = new HashMap<Long, String>(predefinedClipboardNames.length, 1.0f); Map<Long, String> formatMap = new HashMap<>(predefinedClipboardNames.length, 1.0f);
for (int i = 1; i < predefinedClipboardNames.length; i++) { for (int i = 1; i < predefinedClipboardNames.length; i++) {
nameMap.put(predefinedClipboardNames[i], new Long(i)); nameMap.put(predefinedClipboardNames[i], (long) i);
formatMap.put(new Long(i), predefinedClipboardNames[i]); formatMap.put((long) i, predefinedClipboardNames[i]);
} }
predefinedClipboardNameMap = Collections.synchronizedMap(nameMap); predefinedClipboardNameMap = Collections.synchronizedMap(nameMap);
predefinedClipboardFormatMap = Collections.synchronizedMap(formatMap); predefinedClipboardFormatMap = Collections.synchronizedMap(formatMap);
...@@ -77,14 +77,6 @@ public class CDataTransferer extends DataTransferer { ...@@ -77,14 +77,6 @@ public class CDataTransferer extends DataTransferer {
public static final int CF_PNG = 10; public static final int CF_PNG = 10;
public static final int CF_JPEG = 11; 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 CDataTransferer() {}
private static CDataTransferer fTransferer; private static CDataTransferer fTransferer;
...@@ -97,18 +89,22 @@ public class CDataTransferer extends DataTransferer { ...@@ -97,18 +89,22 @@ public class CDataTransferer extends DataTransferer {
return fTransferer; return fTransferer;
} }
@Override
public String getDefaultUnicodeEncoding() { public String getDefaultUnicodeEncoding() {
return "utf-16le"; return "utf-16le";
} }
@Override
public boolean isLocaleDependentTextFormat(long format) { public boolean isLocaleDependentTextFormat(long format) {
return format == CF_STRING; return format == CF_STRING;
} }
@Override
public boolean isFileFormat(long format) { public boolean isFileFormat(long format) {
return format == CF_FILE; return format == CF_FILE;
} }
@Override
public boolean isImageFormat(long format) { public boolean isImageFormat(long format) {
int ifmt = (int)format; int ifmt = (int)format;
switch(ifmt) { switch(ifmt) {
...@@ -122,43 +118,12 @@ public class CDataTransferer extends DataTransferer { ...@@ -122,43 +118,12 @@ public class CDataTransferer extends DataTransferer {
} }
} }
protected Long[] getImageFormatsAsLongArray() { @Override
return imageFormats; public Object translateBytes(byte[] bytes, DataFlavor flavor,
} long format, Transferable transferable) throws IOException {
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);
}
if (format == CF_URL && URL.class.equals(flavor.getRepresentationClass())) if (format == CF_URL && URL.class.equals(flavor.getRepresentationClass()))
{ {
if (bytes == null) {
bytes = inputStreamToByteArray(stream);
stream = null;
}
String charset = getDefaultTextCharset(); String charset = getDefaultTextCharset();
if (transferable != null && transferable.isDataFlavorSupported(javaTextEncodingFlavor)) { if (transferable != null && transferable.isDataFlavorSupported(javaTextEncodingFlavor)) {
try { try {
...@@ -175,9 +140,9 @@ public class CDataTransferer extends DataTransferer { ...@@ -175,9 +140,9 @@ public class CDataTransferer extends DataTransferer {
} }
return super.translateBytes(bytes, flavor, format, transferable); return super.translateBytes(bytes, flavor, format, transferable);
} }
@Override
synchronized protected Long getFormatForNativeAsLong(String str) { synchronized protected Long getFormatForNativeAsLong(String str) {
Long format = predefinedClipboardNameMap.get(str); Long format = predefinedClipboardNameMap.get(str);
...@@ -202,6 +167,7 @@ public class CDataTransferer extends DataTransferer { ...@@ -202,6 +167,7 @@ public class CDataTransferer extends DataTransferer {
// Get registered native format string for an index, return null if unknown: // Get registered native format string for an index, return null if unknown:
private native String formatForIndex(long index); private native String formatForIndex(long index);
@Override
protected String getNativeForFormat(long format) { protected String getNativeForFormat(long format) {
String returnValue = null; String returnValue = null;
...@@ -209,7 +175,7 @@ public class CDataTransferer extends DataTransferer { ...@@ -209,7 +175,7 @@ public class CDataTransferer extends DataTransferer {
if (format >= 0 && format < predefinedClipboardNames.length) { if (format >= 0 && format < predefinedClipboardNames.length) {
returnValue = predefinedClipboardNames[(int) format]; returnValue = predefinedClipboardNames[(int) format];
} else { } else {
Long formatObj = new Long(format); Long formatObj = format;
returnValue = predefinedClipboardFormatMap.get(formatObj); returnValue = predefinedClipboardFormatMap.get(formatObj);
// predefinedClipboardFormatMap may not know this format: // predefinedClipboardFormatMap may not know this format:
...@@ -233,10 +199,13 @@ public class CDataTransferer extends DataTransferer { ...@@ -233,10 +199,13 @@ public class CDataTransferer extends DataTransferer {
private final ToolkitThreadBlockedHandler handler = new CToolkitThreadBlockedHandler(); private final ToolkitThreadBlockedHandler handler = new CToolkitThreadBlockedHandler();
@Override
public ToolkitThreadBlockedHandler getToolkitThreadBlockedHandler() { public ToolkitThreadBlockedHandler getToolkitThreadBlockedHandler() {
return handler; return handler;
} }
private native byte[] imageDataToPlatformImageBytes(int[] rData, int nW, int nH);
@Override
protected byte[] imageToPlatformBytes(Image image, long format) { protected byte[] imageToPlatformBytes(Image image, long format) {
int w = image.getWidth(null); int w = image.getWidth(null);
int h = image.getHeight(null); int h = image.getHeight(null);
...@@ -252,32 +221,28 @@ public class CDataTransferer extends DataTransferer { ...@@ -252,32 +221,28 @@ public class CDataTransferer extends DataTransferer {
} }
private static native String[] nativeDragQueryFile(final byte[] bytes); private static native String[] nativeDragQueryFile(final byte[] bytes);
@Override
protected String[] dragQueryFile(final byte[] bytes) { protected String[] dragQueryFile(final byte[] bytes) {
if (bytes == null) return null; if (bytes == null) return null;
if (new String(bytes).startsWith("Unsupported type")) return null; if (new String(bytes).startsWith("Unsupported type")) return null;
return nativeDragQueryFile(bytes); 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 * Translates a byte array which contains
* platform-specific image data in the given format into an Image. * platform-specific image data in the given format into an Image.
*/ */
protected Image platformImageBytesToImage(byte[] bytes, long format) @Override
throws IOException protected Image platformImageBytesToImage(byte[] bytes, long format) throws IOException {
{
return getImageForByteStream(bytes); return getImageForByteStream(bytes);
} }
private native Image getImageForByteStream(byte[] bytes);
@Override @Override
protected ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList) throws IOException { protected ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (int i = 0; i < fileList.size(); i++) for (String file : fileList) {
{ byte[] bytes = file.getBytes();
byte[] bytes = fileList.get(i).getBytes();
bos.write(bytes, 0, bytes.length); bos.write(bytes, 0, bytes.length);
bos.write(0); bos.write(0);
} }
...@@ -303,246 +268,3 @@ public class CDataTransferer extends DataTransferer { ...@@ -303,246 +268,3 @@ public class CDataTransferer extends DataTransferer {
} }
// ---- 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 = "<!--StartFragment-->";
public static final String END_FRAGMENT_CMT = "<!--EndFragment-->";
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();
}
}
}
...@@ -79,3 +79,5 @@ JFIF=image/x-java-image;class=java.awt.Image ...@@ -79,3 +79,5 @@ JFIF=image/x-java-image;class=java.awt.Image
TIFF=image/x-java-image;class=java.awt.Image TIFF=image/x-java-image;class=java.awt.Image
RICH_TEXT=text/rtf RICH_TEXT=text/rtf
HTML=text/html;charset=utf-8;eoln="\r\n";terminators=1 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
<!--
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.
-->
<html>
<!--
@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
-->
<head>
<title> DnD of URL across JVM </title>
</head>
<body>
<h1>URLDragTest<br>Bug ID: 8031964</h1>
<p> This is an AUTOMATIC test, simply wait for completion </p>
<APPLET CODE="URLDragTest.class" WIDTH=200 HEIGHT=200></APPLET>
</body>
</html>
/*
* 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);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册