1 19 20 package org.openide.loaders; 21 import java.lang.reflect.InvocationTargetException ; 22 import java.util.HashSet ; 23 import org.openide.NotifyDescriptor; 24 import org.openide.cookies.EditorCookie; 25 import org.openide.filesystems.*; 26 import org.openide.nodes.Node; 27 import org.openide.text.DataEditorSupport; 28 import org.openide.util.Lookup; 29 import java.io.IOException ; 30 import java.util.Arrays ; 31 import javax.swing.text.Document ; 32 import org.netbeans.junit.*; 33 import org.openide.cookies.OpenCookie; 34 35 38 public class Deadlock60917Test extends NbTestCase { 39 40 public Deadlock60917Test(String name) { 41 super(name); 42 } 43 44 45 protected void setUp() throws Exception { 46 System.setProperty("org.openide.util.Lookup", Deadlock60917Test.class.getName() + "$Lkp"); 47 48 super.setUp(); 49 50 Lookup l = Lookup.getDefault(); 51 if (!(l instanceof Lkp)) { 52 fail("Wrong lookup: " + l); 53 } 54 55 clearWorkDir(); 56 } 57 58 59 60 public void testWhatHappensWhenALoaderBecomesInvalidAndFileIsOpened() throws Exception { 61 final ForgetableLoader l = (ForgetableLoader)DataLoader.getLoader(ForgetableLoader.class); 62 FileSystem lfs = TestUtilHid.createLocalFileSystem(getWorkDir(), new String [] { 63 "folder/f.keep", 64 "folder/f.forget", 65 }); 66 67 FileObject fo = lfs.findResource("folder"); 68 final DataFolder f = DataFolder.findFolder(fo); 69 70 FileObject primary = lfs.findResource("folder/f.keep"); 71 72 final DataObject our = DataObject.find(primary); 73 assertEquals("The right loader", l, our.getLoader()); 74 75 OpenCookie oc = (OpenCookie)our.getCookie(OpenCookie.class); 76 oc.open(); 77 waitEQ(); 78 79 EditorCookie ec = (EditorCookie)our.getCookie(EditorCookie.class); 80 assertNotNull("We have ec", ec); 81 82 Document d = ec.openDocument(); 83 assertNotNull("There is a document", d); 84 85 d.insertString(0, "Ahoj", null); 86 87 assertTrue("Nows the doc is modified", ec.isModified()); 88 assertTrue("DO is modified", our.isModified()); 89 90 class BlockAWT implements Runnable { 91 DataObject[] arr; 92 93 public void run () { 94 synchronized (this) { 95 try { 96 97 wait(1000); 98 } catch (InterruptedException ex) { 99 ex.printStackTrace(); 100 } 101 } 102 arr = f.getChildren(); 103 } 104 } 105 final BlockAWT awt = new BlockAWT(); 106 107 class AddAndRemoveAFile implements FileSystem.AtomicAction { 108 DataObject[] all; 109 110 public void run () throws IOException { 111 javax.swing.SwingUtilities.invokeLater(awt); 112 113 FileObject[] two = (FileObject[])our.files().toArray(new FileObject[0]); 114 assertEquals("Two", 2, two.length); 115 116 two[1].delete(); 120 121 122 l.filesInside = new HashSet (); 123 all = f.getChildren(); 124 if (!l.filesInside.contains(two[0])) { 125 fail("We should query our secondary file: " + l.filesInside); 126 } 127 128 waitEQ(); 129 assertNotNull("Children computed", awt.arr); 130 } 131 } 132 133 AddAndRemoveAFile addRemove = new AddAndRemoveAFile(); 134 f.getPrimaryFile().getFileSystem().runAtomicAction(addRemove); 135 136 DataObject[] all = f.getChildren(); 137 138 assertNotNull("Children computed", awt.arr); 139 assertEquals("Three of them: " + Arrays.asList(awt.arr), 1, awt.arr.length); 140 assertEquals("Still remains the same old object: ", our, awt.arr[0]); 141 } 142 143 public void testWhatHappenUnderLock () throws Exception { 144 org.openide.nodes.Children.MUTEX.readAccess (new org.openide.util.Mutex.ExceptionAction () { 145 public Object run () throws Exception { 146 testWhatHappensWhenALoaderBecomesInvalidAndFileIsOpened(); 147 return null; 148 } 149 }); 150 } 151 152 public static final class ForgetableLoader extends MultiFileLoader { 153 154 HashSet filesInside; 155 156 public ForgetableLoader () { 157 super(MultiDataObject.class); 158 } 159 protected String displayName() { 160 return "ForgetableLoader"; 161 } 162 164 protected FileObject findPrimaryFile(FileObject fo) { 165 if (filesInside != null) { 166 filesInside.add(fo); 169 } else { 170 assertFalse("We cannot be queried from recognizer thread: ", FolderList.isFolderRecognizerThread()); 171 } 172 173 FileObject forget = FileUtil.findBrother(fo, "forget"); 174 FileObject keep = FileUtil.findBrother(fo, "keep"); 175 if (keep == null || forget == null) { 176 return null; 177 } 178 return fo == keep || fo == forget ? keep : null; 179 } 180 protected MultiDataObject createMultiObject(FileObject primaryFile) throws DataObjectExistsException, IOException { 181 MultiDataObject m = new MultiDataObject (primaryFile, this); 182 m.getCookieSet().add((Node.Cookie)DataEditorSupport.create(m, m.getPrimaryEntry(), m.getCookieSet())); 183 return m; 184 } 185 protected MultiDataObject.Entry createPrimaryEntry(MultiDataObject obj, FileObject primaryFile) { 186 return new FileEntry (obj, primaryFile); 187 } 188 protected MultiDataObject.Entry createSecondaryEntry(MultiDataObject obj, FileObject secondaryFile) { 189 return new FileEntry(obj, secondaryFile); 190 } 191 } 192 193 private static void waitEQ() { 194 if (javax.swing.SwingUtilities.isEventDispatchThread()) { 195 return; 196 } 197 198 try { 199 200 javax.swing.SwingUtilities.invokeAndWait(new Runnable () { 201 public void run() { } 202 }); 203 return; 204 } catch (InvocationTargetException ex) { 205 ex.printStackTrace(); 206 } catch (InterruptedException ex) { 207 ex.printStackTrace(); 208 } 209 fail("An exception happened"); 210 } 211 212 public static final class Lkp extends org.openide.util.lookup.AbstractLookup { 213 public Lkp() { 214 this(new org.openide.util.lookup.InstanceContent()); 215 } 216 217 private Lkp(org.openide.util.lookup.InstanceContent ic) { 218 super(ic); 219 ic.add(new Pool ()); 220 ic.add(new DD()); 221 } 222 } 223 224 private static final class Pool extends DataLoaderPool { 225 226 protected java.util.Enumeration loaders () { 227 DataLoader extra = DataLoader.getLoader(ForgetableLoader.class); 228 return org.openide.util.Enumerations.singleton (extra); 229 } 230 } 231 233 private static final class DD extends org.openide.DialogDisplayer { 234 public static Object [] options; 235 236 public java.awt.Dialog createDialog(org.openide.DialogDescriptor descriptor) { 237 throw new IllegalStateException ("Not implemented"); 238 } 239 240 public Object notify(org.openide.NotifyDescriptor descriptor) { 241 options = descriptor.getOptions(); 242 try { 243 waitEQ(); 245 } catch (Exception ex) { 246 ex.printStackTrace(); 247 } 248 249 assertNull (options); 250 return NotifyDescriptor.CLOSED_OPTION; 251 } 252 253 } 255 } 256 | Popular Tags |