
com.sta.cts.XTransformer Maven / Gradle / Ivy
package com.sta.cts;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.OutputStream;
import java.util.StringTokenizer;
import java.io.File;
import java.io.InputStream;
import java.io.FileOutputStream;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.FopFactoryBuilder;
import org.apache.fop.apps.MimeConstants;
import org.apache.batik.transcoder.Transcoder;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.batik.transcoder.image.JPEGTranscoder;
import org.apache.batik.transcoder.image.TIFFTranscoder;
import org.apache.fop.events.Event;
import org.apache.fop.events.EventFormatter;
import org.apache.fop.events.EventListener;
import org.apache.fop.events.model.EventSeverity;
import com.sta.cts.hssf.HSSFHandler;
import com.sta.mlogger.MLogger;
/**
* Name: XTransformer
* Description:
* Die Aufgabe dieser Klasse ist es, eine XML-Datei mit Hilfe einer XSL-Datei
* zu transformieren und das Ergebnis in einer Zieldatei (Typ wird vorgegeben)
* abzulegen. Unterst?tzt werden eine Reihe von Spezial-Transformations-Codes.
*
* Copyright: Copyright (c) 2001-2004, 2011, 2014, 2016-2019, 2021
* Company: >StA-Soft<
* @author StA
* @version 1.0
*/
public class XTransformer
{
/**
* Der verwendete XSLT-Prozessor.
*/
private TransformerFactory tFactory;
//===========================================================================
/**
* Zur Instantiierung eines Transformers.
* @throws Exception falls die Instantiirung fehlschl?gt.
*/
public XTransformer() throws Exception
{
try
{
// 1. Instantiate a TransformerFactory.
tFactory = TransformerFactory.newInstance();
// processor = XSLTProcessorFactory.getProcessor();
}
catch (Exception e)
{
MLogger.err("Error (Transformer): " + e.getMessage());
throw e;
}
}
//===========================================================================
/**
* Parameter pr?fen.
* @param pTransformer der Transformer
* @param pParams Parameter-String
* @throws Exception im Fehlerfall
*/
private void check4Params(Transformer pTransformer, String pParams) throws Exception
{
int i = pParams.indexOf("(");
int j = pParams.indexOf(")");
if ((i < 0) && (j < 0))
{
throw new Exception("Invalid parameter Syntax in XSLFileNames ().");
}
String s = pParams.substring(i + 1, j);
int k = s.indexOf("=");
if (k < 0)
{
throw new Exception("Invalid parameter Syntax in XSLFileNames (=).");
}
String name = s.substring(0, k).trim();
String value = s.substring(k + 1).trim();
pTransformer.setParameter(name, value);
pParams = pParams.substring(j + 1).trim();
if (pParams.startsWith("("))
{
check4Params(pTransformer, pParams);
}
}
/* *
* Versuch, die Datei mit den FOP-Optionen zu lesen
* (gen?gt schon zu Verwendung)
* @throws Exception im Fehlerfall
*/
/*
private void checkOptions4FOP() throws Exception
{
File f = new File("fop/userconfig.xml");
if (f.exists())
{
new Options(f);
}
}
*/
// configure fopFactory as desired
/**
* FOP-Factory-Builder.
*/
private FopFactoryBuilder fopFactoryBuilder = null; // new FopFactoryBuilder(new File(".").toURI());
/**
* FOP-Factory.
*/
private FopFactory fopFactory = null; // FopFactory.newInstance(new File(".").toURI());
/**
* SysOutEventListener.
*/
public class SysOutEventListener implements EventListener
{
@Override
public void processEvent(Event event)
{
String msg = EventFormatter.format(event);
EventSeverity severity = event.getSeverity();
if (severity == EventSeverity.INFO)
{
if ((msg != null) &&
(msg.startsWith("Rendered page #") ||
msg.equals("Font \"Symbol,normal,700\" not found. Substituting with \"Symbol,normal,400\".") ||
msg.equals("Font \"ZapfDingbats,normal,700\" not found. Substituting with \"ZapfDingbats,normal,400\".")))
{
MLogger.println("FOP: " + msg);
}
else
{
MLogger.deb("FOP: " + msg);
}
}
else if (severity == EventSeverity.WARN)
{
if ((msg != null) &&
(msg.startsWith("Rendered page #") ||
msg.equals("Font \"Symbol,normal,700\" not found. Substituting with \"Symbol,normal,400\".") ||
msg.equals("Font \"ZapfDingbats,normal,700\" not found. Substituting with \"ZapfDingbats,normal,400\".")))
{
MLogger.println("FOP: " + msg);
}
else
{
MLogger.inf("FOP: " + msg);
}
}
else if (severity == EventSeverity.ERROR)
{
MLogger.wrn("FOP: " + msg);
}
else if (severity == EventSeverity.FATAL)
{
MLogger.err("FOP: " + msg);
}
else
{
assert false;
}
}
}
/**
* FOP initialisieren.
* @throws Exception im Fehlerfall
*/
private void initFOP() throws Exception
{
if (fopFactoryBuilder == null)
{
/*
try
{
MLogger.deb("FOP-Factory-Builder...");
*/
fopFactoryBuilder = new FopFactoryBuilder(new File(".").toURI());
fopFactoryBuilder.setStrictFOValidation(false);
fopFactoryBuilder.setBreakIndentInheritanceOnReferenceAreaBoundary(true);
fopFactoryBuilder.setSourceResolution(96); // =96dpi (dots/pixels per Inch)
/*
MLogger.deb("FOP-Factory-Builder: Ok.");
}
catch (Exception ex)
{
MLogger.err("FOP-Factory-Builder: Error.");
throw ex;
}
*/
if (new File("fop/fop-conf.xml").exists())
{
/*
try
{
MLogger.deb("FOP-Configuration...");
*/
DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
// Configuration cfg = cfgBuilder.build(getClass().getResourceAsStream("fop/fop-conf.xml"));
Configuration cfg = cfgBuilder.buildFromFile("fop/fop-conf.xml");
fopFactoryBuilder.setConfiguration(cfg);
/*
MLogger.deb("FOP-Configuration: Ok.");
}
catch (Exception ex)
{
MLogger.err("FOP-Configuration: Error.");
throw ex;
}
*/
}
}
if (fopFactory == null)
{
/*
try
{
MLogger.deb("FOP-Factory...");
*/
fopFactory = fopFactoryBuilder.build();
/*
MLogger.deb("FOP-Factory: Ok.");
}
catch (Exception ex)
{
MLogger.err("FOP-Factory: Error.");
throw ex;
}
*/
}
}
/**
* Stream-Source ermitteln, wahlweise aus Datei aus Dateisystem oder aus Ressource aus Klassenpfad.
* @param fn Dateiname bzw. Name der Resource (ohne f?hrenden "/")
* @return Stream-Source
* @throws FileNotFoundException im Fehlerfall
*/
protected StreamSource getStreamSource(String fn) throws FileNotFoundException
{
StreamSource ssrc;
if (new File(fn).exists())
{
ssrc = new StreamSource(fn);
}
else
{
InputStream is = XTransformer.class.getResourceAsStream("/" + fn);
if (is == null)
{
throw new FileNotFoundException("Can't find " + fn);
}
ssrc = new StreamSource(is);
}
return ssrc;
}
/**
* Converts an FO file to a PDF file using FOP.
* @param pMsg Info bei Fehlern
* @param mime Mime-Type
* @param pSrcFileName Quelldateiname (FO-File)
* @param pDstFileName Zieldateiname (PDF-File)
* @throws Exception In case of a problem
*/
private void runRenderer(String pMsg, String mime, String pSrcFileName, String pDstFileName) throws Exception
{
// File fo = new File(pSrcFileName);
File pdf = new File(pDstFileName);
OutputStream out = null;
try
{
initFOP();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
foUserAgent.getEventBroadcaster().addEventListener(new SysOutEventListener());
if (MimeConstants.MIME_PNG.equals(mime))
{
foUserAgent.setOutputFile(new File(pDstFileName));
}
// configure foUserAgent as desired
// Setup output stream. Note: Using BufferedOutputStream
// for performance reasons (helpful with FileOutputStreams).
out = new FileOutputStream(pdf);
out = new BufferedOutputStream(out);
// Construct fop with desired output format
Fop fop = fopFactory.newFop(mime /* MimeConstants.MIME_PDF */, foUserAgent, out);
// Setup JAXP using identity transformer
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(); // identity transformer
// Setup input stream
Source src = getStreamSource(pSrcFileName);
// Resulting SAX events (the generated FO) must be piped through to FOP
Result res = new SAXResult(fop.getDefaultHandler());
// Start XSLT transformation and FOP processing
transformer.transform(src, res);
// Result processing
/*
FormattingResults foResults = fop.getResults();
java.util.List pageSequences = foResults.getPageSequences();
for (java.util.Iterator it = pageSequences.iterator(); it.hasNext(); )
{
PageSequenceResults pageSequenceResults = (PageSequenceResults) it.next();
MLogger.deb("PageSequence " + (String.valueOf(pageSequenceResults.getID()).length() > 0 ? pageSequenceResults.getID() : "") + " generated " + pageSequenceResults.getPageCount() + " pages.");
}
MLogger.deb("Generated " + foResults.getPageCount() + " pages in total.");
*/
}
catch (Exception e)
{
// System.exit(-1);
MLogger.err("Error (" + pMsg + "): " + e.getMessage());
throw e;
}
finally
{
if (out != null)
{
out.close();
}
}
}
/* *
* Renderer starten
* @param pMsg Info bei Fehlern
* @param pRenderer der Renderer
* @param pSrcFileName Quelldateiname
* @param pDstFileName Zieldateiname
* @throws Exception im Fehlerfall
*/
/*
private void runRenderer(String pMsg, org.apache.fop.render.Renderer pRenderer, String pSrcFileName, String pDstFileName) throws Exception
{
try
{
// Version 2 (neu):
Driver driver = new Driver();
org.apache.avalon.framework.logger.Logger logger = new org.apache.avalon.framework.logger.ConsoleLogger(org.apache.avalon.framework.logger.ConsoleLogger.LEVEL_WARN);
org.apache.fop.messaging.MessageHandler.setScreenLogger(logger);
driver.setLogger(logger);
checkOptions4FOP();
FileInputStream fis = new FileInputStream(pSrcFileName);
driver.setInputSource(new InputSource(fis));
FileOutputStream fos = new FileOutputStream(pDstFileName);
driver.setOutputStream(fos);
driver.setRenderer(pRenderer);
driver.run();
fos.close();
}
catch (Exception e)
{
MLogger.err("Error (" + pMsg + "): " + e.getMessage());
throw e;
}
}
*/
/* *
* Renderer starten
* @param pMsg Info bei Fehlern
* @param pRenderer der Renderer
* @param pSrcFileName Quelldateiname
* @param pDstFileName Zieldateiname
* @throws Exception im Fehlerfall
*/
/*
private void runRenderer(String pMsg, int pRenderer, String pSrcFileName, String pDstFileName) throws Exception
{
try
{
// Version 2 (neu):
Driver driver = new Driver();
org.apache.avalon.framework.logger.Logger logger = new org.apache.avalon.framework.logger.ConsoleLogger(org.apache.avalon.framework.logger.ConsoleLogger.LEVEL_WARN);
org.apache.fop.messaging.MessageHandler.setScreenLogger(logger);
driver.setLogger(logger);
checkOptions4FOP();
FileInputStream fis = new FileInputStream(pSrcFileName);
driver.setInputSource(new InputSource(fis));
FileOutputStream fos = new FileOutputStream(pDstFileName);
driver.setOutputStream(fos);
driver.setRenderer(pRenderer);
driver.run();
fos.close();
}
catch (Exception e)
{
MLogger.err("Error (" + pMsg + "): " + e.getMessage());
throw e;
}
}
*/
/**
* Batik ausf?hren.
* @param pSrcFileName Quelldateiname
* @param pDstFileName Zieldateiname
* @throws Exception im Fehlerfall
*/
private void runBatik(String pSrcFileName, String pDstFileName) throws Exception
{
String lcSrc = pSrcFileName.toLowerCase();
String lcDst = pDstFileName.toLowerCase();
Transcoder t;
if (!lcSrc.endsWith(".svg"))
{
String msg = "Error (BATIK): Invalid input file type (" + pSrcFileName + ").";
MLogger.err(msg);
throw new Exception(msg);
}
// create the transcoder
if (lcDst.endsWith(".jpg") || lcDst.endsWith(".jpeg"))
{
// create a JPEG transcoder
t = new JPEGTranscoder();
// set the transcoding hints
t.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, new Float(.8));
}
else if (lcDst.endsWith(".tif") || lcDst.endsWith(".tiff"))
{
// create a TIFF transcoder
t = new TIFFTranscoder();
// set the transcoding hints
// t.addTranscodingHint(TIFFTranscoder.KEY_QUALITY, new Float(.8));
}
else if (lcDst.endsWith(".png"))
{
// create a TIFF transcoder
t = new PNGTranscoder();
// set the transcoding hints
// t.addTranscodingHint(PNGTranscoder.KEY_QUALITY, new Float(.8));
}
else
{
String msg = "Error (BATIK): Invalid output file type (" + pDstFileName + "). Need .jpg | .jpeg | .tif | .tiff!";
MLogger.err(msg);
throw new Exception(msg);
}
// create the transcoder input
// TranscoderInput input = new TranscoderInput(new File(pSrcFileName).toURL().toString());
TranscoderInput input = new TranscoderInput(new File(pSrcFileName).toURI().toURL().toString());
// create the transcoder output
FileOutputStream ostream = new FileOutputStream(pDstFileName);
TranscoderOutput output = new TranscoderOutput(ostream);
// save the image
t.transcode(input, output);
// flush and close the stream then exit
ostream.flush();
ostream.close();
}
/**
* Diese Methode entspricht im wesentlichen dem gekapselten Aufruf von "process"
* des XSLT-Prozessors ("processor.process"). ?bergeben werden hier die
* Dateinamen. Wurde als XSLFileName ein Code f?r eine spezielle Transformation
* angegeben, wird dieser Parameter nicht als Dateiname f?r eine XSL-Datei
* interpretiert.
* Bisher erlaubte Codes: "HXML" - Flache XML-Struktur in eine hierarchische
* umwandeln und Hierarchien zusammenfassen, "FOP" - zur PDF-Erzeugung.
* @param pSrcFileName Name der XML-Quelldatei
* @param pXSLFileName Name der XSL-Datei bzw. Code f?r die Art der
* Transformation
* @param pDstFileName Name der Zieldatei
* @throws Exception falls ein Fehler auftritt
*/
public void transform(String pSrcFileName, String pXSLFileName, String pDstFileName) throws Exception
{
// long time = System.currentTimeMillis();
try
{
MLogger.deb(" Transformer: transform " + pXSLFileName + "...");
if (pXSLFileName.equals("HXML"))
{
HXMLHandler.main(pSrcFileName, pDstFileName);
}
else if (pXSLFileName.startsWith("L2H(") && pXSLFileName.endsWith(")"))
{
String dscFileName = pXSLFileName.substring(4, pXSLFileName.length() - 1);
MLogger.deb(" L2H: " + dscFileName);
Lines2Hierarchy.main(pSrcFileName, dscFileName, pDstFileName);
}
else if (pXSLFileName.equals("FOP"))
{
// runRenderer("FOP", Driver.RENDER_PDF, pSrcFileName, pDstFileName);
runRenderer("FOP", MimeConstants.MIME_PDF, pSrcFileName, pDstFileName);
}
else if (pXSLFileName.equals("PS"))
{
runRenderer("PS", MimeConstants.MIME_POSTSCRIPT, pSrcFileName, pDstFileName);
}
else if (pXSLFileName.equals("TIF"))
{
/*
//Creates TIFFRenderer instance
TIFFRenderer tiffRenderer = TIFFRendererFactory.newTIFFRenderer();
//Creates render/encode param collection
TIFFRendererParams params = new TIFFRendererParams();
//Sets up params
// params.setCompression(TIFFRendererParams.COMPRESSION_DEFLATE); // Bild kann nicht angezeigt werden!!!
// params.setCompression(TIFFRendererParams.COMPRESSION_GROUP3_1D); // Bild hat einen schwarzen Hintergrund und wei?e Schrift.
// params.setCompression(TIFFRendererParams.COMPRESSION_GROUP3_2D); // Bild hat einen schwarzen Hintergrund und wei?e Schrift.
// params.setCompression(TIFFRendererParams.COMPRESSION_GROUP4); // Bild hat einen schwarzen Hintergrund und wei?e Schrift.
// params.setCompression(TIFFRendererParams.COMPRESSION_JPEG_TTN2); // Bild kann nicht angezeigt werden!!!
// params.setCompression(TIFFRendererParams.COMPRESSION_LZW); // Bild kann nicht erzeugt werden!!!
// params.setCompression(TIFFRendererParams.COMPRESSION_NONE); // Bild ok, jedoch sehr gro?.
params.setCompression(TIFFRendererParams.COMPRESSION_PACKBITS);
//Sets params to the renderer
tiffRenderer.setRenderParams(params);
*/
// runRenderer("TIF", tiffRenderer, pSrcFileName, pDstFileName);
runRenderer("TIF", MimeConstants.MIME_TIFF, pSrcFileName, pDstFileName);
}
else if (pXSLFileName.equals("PNG"))
{
runRenderer("PNG", MimeConstants.MIME_PNG, pSrcFileName, pDstFileName);
}
else if (pXSLFileName.equals("RTF"))
{
runRenderer("RTF", MimeConstants.MIME_RTF, pSrcFileName, pDstFileName);
}
else if (pXSLFileName.equals("HSSF"))
{
HSSFHandler.main(pSrcFileName, pDstFileName);
}
else if (pXSLFileName.equals("BATIK"))
{
runBatik(pSrcFileName, pDstFileName);
}
else if (pXSLFileName.equals("HTML2XML"))
{
HTML2XML.runConvHTML2XML(pDstFileName, pSrcFileName);
}
else
{
// Falls pXSLFileName nach trim() mit ")" endet, genau eine "(" und genau
// eine ")" enth?lt, wird der Text dazwischen als Parameter aufgefa?t:
// Name = Wert als String
String xslfn = pXSLFileName;
int i = xslfn.indexOf("(");
String locParams = "";
if (i >= 0)
{
locParams = xslfn.substring(i);
xslfn = pXSLFileName.substring(0, i);
}
// 2. Use the TransformerFactory to process the stylesheet Source and
// generate a Transformer.
// Falls xslfn keine Datei im File-System ist, wird versucht selbige
// als Ressource zu laden.
Transformer transformer = tFactory.newTransformer(getStreamSource(xslfn));
// transformer.setOutputProperty("http://www.oracle.com/xml/is-standalone", "yes"); // hat nicht funktioniert!
transformer.setErrorListener(new MyErrorHandler());
if (i >= 0)
{
check4Params(transformer, locParams);
}
// 3. Use the Transformer to transform an XML Source and send the
// output to a Result object.
FileOutputStream fos = new FileOutputStream(pDstFileName);
transformer.transform(getStreamSource(pSrcFileName), new StreamResult(fos));
fos.close();
}
// time = System.currentTimeMillis() - time;
MLogger.deb(" Transformer: transform " + pXSLFileName + ": Ok.");
}
catch (Exception ex)
{
// time = System.currentTimeMillis() - time;
MLogger.err(" Transformer: transform: Error.", ex);
throw ex;
}
}
/**
* Diese Methode ist in der Lage, eine Folge von Transformationen auf eine
* Quelldatei anzuwenden.
* Die dabei entstehenden tempor?ren Dateien werden z. Z. nicht gel?scht.
* Diese Methode zerlegt im wesentlichen den Parameter pXSLFileNames und ruft
* mit den einzelnen Bestandteilen die Methode "transform" auf.
* @param pSrcFileName Name der XML-Quelldatei
* @param pXSLFileNames Liste von XSL-Dateinamen bzw. Transformations-Codes
* jeweils durch ?;? voneinander getrennt.
* @param pDstFileName Name der Zieldatei
* @param delSrc Datei pSrcFileName wird gel?scht, falls true
* @throws Exception falls ein Fehler auftritt
*/
public void mtransform(String pSrcFileName, String pXSLFileNames, String pDstFileName, boolean delSrc) throws Exception
{
StringTokenizer st;
String n;
String src;
String dst;
int i;
MLogger.deb("Transformer: mtransform...");
// long time = System.currentTimeMillis();
try
{
i = 0;
src = pSrcFileName;
st = new StringTokenizer(pXSLFileNames, ";");
while (st.hasMoreTokens())
{
n = st.nextToken();
if (st.hasMoreTokens())
{
dst = pSrcFileName + i; // ... kann ggf. auch anders erfolgen ...
}
else
{
dst = pDstFileName;
}
transform(src, n.trim(), dst);
// Quelldatei l?schen, falls es sich um eine tempor?re Datei handelt.
// F?r die 1. Quelldatei wird delSrc schon beim Aufruf festgelegt.
if (delSrc)
{
MLogger.deb(" Delete file: " + src);
if (!new File(src).delete())
{
MLogger.err(" Error deleting file: " + src);
}
}
// Bei allen weiteren (Quell-) Dateien handelt es sich mit Sicherheit
// um tempor?re Dateien.
delSrc = true;
src = dst;
i++;
}
}
catch (Exception ex)
{
MLogger.err(" Transformer: mtransform: Error.", ex);
throw ex;
}
MLogger.deb("Transformer: mtransform: Ok.");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy