libjava/ChangeLog:
[official-gcc.git] / libjava / classpath / tools / gnu / classpath / tools / doclets / xmldoclet / doctranslet / DocTranslet.java
blob573ca368c6afb7402c0885512d4300d17e279039
1 /* gnu.classpath.tools.doclets.xmldoclet.doctranslet.DocTranslet
2 Copyright (C) 2001 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
21 package gnu.classpath.tools.doclets.xmldoclet.doctranslet;
23 import java.io.ByteArrayInputStream;
24 import java.io.ByteArrayOutputStream;
25 import java.io.File;
26 import java.io.FileOutputStream;
27 import java.io.InputStream;
28 import java.io.IOException;
29 import java.io.OutputStream;
30 import java.io.PrintStream;
32 import java.net.MalformedURLException;
33 import java.net.URL;
35 import java.util.ArrayList;
36 import java.util.Iterator;
37 import java.util.List;
38 import java.util.HashMap;
39 import java.util.Map;
41 import java.util.jar.JarFile;
42 import java.util.jar.Manifest;
43 import java.util.jar.Attributes;
45 import javax.xml.transform.ErrorListener;
46 import javax.xml.transform.Source;
47 import javax.xml.transform.Transformer;
48 import javax.xml.transform.TransformerException;
49 import javax.xml.transform.TransformerFactory;
50 import javax.xml.transform.TransformerFactoryConfigurationError;
51 import javax.xml.transform.URIResolver;
53 import javax.xml.transform.dom.DOMResult;
55 import javax.xml.transform.stream.StreamResult;
56 import javax.xml.transform.stream.StreamSource;
58 import javax.xml.parsers.DocumentBuilderFactory;
59 import javax.xml.parsers.DocumentBuilder;
60 import javax.xml.parsers.ParserConfigurationException;
62 import org.w3c.dom.Document;
63 import org.w3c.dom.Element;
64 import org.w3c.dom.Node;
65 import org.w3c.dom.NodeList;
67 import org.xml.sax.SAXException;
69 import gnu.classpath.tools.IOToolkit;
70 import gnu.classpath.tools.doclets.xmldoclet.Driver;
72 import com.sun.javadoc.DocErrorReporter;
74 public class DocTranslet implements ErrorListener {
76 private static class DocErrorReporterOutputStream
77 extends OutputStream
79 private ByteArrayOutputStream out = new ByteArrayOutputStream();
80 private DocErrorReporter reporter;
82 public DocErrorReporterOutputStream(DocErrorReporter reporter) {
83 this.reporter = reporter;
86 public void write(int ch) {
87 out.write(ch);
88 if (ch == 10) {
89 reporter.printNotice(out.toString());
90 out.reset();
95 private String mainResourceFilename;
96 private ClassLoader classLoader;
97 private Map transformerMap = new java.util.HashMap(); //WeakHashMap();
98 private DocTransletOptions options;
100 protected DocTranslet(String mainResourceFilename,
101 ClassLoader classLoader)
102 throws DocTransletConfigurationException {
104 if (mainResourceFilename.length() > 0 && mainResourceFilename.charAt(0) == '/') {
105 mainResourceFilename = mainResourceFilename.substring(1);
107 this.mainResourceFilename = mainResourceFilename;
108 this.classLoader = classLoader;
111 private static boolean equalsFile(File file1, File file2) {
112 return file1.getAbsolutePath().equals(file2.getAbsolutePath());
115 private static File getParentFile(File file) {
116 String filename = file.getAbsolutePath();
117 if (filename.endsWith(File.separator)) {
118 filename = filename.substring(0, filename.length() - 1);
120 int lastSlash = filename.lastIndexOf(File.separatorChar);
121 if (lastSlash > 0) {
122 filename = filename.substring(0, lastSlash);
124 else {
125 filename = File.separator;
128 return new File(filename);
131 private static boolean cacheXSLTSheets = true;
133 public void apply(File xmlSourceDirectory, File targetDirectory,
134 DocErrorReporter reporter)
135 throws DocTransletException {
137 PrintStream err = System.err;
139 try{
140 URL mainResourceURL = classLoader == null ?
141 ClassLoader.getSystemResource(mainResourceFilename):
142 classLoader.getResource(mainResourceFilename);
144 if (null == mainResourceURL) {
145 throw new DocTransletException("Cannot find resource '" + mainResourceFilename + "'");
149 Map parameters = new HashMap();
150 parameters.put("gjdoc.xmldoclet.version", Driver.XMLDOCLET_VERSION);
152 parameters.put("gjdoc.option.nonavbar", xsltBoolean(options.nonavbar));
153 parameters.put("gjdoc.option.noindex", xsltBoolean(options.noindex));
154 parameters.put("gjdoc.option.notree", xsltBoolean(options.notree));
155 parameters.put("gjdoc.option.nocomment", xsltBoolean(options.nocomment));
156 parameters.put("gjdoc.option.nohelp", xsltBoolean(options.nohelp));
157 parameters.put("gjdoc.option.splitindex", xsltBoolean(options.splitindex));
158 parameters.put("gjdoc.option.linksource", xsltBoolean(options.linksource));
159 parameters.put("gjdoc.option.nodeprecatedlist", xsltBoolean(options.nodeprecatedlist));
160 parameters.put("gjdoc.option.uses", xsltBoolean(options.uses));
161 parameters.put("gjdoc.option.windowtitle", options.windowtitle);
162 parameters.put("gjdoc.option.helpfile", options.helpfile);
163 parameters.put("gjdoc.option.stylesheetfile", options.stylesheetfile);
164 parameters.put("gjdoc.option.header", options.header);
165 parameters.put("gjdoc.option.footer", options.footer);
166 parameters.put("gjdoc.option.bottom", options.bottom);
167 parameters.put("gjdoc.option.doctitle", options.doctitle);
169 List outputFileList = getOutputFileList(mainResourceURL,
170 xmlSourceDirectory,
171 parameters);
173 reporter.printNotice("Running DocTranslet...");
175 TransformerFactory transformerFactory
176 = TransformerFactory.newInstance();
178 transformerFactory.setErrorListener(this);
180 boolean isLibxmlJ
181 = transformerFactory.getClass().getName().equals("gnu.xml.libxmlj.transform.TransformerFactoryImpl");
183 for (Iterator it = outputFileList.iterator(); it.hasNext(); ) {
185 if (isLibxmlJ) {
186 System.gc();
187 Runtime.getRuntime().runFinalization();
190 OutputFileInfo fileInfo = (OutputFileInfo)it.next();
192 File targetFile = new File(targetDirectory, fileInfo.getName());
193 File packageTargetDir = getParentFile(targetFile);
195 if (!packageTargetDir.exists() && !packageTargetDir.mkdirs()) {
196 throw new DocTransletException("Target directory " + packageTargetDir + " does not exist and cannot be created.");
199 if (options.linksource) {
200 File sourceTargetDirectory = new File(targetDirectory, "src-html");
201 File sourceTargetFile = new File(sourceTargetDirectory, fileInfo.getName());
202 File sourcePackageTargetDir = getParentFile(sourceTargetFile);
204 if (!sourcePackageTargetDir.exists() && !sourcePackageTargetDir.mkdirs()) {
205 throw new DocTransletException("Target directory " + packageTargetDir + " does not exist and cannot be created.");
209 if (options.uses) {
210 File usesTargetDirectory = new File(targetDirectory, "class-use");
211 File usesTargetFile = new File(usesTargetDirectory, fileInfo.getName());
212 File usesPackageTargetDir = getParentFile(usesTargetFile);
214 if (!usesPackageTargetDir.exists() && !usesPackageTargetDir.mkdirs()) {
215 throw new DocTransletException("Target directory " + packageTargetDir + " does not exist and cannot be created.");
219 if (null != fileInfo.getSource()) {
221 reporter.printNotice("Copying " + fileInfo.getComment() + "...");
222 InputStream in = new URL(mainResourceURL, fileInfo.getSource()).openStream();
223 FileOutputStream out = new FileOutputStream(targetFile.getAbsolutePath());
224 IOToolkit.copyStream(in, out);
225 in.close();
226 out.close();
228 else {
230 reporter.printNotice("Generating " + fileInfo.getComment() + "...");
232 String pathToRoot = "";
233 for (File file = getParentFile(targetFile); !equalsFile(file, targetDirectory); file = getParentFile(file)) {
234 pathToRoot += "../";
237 StreamResult out = new StreamResult(targetFile.getAbsolutePath());
239 StreamSource in = new StreamSource(new File(xmlSourceDirectory, "index.xml").getAbsolutePath());
240 URL resource = new URL(mainResourceURL, fileInfo.getSheet());
243 StreamSource xsltSource = new StreamSource(resource.toExternalForm());
245 if (null != fileInfo.getInfo()) {
246 parameters.put("gjdoc.outputfile.info", fileInfo.getInfo());
248 parameters.put("gjdoc.pathtoroot", pathToRoot);
250 Transformer transformer;
251 transformer = (Transformer)transformerMap.get(xsltSource.getSystemId());
252 if (null == transformer) {
253 transformer = transformerFactory.newTransformer(xsltSource);
254 if (cacheXSLTSheets) {
255 transformerMap.put(xsltSource.getSystemId(), transformer);
259 transformer.clearParameters();
260 for (Iterator pit = parameters.keySet().iterator(); pit.hasNext(); ) {
261 String key = (String)pit.next();
262 String value = (String)parameters.get(key);
263 transformer.setParameter(key, value);
266 transformer.setErrorListener(this);
267 DocErrorReporterOutputStream errorReporterOut
268 = new DocErrorReporterOutputStream(reporter);
269 System.setErr(new PrintStream(errorReporterOut));
271 transformer.transform(in, out);
272 errorReporterOut.flush();
276 catch (MalformedURLException e) {
277 throw new DocTransletException(e);
279 catch (TransformerFactoryConfigurationError e) {
280 throw new DocTransletException(e);
282 catch (TransformerException e) {
283 throw new DocTransletException(e.getMessageAndLocation(), e);
285 catch (IOException e) {
286 throw new DocTransletException(e);
288 finally {
289 System.setErr(err);
293 private List getOutputFileList(URL resource, File xmlSourceDirectory, Map parameters)
294 throws DocTransletException {
296 try {
297 List result;
299 OutputStream out = new ByteArrayOutputStream();
301 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
302 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
303 Document document = documentBuilder.newDocument();
304 DOMResult domResult = new DOMResult(document);
306 StreamSource source = new StreamSource(resource.toExternalForm());
308 TransformerFactory transformerFactory = TransformerFactory.newInstance();
309 Transformer transformer = (Transformer)transformerFactory.newTransformer(source);
311 transformer.clearParameters();
312 for (Iterator pit = parameters.keySet().iterator(); pit.hasNext(); ) {
313 String key = (String)pit.next();
314 String value = (String)parameters.get(key);
315 transformer.setParameter(key, value);
318 transformer.transform(new StreamSource(new File(xmlSourceDirectory,
319 "index.xml").getAbsolutePath()),
320 domResult);
324 NodeList nodeList = document.getElementsByTagName("outputfile");
325 result = new ArrayList(nodeList.getLength());
327 for (int i=0; i<nodeList.getLength(); ++i) {
328 Element elem = (Element)nodeList.item(i);
329 String name = getTextContent(elem.getElementsByTagName("name").item(0));
330 String source
331 = (null != elem.getElementsByTagName("source").item(0))
332 ? getTextContent(elem.getElementsByTagName("source").item(0))
333 : null;
334 String sheet
335 = (null != elem.getElementsByTagName("sheet").item(0))
336 ? getTextContent(elem.getElementsByTagName("sheet").item(0))
337 : null;
338 String comment = getTextContent(elem.getElementsByTagName("comment").item(0));
339 String info = null;
340 if (elem.getElementsByTagName("info").getLength() > 0) {
341 if (null != elem.getElementsByTagName("info").item(0).getFirstChild()) {
342 info = getTextContent(elem.getElementsByTagName("info").item(0));
344 else {
345 info = "";
348 result.add(new OutputFileInfo(name, source, sheet, comment, info));
351 return result;
353 catch (TransformerFactoryConfigurationError e) {
354 throw new DocTransletException(e);
356 catch (TransformerException e) {
357 throw new DocTransletException(e.getMessageAndLocation(), e);
359 catch (ParserConfigurationException e) {
360 throw new DocTransletException(e);
364 private String getTextContent(Node elem)
366 StringBuffer result = new StringBuffer();
367 NodeList children = elem.getChildNodes();
368 for (int i=0; i<children.getLength(); ++i) {
369 Node item = children.item(i);
370 if (null != item) {
371 String value = item.getNodeValue();
372 if (null != value) {
373 result.append(value);
377 return result.toString();
380 public void setOptions(DocTransletOptions options) {
381 this.options = options;
385 public static DocTranslet fromClasspath(String resourceName)
386 throws DocTransletConfigurationException {
388 return new DocTranslet(resourceName,
389 DocTranslet.class.getClassLoader());
392 public static DocTranslet fromJarFile(File jarFile)
393 throws DocTransletConfigurationException {
395 try {
396 JarFile inputJarFile = new JarFile(jarFile, false, JarFile.OPEN_READ);
398 Manifest manifest = inputJarFile.getManifest();
400 if (null == manifest) {
402 throw new DocTransletConfigurationException("Jar file '" + jarFile + "' doesn't contain a manifest.");
405 Attributes mainAttributes = manifest.getMainAttributes();
407 String docTransletMainEntry = mainAttributes.getValue("doctranslet-main-entry");
409 if (null == docTransletMainEntry) {
411 throw new DocTransletConfigurationException("Manifest in Jar file '" + jarFile + "' doesn't contain a doctranslet-main-entry specification.");
414 return new DocTranslet(docTransletMainEntry,
415 new JarClassLoader(inputJarFile));
417 catch (IOException e) {
418 throw new DocTransletConfigurationException(e);
422 private static String xsltBoolean(boolean b) {
423 return b ? "1" : "";
426 public void error (TransformerException exception)
427 throws TransformerException {
429 throw exception;
432 public void fatalError (TransformerException exception)
433 throws TransformerException {
435 throw exception;
438 public void warning (TransformerException exception)
439 throws TransformerException {
441 System.err.println("WWW: " + exception.getMessage());