diff --git a/make/CompileJavaClasses.gmk b/make/CompileJavaClasses.gmk index a06c41573c478cd757b7abf656d36ba0ae30006e..c4be75532f53b71667cd9cb70f06950f16db99ae 100644 --- a/make/CompileJavaClasses.gmk +++ b/make/CompileJavaClasses.gmk @@ -402,7 +402,8 @@ ifndef OPENJDK SETUP := GENERATE_JDKBYTECODE, \ JAVAC_FLAGS := -cp $(JDK_OUTPUTDIR)/classes, \ SRC := $(JDK_OUTPUTDIR)/gensrc_ab/32bit, \ - BIN := $(JDK_OUTPUTDIR)/classes_ab/32bit)) + BIN := $(JDK_OUTPUTDIR)/classes_ab/32bit, \ + HEADERS := $(JDK_OUTPUTDIR)/gensrc_headers)) $(BUILD_ACCESSBRIDGE_32): $(BUILD_JDK) @@ -410,7 +411,8 @@ ifndef OPENJDK SETUP := GENERATE_JDKBYTECODE, \ JAVAC_FLAGS := -cp $(JDK_OUTPUTDIR)/classes, \ SRC := $(JDK_OUTPUTDIR)/gensrc_ab/legacy, \ - BIN := $(JDK_OUTPUTDIR)/classes_ab/legacy)) + BIN := $(JDK_OUTPUTDIR)/classes_ab/legacy, \ + HEADERS := $(JDK_OUTPUTDIR)/gensrc_headers)) $(BUILD_ACCESSBRIDGE_LEGACY): $(BUILD_JDK) @@ -420,7 +422,8 @@ ifndef OPENJDK SETUP := GENERATE_JDKBYTECODE, \ JAVAC_FLAGS := -cp $(JDK_OUTPUTDIR)/classes, \ SRC := $(JDK_OUTPUTDIR)/gensrc_ab/64bit, \ - BIN := $(JDK_OUTPUTDIR)/classes_ab/64bit)) + BIN := $(JDK_OUTPUTDIR)/classes_ab/64bit, \ + HEADERS := $(JDK_OUTPUTDIR)/gensrc_headers)) $(BUILD_ACCESSBRIDGE_64): $(BUILD_JDK) diff --git a/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/src/share/classes/sun/awt/datatransfer/DataTransferer.java index 3d79770b04aa8b654204f07388e058eda4541a31..1ebcc1a56a842a9e68d868c72f3f16c263c7e337 100644 --- a/src/share/classes/sun/awt/datatransfer/DataTransferer.java +++ b/src/share/classes/sun/awt/datatransfer/DataTransferer.java @@ -1598,6 +1598,30 @@ search: // Turn the list of Files into a List and return theObject = Arrays.asList(files); + // Source data is a URI list. Convert to DataFlavor.javaFileListFlavor + // where possible. + } else if (isURIListFormat(format) + && DataFlavor.javaFileListFlavor.equals(flavor)) { + + try (ByteArrayInputStream str = new ByteArrayInputStream(bytes)) { + + URI uris[] = dragQueryURIs(str, format, localeTransferable); + if (uris == null) { + return null; + } + List files = new ArrayList<>(); + for (URI uri : uris) { + try { + files.add(new File(uri)); + } catch (IllegalArgumentException illegalArg) { + // When converting from URIs to less generic files, + // common practice (Wine, SWT) seems to be to + // silently drop the URIs that aren't local files. + } + } + theObject = files; + } + // Target data is a String. Strip terminating NUL bytes. Decode bytes // into characters. Search-and-replace EOLN. } else if (String.class.equals(flavor.getRepresentationClass()) && diff --git a/src/solaris/classes/sun/awt/X11/XDataTransferer.java b/src/solaris/classes/sun/awt/X11/XDataTransferer.java index 8e3a0b17aa7f4e831f1b6b3c82ec3b5b7f9c937f..87f394d0531ecbb357bddbca0a755fdafbf7559d 100644 --- a/src/solaris/classes/sun/awt/X11/XDataTransferer.java +++ b/src/solaris/classes/sun/awt/X11/XDataTransferer.java @@ -242,6 +242,7 @@ public class XDataTransferer extends DataTransferer { } } + @Override protected String[] dragQueryFile(byte[] bytes) { XToolkit.awtLock(); try { @@ -252,8 +253,8 @@ public class XDataTransferer extends DataTransferer { } } + @Override protected URI[] dragQueryURIs(InputStream stream, - byte[] bytes, long format, Transferable localeTransferable) throws IOException { diff --git a/src/solaris/classes/sun/awt/X11/XDesktopPeer.java b/src/solaris/classes/sun/awt/X11/XDesktopPeer.java index 94ba7529a5444bfb05d25698e17dc2ef80a891c2..ae5f681d97dc338c6a16f7d057d07155078bc5cf 100644 --- a/src/solaris/classes/sun/awt/X11/XDesktopPeer.java +++ b/src/solaris/classes/sun/awt/X11/XDesktopPeer.java @@ -33,6 +33,9 @@ import java.net.URI; import java.awt.Desktop.Action; import java.awt.peer.DesktopPeer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** @@ -43,6 +46,10 @@ import java.awt.peer.DesktopPeer; */ public class XDesktopPeer implements DesktopPeer { + // supportedActions may be changed from native within an init() call + private static final List supportedActions + = new ArrayList<>(Arrays.asList(Action.OPEN, Action.MAIL, Action.BROWSE)); + private static boolean nativeLibraryLoaded = false; private static boolean initExecuted = false; @@ -65,11 +72,11 @@ public class XDesktopPeer implements DesktopPeer { static boolean isDesktopSupported() { initWithLock(); - return nativeLibraryLoaded; + return nativeLibraryLoaded && !supportedActions.isEmpty(); } public boolean isSupported(Action type) { - return type != Action.PRINT && type != Action.EDIT; + return supportedActions.contains(type); } public void open(File file) throws IOException { diff --git a/src/solaris/classes/sun/awt/X11/XWindow.java b/src/solaris/classes/sun/awt/X11/XWindow.java index 6791ce78ae372e79a8f086d27013df143008093f..6aa9d514a7f09350a2bd0f6b9894b36570baa6a6 100644 --- a/src/solaris/classes/sun/awt/X11/XWindow.java +++ b/src/solaris/classes/sun/awt/X11/XWindow.java @@ -456,6 +456,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { ColorModel cm = getColorModel(); int pixel = PixelConverter.instance.rgbToPixel(c.getRGB(), cm); XlibWrapper.XSetWindowBackground(XToolkit.getDisplay(), getContentWindow(), pixel); + XlibWrapper.XClearWindow(XToolkit.getDisplay(), getContentWindow()); } finally { XToolkit.awtUnlock(); diff --git a/src/solaris/native/sun/awt/gtk2_interface.c b/src/solaris/native/sun/awt/gtk2_interface.c index cb960b12844d8ac8abdaa6773bf68c4aac49bfdf..efe079794da7b5c6da0fb942e2eb4ac0551dff40 100644 --- a/src/solaris/native/sun/awt/gtk2_interface.c +++ b/src/solaris/native/sun/awt/gtk2_interface.c @@ -438,10 +438,76 @@ gboolean gtk2_check_version() } } +#define ADD_SUPPORTED_ACTION(actionStr) \ +do { \ + jfieldID fld_action = (*env)->GetStaticFieldID(env, cls_action, actionStr, "Ljava/awt/Desktop$Action;"); \ + if (!(*env)->ExceptionCheck(env)) { \ + jobject action = (*env)->GetStaticObjectField(env, cls_action, fld_action); \ + (*env)->CallBooleanMethod(env, supportedActions, mid_arrayListAdd, action); \ + } else { \ + (*env)->ExceptionClear(env); \ + } \ +} while(0); + + +void update_supported_actions(JNIEnv *env) { + GVfs * (*fp_g_vfs_get_default) (void); + const gchar * const * (*fp_g_vfs_get_supported_uri_schemes) (GVfs * vfs); + const gchar * const * schemes = NULL; + + jclass cls_action = (*env)->FindClass(env, "java/awt/Desktop$Action"); + jclass cls_xDesktopPeer = (*env)->FindClass(env, "sun/awt/X11/XDesktopPeer"); + jfieldID fld_supportedActions = (*env)->GetStaticFieldID(env, cls_xDesktopPeer, "supportedActions", "Ljava/util/List;"); + jobject supportedActions = (*env)->GetStaticObjectField(env, cls_xDesktopPeer, fld_supportedActions); + + jclass cls_arrayList = (*env)->FindClass(env, "java/util/ArrayList"); + jmethodID mid_arrayListAdd = (*env)->GetMethodID(env, cls_arrayList, "add", "(Ljava/lang/Object;)Z"); + jmethodID mid_arrayListClear = (*env)->GetMethodID(env, cls_arrayList, "clear", "()V"); + + (*env)->CallVoidMethod(env, supportedActions, mid_arrayListClear); + + ADD_SUPPORTED_ACTION("OPEN"); + + /** + * gtk_show_uri() documentation says: + * + * > you need to install gvfs to get support for uri schemes such as http:// + * > or ftp://, as only local files are handled by GIO itself. + * + * So OPEN action was safely added here. + * However, it looks like Solaris 11 have gvfs support only for 32-bit + * applications only by default. + */ + + fp_g_vfs_get_default = dl_symbol("g_vfs_get_default"); + fp_g_vfs_get_supported_uri_schemes = dl_symbol("g_vfs_get_supported_uri_schemes"); + dlerror(); + + if (fp_g_vfs_get_default && fp_g_vfs_get_supported_uri_schemes) { + GVfs * vfs = fp_g_vfs_get_default(); + schemes = vfs ? fp_g_vfs_get_supported_uri_schemes(vfs) : NULL; + if (schemes) { + int i = 0; + while (schemes[i]) { + if (strcmp(schemes[i], "http") == 0) { + ADD_SUPPORTED_ACTION("BROWSE"); + ADD_SUPPORTED_ACTION("MAIL"); + break; + } + i++; + } + } + } else { +#ifdef INTERNAL_BUILD + fprintf(stderr, "Cannot load g_vfs_get_supported_uri_schemes\n"); +#endif /* INTERNAL_BUILD */ + } + +} /** * Functions for awt_Desktop.c */ -gboolean gtk2_show_uri_load() { +gboolean gtk2_show_uri_load(JNIEnv *env) { gboolean success = FALSE; dlerror(); const char *gtk_version = fp_gtk_check_version(2, 14, 0); @@ -464,9 +530,12 @@ gboolean gtk2_show_uri_load() { #ifdef INTERNAL_BUILD fprintf(stderr, "dlsym(gtk_show_uri) returned NULL\n"); #endif /* INTERNAL_BUILD */ - } else { - success = TRUE; - } + } else { +#ifdef __solaris__ + update_supported_actions(env); +#endif + success = TRUE; + } } return success; } @@ -533,7 +602,10 @@ gboolean gtk2_load(JNIEnv *env) } /* GLib */ - fp_glib_check_version = dl_symbol("glib_check_version"); + fp_glib_check_version = dlsym(gtk2_libhandle, "glib_check_version"); + if (!fp_glib_check_version) { + dlerror(); + } fp_g_free = dl_symbol("g_free"); fp_g_object_unref = dl_symbol("g_object_unref"); @@ -709,7 +781,7 @@ gboolean gtk2_load(JNIEnv *env) /** * GLib thread system */ - if (fp_glib_check_version(2, 20, 0) == NULL) { + if (GLIB_CHECK_VERSION(2, 20, 0)) { fp_g_thread_get_initialized = dl_symbol_gthread("g_thread_get_initialized"); } fp_g_thread_init = dl_symbol_gthread("g_thread_init"); @@ -827,7 +899,7 @@ gboolean gtk2_load(JNIEnv *env) // We can use g_thread_get_initialized () but it is available only for // GLib >= 2.20. We rely on GThreadHelper for GLib < 2.20. gboolean is_g_thread_get_initialized = FALSE; - if (fp_glib_check_version(2, 20, 0) == NULL) { + if (GLIB_CHECK_VERSION(2, 20, 0)) { is_g_thread_get_initialized = fp_g_thread_get_initialized(); } diff --git a/src/solaris/native/sun/awt/gtk2_interface.h b/src/solaris/native/sun/awt/gtk2_interface.h index c8fe45360440e2c80ee75e13ca7b69886b49fddc..1523f7464d5b71c110f8a6c325086adf1fbc70bd 100644 --- a/src/solaris/native/sun/awt/gtk2_interface.h +++ b/src/solaris/native/sun/awt/gtk2_interface.h @@ -270,6 +270,7 @@ typedef enum /* We define all structure pointers to be void* */ typedef void GError; typedef void GMainContext; +typedef void GVfs; typedef struct _GSList GSList; struct _GSList @@ -647,10 +648,19 @@ const char *getStrFor(JNIEnv *env, jstring value); * Returns : * NULL if the GLib library is compatible with the given version, or a string * describing the version mismatch. + * Please note that the glib_check_version() is available since 2.6, + * so you should use GLIB_CHECK_VERSION macro instead. */ gchar* (*fp_glib_check_version)(guint required_major, guint required_minor, guint required_micro); +/** + * Returns : + * TRUE if the GLib library is compatible with the given version + */ +#define GLIB_CHECK_VERSION(major, minor, micro) \ + (fp_glib_check_version && fp_glib_check_version(major, minor, micro) == NULL) + /* * Check whether the gtk2 library is available and meets the minimum * version requirement. If the library is already loaded this method has no @@ -680,7 +690,7 @@ gboolean gtk2_load(JNIEnv *env); * gtk2_load, so it must be invoked only after a successful gtk2_load * invocation */ -gboolean gtk2_show_uri_load(); +gboolean gtk2_show_uri_load(JNIEnv *env); /* * Unload the gtk2 library. If the library is already unloaded this method has @@ -811,7 +821,7 @@ guint (*fp_gtk_main_level)(void); /** * This function is available for GLIB > 2.20, so it MUST be - * called within (fp_glib_check_version(2, 20, 0) == NULL) check. + * called within GLIB_CHECK_VERSION(2, 20, 0) check. */ gboolean (*fp_g_thread_get_initialized)(void); diff --git a/src/solaris/native/sun/xawt/awt_Desktop.c b/src/solaris/native/sun/xawt/awt_Desktop.c index 55c769096355bb49ed0bbfc3e41ccc04f3d023d7..16c50eae7a261d0650145b855d3f75d4a831633d 100644 --- a/src/solaris/native/sun/xawt/awt_Desktop.c +++ b/src/solaris/native/sun/xawt/awt_Desktop.c @@ -42,7 +42,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XDesktopPeer_init return JNI_TRUE; } - if (gtk2_load(env) && gtk2_show_uri_load()) { + if (gtk2_load(env) && gtk2_show_uri_load(env)) { gtk_has_been_loaded = TRUE; return JNI_TRUE; } else if (gnome_load()) { diff --git a/test/java/awt/Desktop/OpenByUNCPathNameTest/OpenByUNCPathNameTest.java b/test/java/awt/Desktop/OpenByUNCPathNameTest/OpenByUNCPathNameTest.java index 052f36f7453f98ab1b6af54db0046efee56f8f6a..9a5d075999fcc0c41c323312ac47908104c4dfb6 100644 --- a/test/java/awt/Desktop/OpenByUNCPathNameTest/OpenByUNCPathNameTest.java +++ b/test/java/awt/Desktop/OpenByUNCPathNameTest/OpenByUNCPathNameTest.java @@ -45,6 +45,10 @@ public class OpenByUNCPathNameTest { System.out.println("java.awt.Desktop is not supported on this platform."); } else { Desktop desktop = Desktop.getDesktop(); + if (!desktop.isSupported(Desktop.Action.OPEN)) { + System.out.println("Action.OPEN is not supported on this platform."); + return; + } File file = File.createTempFile("Read Me File", ".txt"); try { // Test opening of the file with Windows local file path. diff --git a/test/java/awt/Window/BackgroundIsNotUpdated/BackgroundIsNotUpdated.java b/test/java/awt/Window/BackgroundIsNotUpdated/BackgroundIsNotUpdated.java new file mode 100644 index 0000000000000000000000000000000000000000..003c0932b03d7b64bb3d0e763280abcbdff28536 --- /dev/null +++ b/test/java/awt/Window/BackgroundIsNotUpdated/BackgroundIsNotUpdated.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013, 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. + */ + +import java.awt.AWTException; +import java.awt.Color; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.Window; + +import sun.awt.SunToolkit; + +/** + * @test + * @bug 8001472 + * @summary Background of the window should not depend from the paint()/update() + * @author Sergey Bylokhov + */ +public final class BackgroundIsNotUpdated extends Window { + + public BackgroundIsNotUpdated(final Frame owner) { + super(owner); + } + + @Override + public void paint(final Graphics ignored) { + // Intentionally left blank + } + + @Override + public void update(final Graphics ignored) { + // Intentionally left blank + } + + public static void main(final String[] args) throws AWTException { + final Window window = new BackgroundIsNotUpdated(null); + window.setSize(300, 300); + window.setLocationRelativeTo(null); + window.setVisible(true); + sleep(); + window.setBackground(Color.GREEN); + sleep(); + final Robot robot = new Robot(); + robot.setAutoDelay(200); + Point point = window.getLocationOnScreen(); + Color color = robot.getPixelColor(point.x + window.getWidth() / 2, + point.y + window.getHeight() / 2); + window.dispose(); + if (!color.equals(Color.GREEN)) { + throw new RuntimeException( + "Expected: " + Color.GREEN + " , Actual: " + color); + } + } + + private static void sleep() { + try { + ((SunToolkit) Toolkit.getDefaultToolkit()).realSync(); + Thread.sleep(1000); + } catch (InterruptedException ignored) { + } + } +} diff --git a/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/InterprocessMessages.java b/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/InterprocessMessages.java new file mode 100644 index 0000000000000000000000000000000000000000..343b9fc6d340c5ef7a6bc180ad03dc23e631d487 --- /dev/null +++ b/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/InterprocessMessages.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2007, 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. + */ + +public interface InterprocessMessages { + final static int EXECUTION_IS_SUCCESSFULL = 0; + final static int WRONG_FILES_NUMBER_ON_TARGET = 212; +} diff --git a/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/SourceFileListFrame.java b/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/SourceFileListFrame.java new file mode 100644 index 0000000000000000000000000000000000000000..c41299c8883452fb408f6929ade0a04700dd17ae --- /dev/null +++ b/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/SourceFileListFrame.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013, 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. + */ + +import test.java.awt.regtesthelpers.Util; + +import java.awt.*; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.io.File; +import java.net.URI; +import java.util.Arrays; +import java.util.stream.Collectors; +import java.util.stream.Stream; + + +class SourceFileListFrame extends Frame implements DragGestureListener { + + private final static int SOURCE_POINT_SHIFT = 3; + + private List list = new List(URIListToFileListBetweenJVMsTest.VISIBLE_RAWS_IN_LIST); + private File[] files; + + SourceFileListFrame() { + super("Source File List Frame"); + extractFilesFromTheWorkingDirectory(); + initList(); + initGUI(); + new DragSource().createDefaultDragGestureRecognizer(list, + DnDConstants.ACTION_COPY,this); + } + + private void extractFilesFromTheWorkingDirectory() { + files = new File(System.getProperty("java.home", "")).listFiles(); + } + + private void initList() { + for (File currFile:files) { + list.add(currFile.getName()); + } + } + + private void initGUI() { + this.addWindowListener(Util.getClosingWindowAdapter()); + this.setLocation(300,250); + this.add(new Panel().add(list)); + this.pack(); + this.setVisible(true); + } + + int getNextLocationX() { + return getX()+getWidth(); + } + + int getNextLocationY() { + return getY(); + } + + int getDragSourcePointX() { + return (int)list.getLocationOnScreen().getX()+(list.getWidth()/2); + } + + int getDragSourcePointY() { + return (int)list.getLocationOnScreen().getY()+ SOURCE_POINT_SHIFT; + } + + int getSourceFilesNumber() { + return files.length; + } + + public void dragGestureRecognized(DragGestureEvent dge) { + java.util.List uriList = Stream.of(list.getItems()) + .map(File::new) + .map(File::toURI) + .collect(Collectors.toList()); + + dge.startDrag(null, new URIListTransferable(uriList)); + } +} diff --git a/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/TargetFileListFrame.java b/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/TargetFileListFrame.java new file mode 100644 index 0000000000000000000000000000000000000000..ac5ce7475e937879ce1795141f96b15f1081a623 --- /dev/null +++ b/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/TargetFileListFrame.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013, 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. + */ + +import java.awt.*; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.*; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.File; +import java.io.IOException; + +class TargetFileListFrame extends Frame implements DropTargetListener { + + private List list = new List(URIListToFileListBetweenJVMsTest.VISIBLE_RAWS_IN_LIST); + private int expectationTransferredFilesNumber; + + TargetFileListFrame(Point location, int expectationTransferredFilesNumber) { + this.expectationTransferredFilesNumber = expectationTransferredFilesNumber; + initGUI(location); + setDropTarget(new DropTarget(list, DnDConstants.ACTION_COPY, this)); + } + + private void initGUI(Point location) { + this.setLocation(location); + this.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + TargetFileListFrame.this.dispose(); + } + }); + this.add(new Panel().add(list)); + this.pack(); + this.setVisible(true); + } + + public void dragEnter(DropTargetDragEvent dtde) { + if (dtde.getCurrentDataFlavorsAsList().contains(DataFlavor.javaFileListFlavor)) { + dtde.acceptDrag(DnDConstants.ACTION_COPY); + } + } + + public void dragOver(DropTargetDragEvent dtde) { + if (dtde.getCurrentDataFlavorsAsList().contains(DataFlavor.javaFileListFlavor)) { + dtde.acceptDrag(DnDConstants.ACTION_COPY); + } + } + + public void dropActionChanged(DropTargetDragEvent dtde) { + if (dtde.getCurrentDataFlavorsAsList().contains(DataFlavor.javaFileListFlavor)) { + dtde.acceptDrag(DnDConstants.ACTION_COPY); + } + } + + public void dragExit(DropTargetEvent dte) {} + + public void drop(DropTargetDropEvent dtde) { + list.removeAll(); + dtde.acceptDrop(DnDConstants.ACTION_COPY); + java.util.List fileList = extractListOfFiles(dtde); + for (File file:fileList) { + list.add(file.getName()); + } + + if (fileList.size() != expectationTransferredFilesNumber) + { + System.err.println("ERROR: Expected file number:" + + expectationTransferredFilesNumber + + "; Received file number: " + + fileList.size()); + TargetFileListFrame.this.dispose(); + System.exit(InterprocessMessages.WRONG_FILES_NUMBER_ON_TARGET); + } + + TargetFileListFrame.this.dispose(); + + } + + private java.util.List extractListOfFiles(DropTargetDropEvent dtde) { + java.util.List fileList = null; + try { + fileList = (java.util.List)dtde.getTransferable().getTransferData(DataFlavor.javaFileListFlavor); + } catch (UnsupportedFlavorException | IOException e) { + e.printStackTrace(); + } + return fileList; + } + + Point getDropTargetPoint() { + return new Point((int)list.getLocationOnScreen().getX()+(list.getWidth()/2), + (int)list.getLocationOnScreen().getY()+(list.getHeight()/2)); + } +} diff --git a/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/URIListToFileListBetweenJVMsTest.html b/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/URIListToFileListBetweenJVMsTest.html new file mode 100644 index 0000000000000000000000000000000000000000..19ee5def8670507d92a0626713dfa91a59c1a163 --- /dev/null +++ b/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/URIListToFileListBetweenJVMsTest.html @@ -0,0 +1,48 @@ + + + + + + DnD of File-List across JVM + + + +

URIListToFileListBetweenJVMsTest
Bug ID: 5079469

+ +

This is an AUTOMATIC test, simply wait for completion

+ + + + diff --git a/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/URIListToFileListBetweenJVMsTest.java b/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/URIListToFileListBetweenJVMsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9e78362774c9caf71e3641763aafc28d5d0b44a0 --- /dev/null +++ b/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/URIListToFileListBetweenJVMsTest.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013, 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 8029565 + @summary Conversion of a URI list to File list fails + @author Petr Pchelko + @library ../../regtesthelpers + @library ../../regtesthelpers/process + @build Util + @build ProcessResults ProcessCommunicator + @run applet/othervm URIListToFileListBetweenJVMsTest.html + */ + +/** + * URIListToFileListBetweenJVMsTest.java + * + * summary: DnD of File-List across JVM adds two empty items to the list + */ + +import test.java.awt.regtesthelpers.Util; +import test.java.awt.regtesthelpers.process.ProcessCommunicator; +import test.java.awt.regtesthelpers.process.ProcessResults; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.InputEvent; + +import static java.lang.Thread.sleep; + +public class URIListToFileListBetweenJVMsTest extends Applet { + + // information related to the test in common + static int VISIBLE_RAWS_IN_LIST=15; + + public void init() { + setLayout(new BorderLayout()); + } + + public void start() { + + SourceFileListFrame sourceFrame = new SourceFileListFrame(); + + Util.waitForIdle(null); + + String [] args = new String [] { + String.valueOf(sourceFrame.getNextLocationX()), + String.valueOf(sourceFrame.getNextLocationY()), + String.valueOf(sourceFrame.getDragSourcePointX()), + String.valueOf(sourceFrame.getDragSourcePointY()), + String.valueOf(sourceFrame.getSourceFilesNumber()) + }; + + ProcessResults processResults = ProcessCommunicator.executeChildProcess(this.getClass(), args); + + verifyTestResults(processResults); + + } + + private static void verifyTestResults(ProcessResults processResults) { + if ( InterprocessMessages.WRONG_FILES_NUMBER_ON_TARGET == processResults.getExitValue()) { + processResults.printProcessErrorOutput(System.err); + throw new RuntimeException("TEST IS FAILED: Target has recieved wrong number of files."); + } + processResults.verifyStdErr(System.err); + processResults.verifyProcessExitValue(System.err); + processResults.printProcessStandartOutput(System.out); + } + + //We cannot make an instance of the applet without the default constructor + public URIListToFileListBetweenJVMsTest() { + super(); + } + + //We need in this constructor to pass frame position between JVMs + public URIListToFileListBetweenJVMsTest(Point targetFrameLocation, + Point dragSourcePoint, + int transferredFilesNumber) throws InterruptedException + { + TargetFileListFrame targetFrame = new TargetFileListFrame(targetFrameLocation, transferredFilesNumber); + + Util.waitForIdle(null); + + final Robot robot = Util.createRobot(); + + robot.mouseMove((int)dragSourcePoint.getX(),(int)dragSourcePoint.getY()); + sleep(100); + robot.mousePress(InputEvent.BUTTON1_MASK); + sleep(100); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + sleep(100); + + Util.drag(robot, dragSourcePoint, targetFrame.getDropTargetPoint(), InputEvent.BUTTON1_MASK); + + } + + enum InterprocessArguments { + TARGET_FRAME_X_POSITION_ARGUMENT, + TARGET_FRAME_Y_POSITION_ARGUMENT, + DRAG_SOURCE_POINT_X_ARGUMENT, + DRAG_SOURCE_POINT_Y_ARGUMENT, + FILES_IN_THE_LIST_NUMBER_ARGUMENT; + + int extract (String [] args) { + return Integer.parseInt(args[this.ordinal()]); + } + } + + public static void main (String [] args) throws Exception { + Point dragSourcePoint = new Point(InterprocessArguments.DRAG_SOURCE_POINT_X_ARGUMENT.extract(args), + InterprocessArguments.DRAG_SOURCE_POINT_Y_ARGUMENT.extract(args)); + Point targetFrameLocation = new Point(InterprocessArguments.TARGET_FRAME_X_POSITION_ARGUMENT.extract(args), + InterprocessArguments.TARGET_FRAME_Y_POSITION_ARGUMENT.extract(args)); + int transferredFilesNumber = InterprocessArguments.FILES_IN_THE_LIST_NUMBER_ARGUMENT.extract(args); + + new URIListToFileListBetweenJVMsTest(targetFrameLocation, dragSourcePoint, transferredFilesNumber); + } +} diff --git a/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/URIListTransferable.java b/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/URIListTransferable.java new file mode 100644 index 0000000000000000000000000000000000000000..51fc93e5c4e83a8085e1f510ddfc41b6587c1728 --- /dev/null +++ b/test/java/awt/dnd/URIListToFileListBetweenJVMsTest/URIListTransferable.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013, 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. + */ + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; +import java.net.URI; +import java.util.List; + +class URIListTransferable implements Transferable { + + private final DataFlavor supportedFlavor; + + private List list; + + public URIListTransferable(List list) { + try { + this.supportedFlavor = new DataFlavor("text/uri-list;class=java.lang.String"); + } catch (ClassNotFoundException e) { + throw new RuntimeException("FAILED: could not create a DataFlavor"); + } + this.list = list; + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { supportedFlavor }; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + return supportedFlavor.equals(flavor); + } + + public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { + if (supportedFlavor.equals(flavor)) { + return list.stream() + .map(URI::toASCIIString) + .collect(StringBuilder::new, + (builder, uri)-> { builder.append(uri).append("\r\n"); }, + StringBuilder::append).toString(); + } + throw new UnsupportedFlavorException(flavor); + } +}