1 19 20 package org.netbeans.core; 21 22 import java.awt.Toolkit ; 23 import java.awt.datatransfer.Clipboard ; 24 import java.awt.datatransfer.ClipboardOwner ; 25 import java.awt.datatransfer.DataFlavor ; 26 import java.awt.datatransfer.StringSelection ; 27 import java.awt.datatransfer.Transferable ; 28 import java.awt.datatransfer.UnsupportedFlavorException ; 29 import java.io.IOException ; 30 import java.io.PrintStream ; 31 import java.lang.reflect.InvocationTargetException ; 32 import java.util.Date ; 33 import java.util.logging.Level ; 34 import java.util.logging.Logger ; 35 import javax.swing.SwingUtilities ; 36 import org.netbeans.junit.AssertionFailedErrorException; 37 import org.netbeans.junit.MockServices; 38 import org.netbeans.junit.NbTestCase; 39 import org.openide.util.Lookup; 40 import org.openide.util.datatransfer.ClipboardEvent; 41 import org.openide.util.datatransfer.ClipboardListener; 42 import org.openide.util.datatransfer.ExClipboard; 43 import org.openide.util.datatransfer.ExTransferable; 44 import org.openide.util.datatransfer.TransferListener; 45 46 50 public class NbClipboardNativeTest extends NbTestCase implements ClipboardListener { 51 private NbClipboard ec; 52 private int listenerCalls; 53 private Logger LOG; 54 55 public NbClipboardNativeTest(String name) { 56 super(name); 57 } 58 59 protected void setUp() throws Exception { 60 MockServices.setServices(); 61 LOG = Logger.getLogger("TEST-" + getName()); 62 63 class EmptyTrans implements Transferable , ClipboardOwner { 64 public DataFlavor [] getTransferDataFlavors() { 65 return new DataFlavor [0]; 66 } 67 68 public boolean isDataFlavorSupported(DataFlavor flavor) { 69 return false; 70 } 71 72 public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException , IOException { 73 throw new IOException ("Nothing here"); 74 } 75 76 public void lostOwnership(Clipboard clipboard, Transferable contents) { 77 } 78 } 79 80 81 super.setUp(); 82 83 LOG.info("Setting up"); 84 85 System.setProperty("netbeans.slow.system.clipboard.hack", String.valueOf(slowClipboardHack())); 87 this.ec = new NbClipboard(); 88 89 LOG.info("Clipboard created"); 90 91 EmptyTrans et = new EmptyTrans(); 92 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(et, et); 93 94 waitFinished(this.ec); 95 96 LOG.info("system clipboard content changed"); 97 98 this.ec.addClipboardListener(this); 99 100 LOG.info("Listener added"); 101 } 102 103 protected void tearDown () throws Exception { 104 super.tearDown (); 105 if (ec != null) { 106 this.ec.removeClipboardListener(this); 107 } 108 109 waitFinished(ec); 110 } 111 112 protected boolean slowClipboardHack() { 113 return false; 114 } 115 116 public void testGetClipboardWorks() throws Exception { 117 class Get implements ClipboardListener { 118 Transferable in; 119 120 public void clipboardChanged(ClipboardEvent ev) { 121 in = ec.getContents(this); 122 } 123 } 124 125 Get get = new Get(); 126 ec.addClipboardListener(get); 127 128 StringSelection ss = new StringSelection ("x"); 129 ec.setContents(ss, ss); 130 131 assertEquals("Inside is the right one", ss.getTransferData(DataFlavor.stringFlavor), get.in.getTransferData(DataFlavor.stringFlavor)); 132 } 133 134 public void testWhenCallingGetContentsItChecksSystemClipboardFirstTimeAfterActivation () throws Exception { 135 assertEquals ("No changes yet", 0, listenerCalls); 136 137 Clipboard sc = Toolkit.getDefaultToolkit().getSystemClipboard(); 138 StringSelection ss = new StringSelection ("oldvalue"); 139 sc.setContents(ss, ss); 140 141 142 ec.activateWindowHack (true); 144 waitFinished (ec); 145 146 if (listenerCalls == 0) { 147 fail("We need at least one call: " + listenerCalls); 148 } 149 listenerCalls = 0; 150 151 StringSelection s2 = new StringSelection ("data2"); 152 sc.setContents (s2, s2); 153 154 waitFinished (ec); 155 156 if (slowClipboardHack()) { 157 assertEquals ("No change notified", 0, listenerCalls); 158 } 159 160 Thread.sleep (200); 162 163 Transferable t = this.ec.getContents(this); 164 assertTrue ("String flavor is there", t.isDataFlavorSupported(DataFlavor.stringFlavor)); 165 166 String s = (String )t.getTransferData(DataFlavor.stringFlavor); 167 assertEquals ("The getContents rechecked the system clipboard first time after window activated", "data2", s); 168 169 sc.setContents (ss, ss); 170 171 t = this.ec.getContents(this); 172 s = (String )t.getTransferData(DataFlavor.stringFlavor); 173 if (slowClipboardHack ()) { 174 assertEquals ("The getContents rechecked the clipboard just for the first time, not now, so the content is the same", "data2", s); 175 176 ec.activateWindowHack (true); 177 Thread.sleep (200); 178 179 t = this.ec.getContents(this); 180 s = (String )t.getTransferData(DataFlavor.stringFlavor); 181 assertEquals ("The WINDOW_ACTIVATED rechecks the clipboard", "oldvalue", s); 182 } else { 183 assertEquals ("without slow hack it gets the value immediatelly", "oldvalue", s); 184 } 185 } 186 187 public void testClipboard() throws Exception { 188 MockServices.setServices(Cnv.class); 189 Clipboard c = Lookup.getDefault().lookup(Clipboard .class); 190 ExClipboard ec = Lookup.getDefault().lookup(ExClipboard.class); 191 assertEquals("Clipboard == ExClipboard", c, ec); 192 assertNotNull(Lookup.getDefault().lookup(ExClipboard.Convertor.class)); 193 assertEquals(Cnv.class, Lookup.getDefault().lookup(ExClipboard.Convertor.class).getClass()); 194 c.setContents(new ExTransferable.Single(DataFlavor.stringFlavor) { 195 protected Object getData() throws IOException , UnsupportedFlavorException { 196 return "17"; 197 } 198 }, null); 199 Transferable t = c.getContents(null); 200 assertTrue("still supports stringFlavor", t.isDataFlavorSupported(DataFlavor.stringFlavor)); 201 assertEquals("correct string in clipboard", "17", t.getTransferData(DataFlavor.stringFlavor)); 202 assertTrue("support Integer too", t.isDataFlavorSupported(MYFLAV)); 203 assertEquals("correct Integer", new Integer (17), t.getTransferData(MYFLAV)); 204 } 205 206 private static final DataFlavor MYFLAV = new DataFlavor ("text/x-integer", "Integer"); public static final class Cnv implements ExClipboard.Convertor { 208 public Transferable convert(Transferable t) { 209 Logger.getAnonymousLogger().info("converting..."); 210 if (t.isDataFlavorSupported(DataFlavor.stringFlavor)) { 211 final ExTransferable t2 = ExTransferable.create(t); 212 if (t2.isDataFlavorSupported(DataFlavor.stringFlavor) && !t2.isDataFlavorSupported(MYFLAV)) { 213 t2.put(new ExTransferable.Single(MYFLAV) { 214 protected Object getData() throws IOException , UnsupportedFlavorException { 215 String s = (String )t2.getTransferData(DataFlavor.stringFlavor); 216 try { 217 return new Integer (s); 218 } catch (NumberFormatException nfe) { 219 throw new IOException (nfe.toString()); 220 } 221 } 222 }); 223 } 224 return t2; 225 } else { 226 return t; 227 } 228 } 229 } 230 231 232 public void testOwnershipLostEvent() throws Exception { 234 final int[] holder = new int[] { 0 }; 235 ExTransferable transferable = ExTransferable.create (new StringSelection ("A")); 236 237 transferable.addTransferListener (new TransferListener () { 239 public void accepted (int action) {} 240 public void rejected () {} 241 public void ownershipLost () { holder[0]++; } 242 }); 243 244 Clipboard c = Lookup.getDefault().lookup(Clipboard .class); 245 246 c.setContents(transferable, null); 247 248 assertTrue("Still has ownership", holder[0] == 0); 249 250 c.setContents(new StringSelection ("B"), null); 251 252 assertTrue("Exactly one ownershipLost event have happened.", holder[0] == 1); 253 } 254 255 public void clipboardChanged(ClipboardEvent ev) { 256 listenerCalls++; 257 LOG.log(Level.INFO, "clipboardChanged: " + listenerCalls, new Exception ()); 258 } 259 260 private void waitFinished(NbClipboard ec) { 261 try { 262 ec.waitFinished(); 263 SwingUtilities.invokeAndWait(new Runnable () { 264 public void run() { 265 } 266 }); 267 ec.waitFinished(); 268 SwingUtilities.invokeAndWait(new Runnable () { 269 public void run() { 270 } 271 }); 272 } catch (InterruptedException ex) { 273 throw new AssertionFailedErrorException(ex); 274 } catch (InvocationTargetException ex) { 275 throw new AssertionFailedErrorException(ex); 276 } 277 } 278 279 protected Level logLevel() { 280 return Level.ALL; 281 } 282 283 } 284 | Popular Tags |