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)
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
21 package gnu
.classpath
.tools
.doclets
.xmldoclet
.doctranslet
;
23 import java
.io
.ByteArrayInputStream
;
24 import java
.io
.ByteArrayOutputStream
;
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
;
35 import java
.util
.ArrayList
;
36 import java
.util
.Iterator
;
37 import java
.util
.List
;
38 import java
.util
.HashMap
;
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
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
) {
89 reporter
.printNotice(out
.toString());
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
);
122 filename
= filename
.substring(0, lastSlash
);
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
;
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
,
173 reporter
.printNotice("Running DocTranslet...");
175 TransformerFactory transformerFactory
176 = TransformerFactory
.newInstance();
178 transformerFactory
.setErrorListener(this);
181 = transformerFactory
.getClass().getName().equals("gnu.xml.libxmlj.transform.TransformerFactoryImpl");
183 for (Iterator it
= outputFileList
.iterator(); it
.hasNext(); ) {
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.");
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
);
230 reporter
.printNotice("Generating " + fileInfo
.getComment() + "...");
232 String pathToRoot
= "";
233 for (File file
= getParentFile(targetFile
); !equalsFile(file
, targetDirectory
); file
= getParentFile(file
)) {
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
);
293 private List
getOutputFileList(URL resource
, File xmlSourceDirectory
, Map parameters
)
294 throws DocTransletException
{
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()),
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));
331 = (null != elem
.getElementsByTagName("source").item(0))
332 ?
getTextContent(elem
.getElementsByTagName("source").item(0))
335 = (null != elem
.getElementsByTagName("sheet").item(0))
336 ?
getTextContent(elem
.getElementsByTagName("sheet").item(0))
338 String comment
= getTextContent(elem
.getElementsByTagName("comment").item(0));
340 if (elem
.getElementsByTagName("info").getLength() > 0) {
341 if (null != elem
.getElementsByTagName("info").item(0).getFirstChild()) {
342 info
= getTextContent(elem
.getElementsByTagName("info").item(0));
348 result
.add(new OutputFileInfo(name
, source
, sheet
, comment
, info
));
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
);
371 String value
= item
.getNodeValue();
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
{
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
) {
426 public void error (TransformerException exception
)
427 throws TransformerException
{
432 public void fatalError (TransformerException exception
)
433 throws TransformerException
{
438 public void warning (TransformerException exception
)
439 throws TransformerException
{
441 System
.err
.println("WWW: " + exception
.getMessage());