📄 xsltreport.java
字号:
package de.spieleck.app.jacson.report;
import de.spieleck.app.jacson.JacsonConfigException;
import de.spieleck.app.jacson.JacsonPrintReport;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import de.spieleck.config.ConfigNode;
import de.spieleck.helper.FopAdapter;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.LinkedList;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import de.spieleck.app.jacson.JacsonState;
/**
* This is a really powerful report, considering the output as
* XML and applying a XSL-Transformation on it. Note that a XSLT
* Processor needs some space for internal processing, but this
* is probably still less than the storage requirement of enhanced
* {@link de.spieleck.app.jacson.JacsonEvaluator} classes like
* {@link de.spieleck.app.jacson.eval.AccountingEvaluator}.
* <P>
* You can select ...
* <ul>
* <li>... the output file with a {@link PrintingReport#FILENAME_NODE} (default stdout).</li>
* <li>... the stylesheet with {@link #STYLE_NODE} (default identity).</li>
* <li>... set output properties with {@link #OUTPUTPROPERTY_NODE}.</li>
* <li>... set xsl:param with {@link #PARAMETER_NODE}.</li>
* </ul>
* </p>
* It should be nothing this report cannot create from the input:
* Good XML, good CSV, HTML, PDF (with xsl:fo).
* @author fsn
* @author Patrick Carl
*/
public class XSLTReport
implements JacsonPrintReport
{
public final static String STYLE_NODE = "style";
public final static String OUTPUTPROPERTY_NODE = "output-property";
public final static String PARAMETER_NODE = "parameter";
public final static String NAME_NODE = "name";
public final static String VALUE_NODE = "value";
public final static String NAME_ATT = "name";
public final static String ROOT_ELEM = "xsltreport";
public final static String ITEM_ELEM = "item";
public final static String NAMESPACE = "";
private final static Attributes dummyAtts = new AttributesImpl();
private JacsonState state;
/** In case we have name Attributes, we use this. */
public final AttributesImpl nameAtts = new AttributesImpl();
/** The transformer which does the main work. */
protected TransformerHandler trans;
/** Stack of begin blocks */
LinkedList begins;
public void init(ConfigNode config)
throws JacsonConfigException
{
try
{
SAXTransformerFactory tfac =
(SAXTransformerFactory) TransformerFactory.newInstance();
String style = config.getString(STYLE_NODE, null);
if ( style == null )
trans = tfac.newTransformerHandler();
else
trans = tfac.newTransformerHandler(new StreamSource(style));
}
catch ( TransformerConfigurationException tce )
{
throw new JacsonConfigException("Cannot obtain Transformer.", tce);
}
//
PrintingReport.useFilename(this, config);
//
Transformer tf = trans.getTransformer();
//
// Set Output Properties
Iterator it;
it = config.childrenNamed(OUTPUTPROPERTY_NODE);
while ( it.hasNext() )
{
ConfigNode config2 = (ConfigNode) it.next();
String name = config2.getString(NAME_NODE, null);
String value = config2.getString(VALUE_NODE, null);
if ( name == null || value == null )
throw new JacsonConfigException("Incomplete property: "+config2.getPath());
tf.setOutputProperty(name, value);
}
//
// Set Parameters
it = config.childrenNamed(PARAMETER_NODE);
while ( it.hasNext() )
{
ConfigNode config2 = (ConfigNode) it.next();
String name = config2.getString(NAME_NODE, null);
String value = config2.getString(VALUE_NODE, null);
if ( name == null || value == null )
throw new JacsonConfigException("Incomplete parameter: "+config2.getPath());
tf.setParameter(name, value);
}
//
begins = new LinkedList();
nameAtts.addAttribute(NAMESPACE, NAME_ATT, NAME_ATT, "CDATA", "");
//
try
{
trans.startDocument();
trans.startElement(NAMESPACE, ROOT_ELEM, ROOT_ELEM,dummyAtts);
}
catch ( SAXException se )
{
throw new JacsonConfigException("Cannot init xml document", se);
}
}
/** Attach an appropriate Result to the Transformer. */
public void setOutputStream(OutputStream os)
throws JacsonConfigException
{
// See if we should use FOP
String mime=trans.getTransformer().getOutputProperty("media-type");
Result res = FopAdapter.getFopResult(mime, os);
if ( res != null )
trans.setResult(res);
else
setPrintWriter(new PrintWriter(os));
}
/** Attach an appropriate Result to the Transformer. */
public void setPrintWriter(PrintWriter pw)
throws JacsonConfigException
{
try
{
Result res = new StreamResult(pw);
trans.setResult(res);
}
catch ( Exception e )
{
e.printStackTrace();
throw new JacsonConfigException("Streamresult causes:",e);
}
}
public void begin(String id)
{
try
{
trans.startElement(NAMESPACE, id, id,dummyAtts);
}
catch ( SAXException ignore )
{
ignore.printStackTrace();
}
begins.addLast(id);
}
public void report(String localName, String value)
{
nameAtts.setValue(0, localName);
char[] chs = value.toCharArray();
try
{
trans.startElement(NAMESPACE, ITEM_ELEM, ITEM_ELEM, nameAtts);
trans.characters(chs, 0, chs.length);
trans.endElement(NAMESPACE, ITEM_ELEM, ITEM_ELEM);
}
catch ( SAXException ignore )
{
ignore.printStackTrace();
}
}
public void end()
{
try
{
String h = (String) begins.removeLast();
trans.endElement(NAMESPACE, h, h);
}
catch ( SAXException ignore )
{
ignore.printStackTrace();
}
}
public void finish()
{
finish(true);
}
public void finish(boolean close)
{
try
{
trans.endElement(NAMESPACE, ROOT_ELEM, ROOT_ELEM);
trans.endDocument();
}
catch ( SAXException ignore )
{
ignore.printStackTrace();
}
}
public void registerState(JacsonState state)
{
this.state = state;
}
public JacsonState getRegState()
{
return state;
}
}
//
// Jacson - Text Filtering with Java.
// Copyright (C) 2002 Frank S. Nestel (nestefan -at- users.sourceforge.net)
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -