1 19 20 package org.netbeans.modules.apisupport.project.layers; 21 import java.io.File ; 22 import java.io.IOException ; 23 import java.net.URL ; 24 import java.util.Arrays ; 25 import java.util.Collections ; 26 import java.util.HashMap ; 27 import java.util.HashSet ; 28 import java.util.Iterator ; 29 import java.util.Map ; 30 import java.util.Set ; 31 import org.netbeans.modules.apisupport.project.TestBase; 32 import org.openide.filesystems.FileAttributeEvent; 33 import org.openide.filesystems.FileChangeListener; 34 import org.openide.filesystems.FileEvent; 35 import org.openide.filesystems.FileLock; 36 import org.openide.filesystems.FileObject; 37 import org.openide.filesystems.FileRenameEvent; 38 import org.openide.filesystems.FileSystem; 39 import org.openide.filesystems.FileUtil; 40 import org.openide.filesystems.MultiFileSystem; 41 import org.openide.loaders.DataFolder; 42 import org.openide.loaders.DataObject; 43 44 48 public class WritableXMLFileSystemTest extends LayerTestBase { 49 50 public WritableXMLFileSystemTest(String name) { 51 super(name); 52 } 53 54 public void testBasicStructureReads() throws Exception { 55 FileSystem fs = new Layer("<file name='x'/>").read(); 56 FileObject[] top = fs.getRoot().getChildren(); 57 assertEquals(1, top.length); 58 FileObject x = top[0]; 59 assertEquals("x", x.getNameExt()); 60 assertEquals(0L, x.getSize()); 61 assertTrue(x.isData()); 62 fs = new Layer("<folder name='x'><file name='y'/></folder><file name='z'/>").read(); 63 top = fs.getRoot().getChildren(); 64 assertEquals(2, top.length); 65 FileObject z = fs.findResource("z"); 66 assertNotNull(z); 67 assertTrue(z.isData()); 68 FileObject y = fs.findResource("x/y"); 69 assertNotNull(y); 70 assertTrue(y.isData()); 71 x = fs.findResource("x"); 72 assertEquals(x, y.getParent()); 73 assertTrue(x.isFolder()); 74 assertEquals(1, x.getChildren().length); 75 } 76 77 public void testExternalFileReads() throws Exception { 78 FileSystem fs = new Layer("<file name='x' url='x.txt'/>", Collections.singletonMap("x.txt", "stuff")).read(); 79 FileObject x = fs.findResource("x"); 80 assertNotNull(x); 81 assertTrue(x.isData()); 82 assertEquals(5L, x.getSize()); 83 assertEquals("stuff", TestBase.slurp(x)); 84 fs = new Layer("<file name='x' url='subdir/x.txt'/>", Collections.singletonMap("subdir/x.txt", "more stuff")).read(); 85 x = fs.findResource("x"); 86 assertNotNull(x); 87 assertEquals("more stuff", TestBase.slurp(x)); 88 } 90 91 public void testSimpleAttributeReads() throws Exception { 92 FileSystem fs = new Layer("<file name='x'><attr name='a' stringvalue='v'/> <attr name='b' urlvalue='file:/nothing'/></file> " + 93 "<folder name='y'> <file name='ignore'/><attr name='a' boolvalue='true'/><!--ignore--></folder>").read(); 94 FileObject x = fs.findResource("x"); 95 assertEquals(new HashSet (Arrays.asList(new String [] {"a", "b"})), new HashSet (Collections.list(x.getAttributes()))); 96 assertEquals("v", x.getAttribute("a")); 97 assertEquals(new URL ("file:/nothing"), x.getAttribute("b")); 98 assertEquals(null, x.getAttribute("dummy")); 99 FileObject y = fs.findResource("y"); 100 assertEquals(Collections.singletonList("a"), Collections.list(y.getAttributes())); 101 assertEquals(Boolean.TRUE, y.getAttribute("a")); 102 fs = new Layer("<attr name='a' stringvalue='This \\u0007 is a beep!'/>").read(); 103 assertEquals("Unicode escapes handled correctly (for non-XML-encodable chars)", "This \u0007 is a beep!", fs.getRoot().getAttribute("a")); 104 fs = new Layer("<attr name='a' stringvalue='\\ - \\u - \\u123 - \\uxyzw'/>").read(); 105 assertEquals("Malformed escapes also handled", "\\ - \\u - \\u123 - \\uxyzw", fs.getRoot().getAttribute("a")); 106 fs = new Layer("<attr name='a' urlvalue='yadayada'/>").read(); 107 assertEquals("Malformed URLs also handled", null, fs.getRoot().getAttribute("a")); 108 } 110 111 public void testCodeAttributeReads() throws Exception { 112 FileSystem fs = new Layer("<file name='x'><attr name='a' stringvalue='v'/><attr name='b' newvalue='some.Class'/> " + 113 "<attr name='c' methodvalue='some.Class.m'/></file>").read(); 114 FileObject x = fs.findResource("x"); 115 assertEquals("v", x.getAttribute("literal:a")); 116 assertEquals("new:some.Class", x.getAttribute("literal:b")); 117 assertEquals("method:some.Class.m", x.getAttribute("literal:c")); 118 } 121 122 public void testCreateNewFolder() throws Exception { 123 Layer l = new Layer(""); 124 FileSystem fs = l.read(); 125 FileObject x = fs.getRoot().createFolder("x"); 126 assertEquals("in-memory write worked", 1, fs.getRoot().getChildren().length); 127 assertEquals("wrote correct content for top-level folder", " <folder name=\"x\"/>\n", l.write()); 128 x.createFolder("y"); 129 assertEquals("wrote correct content for 2nd-level folder", " <folder name=\"x\">\n <folder name=\"y\"/>\n </folder>\n", l.write()); 130 l = new Layer(" <folder name=\"original\"/>\n"); 131 fs = l.read(); 132 fs.getRoot().createFolder("aardvark"); 133 fs.getRoot().createFolder("xyzzy"); 134 assertEquals("alphabetized new folders", " <folder name=\"aardvark\"/>\n <folder name=\"original\"/>\n <folder name=\"xyzzy\"/>\n", l.write()); 135 } 136 137 public void testCreateNewEmptyFile() throws Exception { 138 Layer l = new Layer(""); 139 FileSystem fs = l.read(); 140 FileUtil.createData(fs.getRoot(), "Menu/Tools/foo"); 141 FileUtil.createData(fs.getRoot(), "Menu/Tools/bar"); 142 FileUtil.createFolder(fs.getRoot(), "Menu/Tools/baz"); 143 assertEquals("correct files written", 144 " <folder name=\"Menu\">\n" + 145 " <folder name=\"Tools\">\n" + 146 " <file name=\"bar\"/>\n" + 147 " <folder name=\"baz\"/>\n" + 148 " <file name=\"foo\"/>\n" + 149 " </folder>\n" + 150 " </folder>\n", 151 l.write()); 152 assertEquals("no external files created", Collections.EMPTY_MAP, l.files()); 153 } 154 155 public void testCreateFileWithContents() throws Exception { 156 Layer l = new Layer(""); 157 FileSystem fs = l.read(); 158 FileObject f = FileUtil.createData(fs.getRoot(), "Templates/Other/Foo.java"); 159 f.setAttribute("hello", "there"); 160 TestBase.dump(f, "some stuff"); 161 String xml = 162 " <folder name=\"Templates\">\n" + 163 " <folder name=\"Other\">\n" + 164 " <file name=\"Foo.java\" url=\"Foo_java\">\n" + 166 " <attr name=\"hello\" stringvalue=\"there\"/>\n" + 167 " </file>\n" + 168 " </folder>\n" + 169 " </folder>\n"; 170 assertEquals("correct XML written", xml, l.write()); 171 Map m = new HashMap (); 172 m.put("Foo_java", "some stuff"); 173 assertEquals("one external file created in " + l, m, l.files()); 174 TestBase.dump(f, "new stuff"); 175 assertEquals("same XML as before", xml, l.write()); 176 m.put("Foo_java", "new stuff"); 177 assertEquals("different external file", m, l.files()); 178 f = FileUtil.createData(fs.getRoot(), "Templates/Other2/Foo.java"); 179 TestBase.dump(f, "unrelated stuff"); 180 f = FileUtil.createData(fs.getRoot(), "Templates/Other2/Bar.xml"); 181 TestBase.dump(f, "unrelated XML stuff"); 182 f = FileUtil.createData(fs.getRoot(), "Services/foo.settings"); 183 TestBase.dump(f, "scary stuff"); 184 xml = 185 " <folder name=\"Services\">\n" + 186 " <file name=\"foo.settings\" url=\"fooSettings.xml\"/>\n" + 188 " </folder>\n" + 189 " <folder name=\"Templates\">\n" + 190 " <folder name=\"Other\">\n" + 191 " <file name=\"Foo.java\" url=\"Foo_java\">\n" + 192 " <attr name=\"hello\" stringvalue=\"there\"/>\n" + 193 " </file>\n" + 194 " </folder>\n" + 195 " <folder name=\"Other2\">\n" + 196 " <file name=\"Bar.xml\" url=\"Bar.xml\"/>\n" + 198 " <file name=\"Foo.java\" url=\"Foo_1_java\"/>\n" + 199 " </folder>\n" + 200 " </folder>\n"; 201 assertEquals("right XML written for remaining files", xml, l.write()); 202 m.put("Foo_1_java", "unrelated stuff"); 203 m.put("Bar.xml", "unrelated XML stuff"); 204 m.put("fooSettings.xml", "scary stuff"); 205 assertEquals("right external files", m, l.files()); 206 l = new Layer("", Collections.singletonMap("file.txt", "existing stuff")); 207 fs = l.read(); 208 f = FileUtil.createData(fs.getRoot(), "wherever/file.txt"); 209 TestBase.dump(f, "unrelated stuff"); 210 xml = 211 " <folder name=\"wherever\">\n" + 212 " <file name=\"file.txt\" url=\"file_1.txt\"/>\n" + 215 " </folder>\n"; 216 assertEquals("wrote new file contents to non-clobbering location", xml, l.write()); 217 m.clear(); 218 m.put("file.txt", "existing stuff"); 219 m.put("file_1.txt", "unrelated stuff"); 220 assertEquals("right external files", m, l.files()); 221 l = new Layer(""); 222 fs = l.read(); 223 f = FileUtil.createData(fs.getRoot(), "one/bare"); 224 TestBase.dump(f, "bare #1"); 225 f = FileUtil.createData(fs.getRoot(), "two/bare"); 226 TestBase.dump(f, "bare #2"); 227 f = FileUtil.createData(fs.getRoot(), "three/bare"); 228 TestBase.dump(f, "bare #3"); 229 xml = 230 " <folder name=\"one\">\n" + 231 " <file name=\"bare\" url=\"bare\"/>\n" + 232 " </folder>\n" + 233 " <folder name=\"three\">\n" + 235 " <file name=\"bare\" url=\"bare_2\"/>\n" + 237 " </folder>\n" + 238 " <folder name=\"two\">\n" + 239 " <file name=\"bare\" url=\"bare_1\"/>\n" + 241 " </folder>\n"; 242 assertEquals("right counter usage", xml, l.write()); 243 m.clear(); 244 m.put("bare", "bare #1"); 245 m.put("bare_1", "bare #2"); 246 m.put("bare_2", "bare #3"); 247 assertEquals("right external files", m, l.files()); 248 } 249 251 public void testAddAttributes() throws Exception { 252 Layer l = new Layer(""); 253 FileSystem fs = l.read(); 254 FileObject f = fs.getRoot().createFolder("f"); 255 f.createData("b"); 256 FileObject a = f.createData("a"); 257 f.createData("c"); 258 a.setAttribute("x", "v1"); 259 a.setAttribute("y", new URL ("file:/v2")); 260 f.setAttribute("a/b", Boolean.TRUE); 261 f.setAttribute("b/c", Boolean.TRUE); 262 f.setAttribute("misc", "whatever"); 263 assertEquals("correct attrs written", 264 " <folder name=\"f\">\n" + 265 " <attr name=\"misc\" stringvalue=\"whatever\"/>\n" + 266 " <file name=\"a\">\n" + 267 " <attr name=\"x\" stringvalue=\"v1\"/>\n" + 268 " <attr name=\"y\" urlvalue=\"file:/v2\"/>\n" + 269 " </file>\n" + 270 " <attr name=\"a/b\" boolvalue=\"true\"/>\n" + 271 " <file name=\"b\"/>\n" + 272 " <attr name=\"b/c\" boolvalue=\"true\"/>\n" + 273 " <file name=\"c\"/>\n" + 274 " </folder>\n", 275 l.write()); 276 } 278 279 public void testDeleteReplaceAttributes() throws Exception { 280 Layer l = new Layer( 281 " <file name=\"x\">\n" + 282 " <attr name=\"foo\" stringvalue=\"bar\"/>\n" + 283 " </file>\n"); 284 FileSystem fs = l.read(); 285 FileObject x = fs.findResource("x"); 286 x.setAttribute("foo", Boolean.TRUE); 287 assertEquals("replaced attr", 288 " <file name=\"x\">\n" + 289 " <attr name=\"foo\" boolvalue=\"true\"/>\n" + 290 " </file>\n", 291 l.write()); 292 x.setAttribute("foo", null); 293 assertEquals("deleted attr", 294 " <file name=\"x\"/>\n", 295 l.write()); 296 x.setAttribute("foo", null); 297 assertEquals("cannot delete attr twice", 298 " <file name=\"x\"/>\n", 299 l.write()); 300 309 } 310 311 public void testCodeAttributeWrites() throws Exception { 312 Layer l = new Layer(""); 313 FileSystem fs = l.read(); 314 FileObject x = fs.getRoot().createData("x"); 315 x.setAttribute("nv", "newvalue:org.foo.Clazz"); 316 x.setAttribute("mv", "methodvalue:org.foo.Clazz.create"); 317 assertEquals("special attrs written to XML", 318 " <file name=\"x\">\n" + 319 " <attr name=\"mv\" methodvalue=\"org.foo.Clazz.create\"/>\n" + 320 " <attr name=\"nv\" newvalue=\"org.foo.Clazz\"/>\n" + 321 " </file>\n", 322 l.write()); 323 } 324 325 public void testOpenideFolderOrder() throws Exception { 326 Layer l = new Layer(""); 327 FileSystem fs = l.read(); 328 FileObject r = fs.getRoot(); 329 FileObject a = r.createData("a"); 330 FileObject b = r.createData("b"); 331 FileObject f = r.createFolder("f"); 332 FileObject c = f.createData("c"); 333 FileObject d = f.createData("d"); 334 FileObject e = f.createData("e"); 335 DataFolder.findFolder(r).setOrder(new DataObject[] {DataObject.find(a), DataObject.find(b)}); 336 DataFolder.findFolder(f).setOrder(new DataObject[] {DataObject.find(c), DataObject.find(d), DataObject.find(e)}); 337 assertEquals("correct ordering XML", 338 " <file name=\"a\"/>\n" + 339 " <attr name=\"a/b\" boolvalue=\"true\"/>\n" + 340 " <file name=\"b\"/>\n" + 341 " <folder name=\"f\">\n" + 342 " <file name=\"c\"/>\n" + 343 " <attr name=\"c/d\" boolvalue=\"true\"/>\n" + 344 " <file name=\"d\"/>\n" + 345 " <attr name=\"d/e\" boolvalue=\"true\"/>\n" + 346 " <file name=\"e\"/>\n" + 347 " </folder>\n", 348 l.write()); 349 l = new Layer(""); 350 fs = l.read(); 351 r = fs.getRoot(); 352 b = r.createData("b"); 353 c = r.createFolder("c"); 354 r.setAttribute("c/b", Boolean.TRUE); 355 r.setAttribute("d/c", Boolean.TRUE); 356 r.setAttribute("b/a", Boolean.TRUE); 357 assertEquals("ordering attrs reorder entries in a folder", 358 " <attr name=\"d/c\" boolvalue=\"true\"/>\n" + 359 " <folder name=\"c\"/>\n" + 360 " <attr name=\"c/b\" boolvalue=\"true\"/>\n" + 361 " <file name=\"b\"/>\n" + 362 " <attr name=\"b/a\" boolvalue=\"true\"/>\n", 363 l.write()); 364 l = new Layer(""); 365 fs = l.read(); 366 r = fs.getRoot(); 367 FileObject main = r.createData("main"); 368 FileObject before = r.createData("s-before"); 369 r.setAttribute("pre/s-before", Boolean.TRUE); 370 r.setAttribute("s-before/main", Boolean.TRUE); 371 assertEquals( 372 " <attr name=\"pre/s-before\" boolvalue=\"true\"/>\n" + 373 " <file name=\"s-before\"/>\n" + 374 " <attr name=\"s-before/main\" boolvalue=\"true\"/>\n" + 375 " <file name=\"main\"/>\n", 376 l.write()); 377 l = new Layer(""); 379 fs = l.read(); 380 FileUtil.createData(fs.getRoot(), "f/two"); 381 FileSystem ro = FileUtil.createMemoryFileSystem(); 382 f = ro.getRoot().createFolder("f"); 383 f.createData("one"); 384 f.setAttribute("one/three", Boolean.TRUE); 385 f.createData("three"); 386 f.createData("four"); 387 f.setAttribute("three/four", Boolean.TRUE); 388 FileSystem merge = new MultiFileSystem(new FileSystem[] {fs, ro}); 389 DataObject one = DataObject.find(merge.findResource("f/one")); 390 DataObject two = DataObject.find(merge.findResource("f/two")); 391 DataObject three = DataObject.find(merge.findResource("f/three")); 392 DataObject four = DataObject.find(merge.findResource("f/four")); 393 DataFolder.findFolder(merge.findResource("f")).setOrder(new DataObject[] {one, two, three, four}); 394 assertEquals("correct insertion of new file into existing folder", 395 " <folder name=\"f\">\n" + 396 " <attr name=\"one/two\" boolvalue=\"true\"/>\n" + 397 " <file name=\"two\"/>\n" + 398 " <attr name=\"two/three\" boolvalue=\"true\"/>\n" + 399 " </folder>\n", 400 l.write()); 401 l = new Layer(""); 402 fs = l.read(); 403 FileUtil.createData(fs.getRoot(), "f/two"); 404 merge = new MultiFileSystem(new FileSystem[] {fs, ro}); 405 assertEquals(Boolean.TRUE, merge.findResource("f").getAttribute("one/three")); 406 one = DataObject.find(merge.findResource("f/one")); 407 two = DataObject.find(merge.findResource("f/two")); 408 three = DataObject.find(merge.findResource("f/three")); 409 four = DataObject.find(merge.findResource("f/four")); 410 DataFolder.findFolder(merge.findResource("f")).setOrder(new DataObject[] {four, three, two, one}); 411 assertEquals("correct insertion of new file into existing folder w/ override of old order", 412 " <folder name=\"f\">\n" + 413 " <attr name=\"three/two\" boolvalue=\"true\"/>\n" + 414 " <file name=\"two\"/>\n" + 415 " <attr name=\"two/one\" boolvalue=\"true\"/>\n" + 416 " <attr name=\"three/four\" boolvalue=\"false\"/>\n" + 418 " <attr name=\"one/three\" boolvalue=\"false\"/>\n" + 419 " </folder>\n", 420 l.write()); 421 } 423 424 public void testDeleteFileOrFolder() throws Exception { 425 Layer l = new Layer(""); 426 FileSystem fs = l.read(); 427 FileObject f = fs.getRoot().createFolder("f"); 428 FileObject x = f.createData("x"); 429 x.setAttribute("foo", "bar"); 430 TestBase.dump(x, "stuff"); 431 FileObject y = FileUtil.createData(fs.getRoot(), "y"); 432 x.delete(); 433 assertEquals("one file and one folder left", 434 " <folder name=\"f\"/>\n" + 435 " <file name=\"y\"/>\n", 436 l.write()); 437 assertEquals("no external files left", Collections.EMPTY_MAP, l.files()); 438 f.delete(); 439 assertEquals("one file left", 440 " <file name=\"y\"/>\n", 441 l.write()); 442 y.delete(); 443 assertEquals("layer now empty again", "", l.write()); 444 l = new Layer(""); 445 fs = l.read(); 446 f = fs.getRoot().createFolder("f"); 447 x = f.createData("x"); 448 TestBase.dump(x, "stuff"); 449 f.delete(); 450 assertEquals("layer empty again", "", l.write()); 451 assertEquals("no external files left even after only implicitly deleting file", Collections.EMPTY_MAP, l.files()); 452 l = new Layer(""); 454 fs = l.read(); 455 FileObject a = fs.getRoot().createData("a"); 456 FileObject b = fs.getRoot().createData("b"); 457 FileObject c = fs.getRoot().createData("c"); 458 FileObject d = fs.getRoot().createData("d"); 459 a.delete(); 460 assertEquals("right indentation cleanup for deletion of first child", 461 " <file name=\"b\"/>\n" + 462 " <file name=\"c\"/>\n" + 463 " <file name=\"d\"/>\n", 464 l.write()); 465 c.delete(); 466 assertEquals("right indentation cleanup for deletion of interior child", 467 " <file name=\"b\"/>\n" + 468 " <file name=\"d\"/>\n", 469 l.write()); 470 d.delete(); 471 assertEquals("right indentation cleanup for deletion of last child", 472 " <file name=\"b\"/>\n", 473 l.write()); 474 } 475 476 public void testRename() throws Exception { 477 Layer l = new Layer(" <folder name=\"folder1\">\n <file name=\"file1.txt\">\n <attr name=\"a\" stringvalue=\"v\"/>\n </file>\n </folder>\n"); 478 FileSystem fs = l.read(); 479 FileObject f = fs.findResource("folder1"); 480 assertNotNull(f); 481 FileLock lock = f.lock(); 482 f.rename(lock, "folder2", null); 483 lock.releaseLock(); 484 f = fs.findResource("folder2/file1.txt"); 485 assertNotNull(f); 486 lock = f.lock(); 487 f.rename(lock, "file2.txt", null); 488 lock.releaseLock(); 489 assertEquals("#63989: correct rename handling", " <folder name=\"folder2\">\n <file name=\"file2.txt\">\n <attr name=\"a\" stringvalue=\"v\"/>\n </file>\n </folder>\n", l.write()); 490 } 492 493 public void testSomeFormattingPreserved() throws Exception { 494 String orig = " <file name=\"orig\"><!-- hi --><attr name=\"a\" boolvalue=\"true\"/>" + 495 "<attr boolvalue=\"true\" name=\"b\"/></file>\n"; 496 Layer l = new Layer(orig); 497 FileSystem fs = l.read(); 498 fs.getRoot().createData("aardvark"); 499 fs.getRoot().createData("zyzzyva"); 500 assertEquals("kept original XML intact", 501 " <file name=\"aardvark\"/>\n" + 502 orig + 503 " <file name=\"zyzzyva\"/>\n", 504 l.write()); 505 } 510 511 public void testStructuralModificationsFired() throws Exception { 512 Layer l = new Layer("<folder name='f'/><file name='x'/>"); 513 FileSystem fs = l.read(); 514 Listener fcl = new Listener(); 515 fs.addFileChangeListener(fcl); 516 FileUtil.createData(fs.getRoot(), "a"); 517 FileUtil.createData(fs.getRoot(), "f/b"); 518 fs.findResource("x").delete(); 519 assertEquals("expected things fired", 520 new HashSet (Arrays.asList(new String [] {"a", "f/b", "x"})), 521 fcl.changes()); 522 } 523 524 public void testTextualModificationsFired() throws Exception { 525 Layer l = new Layer("<folder name='f'><file name='x'/></folder><file name='y'/>"); 526 FileSystem fs = l.read(); 527 Listener fcl = new Listener(); 528 fs.addFileChangeListener(fcl); 529 l.edit("<folder name='f'/><file name='y'/><file name='z'/>"); 530 Set changes = fcl.changes(); 531 537 assertTrue("something fired", !changes.isEmpty()); 538 assertNull(fs.findResource("f/x")); 539 assertNotNull(fs.findResource("z")); 540 l.edit("<folder name='f'><file name='x2'/></folder><file name='y'/><file name='z'/>"); 541 546 assertNotNull(fs.findResource("f/x2")); 547 assertNotNull(fs.findResource("z")); 548 } 549 550 public void testExternalFileChangesRefired() throws Exception { 551 Layer l = new Layer(""); 552 FileSystem fs = l.read(); 553 FileObject foo = fs.getRoot().createData("foo"); 554 TestBase.dump(foo, "foo text"); 555 long start = foo.lastModified().getTime(); 556 assertEquals(start, l.externalLastModified("foo")); 557 Thread.sleep(1000L); Listener fcl = new Listener(); 559 fs.addFileChangeListener(fcl); 560 l.editExternal("foo", "new text"); 561 long end = foo.lastModified().getTime(); 562 assertEquals(end, l.externalLastModified("foo")); 563 assertTrue("foo was touched", end > start); 564 assertEquals("expected things fired", 565 Collections.singleton("foo"), 566 fcl.changes()); 567 } 568 569 public void testHeapUsage() throws Exception { 570 Layer l = new Layer(""); 571 FileSystem fs = l.read(); 572 Object buffer = new byte[(int) (Runtime.getRuntime().freeMemory() * 2 / 3)]; 573 int count = 1000; 574 int bytesPerFile = 4000; for (int i = 0; i < count; i++) { 576 try { 577 fs.getRoot().createData("file" + i); 578 } catch (OutOfMemoryError e) { 579 fail("Ran out of heap on file #" + i); 580 } 581 } 582 assertSize("Filesystem not too big", count * bytesPerFile, l); 583 } 584 585 588 private final class Layer { 589 private final File folder; 590 private final FileObject f; 591 private LayerUtils.SavableTreeEditorCookie cookie; 592 598 public Layer(String xml) throws Exception { 599 folder = makeFolder(); 600 f = makeLayer(xml); 601 } 602 606 public Layer(String xml, Map files) throws Exception { 607 this(xml); 608 Iterator it = files.entrySet().iterator(); 609 while (it.hasNext()) { 610 Map.Entry entry = (Map.Entry ) it.next(); 611 String fname = (String ) entry.getKey(); 612 String contents = (String ) entry.getValue(); 613 File f = new File (folder, fname.replace('/', File.separatorChar)); 614 f.getParentFile().mkdirs(); 615 TestBase.dump(f, contents); 616 } 617 } 618 private File makeFolder() throws Exception { 619 File f = File.createTempFile("layerdata", "", getWorkDir()); 620 f.delete(); 621 f.mkdir(); 622 return f; 623 } 624 private final String HEADER = 625 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 626 "<!DOCTYPE filesystem PUBLIC \"-//NetBeans//DTD Filesystem 1.1//EN\" \"http://www.netbeans.org/dtds/filesystem-1_1.dtd\">\n" + 627 "<filesystem>\n"; 628 private final String FOOTER = "</filesystem>\n"; 629 private FileObject makeLayer(String xml) throws Exception { 630 File f = new File (folder, "layer.xml"); 631 TestBase.dump(f, HEADER + xml + FOOTER); 632 return FileUtil.toFileObject(f); 633 } 634 637 public WritableXMLFileSystem read() throws Exception { 638 cookie = LayerUtils.cookieForFile(f); 639 return new WritableXMLFileSystem(f.getURL(), cookie, null); 640 } 641 645 public String write() throws Exception { 646 cookie.save(); 647 String raw = TestBase.slurp(f); 648 assertTrue("unexpected header in '" + raw + "'", raw.startsWith(HEADER)); 649 assertTrue("unexpected footer in '" + raw + "'", raw.endsWith(FOOTER)); 650 return raw.substring(HEADER.length(), raw.length() - FOOTER.length()); 651 } 652 655 public void edit(String newText) throws Exception { 656 TestBase.dump(f, HEADER + newText + FOOTER); 657 } 658 661 public void editExternal(String path, String newText) throws Exception { 662 assert !path.equals("layer.xml"); 663 File f = new File (folder, path.replace('/', File.separatorChar)); 664 assert f.isFile(); 665 TestBase.dump(FileUtil.toFileObject(f), newText); 666 } 667 public long externalLastModified(String path) { 668 File f = new File (folder, path.replace('/', File.separatorChar)); 669 return FileUtil.toFileObject(f).lastModified().getTime(); 670 } 671 675 public Map files() throws IOException { 676 Map m = new HashMap (); 677 traverse(m, folder, ""); 678 return m; 679 } 680 private void traverse(Map m, File folder, String prefix) throws IOException { 681 String [] kids = folder.list(); 682 if (kids == null) { 683 throw new IOException (folder.toString()); 684 } 685 for (int i = 0; i < kids.length; i++) { 686 String path = prefix + kids[i]; 687 if (path.equals("layer.xml")) { 688 continue; 689 } 690 File f = new File (folder, kids[i]); 691 if (f.isDirectory()) { 692 traverse(m, f, prefix + kids[i] + '/'); 693 } else { 694 m.put(path, TestBase.slurp(f)); 695 } 696 } 697 } 698 public String toString() { 699 return "Layer[" + folder + "]"; 700 } 701 } 702 703 private static final class Listener implements FileChangeListener { 704 705 private Set changes = new HashSet (); 706 707 public Listener() {} 708 709 public Set changes() { 710 Set _changes = changes; 711 changes = new HashSet (); 712 return _changes; 713 } 714 715 public void fileFolderCreated(FileEvent fe) { 716 changed(fe); 717 } 718 public void fileDataCreated(FileEvent fe) { 719 changed(fe); 720 } 721 public void fileChanged(FileEvent fe) { 722 changed(fe); 723 } 724 public void fileDeleted(FileEvent fe) { 725 changed(fe); 726 } 727 public void fileRenamed(FileRenameEvent fe) { 728 changed(fe); 729 } 730 public void fileAttributeChanged(FileAttributeEvent fe) { 731 changed(fe); 732 } 733 734 private void changed(FileEvent fe) { 735 changes.add(fe.getFile().getPath()); 736 } 737 738 } 739 740 } 741 | Popular Tags |