1 19 20 import java.io.File ; 21 import java.io.FileOutputStream ; 22 import java.io.FileReader ; 23 import java.io.OutputStream ; 24 import java.io.PrintStream ; 25 import java.io.Reader ; 26 import java.io.StringReader ; 27 import java.net.URI ; 28 import java.util.ArrayList ; 29 import java.util.Date ; 30 import java.util.HashMap ; 31 import java.util.HashSet ; 32 import java.util.Iterator ; 33 import java.util.List ; 34 import java.util.Locale ; 35 import java.util.Map ; 36 import java.util.Properties ; 37 import java.util.Set ; 38 import java.util.regex.Matcher ; 39 import java.util.regex.Pattern ; 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.TransformerFactory ; 46 import javax.xml.transform.dom.DOMSource ; 47 import javax.xml.transform.stream.StreamResult ; 48 import javax.xml.transform.stream.StreamSource ; 49 import org.apache.tools.ant.BuildException; 50 import org.apache.tools.ant.Project; 51 import org.apache.tools.ant.Task; 52 import org.w3c.dom.DOMImplementation ; 53 import org.w3c.dom.Document ; 54 import org.w3c.dom.DocumentType ; 55 import org.w3c.dom.Element ; 56 57 62 public class MakeManual extends Task { 63 64 private File dir; 65 public void setDir(File d) { 66 dir = d; 67 } 68 69 private File hs; 70 public void setHS(File f) { 71 hs = f; 72 } 73 74 public void execute() throws BuildException { 75 if (dir == null || hs == null) { 76 throw new BuildException(); 77 } 78 File antdocs = new File (dir, "ant-docs"); 79 if (!antdocs.isDirectory()) { 80 throw new BuildException(); 81 } 82 try { 83 String [] stylesheets = {"antmanual.css", "style.css"}; 84 for (int i = 0; i < stylesheets.length; i++) { 85 OutputStream os = new FileOutputStream (new File (antdocs, "stylesheets/" + stylesheets[i])); 86 try { 87 PrintStream ps = new PrintStream (os); 88 ps.println("/* This document was modified on " + new Date () + " by ant.netbeans.org to meet accessibility guidelines. */"); 89 ps.println("@import \"../../../../../../../netbeans/modules/usersguide/ide.css\";"); 90 ps.flush(); 91 } finally { 92 os.close(); 93 } 94 } 95 Properties taskdefs = new Properties (); 96 taskdefs.load(Project.class.getResourceAsStream("/org/apache/tools/ant/taskdefs/defaults.properties")); 97 Properties typedefs = new Properties (); 98 typedefs.load(Project.class.getResourceAsStream("/org/apache/tools/ant/types/defaults.properties")); 99 TocItem top = tockify(antdocs, "toc.html", null, null, new HashSet (), taskdefs.keySet(), typedefs.keySet()); 100 writeMapAndToc(top); 101 } catch (Exception x) { 102 throw new BuildException(x); 103 } 104 } 106 107 private static int depth = 0; 108 private TocItem tockify(File antdocs, String path, String anchor, String linktext, Set files, Set tasknames, Set typenames) throws Exception { 109 String file = anchor != null ? path + "#" + anchor : path; 110 if (!files.add(file)) { 111 return null; 112 } 113 File f = new File (antdocs, path.replace('/', File.separatorChar)); 114 if (!f.isFile()) { 115 return null; 116 } 117 String id; 118 String token = anchor != null ? anchor : path.replaceFirst("\\.html$", "").replaceFirst("^.+/", ""); 119 String linktextlower = linktext != null ? linktext.toLowerCase(Locale.US) : ""; 120 if (tasknames.contains(token)) { 121 id = "org.apache.tools.ant.module.tasks." + token; 122 } else if (tasknames.contains(linktextlower)) { 123 id = "org.apache.tools.ant.module.tasks." + linktextlower; 124 } else if (typenames.contains(token)) { 125 id = "org.apache.tools.ant.module.types." + token; 126 } else if (typenames.contains(linktextlower)) { 127 id = "org.apache.tools.ant.module.types." + linktextlower; 128 } else { 129 id = "org.apache.tools.ant.module.ant-docs." + path.replaceFirst("\\.html$", "").replace('/', '.'); 130 if (anchor != null) { 131 id += "." + anchor; 132 } 133 } 134 String title = linktext != null ? linktext : "Ant 1.7.0 Manual"; 135 String log = ""; 136 for (int i = 0; i < depth; i++) { 137 log += "\t"; 138 } 139 log(log + path + " as " + id + ": \"" + title + "\""); 140 StringBuffer contents = new StringBuffer (); 141 Reader r = new FileReader (f); 142 try { 143 int c; 144 while ((c = r.read()) != -1) { 145 contents.append((char) c); 146 } 147 } finally { 148 r.close(); 149 } 150 158 TocItem ti = new TocItem(id, file, title); 159 if (path.matches("(toc|.+list|tutorials)\\.html")) { 160 depth++; 161 Matcher m = Pattern.compile("<a HREF=\"([^\"#]+)(#([^\"]+))?\".*?>(.+?)</a>", Pattern.CASE_INSENSITIVE).matcher(contents); 162 while (m.find()) { 163 String relurl = m.group(1); 164 String newanchor = m.group(3); 165 String newpath = URI.create(path).resolve(relurl).toString(); 166 if (path.equals("coretasklist.html") && newpath.equals("optionaltasklist.html")) { 167 continue; 169 } 170 if (path.equals("developlist.html") && newpath.startsWith("tutorial-")) { 171 continue; 173 } 174 String newlinktext = m.group(4).replaceAll("<[iI]>(.+?)</[iI]>", "($1)").replace("&", "&"); 175 TocItem subitem = tockify(antdocs, newpath, newanchor, newlinktext, files, tasknames, typenames); 176 if (subitem != null) { 177 ti.subitems.add(subitem); 178 } 179 } 180 depth--; 181 } 182 return ti; 183 } 184 185 private void writeMapAndToc(TocItem top) throws Exception { 186 Document mapXml = createDocument("map", "-//Sun Microsystems Inc.//DTD JavaHelp Map Version 2.0//EN", "http://java.sun.com/products/javahelp/map_2_0.dtd"); 187 mapXml.getDocumentElement().setAttribute("version", "2.0"); 188 Document tocXml = createDocument("toc", "-//Sun Microsystems Inc.//DTD JavaHelp TOC Version 2.0//EN", "http://java.sun.com/products/javahelp/toc_2_0.dtd"); 189 tocXml.getDocumentElement().setAttribute("version", "2.0"); 190 insertTocItem(top, mapXml, tocXml.getDocumentElement(), new HashMap ()); 191 write(new File (dir, "map.xml"), mapXml); 192 write(new File (dir, "toc.xml"), tocXml); 193 } 194 private static Element insertTocItem(TocItem ti, Document mapXml, Element toc, Map mapEntries) { 195 Element el = toc.getOwnerDocument().createElement("tocitem"); 196 if (ti.id != null) { 197 if (mapEntries.containsKey(ti.id) && !mapEntries.get(ti.id).equals(ti.file)) { 198 throw new IllegalArgumentException ("Dupes: " + ti.id + " " + ti.file + " " + mapEntries.get(ti.id)); 199 } 200 mapEntries.put(ti.id, ti.file); 201 el.setAttribute("target", ti.id); 202 Element map = mapXml.createElement("mapID"); 203 map.setAttribute("target", ti.id); 204 map.setAttribute("url", "ant-docs/" + ti.file); 205 mapXml.getDocumentElement().appendChild(map); 206 } 207 toc.appendChild(el); 208 el.setAttribute("text", ti.text); 209 Iterator it = ti.subitems.iterator(); 210 while (it.hasNext()) { 211 insertTocItem((TocItem) it.next(), mapXml, el, mapEntries); 212 } 213 return el; 214 } 215 private static class TocItem { 216 final String id; 217 final String file; 218 final String text; 219 final List subitems = new ArrayList (); 220 public TocItem(String id, String file, String text) { 221 assert id != null ^ file == null; 222 assert text != null; 223 this.id = id; 224 this.file = file; 225 this.text = text; 226 } 227 } 228 229 231 private static final String IDENTITY_XSLT_WITH_INDENT = 232 "<xsl:stylesheet version='1.0' " + 233 "xmlns:xsl='http://www.w3.org/1999/XSL/Transform' " + 234 "xmlns:xalan='http://xml.apache.org/xslt' " + 235 "exclude-result-prefixes='xalan'>" + 236 "<xsl:output method='xml' indent='yes' xalan:indent-amount='4'/>" + 237 "<xsl:template match='@*|node()'>" + 238 "<xsl:copy>" + 239 "<xsl:apply-templates select='@*|node()'/>" + 240 "</xsl:copy>" + 241 "</xsl:template>" + 242 "</xsl:stylesheet>"; 243 private static void write(File xml, Document doc) throws Exception { 244 OutputStream out = new FileOutputStream (xml); 245 try { 246 Transformer t = TransformerFactory.newInstance().newTransformer( 247 new StreamSource (new StringReader (IDENTITY_XSLT_WITH_INDENT))); 248 DocumentType dt = doc.getDoctype(); 249 if (dt != null) { 250 String pub = dt.getPublicId(); 251 if (pub != null) { 252 t.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, pub); 253 } 254 t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, dt.getSystemId()); 255 } 256 t.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 257 Source source = new DOMSource (doc); 258 Result result = new StreamResult (out); 259 t.transform(source, result); 260 } finally { 261 out.close(); 262 } 263 } 264 265 private static Document createDocument(String root, String doctypePublicID, String doctypeSystemID) throws Exception { 266 DOMImplementation impl = DocumentBuilderFactory.newInstance().newDocumentBuilder().getDOMImplementation(); 267 DocumentType dtd = null; 268 if (doctypeSystemID != null) { 269 dtd = impl.createDocumentType(root, doctypePublicID, doctypeSystemID); 270 } 271 return impl.createDocument(null, root, dtd); 272 } 273 274 } 275 | Popular Tags |