1 19 package org.netbeans.nbbuild; 20 21 import java.io.BufferedOutputStream ; 22 import java.io.File ; 23 import java.io.FileInputStream ; 24 import java.io.FileOutputStream ; 25 import java.io.FileWriter ; 26 import java.io.IOException ; 27 import java.io.InputStreamReader ; 28 import java.io.OutputStream ; 29 import java.io.OutputStreamWriter ; 30 import java.io.StringWriter ; 31 import java.io.Writer ; 32 import java.net.URL ; 33 import java.text.DateFormat ; 34 import java.util.Date ; 35 import java.util.HashMap ; 36 import java.util.Map ; 37 import java.util.SortedSet ; 38 import java.util.TreeSet ; 39 import javax.xml.parsers.DocumentBuilder ; 40 import javax.xml.parsers.DocumentBuilderFactory ; 41 import javax.xml.transform.OutputKeys ; 42 import javax.xml.transform.Result ; 43 import javax.xml.transform.Source ; 44 import javax.xml.transform.Transformer ; 45 import javax.xml.transform.TransformerConfigurationException ; 46 import javax.xml.transform.TransformerException ; 47 import javax.xml.transform.TransformerFactory ; 48 import javax.xml.transform.URIResolver ; 49 import javax.xml.transform.dom.DOMResult ; 50 import javax.xml.transform.dom.DOMSource ; 51 import javax.xml.transform.stream.StreamResult ; 52 import javax.xml.transform.stream.StreamSource ; 53 import org.apache.tools.ant.BuildException; 54 import org.apache.tools.ant.Project; 55 import org.apache.tools.ant.Task; 56 import org.w3c.dom.Attr ; 57 import org.w3c.dom.Document ; 58 import org.w3c.dom.Element ; 59 import org.w3c.dom.Node ; 60 import org.w3c.dom.NodeList ; 61 import org.xml.sax.EntityResolver ; 62 import org.xml.sax.ErrorHandler ; 63 import org.xml.sax.InputSource ; 64 import org.xml.sax.SAXException ; 65 import org.xml.sax.SAXParseException ; 66 67 71 public class Arch extends Task implements ErrorHandler , EntityResolver , URIResolver { 72 73 74 private Map <String ,Element > answers; 75 private Map <String ,Element > questions; 76 77 private SAXParseException parseException; 78 79 public Arch() { 80 } 81 82 86 private File questionsFile; 87 88 public void setAnswers (File f) { 89 questionsFile = f; 90 } 91 92 93 private File output; 94 96 public void setOutput (File f) { 97 output = f; 98 } 99 100 private String stylesheet = null; 102 public void setStylesheet(String s) { 103 stylesheet = s; 104 } 105 private String overviewlink = null; 106 public void setOverviewlink(String s) { 107 overviewlink = s; 108 } 109 private String footer = null; 110 public void setFooter(String s) { 111 footer = s; 112 } 113 private File xsl = null; 114 public void setXSL (File xsl) { 115 this.xsl = xsl; 116 } 117 118 private File apichanges = null; 119 public void setApichanges (File apichanges) { 120 this.apichanges = apichanges; 121 } 122 123 private File project = null; 124 public void setProject (File x) { 125 this.project = x; 126 } 127 128 129 public void execute () throws BuildException { 130 if ( questionsFile == null ) { 131 throw new BuildException ("questions file must be provided"); 132 } 133 134 if ( output == null ) { 135 throw new BuildException ("output file must be specified"); 136 } 137 138 boolean generateTemplate = !questionsFile.exists(); 139 140 if ( 141 !generateTemplate && 142 output.exists() && 143 questionsFile.lastModified() <= output.lastModified() && 144 this.getProject().getProperty ("arch.generate") == null 145 ) { 146 return; 148 } 149 150 151 Document q; 152 Source qSource; 153 DocumentBuilderFactory factory; 154 DocumentBuilder builder; 155 try { 156 factory = DocumentBuilderFactory.newInstance (); 157 factory.setValidating(!generateTemplate && !"true".equals(this.getProject().getProperty ("arch.private.disable.validation.for.test.purposes"))); 159 builder = factory.newDocumentBuilder(); 160 builder.setErrorHandler(this); 161 builder.setEntityResolver(this); 162 163 if (generateTemplate) { 164 q = builder.parse(Arch.class.getResourceAsStream("Arch-api-questions.xml")); 165 qSource = new DOMSource (q); 166 } else { 167 q = builder.parse (questionsFile); 168 qSource = new DOMSource (q); 169 } 170 171 if (parseException != null) { 172 throw parseException; 173 } 174 175 } catch (SAXParseException ex) { 176 log(ex.getSystemId() + ":" + ex.getLineNumber() + ": " + ex.getLocalizedMessage(), Project.MSG_ERR); 177 throw new BuildException(questionsFile.getAbsolutePath() + " is malformed or invalid", ex, getLocation()); 178 } catch (Exception ex) { 179 throw new BuildException ("File " + questionsFile + " cannot be parsed: " + ex.getLocalizedMessage(), ex, getLocation()); 180 } 181 182 questions = readElements (q, "question"); 183 184 String questionsVersion; 185 { 186 NodeList apiQuestions = q.getElementsByTagName("api-questions"); 187 if (apiQuestions.getLength () != 1) { 188 throw new BuildException ("No element api-questions"); 189 } 190 questionsVersion = ((Element )apiQuestions.item (0)).getAttribute ("version"); 191 if (questionsVersion == null) { 192 throw new BuildException ("Element api-questions does not have attribute version"); 193 } 194 } 195 196 if (questions.size () == 0) { 197 throw new BuildException ("There are no <question> elements in the file!"); 198 } 199 200 if (generateTemplate) { 201 log ("Input file " + questionsFile + " does not exist. Generating it with skeleton answers."); 202 try { 203 SortedSet <String > s = new TreeSet <String >(questions.keySet()); 204 generateTemplateFile(questionsVersion, s); 205 } catch (IOException ex) { 206 throw new BuildException (ex); 207 } 208 209 return; 210 } 211 212 answers = readElements (q, "answer"); 213 214 215 { 216 218 NodeList apiAnswers = q.getElementsByTagName("api-answers"); 220 221 if (apiAnswers.getLength() != 1) { 222 throw new BuildException ("No element api-answers"); 223 } 224 225 String answersVersion = ((Element )apiAnswers.item (0)).getAttribute ("question-version"); 226 227 if (answersVersion == null) { 228 throw new BuildException ("Element api-answers does not have attribute question-version"); 229 } 230 231 if (!answersVersion.equals(questionsVersion)) { 232 String msg = questionsFile.getAbsolutePath() + ": answers were created for questions version \"" + answersVersion + "\" but current version of questions is \"" + questionsVersion + "\""; 233 if ("false".equals (this.getProject().getProperty("arch.warn"))) { 234 throw new BuildException (msg); 235 } else { 236 log (msg, Project.MSG_WARN); 237 } 238 } 239 } 240 241 { 242 SortedSet <String > s = new TreeSet <String >(questions.keySet()); 244 s.removeAll (answers.keySet ()); 245 if (!s.isEmpty()) { 246 if ("true".equals (this.getProject().getProperty ("arch.generate"))) { 247 log ("Missing answers to questions: " + s); 248 log ("Generating the answers to end of file " + questionsFile); 249 try { 250 generateMissingQuestions (s); 251 } catch (IOException ex) { 252 throw new BuildException (ex); 253 } 254 qSource = new StreamSource (questionsFile); 255 try { 256 q = builder.parse(questionsFile); 257 } catch (IOException ex) { 258 throw new BuildException(ex); 259 } catch (SAXException ex) { 260 throw new BuildException(ex); 261 } 262 } else { 263 log ( 264 questionsFile.getAbsolutePath() + ": some questions have not been answered: " + s + "\n" + 265 "Run with -Darch.generate=true to add missing questions into the end of question file" 266 , Project.MSG_WARN); 267 } 268 } 269 } 270 271 272 if (apichanges != null) { 273 log("Reading apichanges from " + apichanges); 275 276 Document api; 277 try { 278 api = builder.parse (apichanges); 279 } catch (SAXParseException ex) { 280 log(ex.getSystemId() + ":" + ex.getLineNumber() + ": " + ex.getLocalizedMessage(), Project.MSG_ERR); 281 throw new BuildException(apichanges.getAbsolutePath() + " is malformed or invalid", ex, getLocation()); 282 } catch (Exception ex) { 283 throw new BuildException ("File " + apichanges + " cannot be parsed: " + ex.getLocalizedMessage(), ex, getLocation()); 284 } 285 286 NodeList node = api.getElementsByTagName("apichanges"); 287 if (node.getLength() != 1) { 288 throw new BuildException("Expected one element <apichanges/> in " + apichanges + "but was: " + node.getLength()); 289 } 290 291 Node n = node.item(0); 292 Node el = q.getElementsByTagName("api-answers").item(0); 293 294 el.appendChild(q.importNode(n, true)); 295 296 297 qSource = new DOMSource (q); 298 qSource.setSystemId(questionsFile.toURI().toString()); 299 } 300 301 302 if (project != null) { 303 log("Reading project from " + project); 305 306 307 308 Document prj; 309 try { 310 DocumentBuilderFactory fack = DocumentBuilderFactory.newInstance(); 311 fack.setNamespaceAware(false); 312 prj = fack.newDocumentBuilder().parse (project); 313 } catch (SAXParseException ex) { 314 log(ex.getSystemId() + ":" + ex.getLineNumber() + ": " + ex.getLocalizedMessage(), Project.MSG_ERR); 315 throw new BuildException(project.getAbsolutePath() + " is malformed or invalid", ex, getLocation()); 316 } catch (Exception ex) { 317 throw new BuildException ("File " + project + " cannot be parsed: " + ex.getLocalizedMessage(), ex, getLocation()); 318 } 319 320 343 { 344 NodeList deps = prj.getElementsByTagName("code-name-base"); 345 for (int i = 0; i < deps.getLength(); i++) { 346 Node name = deps.item(i); 347 String api = name.getChildNodes().item(0).getNodeValue(); 348 String human = this.getProject().getProperty("arch." + api + ".name"); 349 if (human != null) { 350 if (human.equals("")) { 351 throw new BuildException("Empty name for " + api + " from " + project); 352 } 353 354 Element e = prj.createElement("api-name"); 355 e.appendChild(prj.createTextNode(human)); 356 name.getParentNode().insertBefore(e, name); 357 } 358 String category = this.getProject().getProperty("arch." + api + ".category"); 359 if (category != null) { 360 if (category.equals("")) { 361 throw new BuildException("Empty category for " + api + " from " + project); 362 } 363 Element e = prj.createElement("api-category"); 364 e.appendChild(prj.createTextNode(category)); 365 name.getParentNode().insertBefore(e, name); 366 } 367 368 } 369 } 370 371 { 376 File f = project; 377 StringBuffer sb = new StringBuffer (); 378 String sep = ""; 379 for (;;) { 380 if (new File (f, "nbbuild").isDirectory()) { 381 break; 382 } 383 384 if (f.isDirectory() && !"nbproject".equals (f.getName())) { 385 sb.insert(0, sep); 386 sep = "/"; 387 sb.insert(0, f.getName()); 388 } 389 390 f = f.getParentFile(); 391 if (f == null) { 392 sb.setLength(0); 394 break; 395 } 396 } 397 Element el = prj.createElement("cvs-location"); 398 el.appendChild(prj.createTextNode(sb.toString())); 399 prj.getDocumentElement().appendChild(el); 400 } 401 402 403 DOMSource prjSrc = new DOMSource (prj); 404 405 NodeList node = prj.getElementsByTagName("project"); 406 if (node.getLength() != 1) { 407 throw new BuildException("Expected one element <project/> in " + project + "but was: " + node.getLength()); 408 } 409 410 NodeList list= q.getElementsByTagName("answer"); 411 for (int i = 0; i < list.getLength(); i++) { 412 Node n = list.item(i); 413 String id = n.getAttributes().getNamedItem("id").getNodeValue(); 414 URL u = Arch.class.getResource("Arch-default-" + id + ".xsl"); 415 if (u != null) { 416 log("Found default answer to " + id + " question", Project.MSG_VERBOSE); 417 Node defaultAnswer = findDefaultAnswer(n); 418 if (defaultAnswer != null && 419 "none".equals(defaultAnswer.getAttributes().getNamedItem("generate").getNodeValue()) 420 ) { 421 log("Skipping answer as there is <defaultanswer generate='none'", Project.MSG_VERBOSE); 422 continue; 424 } 425 426 DOMResult res = new DOMResult (q.createElement("p")); 427 try { 428 StreamSource defXSL = new StreamSource (u.openStream()); 429 430 TransformerFactory fack = TransformerFactory.newInstance(); 431 Transformer t = fack.newTransformer(defXSL); 432 t.transform(prjSrc, res); 433 } catch (IOException ex) { 434 throw new BuildException (ex); 435 } catch (TransformerException ex) { 436 throw new BuildException (ex); 437 } 438 439 if (defaultAnswer != null) { 440 log("Replacing default answer", Project.MSG_VERBOSE); 441 defaultAnswer.getParentNode().replaceChild(res.getNode(), defaultAnswer); 442 } else { 443 log("Adding default answer to the end of previous one", Project.MSG_VERBOSE); 444 Element para = q.createElement("p"); 445 para.appendChild(q.createTextNode("The default answer to this question is:")); 446 para.appendChild(q.createComment("If you do not want default answer to be generated you can use <defaultanswer generate='none' /> here")); 447 para.appendChild(q.createElement("br")); 448 para.appendChild(res.getNode()); 449 n.appendChild(para); 450 } 451 } 452 } 453 454 455 qSource = new DOMSource (q); 456 qSource.setSystemId(questionsFile.toURI().toString()); 457 } 458 459 if (this.getProject().getProperty("javadoc.title") != null) { 460 NodeList deps = q.getElementsByTagName("api-answers"); 462 if (deps.getLength() != 1) { 463 throw new BuildException("Strange number of api-answers elements: " + deps.getLength()); 464 } 465 466 Node module = deps.item(0).getAttributes().getNamedItem("module"); 467 if (module == null) { 468 Attr attr = q.createAttribute("module"); 469 deps.item(0).getAttributes().setNamedItem(attr); 470 attr.setValue(this.getProject().getProperty("javadoc.title")); 471 } 472 473 qSource = new DOMSource (q); 474 qSource.setSystemId(questionsFile.toURI().toString()); 475 } 476 477 478 try { 480 StreamSource ss; 481 String file = this.xsl != null ? this.xsl.toString() : getProject().getProperty ("arch.xsl"); 482 483 if (file != null) { 484 log ("Using " + file + " as the XSL stylesheet"); 485 ss = new StreamSource (file); 486 } else { 487 ss = new StreamSource ( 488 getClass ().getResourceAsStream ("Arch.xsl") 489 ); 490 } 491 492 log("Transforming " + questionsFile + " into " + output); 493 494 TransformerFactory trans; 495 trans = TransformerFactory.newInstance(); 496 trans.setURIResolver(this); 497 Transformer t = trans.newTransformer(ss); 498 OutputStream os = new BufferedOutputStream (new FileOutputStream (output)); 499 StreamResult r = new StreamResult (os); 500 if (stylesheet == null) { 501 stylesheet = this.getProject ().getProperty ("arch.stylesheet"); 502 } 503 if (stylesheet != null) { 504 t.setParameter("arch.stylesheet", stylesheet); 505 } 506 if (overviewlink != null) { 507 t.setParameter("arch.overviewlink", overviewlink); 508 } 509 if (footer != null) { 510 t.setParameter("arch.footer", footer); 511 } 512 t.setParameter("arch.answers.date", DateFormat.getDateInstance().format(new Date (questionsFile.lastModified()))); 513 514 String archTarget = output.toString(); 515 int slash = archTarget.lastIndexOf(File.separatorChar); 516 if (slash > 0) { 517 archTarget = archTarget.substring (slash + 1); 518 } 519 String archPref = getProject ().getProperty ("arch.target"); 520 if (archPref != null) { 521 archTarget = archPref + "/" + archTarget; 522 } 523 524 t.setParameter("arch.target", archTarget); 525 String when = getProject().getProperty("arch.when"); 526 if (when != null) { 527 t.setParameter("arch.when", when); 528 } 529 t.transform(qSource, r); 530 os.close (); 531 } catch (IOException ex) { 532 throw new BuildException (ex); 533 } catch (TransformerConfigurationException ex) { 534 throw new BuildException (ex); 535 } catch (TransformerException ex) { 536 throw new BuildException (ex); 537 } 538 } 539 540 private void generateMissingQuestions(SortedSet <String > missing) throws IOException , BuildException { 541 StringBuffer sb = new StringBuffer (); 542 InputStreamReader is = new InputStreamReader (new FileInputStream (questionsFile.toString())); 543 char[] arr = new char[4096]; 544 for (;;) { 545 int len = is.read(arr); 546 if (len == -1) break; 547 548 sb.append(arr, 0, len); 549 } 550 551 int indx = sb.indexOf("</api-answers>"); 552 if (indx == -1) { 553 throw new BuildException("There is no </api-answers> in " + questionsFile); 554 } 555 556 sb.delete (indx, indx + "</api-answers>".length()); 557 558 Writer w = new OutputStreamWriter (new FileOutputStream (questionsFile.toString ())); 559 w.write(sb.toString()); 560 writeQuestions (w, missing); 561 w.write("</api-answers>\n"); 562 w.close(); 563 } 564 565 private void writeQuestions(Writer w, SortedSet <String > missing) throws IOException { 566 for (String s : missing) { 567 Element n = questions.get(s); 568 569 w.write("\n\n<!--\n "); 571 w.write(elementToString(n)); 572 w.write("\n-->\n"); 573 574 URL u = Arch.class.getResource("Arch-default-" + s + ".xsl"); 575 if (u != null) { 576 w.write(" <answer id=\"" + s + "\">\n <defaultanswer generate='here' />\n </answer>\n\n"); 578 } else { 579 w.write(" <answer id=\"" + s + "\">\n <p>\n XXX no answer for " + s + "\n </p>\n </answer>\n\n"); 580 } 581 } 582 } 583 584 585 private static String findNbRoot (File f) { 586 StringBuffer result = new StringBuffer (); 587 f = f.getParentFile(); 588 589 while (f != null) { 590 File x = new File (f, 591 "nbbuild" + File.separatorChar + 592 "antsrc" + File.separatorChar + 593 "org" + File.separatorChar + 594 "netbeans" + File.separatorChar + 595 "nbbuild" + File.separatorChar + 596 "Arch.dtd" 597 ); 598 if (x.exists ()) { 599 return result.toString(); 600 } 601 result.append("../"); f = f.getParentFile(); 603 } 604 return null; 605 } 606 607 private void generateTemplateFile(String versionOfQuestions, SortedSet <String > missing) throws IOException { 608 String nbRoot = findNbRoot(questionsFile); 609 if (nbRoot == null) { 610 nbRoot = "http://www.netbeans.org/source/browse/~checkout~/"; 611 } 612 613 Writer w = new FileWriter (questionsFile); 614 615 w.write ("<?xml version=\"1.0\" encoding=\"UTF-8\"?><!-- -*- sgml-indent-step: 1 -*- -->\n"); 616 w.write ("<!--\n"); 617 w.write("The contents of this file are subject to the terms of the Common Development\n"); 618 w.write("and Distribution License (the License). You may not use this file except in\n"); 619 w.write("compliance with the License.\n"); 620 w.write("\n"); 621 w.write("You can obtain a copy of the License at http://www.netbeans.org/cddl.html\n"); 622 w.write("or http://www.netbeans.org/cddl.txt.\n"); 623 w.write("\n"); 624 w.write("When distributing Covered Code, include this CDDL Header Notice in each file\n"); 625 w.write("and include the License file at http://www.netbeans.org/cddl.txt.\n"); 626 w.write("If applicable, add the following below the CDDL Header, with the fields\n"); 627 w.write("enclosed by brackets [] replaced by your own identifying information:\n"); 628 w.write("\"Portions Copyrighted [year] [name of copyright owner]\"\n"); 629 w.write("\n"); 630 w.write("The Original Software is NetBeans. The Initial Developer of the Original\n"); 631 w.write("Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun\n"); 632 w.write("Microsystems, Inc. All Rights Reserved.\n"); 633 w.write ("-->\n"); 634 w.write ("<!DOCTYPE api-answers PUBLIC \"-//NetBeans//DTD Arch Answers//EN\" \""); w.write (nbRoot); w.write ("nbbuild/antsrc/org/netbeans/nbbuild/Arch.dtd\" [\n"); 635 w.write (" <!ENTITY api-questions SYSTEM \""); w.write (nbRoot); w.write ("nbbuild/antsrc/org/netbeans/nbbuild/Arch-api-questions.xml\">\n"); 636 w.write ("]>\n"); 637 w.write ("\n"); 638 w.write ("<api-answers\n"); 639 w.write (" question-version=\""); w.write (versionOfQuestions); w.write ("\"\n"); 640 w.write (" author=\"yourname@netbeans.org\"\n"); 641 w.write (">\n\n"); 642 w.write (" &api-questions;\n"); 643 644 writeQuestions (w, missing); 645 646 w.write ("</api-answers>\n"); 647 648 w.close (); 649 } 650 651 private static Map <String ,Element > readElements (Document q, String name) { 652 Map <String ,Element > map = new HashMap <String ,Element >(); 653 654 NodeList list = q.getElementsByTagName(name); 655 for (int i = 0; i < list.getLength(); i++) { 656 Node n = list.item (i).getAttributes().getNamedItem("id"); 657 if (n == null) { 658 throw new BuildException ("Question without id tag"); 659 } 660 String id = n.getNodeValue(); 661 662 map.put(id, (Element ) list.item(i)); 663 } 664 665 return map; 666 } 667 668 public void error(SAXParseException exception) throws SAXException { 669 if (parseException != null) { 670 log(parseException.getSystemId() + ":" + parseException.getLineNumber() + ": " + parseException.getLocalizedMessage(), Project.MSG_ERR); 671 } 672 parseException = exception; 673 } 674 675 public void fatalError(SAXParseException exception) throws SAXException { 676 throw exception; 677 } 678 679 public void warning(SAXParseException exception) throws SAXException { 680 if (exception.getLocalizedMessage().startsWith("Using original entity definition for")) { 681 return; 683 } 684 log(exception.getSystemId() + ":" + exception.getLineNumber() + ": " + exception.getLocalizedMessage(), Project.MSG_WARN); 685 } 686 687 private static String elementToString(Element e) throws IOException { 688 try { 689 Transformer t = TransformerFactory.newInstance().newTransformer(); 690 t.setOutputProperty(OutputKeys.INDENT, "no"); t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); Source source = new DOMSource (e); 693 StringWriter w = new StringWriter (); 694 Result result = new StreamResult (w); 695 t.transform(source, result); 696 return w.toString(); 697 } catch (Exception x) { 698 throw (IOException )new IOException (x.toString()).initCause(x); 699 } 700 } 701 702 private static Node findDefaultAnswer(Node n) { 703 if (n.getNodeName().equals ("defaultanswer")) { 704 return n; 705 } 706 707 NodeList arr = n.getChildNodes(); 708 for (int i = 0; i < arr.getLength(); i++) { 709 Node found = findDefaultAnswer(arr.item(i)); 710 if (found != null) { 711 return found; 712 } 713 } 714 return null; 715 } 716 717 private static Map <String ,String > publicIds; 718 static { 719 publicIds = new HashMap <String ,String >(); 720 publicIds.put("xhtml1-strict.dtd", "Arch-fake-xhtml.dtd"); 721 publicIds.put("Arch.dtd", "Arch.dtd"); 722 publicIds.put("Arch-api-questions.xml", "Arch-api-questions.xml"); 723 724 } 725 726 public InputSource resolveEntity(String publicId, String systemId) throws SAXException , IOException { 727 log("publicId: " + publicId + " systemId: " + systemId, Project.MSG_VERBOSE); 728 729 int idx = systemId.lastIndexOf('/'); 730 String last = systemId.substring(idx + 1); 731 732 if (last.equals("xhtml1-strict.dtd")) { 733 String dtd = "libs/external/dtds/xhtml1-20020801/DTD/xhtml1-strict.dtd".replace('/', File.separatorChar); 735 File f = questionsFile.getParentFile(); 736 while (f != null) { 737 File check = new File (f, dtd); 738 if (check.isFile()) { 739 String r = check.toURI().toString(); 740 log("Replacing entity " + publicId + " at " + systemId + " with " + r); 741 return new InputSource (r); 742 } 743 f = f.getParentFile(); 744 } 745 } 746 747 String replace = publicIds.get(last); 748 if (replace == null) { 749 log("Not replacing id", Project.MSG_VERBOSE); 750 return null; 751 } 752 753 try { 754 URL u = new URL (systemId); 755 u.openStream(); 756 log("systemId " + systemId + " exists, leaving", Project.MSG_VERBOSE); 757 return null; 758 } catch (IOException ex) { 759 } 761 762 InputSource is; 763 log("Replacing entity " + publicId + " at " + systemId + " with " + replace); 764 if (replace.startsWith("http://")) { 765 is = new InputSource (new URL (replace).openStream()); 766 is.setSystemId(replace); 767 } else { 768 is = new InputSource (Arch.class.getResourceAsStream(replace)); 769 is.setSystemId(replace); 770 } 771 return is; 772 } 773 774 public Source resolve(String href, String base) throws TransformerException { 775 return null; 776 } 777 } 778 | Popular Tags |