/*
* Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package org.visage.tools.xslhtml;
import org.visage.tools.script.VisageScriptEngineFactory;
import org.visage.tools.xmldoclet.Util;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptException;
import javax.swing.JComponent;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import static java.util.logging.Level.*;
/**
*
* @author joshua.marinacci@sun.com
*/
public class XHTMLProcessingUtils {
private static PrintWriter pw = null;
private static ResourceBundle messageRB = null;
private static Logger logger = Logger.getLogger(XHTMLProcessingUtils.class.getName());;
private static boolean SDK_THEME = true;
static {
// set verbose for initial development
logger.setLevel(ALL); //TODO: remove or set to INFO when finished
}
private static final String PARAMETER_PROFILES_ENABLED = "profiles-enabled";
private static final String PARAMETER_TARGET_PROFILE = "target-profile";
/**
* Transform XMLDoclet output to XHTML using XSLT.
*
* @param xmlInputPath the path of the XMLDoclet output to transform
* @param xsltStream the XSLT to implement the transformation, as an input stream.
* @throws java.lang.Exception
*/
public static void process(List<String> xmlInputs, InputStream xsltStream,
String sourcePath, File docsdir, Map<String,String> parameters
) throws Exception {
if (xmlInputs == null || xmlInputs.size() == 0)
throw new IllegalArgumentException("no XML input file(s)");
System.out.println(getString("transforming.to.html"));
// TODO code application logic here
//hack to get this to work on the mac
System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
"com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
System.setProperty("javax.xml.parsers.SAXParserFactory",
"com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
if (xsltStream == null) {
if(SDK_THEME) {
xsltStream = XHTMLProcessingUtils.class.getResourceAsStream("resources/sdk.xsl");
} else {
xsltStream = XHTMLProcessingUtils.class.getResourceAsStream("resources/javadoc.xsl");
}
}
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setErrorHandler(new ErrorHandler() {
public void warning(SAXParseException exception) throws SAXException {
pe(WARNING, "warning: ", exception);
}
public void error(SAXParseException exception) throws SAXException {
pe(SEVERE, "error: ", exception);
}
public void fatalError(SAXParseException exception) throws SAXException {
pe(SEVERE, "fatal error", exception);
}
private void pe(Level level, String string, SAXParseException exception) {
p(level, string + " line: " + exception.getLineNumber() + " column: " +
exception.getColumnNumber() + " " + exception.getLocalizedMessage());
}
});
//File docsdir = new File("visagedocs");
if (!docsdir.exists()) {
docsdir.mkdir();
}
p(INFO, getString("copying"));
copyResource(docsdir,"empty.html");
copyResource(docsdir,"general.css");
copyResource(docsdir,"sdk.css");
copyResource(docsdir,"mootools-1.2.1-yui.js");
copyResource(docsdir,"sdk.js");
copyResource(docsdir,"sessvars.js");
File images = new File(docsdir,"images");
images.mkdir();
copy(XHTMLProcessingUtils.class.getResource("resources/quote-background-1.gif"), new File(images, "quote-background-1.gif"));
copyResource(images,"Visage_arrow_down.png");
copyResource(images,"Visage_arrow_right.png");
copyResource(images,"Visage_arrow_up.png");
copyResource(images,"Visage_highlight_dot.png");
p(INFO, getString("transforming"));
//File xsltFile = new File("javadoc.xsl");
//p("reading xslt exists in: " + xsltFile.exists());
Source xslt = new StreamSource(xsltStream);
TransformerFactory transFact = TransformerFactory.newInstance();
transFact.setURIResolver(new URIResolver() {
public Source resolve(String href, String base) throws TransformerException {
p(INFO, "Trying to resolve: " + href + " " + base);
URL url = XHTMLProcessingUtils.class.getResource("resources/"+href);
p(INFO, "Resolved " + href + ":" + base + " to " + url);
try {
return new StreamSource(url.openStream());
} catch (IOException ex) {
Logger.getLogger(XHTMLProcessingUtils.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}
});
Transformer trans = transFact.newTransformer(xslt);
if(SDK_THEME) {
trans.setParameter("inline-classlist","true");
trans.setParameter("inline-descriptions", "true");
}
for(String key : parameters.keySet()) {
System.out.println("using key: " + key + " " + parameters.get(key));
trans.setParameter(key, parameters.get(key));
}
trans.setErrorListener(new MainErrorListener());
//build xml doc for the packages
Document packages_doc = builder.newDocument();
Element package_list_elem = packages_doc.createElement("packageList");
packages_doc.appendChild(package_list_elem);
//merge all xml files into single document
Document unified = builder.newDocument();
Element javadocElement = unified.createElement("javadoc");
unified.appendChild(javadocElement);
mergeDocuments(xmlInputs, builder, unified, javadocElement);
// print out packages list
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList packages = (NodeList) xpath.evaluate("/javadoc/package", unified, XPathConstants.NODESET);
p(INFO, MessageFormat.format(getString("creating.packages"), packages.getLength()));
// collect all package names in this array
String[] pkgNames = new String[packages.getLength()];
//for each package, generate the package itself and append to package list doc
for (int i = 0; i < packages.getLength(); i++) {
Element pkg = ((Element) packages.item(i));
String name = pkg.getAttribute("name");
Element package_elem = packages_doc.createElement("package");
package_elem.setAttribute("name", name);
package_list_elem.appendChild(package_elem);
copyDocComment(pkg,package_elem);
Element first_line = packages_doc.createElement("first-line-comment");
first_line.appendChild(packages_doc.createTextNode("first line comment"));
package_elem.appendChild(first_line);
processPackage(name, pkg, xpath, docsdir, trans, package_elem);
pkgNames[i] = name;
}
//}
//transform the package list doc
trans.setParameter("root-path", "./");
package_list_elem.setAttribute("mode", "overview-summary");
trans.transform(new DOMSource(packages_doc), new StreamResult(new File(docsdir,"index.html")));
Transformer indexTrans = transFact.newTransformer(new StreamSource(XHTMLProcessingUtils.class.getResourceAsStream("resources/master-index.xsl")));
indexTrans.setParameter("root-path", "./");
indexTrans.transform(new DOMSource(unified), new StreamResult(new File(docsdir,"master-index.html")));
// copy "doc-files" for all packages to output
Util.copyDocFiles(pkgNames, sourcePath, docsdir);
p(INFO,getString("finished"));
}
private static void mergeDocuments(List<String> xmlInputs, DocumentBuilder builder, Document unified, Element javadocElement)
throws DOMException, SAXException, XPathExpressionException, IOException {
Map<String,Element> packageMap = new HashMap<String,Element>();
for (String xmlInputPath : xmlInputs) {
File file = new File(xmlInputPath);
p(INFO, MessageFormat.format(getString("reading.doc"), file.getAbsolutePath()));
p(FINE, "exists: " + file.exists());
Document doc = builder.parse(file);
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList packages = (NodeList) xpath.evaluate("/javadoc/package", doc, XPathConstants.NODESET);
p(INFO,"found " + packages.getLength()+" packages");
for (int i = 0; i < packages.getLength(); i++) {
Element copy = (Element) unified.importNode(packages.item(i), true);
String pkgName = copy.getAttribute("name");
if(!packageMap.containsKey(pkgName)) {
packageMap.put(pkgName, copy);
} else {
Element pkg = packageMap.get(pkgName);
NodeList classes = copy.getChildNodes();
//copy to a List for safety before we start moving nodes around
List<Node> classesList = new ArrayList<Node>();
for(int j=0; j<classes.getLength();j++) {
classesList.add(classes.item(j));
}
for(Node cls : classesList) {
pkg.appendChild(cls);
}
}
}
}
for(String pkgName : packageMap.keySet()) {
Element pkg = packageMap.get(pkgName);
javadocElement.appendChild(pkg);
}
}
/*//keep this around for now.
private static void p(Level INFO, Element javadocElement, String tab) {
p(INFO,javadocElement,tab,-1);
}
private static void p(Level INFO, Element javadocElement, String tab, int depth) {
if(depth ==0) return;
p(INFO,tab+"<element: " + javadocElement.getTagName() + " " + javadocElement.hashCode());
for(int i=0; i<javadocElement.getAttributes().getLength(); i++) {
Attr attr = (Attr) javadocElement.getAttributes().item(i);
p(INFO,tab+" attr: " + attr.getName() + "=" + attr.getValue());
}
for(int i=0; i<javadocElement.getChildNodes().getLength();i++) {
Node n = javadocElement.getChildNodes().item(i);
if(n instanceof Element) {
p(INFO,(Element)n,tab+" ",depth-1);
} else {
p(INFO,tab+" child = " + n.getNodeName() + " " + n.getNodeValue() + " " + n.hashCode());
}
}
p(INFO,tab+"</element: " + javadocElement.getTagName());
}
*/
// Not used
/* private static void p(Transformer trans, Document packages_doc) throws TransformerException {
trans.transform(new DOMSource(packages_doc), new StreamResult(System.out));
}*/
private static void processPackage(String packageName, Element pkg, XPath xpath, File docsdir, Transformer trans, Element package_elem) throws TransformerException, XPathExpressionException, IOException, FileNotFoundException, ParserConfigurationException {
File packageDir = new File(docsdir, packageName);
packageDir.mkdir();
//classes
NodeList classesNodeList = (NodeList) xpath.evaluate(
"*[name() = 'class' or name() = 'abstractClass' or name() = 'interface']",
pkg, XPathConstants.NODESET);
List<Element> classes = sort(classesNodeList);
p(INFO, MessageFormat.format(getString("creating.classes"), classes.size(), packageName));
Document classes_doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element class_list = classes_doc.createElement("classList");
class_list.setAttribute("packageName", packageName);
classes_doc.appendChild(class_list);
for(Element clazz : classes) {
processClass(clazz, class_list, xpath, trans, packageDir);
Element clazz_elem = (Element) package_elem.getOwnerDocument().importNode(clazz, true);
package_elem.appendChild(clazz_elem);
}
class_list.setAttribute("mode", "overview-frame");
trans.setParameter("root-path", "../");
trans.transform(new DOMSource(classes_doc), new StreamResult(new File(packageDir,"package-frame.html")));
class_list.setAttribute("mode", "overview-summary");
trans.setParameter("root-path", "../");
trans.transform(new DOMSource(classes_doc), new StreamResult(new File(packageDir,"package-summary.html")));
}
private static void processClass(Element clazz, Element class_list, XPath xpath, Transformer trans, File packageDir) throws TransformerException, IOException, XPathExpressionException {
String qualifiedName = clazz.getAttribute("qualifiedName");
String name = clazz.getAttribute("name");
String profile = (String) xpath.evaluate("docComment/tags/profile/text()", clazz, XPathConstants.STRING);
if("true".equals(trans.getParameter(PARAMETER_PROFILES_ENABLED))) {
Object target_profile = trans.getParameter(PARAMETER_TARGET_PROFILE);
if(profile != null && profile.equals(target_profile)) {
//p(INFO, "profiles match");
} else {
//p(INFO, "Profiles don't match. skipping");
return;
}
}
//add to class list
Document doc = class_list.getOwnerDocument();
Element class_elem = doc.createElement("class");
class_list.appendChild(class_elem);
class_elem.setAttribute("name", name);
class_elem.setAttribute("qualifiedName", qualifiedName);
Element first_line = doc.createElement("first-line-comment");
first_line.appendChild(doc.createTextNode("first line comment"));
class_elem.appendChild(first_line);
copyClassDoc(clazz,class_elem);
processInlineExamples(clazz, class_elem, packageDir);
File xhtmlFile = new File(packageDir, qualifiedName + ".html");
Result xhtmlResult = new StreamResult(xhtmlFile);
Source xmlSource = new DOMSource(clazz.getOwnerDocument());
trans.setParameter("target-class", qualifiedName);
trans.setParameter("root-path", "../");
trans.transform(xmlSource, xhtmlResult);
}
private static void copyClassDoc(Element clazz, Element class_elem) {
Element docComment = (Element) clazz.getElementsByTagName("docComment").item(0);
if(docComment == null) return;
NodeList firstSent = docComment.getElementsByTagName("firstSentenceTags");
if(firstSent.getLength() > 0) {
class_elem.appendChild(class_elem.getOwnerDocument().importNode(firstSent.item(0),true));
}
NodeList tags = docComment.getElementsByTagName("tags");
if(tags.getLength() > 0) {
for(int i=0; i<tags.getLength(); i++) {
Node tag = tags.item(i);
class_elem.appendChild(class_elem.getOwnerDocument().importNode(tag,true));
}
}
}
private static void copyDocComment(Element pkg, Element package_elem) {
Element docComment = getFirstChildNamed(pkg, "docComment");
if (docComment != null) {
Node copy = package_elem.getOwnerDocument().importNode(docComment, true);
package_elem.appendChild(copy);
}
}
// return the first child element of the given name, if not found return null
private static Element getFirstChildNamed(Element elem, String childName) {
NodeList children = elem.getChildNodes();
final int length = children.getLength();
for (int index = 0; index < length; index++) {
Node node = children.item(index);
if ((node instanceof Element) &&
((Element)node).getTagName().equals(childName)){
return (Element)node;
}
}
return null;
}
private static List<Element> sort(NodeList classesNodeList) {
List<Element> nodes = new ArrayList<Element>();
for(int i=0; i<classesNodeList.getLength(); i++) {
nodes.add((Element)classesNodeList.item(i));
}
Collections.sort(nodes,new Comparator<Element>() {
public int compare(Element o1, Element o2) {
return o1.getAttribute("qualifiedName").compareTo(
o2.getAttribute("qualifiedName"));
}
}
);
return nodes;
}
private static void copy(URL url, File file) throws FileNotFoundException, IOException {
p(FINE, "copying from: " + url);
p(FINE, "copying to: " + file.getAbsolutePath());
InputStream in = url.openStream();
FileOutputStream out = new FileOutputStream(file);
byte[] buf = new byte[1024];
while (true) {
int n = in.read(buf);
if (n < 0) {
break;
}
out.write(buf, 0, n);
}
}
private static void copyResource(File docsdir, String string) throws FileNotFoundException, IOException {
copy(XHTMLProcessingUtils.class.getResource("resources/"+string),new File(docsdir,string));
}
/* Not used
private static void copy(File infile, File outfile) throws FileNotFoundException, IOException {
FileInputStream in = new FileInputStream(infile);
FileOutputStream out = new FileOutputStream(outfile);
byte[] buf = new byte[1024];
while (true) {
int n = in.read(buf);
if (n < 0) {
break;
}
out.write(buf, 0, n);
}
}
*/
static String getString(String key) {
ResourceBundle msgRB = messageRB;
if (msgRB == null) {
try {
messageRB = msgRB =
ResourceBundle.getBundle("org.visage.tools.xslhtml.resources.xslhtml");
} catch (MissingResourceException e) {
throw new Error("Fatal: Resource for visagedoc is missing");
}
}
return msgRB.getString(key);
}
private static void p(Level level, String string) {
if (level.intValue() >= logger.getLevel().intValue())
System.err.println(string);
}
private static void p(Level level, String string, Throwable t) {
if (level.intValue() >= logger.getLevel().intValue()) {
StringBuilder sb = new StringBuilder();
sb.append(string);
if (t != null) {
sb.append(System.getProperty("line.separator"));
try {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
pw.close();
sb.append(sw.toString());
} catch (Exception ex) {
}
}
System.err.println(sb.toString());
}
}
/* Not used
private static void p(String string) {
System.out.println(string);
}
*/
/**
* Command-line/debugging entry
*/
public static void main(String[] args) throws Exception {
List<String> inputs = new ArrayList<String>();
inputs.add("javadoc.xml");
process(inputs, null, ".", new File("visagedocs_test"), new HashMap<String, String>());
}
private static class MainErrorListener implements ErrorListener {
public MainErrorListener() {
}
public void warning(TransformerException exception) throws TransformerException {
p(WARNING, "warning: " + exception);
}
public void error(TransformerException exception) throws TransformerException {
Throwable thr = exception;
while (true) {
p(SEVERE, "error: " + exception.getMessageAndLocation(), thr.getCause());
if (thr.getCause() != null) {
thr = thr.getCause();
} else {
break;
}
}
}
public void fatalError(TransformerException exception) throws TransformerException {
p(SEVERE, "fatal error: " + exception.getMessageAndLocation(), exception);
}
}
private static void processInlineExamples(Element clazz, Element class_elem, File packageDir) {
NodeList examples = clazz.getElementsByTagName("example");
if(examples != null & examples.getLength() > 0) {
for(int i=0; i<examples.getLength(); i++) {
Element example = (Element) examples.item(i);
processExampleCode(example, packageDir, clazz, i, true);
}
}
NodeList highlights = clazz.getElementsByTagName("highlight");
if(highlights != null && highlights.getLength() > 0) {
for(int i=0; i<highlights.getLength(); i++) {
Element highlight = (Element) highlights.item(i);
processExampleCode(highlight, packageDir, clazz, i, false);
}
}
}
private static void processExampleCode(Element example, File packageDir, Element clazz, int i, boolean renderScreenshot) throws DOMException {
//p(INFO, MessageFormat.format(getString("processing.example"), clazz.getAttribute("name")));
//p(INFO, example.getTextContent());
//String script = "import visage.gui.*; CubicCurve { x1: 0 y1: 50 ctrlX1: 25 ctrlY1: 0 ctrlX2: 75 ctrlY2: 100 x2: 100 y2: 50 fill:Color.RED }";
String script = example.getTextContent();
StringBuffer out = new StringBuffer();
out.append("<p>the code:</p>");
out.append("<pre class='example-code'><code>");
String styledScript = highlight(script);
out.append(styledScript);
out.append("</code></pre>");
if(renderScreenshot) {
File imgFile = new File(packageDir, clazz.getAttribute("name") + i + ".png");
boolean success = renderScriptToImageAsync(imgFile, script, clazz.getAttribute("name"));
if (success) {
out.append("<p>produces:</p>");
out.append("<p>");
out.append("<img class='example-screenshot' src='" + imgFile.getName() + "'/>");
out.append("</p>");
}
}
example.setTextContent(out.toString());
}
private static String highlight(String text) {
//String pattern = "(/\\*)";
//String replace = "<span class='comment'>/*";
//comments
text = text.replaceAll("/\\*", "<i class='comment'>/*");
text = text.replaceAll("\\*/","*/</i>");
//imports
text = text.replaceAll("(import|package)","<b>$1</b>");
//keywords
text = text.replaceAll("(var)","<b class='keyword'>$1</b>");
//attribute names
text = text.replaceAll("(\\w\\w*):","<b>$1</b>:");
//attribute values
text = text.replaceAll("(\\d+)","<span class='number-literal'>$1</span>");
text = text.replaceAll("(\".*\")","<span class='string-literal'>$1</span>");
//put inside of precode
//text = "<pre><code>"+text+"</code></pre>";
//text = "<html><head><link rel='stylesheet' href='test.css'/></head><body>"+
// text +"</body></html>";
return text;
}
private static boolean renderScriptToImageAsync(final File imgFile,
final String script,
final String name) {
final boolean[] result = new boolean[1];
try {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
try {
renderScriptToImage(imgFile, script);
result[0] = true;
} catch (Throwable ex) {
System.out.println("error processing code: " + name);
System.out.println("error processing : " + script);
ex.printStackTrace();
result[0] = false;
}
}
});
} catch (Throwable ex) {
System.out.println("error processing code: " + name);
System.out.println("error processing : " + script);
ex.printStackTrace();
result[0] = false;
}
return result[0];
}
@SuppressWarnings("unchecked")
private static void renderScriptToImage(File imgFile, String script) throws ScriptException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException, ClassNotFoundException {
ScriptEngineFactory factory = new VisageScriptEngineFactory();
ScriptEngine scrEng = factory.getScriptEngine();
if (pw == null) {
pw = new PrintWriter(System.err);
}
scrEng.getContext().setErrorWriter(pw);
try {
Object ret = scrEng.eval(script);
// FIXME: should we use visage.reflect here?
Class<?> visageStageClass = Class.forName("visage.stage.Stage");
Class<?> visageSceneClass = Class.forName("visage.scene.Scene");
Class<?> visageNodeClass = Class.forName("visage.scene.Node");
Object scene = null;
if (visageSceneClass.isInstance(ret)) {
scene = ret;
} else if (visageStageClass.isInstance(ret)) {
try {
scene = visageStageClass.getMethod("get$scene").invoke(ret);
} catch (Exception ex) {
pw.println("visagedoc: Exception while processing " + imgFile);
ex.printStackTrace(pw);
pw.flush();
return;
}
} else if (visageNodeClass.isInstance(ret)) {
try {
scene = visageNodeClass.getMethod("get$scene").invoke(ret);
} catch (Exception ex) {
pw.println("visagedoc: Exception while processing " + imgFile);
ex.printStackTrace(pw);
}
if (scene == null) {
// Node is not added to a scene. Create a scene with this
// node as "content" of it. Need to change file name to
// get proper "eval" return value!
scrEng.put(ScriptEngine.FILENAME, "___SCENE_WRAPPER___.visage");
scrEng.put("node", ret);
scene = scrEng.eval(
"visage.scene.Scene { " +
" content: [ node as visage.scene.Node ] " +
"}");
}
} else {
Object visageclass = ret.getClass();
pw.println("ERROR: Unrecongized Visage class: " + visageclass);
pw.flush();
return;
}
try {
Method renderToImage = visageSceneClass.getMethod("renderToImage", Object.class);
BufferedImage img = (BufferedImage) renderToImage.invoke(scene, (Object)null);
ImageIO.write(img, "png", imgFile);
} catch (Exception ex) {
pw.println("visagedoc: Exception while processing " + imgFile);
ex.printStackTrace(pw);
}
} catch (javax.script.ScriptException ex) {
pw.println("visagedoc: Exception while processing " + imgFile);
pw.println(ex.getMessage());
pw.println(" at: line = " + ex.getLineNumber() + " column = " + ex.getColumnNumber());
pw.println("file = " + ex.getFileName());
pw.println("exception = "+ ex.toString());
pw.println(ex.getMessage());
ex.printStackTrace(pw);
pw.println("cause = " + ex.getCause());
} finally {
pw.flush();
}
}
}