1 19 20 package org.netbeans.spi.project.support.ant; 21 22 import java.beans.PropertyChangeEvent ; 23 import java.beans.PropertyChangeListener ; 24 import java.io.File ; 25 import java.io.FileInputStream ; 26 import java.io.FileOutputStream ; 27 import java.io.IOException ; 28 import java.io.InputStream ; 29 import java.io.InputStreamReader ; 30 import java.io.OutputStream ; 31 import java.io.OutputStreamWriter ; 32 import java.io.Reader ; 33 import java.io.Writer ; 34 import java.net.URI ; 35 import java.net.URISyntaxException ; 36 import java.net.URL ; 37 import java.util.ArrayList ; 38 import java.util.HashMap ; 39 import java.util.HashSet ; 40 import java.util.List ; 41 import java.util.Map ; 42 import java.util.Properties ; 43 import java.util.Set ; 44 import java.util.regex.Matcher ; 45 import java.util.regex.Pattern ; 46 import java.util.regex.PatternSyntaxException ; 47 import javax.swing.Icon ; 48 import javax.swing.event.ChangeEvent ; 49 import javax.swing.event.ChangeListener ; 50 import org.netbeans.api.diff.Difference; 51 import org.netbeans.api.project.Project; 52 import org.netbeans.api.project.ant.AntArtifact; 53 import org.netbeans.modules.diff.builtin.provider.BuiltInDiffProvider; 54 import org.netbeans.modules.project.ant.Util; 55 import org.netbeans.spi.diff.DiffProvider; 56 import org.netbeans.spi.project.AuxiliaryConfiguration; 57 import org.netbeans.api.project.ProjectInformation; 58 import org.netbeans.api.project.ProjectManager; 59 import org.netbeans.spi.project.ant.AntArtifactProvider; 60 import org.netbeans.spi.queries.CollocationQueryImplementation; 61 import org.openide.filesystems.FileObject; 62 import org.openide.util.Lookup; 63 import org.openide.util.lookup.Lookups; 64 import org.openide.xml.XMLUtil; 65 import org.w3c.dom.Document ; 66 import org.w3c.dom.Element ; 67 68 import org.xml.sax.InputSource ; 69 import org.xml.sax.SAXException ; 70 71 75 public class AntBasedTestUtil { 76 77 private AntBasedTestUtil() {} 78 79 99 public static AntBasedProjectType testAntBasedProjectType() { 100 return new TestAntBasedProjectType(); 101 } 102 103 106 public interface AntArtifactProviderMutable extends AntArtifactProvider { 107 void setBuildArtifacts(AntArtifact[] arts); 108 } 109 110 private static final class TestAntBasedProjectType implements AntBasedProjectType { 111 112 TestAntBasedProjectType() {} 113 114 public String getType() { 115 return "test"; 116 } 117 118 public Project createProject(AntProjectHelper helper) throws IOException { 119 return new TestAntBasedProject(helper); 120 } 121 122 public String getPrimaryConfigurationDataElementName(boolean shared) { 123 return "data"; 124 } 125 126 public String getPrimaryConfigurationDataElementNamespace(boolean shared) { 127 return shared ? "urn:test:shared" : "urn:test:private"; 128 } 129 130 } 131 132 private static final class TestAntBasedProject implements Project { 133 134 private final AntProjectHelper helper; 135 private final ReferenceHelper refHelper; 136 private final GeneratedFilesHelper genFilesHelper; 137 private final Lookup l; 138 139 TestAntBasedProject(AntProjectHelper helper) throws IOException { 140 if (helper.getProjectDirectory().getFileObject("nbproject/broken") != null) { 141 throw new IOException ("broken"); 142 } 143 this.helper = helper; 144 AuxiliaryConfiguration aux = helper.createAuxiliaryConfiguration(); 145 refHelper = new ReferenceHelper(helper, aux, helper.getStandardPropertyEvaluator()); 146 genFilesHelper = new GeneratedFilesHelper(helper); 147 l = Lookups.fixed(new Object [] { 148 new TestInfo(), 149 helper, 150 refHelper, 151 genFilesHelper, 152 aux, 153 helper.createCacheDirectoryProvider(), 154 refHelper.createSubprojectProvider(), 155 new TestAntArtifactProvider(), 156 new ProjectXmlSavedHook() { 157 protected void projectXmlSaved() throws IOException { 158 genFilesHelper.refreshBuildScript( 159 GeneratedFilesHelper.BUILD_IMPL_XML_PATH, 160 AntBasedTestUtil.class.getResource("data/build-impl.xsl"), 161 false); 162 genFilesHelper.refreshBuildScript( 163 GeneratedFilesHelper.BUILD_XML_PATH, 164 testBuildXmlStylesheet(), 165 false); 166 } 167 }, 168 "hello", 169 }); 170 } 171 172 public FileObject getProjectDirectory() { 173 return helper.getProjectDirectory(); 174 } 175 176 public Lookup getLookup() { 177 return l; 178 } 179 180 public String toString() { 181 return "TestAntBasedProject[" + getProjectDirectory() + "]"; 182 } 183 184 private final class TestInfo implements ProjectInformation { 185 186 TestInfo() {} 187 188 private String getText(String elementName) { 189 Element data = helper.getPrimaryConfigurationData(true); 190 Element el = Util.findElement(data, elementName, "urn:test:shared"); 191 if (el != null) { 192 String text = Util.findText(el); 193 if (text != null) { 194 return text; 195 } 196 } 197 return getProjectDirectory().getNameExt(); 199 } 200 201 public String getName() { 202 return getText("name"); 203 } 204 205 public String getDisplayName() { 206 return getText("display-name"); 207 } 208 209 public Icon getIcon() { 210 return null; 211 } 212 213 public Project getProject() { 214 return TestAntBasedProject.this; 215 } 216 217 public void addPropertyChangeListener(PropertyChangeListener listener) {} 218 public void removePropertyChangeListener(PropertyChangeListener listener) {} 219 220 } 221 222 private final class TestAntArtifactProvider implements AntArtifactProviderMutable { 223 224 private AntArtifact[] arts; 225 226 TestAntArtifactProvider() {} 227 228 public AntArtifact[] getBuildArtifacts() { 229 if (arts != null) { 230 return arts; 231 } 232 URI [] uris = null; 233 try { 234 uris = new URI []{new URI ("dist/foo.jar"), new URI ("dist/bar.jar")}; 235 } catch (URISyntaxException ex) { 236 ex.printStackTrace(); 237 } 238 return new AntArtifact[] { 239 helper.createSimpleAntArtifact("jar", "build.jar", helper.getStandardPropertyEvaluator(), "dojar", "clean"), 240 helper.createSimpleAntArtifact("javadoc", "build.javadoc", helper.getStandardPropertyEvaluator(), "dojavadoc", "clean"), 241 new TestAntArtifact(uris, helper), 242 }; 243 } 244 245 public void setBuildArtifacts(AntArtifact[] arts) { 246 this.arts = arts; 247 } 248 249 } 250 251 } 252 253 260 public static Properties slurpProperties(AntProjectHelper h, String path) throws IOException { 261 Properties p = new Properties (); 262 File f = h.resolveFile(path); 263 if (!f.isFile()) { 264 return null; 265 } 266 InputStream is = new FileInputStream (f); 267 try { 268 p.load(is); 269 } finally { 270 is.close(); 271 } 272 return p; 273 } 274 275 283 public static Document slurpXml(AntProjectHelper h, String path) throws IOException , SAXException { 284 File f = h.resolveFile(path); 285 if (!f.isFile()) { 286 return null; 287 } 288 return XMLUtil.parse(new InputSource (f.toURI().toString()), false, true, Util.defaultErrorHandler(), null); 289 } 290 291 299 public static String slurpText(AntProjectHelper h, String path) throws IOException { 300 File f = h.resolveFile(path); 301 if (!f.isFile()) { 302 return null; 303 } 304 InputStream is = new FileInputStream (f); 305 try { 306 Reader r = new InputStreamReader (is, "UTF-8"); 307 StringBuffer b = new StringBuffer (); 308 char[] buf = new char[4096]; 309 int read; 310 while ((read = r.read(buf)) != -1) { 311 b.append(buf, 0, read); 312 } 313 return b.toString(); 314 } finally { 315 is.close(); 316 } 317 } 318 319 323 public static URL testBuildXmlStylesheet() { 324 return AntBasedTestUtil.class.getResource("data/build.xsl"); 325 } 326 327 330 public static final class TestListener implements AntProjectListener { 331 332 private final List <AntProjectEvent> events = new ArrayList <AntProjectEvent>(); 333 334 335 public TestListener() {} 336 337 342 public AntProjectEvent[] events() { 343 AntProjectEvent[] evs = events.toArray(new AntProjectEvent[0]); 344 events.clear(); 345 return evs; 346 } 347 348 public void configurationXmlChanged(AntProjectEvent ev) { 349 assert ev.getPath().equals(AntProjectHelper.PROJECT_XML_PATH) || ev.getPath().equals(AntProjectHelper.PRIVATE_XML_PATH); 350 events.add(ev); 351 } 352 353 public void propertiesChanged(AntProjectEvent ev) { 354 assert !ev.getPath().equals(AntProjectHelper.PROJECT_XML_PATH) && !ev.getPath().equals(AntProjectHelper.PRIVATE_XML_PATH); 355 events.add(ev); 356 } 357 358 } 359 360 375 public static int[] countTextDiffs(Reader r1, Reader r2) throws IOException { 376 DiffProvider dp = new BuiltInDiffProvider(); 377 Difference[] diffs = dp.computeDiff(r1, r2); 378 int[] count = new int[3]; 379 for (int i = 0; i < diffs.length; i++) { 380 switch (diffs[i].getType()) { 381 case Difference.CHANGE: 382 count[0] += Math.max(diffs[i].getFirstEnd() - diffs[i].getFirstStart()+1, diffs[i].getSecondEnd() - diffs[i].getSecondStart()+1); 383 break; 384 case Difference.ADD: 385 count[1] += (diffs[i].getSecondEnd() - diffs[i].getSecondStart()+1); 386 break; 387 case Difference.DELETE: 388 count[2] += (diffs[i].getFirstEnd() - diffs[i].getFirstStart()+1); 389 break; 390 default: 391 assert false : diffs[i]; 392 } 393 } 394 return count; 395 } 396 397 404 public static CollocationQueryImplementation testCollocationQueryImplementation(File root) { 405 return new TestCollocationQueryImplementation(root); 406 } 407 408 private static final class TestCollocationQueryImplementation implements CollocationQueryImplementation { 409 410 private final File root; 411 private final String rootPath; 412 private final File separate; 413 private final String separatePath; 414 private final String transientPath; 415 416 TestCollocationQueryImplementation(File root) { 417 this.root = root; 418 rootPath = root.getAbsolutePath(); 419 separate = new File (root, "separate"); 420 separatePath = separate.getAbsolutePath(); 421 transientPath = new File (root, "transient").getAbsolutePath(); 422 } 423 424 public boolean areCollocated(File file1, File file2) { 425 File root1 = findRoot(file1); 426 if (root1 == null) { 427 return false; 428 } else { 429 return root1.equals(findRoot(file2)); 430 } 431 } 432 433 public File findRoot(File file) { 434 String path = file.getAbsolutePath(); 435 if (!path.startsWith(rootPath)) { 436 return null; 437 } 438 if (path.startsWith(separatePath)) { 439 return separate; 440 } 441 if (path.startsWith(transientPath)) { 442 return null; 443 } 444 return root; 445 } 446 447 } 448 449 458 public static int replaceInFile(File f, String from, String to) throws IOException { 459 StringBuffer b = new StringBuffer ((int)f.length()); 460 InputStream is = new FileInputStream (f); 461 try { 462 Reader r = new InputStreamReader (is, "UTF-8"); 463 char[] buf = new char[4096]; 464 int i; 465 while ((i = r.read(buf)) != -1) { 466 b.append(buf, 0, i); 467 } 468 } finally { 469 is.close(); 470 } 471 String s = b.toString(); 472 String rx = "\\Q" + from + "\\E"; 473 Pattern patt; 474 try { 475 patt = Pattern.compile(rx); 476 } catch (PatternSyntaxException e) { 477 assert false : e; 478 return -1; 479 } 480 Matcher m = patt.matcher(s); 481 int count = 0; 482 while (m.find()) { 483 count++; 484 } 485 String s2 = s.replaceAll(rx, to); 486 assert s2.length() - s.length() == count * (to.length() - from.length()); 487 OutputStream os = new FileOutputStream (f); 488 try { 489 Writer w = new OutputStreamWriter (os, "UTF-8"); 490 w.write(s2); 491 w.flush(); 492 } finally { 493 os.close(); 494 } 495 return count; 496 } 497 498 public static final class TestPCL implements PropertyChangeListener { 499 500 public final Set <String > changed = new HashSet <String >(); 501 public final Map <String ,String > newvals = new HashMap <String ,String >(); 502 public final Map <String ,String > oldvals = new HashMap <String ,String >(); 503 504 public TestPCL() {} 505 506 public void reset() { 507 changed.clear(); 508 newvals.clear(); 509 oldvals.clear(); 510 } 511 512 public void propertyChange(PropertyChangeEvent evt) { 513 String prop = evt.getPropertyName(); 514 String nue = (String )evt.getNewValue(); 515 String old = (String )evt.getOldValue(); 516 changed.add(prop); 517 if (prop != null) { 518 newvals.put(prop, nue); 519 oldvals.put(prop, old); 520 } else { 521 assert nue == null : "null prop name -> null new value"; 522 assert old == null : "null prop name -> null old value"; 523 } 524 } 525 526 } 527 528 532 public static final class TestCL implements ChangeListener { 533 534 private boolean fired; 535 536 public TestCL() {} 537 538 public synchronized void stateChanged(ChangeEvent e) { 539 fired = true; 540 notify(); 541 } 542 543 548 public synchronized boolean expect() { 549 boolean f = fired; 550 fired = false; 551 return f; 552 } 553 554 560 public synchronized boolean expect(long timeout) throws InterruptedException { 561 if (!fired) { 562 wait(timeout); 563 } 564 return expect(); 565 } 566 567 } 568 569 public static class TestAntArtifact extends AntArtifact { 570 571 private URI [] uris; 572 private Project p; 573 private AntProjectHelper h; 574 575 public TestAntArtifact(URI [] uris, AntProjectHelper h) { 576 this.uris = uris; 577 try { 578 this.p = ProjectManager.getDefault().findProject(h.getProjectDirectory()); 579 } catch ( Exception e) { 580 e.printStackTrace(); 581 } 582 this.h = h; 583 } 584 585 public String getType() { 586 return "multi-jar"; } 588 589 public File getScriptLocation() { 590 return h.resolveFile(GeneratedFilesHelper.BUILD_XML_PATH); 591 } 592 593 public String getTargetName() { 594 return "build"; } 596 597 public String getCleanTargetName() { 598 return "clean"; } 600 601 public URI [] getArtifactLocations() { 602 return uris; 603 } 604 605 public Project getProject() { 606 return p; 607 } 608 609 } 610 611 public static final class TestMutablePropertyProvider implements PropertyProvider { 612 613 public final Map <String ,String > defs; 614 private final List <ChangeListener > listeners = new ArrayList <ChangeListener >(); 615 616 public TestMutablePropertyProvider(Map <String ,String > defs) { 617 this.defs = defs; 618 } 619 620 public void mutated() { 621 ChangeEvent ev = new ChangeEvent (this); 622 for (ChangeListener l : listeners) { 623 l.stateChanged(ev); 624 } 625 } 626 627 public Map <String ,String > getProperties() { 628 return defs; 629 } 630 631 public void addChangeListener(ChangeListener l) { 632 listeners.add(l); 633 } 634 635 public void removeChangeListener(ChangeListener l) { 636 listeners.remove(l); 637 } 638 639 } 640 641 } 642 | Popular Tags |