KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > nbbuild > Arch


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.nbbuild;
20
21 import java.io.BufferedOutputStream JavaDoc;
22 import java.io.File JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24 import java.io.FileOutputStream JavaDoc;
25 import java.io.FileWriter JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.InputStreamReader JavaDoc;
28 import java.io.OutputStream JavaDoc;
29 import java.io.OutputStreamWriter JavaDoc;
30 import java.io.StringWriter JavaDoc;
31 import java.io.Writer JavaDoc;
32 import java.net.URL JavaDoc;
33 import java.text.DateFormat JavaDoc;
34 import java.util.Date JavaDoc;
35 import java.util.HashMap JavaDoc;
36 import java.util.Map JavaDoc;
37 import java.util.SortedSet JavaDoc;
38 import java.util.TreeSet JavaDoc;
39 import javax.xml.parsers.DocumentBuilder JavaDoc;
40 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
41 import javax.xml.transform.OutputKeys JavaDoc;
42 import javax.xml.transform.Result JavaDoc;
43 import javax.xml.transform.Source JavaDoc;
44 import javax.xml.transform.Transformer JavaDoc;
45 import javax.xml.transform.TransformerConfigurationException JavaDoc;
46 import javax.xml.transform.TransformerException JavaDoc;
47 import javax.xml.transform.TransformerFactory JavaDoc;
48 import javax.xml.transform.URIResolver JavaDoc;
49 import javax.xml.transform.dom.DOMResult JavaDoc;
50 import javax.xml.transform.dom.DOMSource JavaDoc;
51 import javax.xml.transform.stream.StreamResult JavaDoc;
52 import javax.xml.transform.stream.StreamSource JavaDoc;
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 JavaDoc;
57 import org.w3c.dom.Document JavaDoc;
58 import org.w3c.dom.Element JavaDoc;
59 import org.w3c.dom.Node JavaDoc;
60 import org.w3c.dom.NodeList JavaDoc;
61 import org.xml.sax.EntityResolver JavaDoc;
62 import org.xml.sax.ErrorHandler JavaDoc;
63 import org.xml.sax.InputSource JavaDoc;
64 import org.xml.sax.SAXException JavaDoc;
65 import org.xml.sax.SAXParseException JavaDoc;
66
67 /**
68  * Task to process Arch questions and answers document.
69  * @author Jaroslav Tulach, Jesse Glick
70  */

