1 19 20 21 package org.openide.text; 22 23 import java.io.IOException ; 24 import java.util.Collections ; 25 import java.util.HashSet ; 26 import java.util.Set ; 27 import org.netbeans.junit.NbTestCase; 28 import org.openide.actions.CopyAction; 29 import org.openide.actions.CutAction; 30 import org.openide.actions.DeleteAction; 31 import org.openide.actions.FileSystemAction; 32 import org.openide.actions.OpenAction; 33 import org.openide.actions.PasteAction; 34 import org.openide.actions.PropertiesAction; 35 import org.openide.actions.RenameAction; 36 import org.openide.actions.SaveAsTemplateAction; 37 import org.openide.actions.ToolsAction; 38 import org.openide.cookies.CloseCookie; 39 import org.openide.cookies.EditCookie; 40 import org.openide.cookies.EditorCookie; 41 import org.openide.cookies.OpenCookie; 42 import org.openide.cookies.PrintCookie; 43 import org.openide.cookies.SaveCookie; 44 import org.openide.filesystems.FileLock; 45 import org.openide.filesystems.FileObject; 46 import org.openide.filesystems.FileStateInvalidException; 47 import org.openide.filesystems.FileSystem; 48 import org.openide.filesystems.Repository; 49 import org.openide.loaders.DataFolder; 50 import org.openide.loaders.DataNode; 51 import org.openide.loaders.DataObject; 52 import org.openide.loaders.DataObjectExistsException; 53 import org.openide.loaders.ExtensionList; 54 import org.openide.loaders.MultiDataObject; 55 import org.openide.loaders.MultiFileLoader; 56 import org.openide.loaders.UniFileLoader; 57 import org.openide.nodes.Children; 58 import org.openide.nodes.CookieSet; 59 import org.openide.nodes.Node; 60 import org.openide.util.HelpCtx; 61 import org.openide.util.Lookup; 62 import org.openide.util.LookupListener; 63 import org.openide.util.NbBundle; 64 import org.openide.util.actions.SystemAction; 65 import org.openide.windows.CloneableOpenSupport; 66 67 public class AnnotationProviderTest extends NbTestCase { 68 69 public AnnotationProviderTest(String s) { 70 super(s); 71 } 72 73 private FileSystem fs; 74 75 protected void setUp() throws Exception { 76 System.setProperty("org.openide.util.Lookup", "org.openide.text.AnnotationProviderTest$Lkp"); 77 78 clearWorkDir (); 79 org.openide.filesystems.LocalFileSystem lfs = new org.openide.filesystems.LocalFileSystem (); 80 lfs.setRootDirectory (getWorkDir ()); 81 fs = lfs; 82 } 83 84 public void testAnnotationProviderIsCalledCorrectly() throws Exception { 85 Object o = Lookup.getDefault().lookup(AnnotationProvider.class); 86 if(o == null) { 87 fail("No annotation provider found"); 88 } 89 90 FileObject fo = fs.getRoot().createData("test", "txt"); 91 92 DataObject data = DataObject.find(fo); 93 94 EditorCookie ec = (EditorCookie)data.getCookie(EditorCookie.class); 95 96 ConsistencyCheckProvider.called = 0; 97 ec.open(); 98 99 CloneableEditorSupport ces = (CloneableEditorSupport)ec; 100 101 assertEquals("Provider called exactly once", 1, ConsistencyCheckProvider.called); 102 assertEquals("Consistent lookup content", data.getPrimaryFile(), ConsistencyCheckProvider.inLkp); 103 104 Line l1 = ces.getLineSet().getCurrent(0); 105 assertEquals("Exactly one annotation attached", 1, l1.getAnnotationCount()); 106 107 ec.close(); 108 Line l2 = ces.getLineSet().getCurrent(0); 110 assertEquals ("Lines are the same", l1, l2); 111 assertEquals("Exactly one annotation attached after close", 1, l2.getAnnotationCount()); 112 113 ConsistencyCheckProvider.called = 0; 114 ec.open(); 115 assertEquals("Provider not called during reopen", 0, ConsistencyCheckProvider.called); 117 assertEquals("Exactly one annotation attached after reopen", 1, ces.getLineSet().getCurrent(0).getAnnotationCount()); 118 } 119 120 public void testContextLookupIsConsistentAfterMove() throws Exception { 121 FileObject fo = fs.getRoot().createData("test2", "txt"); 123 DataObject data = DataObject.find(fo); 124 EditorCookie ec = (EditorCookie)data.getCookie(EditorCookie.class); 125 126 FileObject fld = fs.getRoot().createFolder("folder1"); 128 DataFolder df = DataFolder.findFolder(fld); 129 data.move(df); 130 131 ec.open(); 134 assertEquals("Consistent lookup content", data.getPrimaryFile(), ConsistencyCheckProvider.inLkp); 135 } 136 137 private void forceGC () { 138 for (int i = 0; i < 5; i++) { 139 System.gc (); 140 } 141 } 142 143 public void testContextLookupFiresDuringMove() throws Exception { 144 FileObject fo = fs.getRoot().createData("test3", "txt"); 146 DataObject data = DataObject.find(fo); 147 EditorCookie ec = (EditorCookie)data.getCookie(EditorCookie.class); 148 149 ec.open(); 151 assertEquals("Lookup content consistent before move", data.getPrimaryFile(), ConsistencyCheckProvider.inLkp); 152 153 forceGC (); 154 155 ConsistencyCheckProvider.called = 0; 157 FileObject fld = fs.getRoot().createFolder("folder1"); 158 DataFolder df = DataFolder.findFolder(fld); 159 data.move(df); 160 161 forceGC (); 162 163 assertEquals("Lookup fires one change during move", 1, ConsistencyCheckProvider.changes); 165 assertEquals("Lookup content consistent after move", data.getPrimaryFile(), ConsistencyCheckProvider.inLkp); 166 } 167 168 public static class ConsistencyCheckProvider implements AnnotationProvider, LookupListener { 169 170 private static Set myLines = new HashSet (); 171 private static int called; 172 private static FileObject inLkp; 173 private Lookup.Result result; 174 private static int changes; 175 176 public void annotate(org.openide.text.Line.Set set, org.openide.util.Lookup context) { 177 result = context.lookupResult(FileObject.class); 178 result.addLookupListener(this); 179 inLkp= (FileObject)result.allInstances().iterator().next(); 180 called++; 181 182 Line act = set.getCurrent(0); 183 184 myLines.add(act); 185 act.addAnnotation(new MyAnnotation()); 186 187 } 188 189 public void resultChanged(org.openide.util.LookupEvent ev) { 190 changes++; 191 inLkp= (FileObject)result.allInstances().iterator().next(); 192 } 193 194 } 195 196 197 199 private static class MyAnnotation extends Annotation { 200 201 public String getAnnotationType() { 202 return "nowhere"; 203 } 204 205 public String getShortDescription() { 206 return "Test annotation"; 207 } 208 209 } 210 211 protected boolean runInEQ() { 212 return true; 213 } 214 215 219 220 public static final class TXTDataLoader extends UniFileLoader { 221 222 223 static final long serialVersionUID =-3658061894653334886L; 224 225 226 static final String ATTR_IS_TEXT_FILE = "org.netbeans.modules.text.IsTextFile"; 228 229 230 public TXTDataLoader() { 231 super("org.netbeans.modules.text.TXTDataObject"); } 233 234 235 protected void initialize () { 236 super.initialize(); 237 238 ExtensionList ext = new ExtensionList(); 239 ext.addExtension("txt"); ext.addExtension("doc"); ext.addExtension("me"); ext.addExtension("policy"); ext.addExtension("mf"); ext.addExtension("MF"); ext.addExtension("log"); setExtensions(ext); 247 } 248 249 250 protected String defaultDisplayName() { 251 return NbBundle.getBundle(TXTDataLoader.class).getString("PROP_TXTLoader_Name"); 252 } 253 254 255 protected SystemAction[] defaultActions() { 256 return new SystemAction[] { 257 SystemAction.get(OpenAction.class), 258 SystemAction.get (FileSystemAction.class), 259 null, 260 SystemAction.get(CutAction.class), 261 SystemAction.get(CopyAction.class), 262 SystemAction.get(PasteAction.class), 263 null, 264 SystemAction.get(DeleteAction.class), 265 SystemAction.get(RenameAction.class), 266 null, 267 SystemAction.get(SaveAsTemplateAction.class), 268 null, 269 SystemAction.get(ToolsAction.class), 270 SystemAction.get(PropertiesAction.class), 271 }; 272 } 273 274 276 protected FileObject findPrimaryFile (FileObject fo) { 277 boolean isSysFile; 278 try { 279 isSysFile = fo.getFileSystem () == Repository.getDefault ().getDefaultFileSystem (); 280 } catch (FileStateInvalidException fsie) { 281 isSysFile = false; 283 } 284 if (! isSysFile && Boolean.TRUE.equals (fo.getAttribute (ATTR_IS_TEXT_FILE))) 285 return fo; 286 return super.findPrimaryFile (fo); 287 } 288 289 293 protected MultiDataObject createMultiObject(final FileObject fo) 294 throws IOException { 295 return new TXTDataObject(fo, this); 296 } 297 298 } 300 301 public static final class TXTDataObject extends MultiDataObject implements CookieSet.Factory { 302 303 304 static final long serialVersionUID = 4795737295255253334L; 305 306 307 private transient TXTEditorSupport editorSupport; 308 309 310 311 public TXTDataObject(final FileObject obj, final MultiFileLoader loader) throws DataObjectExistsException { 312 super(obj, loader); 313 314 getCookieSet().add(TXTEditorSupport.class, this); 315 } 316 317 318 319 public Node.Cookie createCookie(Class clazz) { 320 if(clazz.isAssignableFrom(TXTEditorSupport.class)) 321 return getEditorSupport(); 322 else 323 return null; 324 } 325 326 CookieSet getCookieSet0() { 328 return getCookieSet(); 329 } 330 331 332 private TXTEditorSupport getEditorSupport() { 333 if(editorSupport == null) { 334 synchronized(this) { 335 if(editorSupport == null) 336 editorSupport = new TXTEditorSupport(this); 337 } 338 } 339 340 return editorSupport; 341 } 342 343 352 protected Node createNodeDelegate () { 353 return new TXTNode(this); 354 } 355 356 359 public HelpCtx getHelpCtx () { 360 return new HelpCtx (TXTDataObject.class); 361 } 362 363 364 368 public static final class TXTNode extends DataNode { 369 370 private static final String TXT_ICON_BASE = "org/netbeans/modules/text/txtObject"; 372 373 public TXTNode (final DataObject dataObject) { 374 super(dataObject, Children.LEAF); 375 setIconBase(TXT_ICON_BASE); 376 } 377 378 379 public SystemAction getDefaultAction () { 380 SystemAction result = super.getDefaultAction(); 381 return result == null ? SystemAction.get(OpenAction.class) : result; 382 } 383 } 385 } 387 388 public static final class TXTEditorSupport extends DataEditorSupport 389 implements OpenCookie, EditCookie, EditorCookie.Observable, PrintCookie, CloseCookie { 390 391 393 private final SaveCookie saveCookie = new SaveCookie() { 394 395 public void save() throws IOException { 396 TXTEditorSupport.this.saveDocument(); 397 TXTEditorSupport.this.getDataObject().setModified(false); 398 } 399 }; 400 401 402 403 TXTEditorSupport(TXTDataObject obj) { 404 super(obj, new Environment(obj)); 405 406 setMIMEType("text/plain"); } 408 409 414 protected boolean notifyModified () { 415 if (!super.notifyModified()) 416 return false; 417 418 addSaveCookie(); 419 420 return true; 421 } 422 423 424 protected void notifyUnmodified () { 425 super.notifyUnmodified(); 426 427 removeSaveCookie(); 428 } 429 430 431 private void addSaveCookie() { 432 TXTDataObject obj = (TXTDataObject)getDataObject(); 433 434 if(obj.getCookie(SaveCookie.class) == null) { 436 obj.getCookieSet0().add(saveCookie); 437 obj.setModified(true); 438 } 439 } 440 441 442 private void removeSaveCookie() { 443 TXTDataObject obj = (TXTDataObject)getDataObject(); 444 445 Node.Cookie cookie = obj.getCookie(SaveCookie.class); 447 448 if(cookie != null && cookie.equals(saveCookie)) { 449 obj.getCookieSet0().remove(saveCookie); 450 obj.setModified(false); 451 } 452 } 453 454 455 458 459 private static class Environment extends DataEditorSupport.Env 460 { 461 private static final long serialVersionUID = 3499855082262173256L; 462 463 464 public Environment(TXTDataObject obj) { 465 super(obj); 466 } 467 468 469 470 protected FileObject getFile() { 471 return getDataObject().getPrimaryFile(); 472 } 473 474 475 protected FileLock takeLock() throws IOException { 476 return ((TXTDataObject)getDataObject()).getPrimaryEntry().takeLock(); 477 } 478 479 483 public CloneableOpenSupport findCloneableOpenSupport() { 484 return (TXTEditorSupport)getDataObject().getCookie(TXTEditorSupport.class); 485 } 486 } 488 } 490 491 private static class MyPool extends org.openide.loaders.DataLoaderPool { 492 protected java.util.Enumeration loaders() { 493 return Collections.enumeration(Collections.singleton( 494 TXTDataLoader.getLoader(TXTDataLoader.class) 495 )); 496 } 497 498 } 499 500 public static class Lkp extends org.openide.util.lookup.AbstractLookup { 501 public Lkp () { 502 this (new org.openide.util.lookup.InstanceContent ()); 503 } 504 505 private Lkp (org.openide.util.lookup.InstanceContent ic) { 506 super (ic); 507 508 ic.add (new MyPool ()); 509 ic.add (new ConsistencyCheckProvider ()); 510 } 511 } 512 } 513 | Popular Tags |