71 public class Arch extends Task implements ErrorHandler JavaDoc, EntityResolver JavaDoc, URIResolver JavaDoc {
72
73     /** map from String ids -> Elements */
74     private Map JavaDoc<String JavaDoc,Element JavaDoc> answers;
75     private Map JavaDoc<String JavaDoc,Element JavaDoc> questions;
76     /** exception during parsing */
77     private SAXParseException JavaDoc parseException;
78     
79     public Arch() {
80     }
81
82     //
83
// itself
84
//
85

86     private File JavaDoc questionsFile;
87     /** Questions and answers file */
88     public void setAnswers (File JavaDoc f) {
89         questionsFile = f;
90     }
91     
92     
93     private File JavaDoc output;
94     /** Output file
95      */

96     public void setOutput (File JavaDoc f) {
97         output = f;
98     }
99     
100     // For use when generating API documentation:
101
private String JavaDoc stylesheet = null;
102     public void setStylesheet(String JavaDoc s) {
103         stylesheet = s;
104     }
105     private String JavaDoc overviewlink = null;
106     public void setOverviewlink(String JavaDoc s) {
107         overviewlink = s;
108     }
109     private String JavaDoc footer = null;
110     public void setFooter(String JavaDoc s) {
111         footer = s;
112     }
113     private File JavaDoc xsl = null;
114     public void setXSL (File JavaDoc xsl) {
115         this.xsl = xsl;
116     }
117     
118     private File JavaDoc apichanges = null;
119     public void setApichanges (File JavaDoc apichanges) {
120         this.apichanges = apichanges;
121     }
122
123     private File JavaDoc project = null;
124     public void setProject (File JavaDoc x) {
125         this.project = x;
126     }
127     
128     /** Run the conversion */
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             // nothing needs to be generated. everything is up to date
147
return;
148         }
149         
150         
151         Document JavaDoc q;
152         Source JavaDoc qSource;
153         DocumentBuilderFactory JavaDoc factory;
154         DocumentBuilder JavaDoc builder;
155         try {
156             factory = DocumentBuilderFactory.newInstance ();
157             factory.setValidating(!generateTemplate && !"true".equals(this.getProject().getProperty ("arch.private.disable.validation.for.test.purposes"))); // NOI18N
158

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 JavaDoc (q);
166             } else {
167                 q = builder.parse (questionsFile);
168                 qSource = new DOMSource JavaDoc (q);
169             }
170             
171             if (parseException != null) {
172                 throw parseException;
173             }
174             
175         } catch (SAXParseException JavaDoc 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 JavaDoc ex) {
179             throw new BuildException ("File " + questionsFile + " cannot be parsed: " + ex.getLocalizedMessage(), ex, getLocation());
180         }
181
182         questions = readElements (q, "question");
183         
184         String JavaDoc questionsVersion;
185         {
186             NodeList JavaDoc apiQuestions = q.getElementsByTagName("api-questions");
187             if (apiQuestions.getLength () != 1) {
188                 throw new BuildException ("No element api-questions");
189             }
190             questionsVersion = ((Element JavaDoc)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 JavaDoc<String JavaDoc> s = new TreeSet JavaDoc<String JavaDoc>(questions.keySet());
204                 generateTemplateFile(questionsVersion, s);
205             } catch (IOException JavaDoc ex) {
206                 throw new BuildException (ex);
207             }
208             
209             return;
210         }
211         
212         answers = readElements (q, "answer");
213         
214         
215         {
216             //System.out.println("doc:\n" + q.getDocumentElement());
217

218             // version of answers and version of questions
219
NodeList JavaDoc apiAnswers = q.getElementsByTagName("api-answers");
220             
221             if (apiAnswers.getLength() != 1) {
222                 throw new BuildException ("No element api-answers");
223             }
224             
225             String JavaDoc answersVersion = ((Element JavaDoc)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 JavaDoc 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             // check all answers have their questions
243
SortedSet JavaDoc<String JavaDoc> s = new TreeSet JavaDoc<String JavaDoc>(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 JavaDoc ex) {
252                         throw new BuildException (ex);
253                     }
254                     qSource = new StreamSource JavaDoc (questionsFile);
255                     try {
256                         q = builder.parse(questionsFile);
257                     } catch (IOException JavaDoc ex) {
258                         throw new BuildException(ex);
259                     } catch (SAXException JavaDoc 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             // read also apichanges and add them to the document
274
log("Reading apichanges from " + apichanges);
275
276             Document JavaDoc api;
277             try {
278                 api = builder.parse (apichanges);
279             } catch (SAXParseException JavaDoc 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 JavaDoc ex) {
283                 throw new BuildException ("File " + apichanges + " cannot be parsed: " + ex.getLocalizedMessage(), ex, getLocation());
284             }
285             
286             NodeList JavaDoc 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 JavaDoc n = node.item(0);
292             Node JavaDoc el = q.getElementsByTagName("api-answers").item(0);
293             
294             el.appendChild(q.importNode(n, true));
295             
296             
297             qSource = new DOMSource JavaDoc(q);
298             qSource.setSystemId(questionsFile.toURI().toString());
299         }
300
301         
302         if (project != null) {
303             // read also project file and apply transformation on defaultanswer tags
304
log("Reading project from " + project);
305
306             
307             
308             Document JavaDoc prj;
309             try {
310                 DocumentBuilderFactory JavaDoc fack = DocumentBuilderFactory.newInstance();
311                 fack.setNamespaceAware(false);
312                 prj = fack.newDocumentBuilder().parse (project);
313             } catch (SAXParseException JavaDoc 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 JavaDoc ex) {
317                 throw new BuildException ("File " + project + " cannot be parsed: " + ex.getLocalizedMessage(), ex, getLocation());
318             }
319             
320             // enhance the project document with info about stability and logical name of an API
321
// use arch.code-name-base.name and arch.code-name-base.category
322
// to modify regular:
323
// <dependency>
324
// <code-name-base>org.openide.util</code-name-base>
325
// <build-prerequisite/>
326
// <compile-dependency/>
327
// <run-dependency>
328
// <specification-version>6.2</specification-version>
329
// </run-dependency>
330
// </dependency>
331
// to include additional items like:
332
// <dependency>
333
// <code-name-base>org.openide.util</code-name-base>
334
// <api-name>UtilitiesAPI</api-name>
335
// <api-category>official</api-category>
336
// <build-prerequisite/>
337
// <compile-dependency/>
338
// <run-dependency>
339
// <specification-version>6.2</specification-version>
340
// </run-dependency>
341
// </dependency>
342

343             {
344                 NodeList JavaDoc deps = prj.getElementsByTagName("code-name-base");
345                 for (int i = 0; i < deps.getLength(); i++) {
346                     Node JavaDoc name = deps.item(i);
347                     String JavaDoc api = name.getChildNodes().item(0).getNodeValue();
348                     String JavaDoc 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 JavaDoc e = prj.createElement("api-name");
355                         e.appendChild(prj.createTextNode(human));
356                         name.getParentNode().insertBefore(e, name);
357                     }
358                     String JavaDoc 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 JavaDoc e = prj.createElement("api-category");
364                         e.appendChild(prj.createTextNode(category));
365                         name.getParentNode().insertBefore(e, name);
366                     }
367                     
368                 }
369             }
370
371             // finds out the lotion in CVS
372
// will be available as element under
373
// <project>
374
// <cvs-location>openide/util</cvs-location>
375
{
376                 File JavaDoc f = project;
377                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
378                 String JavaDoc sep = "";
379                 for (;;) {
380                     if (new File JavaDoc(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                         // not found anything
393
sb.setLength(0);
394                         break;
395                     }
396                 }
397                 Element JavaDoc el = prj.createElement("cvs-location");
398                 el.appendChild(prj.createTextNode(sb.toString()));
399                 prj.getDocumentElement().appendChild(el);
400             }
401             
402             
403             DOMSource JavaDoc prjSrc = new DOMSource JavaDoc(prj);
404             
405             NodeList JavaDoc 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 JavaDoc list= q.getElementsByTagName("answer");
411             for (int i = 0; i < list.getLength(); i++) {
412                 Node JavaDoc n = list.item(i);
413                 String JavaDoc id = n.getAttributes().getNamedItem("id").getNodeValue();
414                 URL JavaDoc 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 JavaDoc 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                         // ok, this default answer is requested to be skipped
423
continue;
424                     }
425                     
426                     DOMResult JavaDoc res = new DOMResult JavaDoc(q.createElement("p"));
427                     try {
428                         StreamSource JavaDoc defXSL = new StreamSource JavaDoc(u.openStream());
429                     
430                         TransformerFactory JavaDoc fack = TransformerFactory.newInstance();
431                         Transformer JavaDoc t = fack.newTransformer(defXSL);
432                         t.transform(prjSrc, res);
433                     } catch (IOException JavaDoc ex) {
434                         throw new BuildException (ex);
435                     } catch (TransformerException JavaDoc 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 JavaDoc 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 JavaDoc(q);
456             qSource.setSystemId(questionsFile.toURI().toString());
457         }
458
459         if (this.getProject().getProperty("javadoc.title") != null) {
460             // verify we have the api-answers@module and possibly add it
461
NodeList JavaDoc 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 JavaDoc module = deps.item(0).getAttributes().getNamedItem("module");
467             if (module == null) {
468                 Attr JavaDoc 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 JavaDoc(q);
474             qSource.setSystemId(questionsFile.toURI().toString());
475         }
476         
477         
478         // apply the transform operation
479
try {
480             StreamSource JavaDoc ss;
481             String JavaDoc 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 JavaDoc (file);
486             } else {
487                 ss = new StreamSource JavaDoc (
488                     getClass ().getResourceAsStream ("Arch.xsl")
489                 );
490             }
491             
492             log("Transforming " + questionsFile + " into " + output);
493
494             TransformerFactory JavaDoc trans;
495             trans = TransformerFactory.newInstance();
496             trans.setURIResolver(this);
497             Transformer JavaDoc t = trans.newTransformer(ss);
498             OutputStream JavaDoc os = new BufferedOutputStream JavaDoc (new FileOutputStream JavaDoc (output));
499             StreamResult JavaDoc r = new StreamResult JavaDoc (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 JavaDoc(questionsFile.lastModified())));
513             
514             String JavaDoc archTarget = output.toString();
515             int slash = archTarget.lastIndexOf(File.separatorChar);
516             if (slash > 0) {
517                 archTarget = archTarget.substring (slash + 1);
518             }
519             String JavaDoc archPref = getProject ().getProperty ("arch.target");
520             if (archPref != null) {
521                 archTarget = archPref + "/" + archTarget;
522             }
523             
524             t.setParameter("arch.target", archTarget);
525             String JavaDoc 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 JavaDoc ex) {
532             throw new BuildException (ex);
533         } catch (TransformerConfigurationException JavaDoc ex) {
534             throw new BuildException (ex);
535         } catch (TransformerException JavaDoc ex) {
536             throw new BuildException (ex);
537         }
538     }
539     
540     private void generateMissingQuestions(SortedSet JavaDoc<String JavaDoc> missing) throws IOException JavaDoc, BuildException {
541         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
542         InputStreamReader JavaDoc is = new InputStreamReader JavaDoc(new FileInputStream JavaDoc(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 JavaDoc w = new OutputStreamWriter JavaDoc (new FileOutputStream JavaDoc (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 JavaDoc w, SortedSet JavaDoc<String JavaDoc> missing) throws IOException JavaDoc {
566         for (String JavaDoc s : missing) {
567             Element JavaDoc n = questions.get(s);
568             
569             //w.write("\n\n<!-- Question: " + s + "\n");
570
w.write("\n\n<!--\n ");
571             w.write(elementToString(n));
572             w.write("\n-->\n");
573             
574             URL JavaDoc u = Arch.class.getResource("Arch-default-" + s + ".xsl");
575             if (u != null) {
576                 // there is default answer
577
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 JavaDoc findNbRoot (File JavaDoc f) {
586         StringBuffer JavaDoc result = new StringBuffer JavaDoc ();
587         f = f.getParentFile();
588         
589         while (f != null) {
590             File JavaDoc x = new File JavaDoc (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("../"); // URI, so pathsep is /
602
f = f.getParentFile();
603         }
604         return null;
605     }
606     
607     private void generateTemplateFile(String JavaDoc versionOfQuestions, SortedSet JavaDoc<String JavaDoc> missing) throws IOException JavaDoc {
608         String JavaDoc nbRoot = findNbRoot(questionsFile);
609         if (nbRoot == null) {
610             nbRoot = "http://www.netbeans.org/source/browse/~checkout~/";
611         }
612         
613         Writer JavaDoc w = new FileWriter JavaDoc (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 JavaDoc<String JavaDoc,Element JavaDoc> readElements (Document JavaDoc q, String JavaDoc name) {
652         Map JavaDoc<String JavaDoc,Element JavaDoc> map = new HashMap JavaDoc<String JavaDoc,Element JavaDoc>();
653        
654         NodeList JavaDoc list = q.getElementsByTagName(name);
655         for (int i = 0; i < list.getLength(); i++) {
656             Node JavaDoc n = list.item (i).getAttributes().getNamedItem("id");
657             if (n == null) {
658                 throw new BuildException ("Question without id tag");
659             }
660             String JavaDoc id = n.getNodeValue();
661
662             map.put(id, (Element JavaDoc) list.item(i));
663         }
664         
665         return map;
666     }
667
668     public void error(SAXParseException JavaDoc exception) throws SAXException JavaDoc {
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 JavaDoc exception) throws SAXException JavaDoc {
676         throw exception;
677     }
678     
679     public void warning(SAXParseException JavaDoc exception) throws SAXException JavaDoc {
680         if (exception.getLocalizedMessage().startsWith("Using original entity definition for")) {
681             // Pointless message, always logged when using XHTML. Ignore.
682
return;
683         }
684         log(exception.getSystemId() + ":" + exception.getLineNumber() + ": " + exception.getLocalizedMessage(), Project.MSG_WARN);
685     }
686     
687     private static String JavaDoc elementToString(Element JavaDoc e) throws IOException JavaDoc {
688         try {
689             Transformer JavaDoc t = TransformerFactory.newInstance().newTransformer();
690             t.setOutputProperty(OutputKeys.INDENT, "no"); // NOI18N
691
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); // NOI18N
692
Source JavaDoc source = new DOMSource JavaDoc(e);
693             StringWriter JavaDoc w = new StringWriter JavaDoc();
694             Result JavaDoc result = new StreamResult JavaDoc(w);
695             t.transform(source, result);
696             return w.toString();
697         } catch (Exception JavaDoc x) {
698             throw (IOException JavaDoc)new IOException JavaDoc(x.toString()).initCause(x);
699         }
700     }
701
702     private static Node JavaDoc findDefaultAnswer(Node JavaDoc n) {
703         if (n.getNodeName().equals ("defaultanswer")) {
704             return n;
705         }
706         
707         NodeList JavaDoc arr = n.getChildNodes();
708         for (int i = 0; i < arr.getLength(); i++) {
709             Node JavaDoc found = findDefaultAnswer(arr.item(i));
710             if (found != null) {
711                 return found;
712             }
713         }
714         return null;
715     }
716     
717     private static Map JavaDoc<String JavaDoc,String JavaDoc> publicIds;
718     static {
719         publicIds = new HashMap JavaDoc<String JavaDoc,String JavaDoc>();
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 JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId) throws SAXException JavaDoc, IOException JavaDoc {
727         log("publicId: " + publicId + " systemId: " + systemId, Project.MSG_VERBOSE);
728         
729         int idx = systemId.lastIndexOf('/');
730         String JavaDoc last = systemId.substring(idx + 1);
731         
732         if (last.equals("xhtml1-strict.dtd")) {
733             // try to find relative libraries
734
String JavaDoc dtd = "libs/external/dtds/xhtml1-20020801/DTD/xhtml1-strict.dtd".replace('/', File.separatorChar);
735             File JavaDoc f = questionsFile.getParentFile();
736             while (f != null) {
737                 File JavaDoc check = new File JavaDoc(f, dtd);
738                 if (check.isFile()) {
739                     String JavaDoc r = check.toURI().toString();
740                     log("Replacing entity " + publicId + " at " + systemId + " with " + r);
741                     return new InputSource JavaDoc(r);
742                 }
743                 f = f.getParentFile();
744             }
745         }
746         
747         String JavaDoc 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 JavaDoc u = new URL JavaDoc(systemId);
755             u.openStream();
756             log("systemId " + systemId + " exists, leaving", Project.MSG_VERBOSE);
757             return null;
758         } catch (IOException JavaDoc ex) {
759             // ok
760
}
761         
762         InputSource JavaDoc is;
763         log("Replacing entity " + publicId + " at " + systemId + " with " + replace);
764         if (replace.startsWith("http://")) {
765             is = new InputSource JavaDoc(new URL JavaDoc(replace).openStream());
766             is.setSystemId(replace);
767         } else {
768             is = new InputSource JavaDoc(Arch.class.getResourceAsStream(replace));
769             is.setSystemId(replace);
770         }
771         return is;
772     }
773
774     public Source JavaDoc resolve(String JavaDoc href, String JavaDoc base) throws TransformerException JavaDoc {
775         return null;
776     }
777 }
778
Popular Tags