Monitor.java example
//------------------FOR DEMO USE ONLY----------------------------------
//-------- Copyright by Artem Saveliev artem@savelev.com ------------
//---------------------------------------------------------------------
package com.broadstr.xslfoserver;
import java.io.*;
import javax.xml.transform.TransformerException;
import org.apache.xpath.XPathAPI;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.channels.FileChannel;
import java.util.TimerTask;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.DocPrintJob;
import javax.print.Doc;
import javax.print.SimpleDoc;
import javax.print.PrintException;
import javax.print.DocFlavor;
import javax.print.DocFlavor.INPUT_STREAM;
import javax.print.attribute.DocAttributeSet;
import javax.print.attribute.HashDocAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Destination;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import org.tanukisoftware.wrapper.WrapperManager;
public class Monitor extends TimerTask {
public String in;
public String out;
public fo2pdf app;
public FilenameFilter fo;
public Document document;
private Element printNameSpace;
public Monitor(){
app = new fo2pdf();
fo = new FOFilter();
}
public void run() {
File pdffile;
File psfile;
String outfile;
String outputType;
File inDir = new File(in);
File outDir = new File(out);
Node n;
File[] fofiles = inDir.listFiles(fo);
if (fofiles == null) return;
for (int fileIndex = 0;fileIndex < fofiles.length; fileIndex++){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Found file " + fofiles[fileIndex].getPath());
outfile = fofiles[fileIndex].getName().replaceAll("\\.fo","");
try{
if (LoadFODOM(fofiles[fileIndex].getPath())){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Loaded FO file");
//-- Convert to PDF if required
NodeList nl;
try{
nl = XPathAPI.selectNodeList(document,"//print:printManifest/out[format='pdf']",printNameSpace);
}
catch (Exception e) {
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_ERROR,"Unable to find PDF format of text, query failed\n\t"+e.getMessage());
throw new Exception("Reading print manifest failed");
}
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"\nTotal PDF requests found: " + nl.getLength());
if (nl.getLength()> 0){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Found PDF generation request in " + fofiles[fileIndex].getName());
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Generating empty file object");
pdffile = new File(out,outfile+".pdf.temp");
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Converting to PDF");
app.convertFO2PDF(fofiles[fileIndex], pdffile);
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Distributing to location");
for(int i=0;i<nl.getLength();i++)
{
n = nl.item(i);
try{
outputType = ((Text)XPathAPI.selectSingleNode(n,"./outputType/text()")).getNodeValue();
}
catch (Exception e) {
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_ERROR,"Reading output type falied");
throw new Exception("Reading output type falied");
}
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Saving to "+outputType);
if (outputType.equals("screen")){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Found request to output PDF to screen in " + fofiles[fileIndex].getName());
copyFile(pdffile.getPath(),new File(out,outfile+".pdf").getPath());
}
else if (outputType.equals("file")){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Found request to output PDF to file in " + fofiles[fileIndex].getName());
copyFile(pdffile.getPath(),((Text)XPathAPI.selectSingleNode(n,"./location/text()")).getNodeValue()+".pdf");
}
else if (outputType.equals("print")){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Found request to output PDF to printer in " + fofiles[fileIndex].getName());
printFile(pdffile,n);
}
}
pdffile.delete();
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Done with PDF generation\n");
}
//-- Convert to PS if required
try{
nl = XPathAPI.selectNodeList(document,"//print:printManifest/out[format='ps']",printNameSpace);
}
catch (Exception e) {
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_ERROR,"Unable to find PS format of text, query failed\n\t"+e.getMessage());
throw new Exception("Reading print manifest failed");
}
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Total PS requests found: " + nl.getLength());
if (nl.getLength()> 0){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Found PS generation request in " + fofiles[fileIndex].getName());
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Generating empty file object");
psfile = new File(out,outfile+".ps.temp");
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Converting to PDF");
app.convertFO2PS(fofiles[fileIndex], psfile);
for(int i=0;i<nl.getLength();i++)
{
n = nl.item(i);
try{
outputType = ((Text)XPathAPI.selectSingleNode(n,"./outputType/text()")).getNodeValue();
}
catch (Exception e) {
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_ERROR,"Reading output type falied");
throw new Exception("Reading output type falied");
}
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Saving to "+outputType);
if (outputType.equals("screen")){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Found request to output PS to screen in " + fofiles[fileIndex].getName());
copyFile(psfile.getPath(),new File(out,outfile+".ps").getPath());
}
else if (outputType.equals("file")){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Found request to output PS to file in " + fofiles[fileIndex].getName());
copyFile(psfile.getPath(),((Text)XPathAPI.selectSingleNode(n,"./location/text()")).getNodeValue()+".ps");
}
else if (outputType.equals("print")){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Found request to output PS to printer in " + fofiles[fileIndex].getName());
printFile(psfile,n);
}
}
psfile.delete();
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Done with PS generation\n");
}
//--- Remove source file after done
try{
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Done with file, deleting " + fofiles[fileIndex].getName());
fofiles[fileIndex].delete();
}
catch (Exception e){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_ERROR,"Unable to delete "+ fofiles[fileIndex].getPath());
}
}
else
fofiles[fileIndex].renameTo(new File(out,outfile+".fo.err"));
} catch (Exception e) {
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_ERROR,"Error: can not process file, general error\n\t" + e.getMessage());
fofiles[fileIndex].renameTo(new File(out,outfile+".fo.err"));
}
}
}
public boolean LoadFODOM(String filename){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Loading FO file");
try {
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Creating Factory");
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Parsing FO file");
document = builder.parse(filename);
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Creating namespace node");
printNameSpace = document.createElementNS("http://www.broadstr.com/xslfoPrinter","print");
document.getDocumentElement().appendChild(printNameSpace);
return true;
}
catch (FactoryConfigurationError e) {
// unable to get a document builder factory
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_ERROR,"Error: can not parse file in DOM, factory config error\n" + e.getMessage());
return false;
}
catch (ParserConfigurationException e) {
// parser was unable to be configured
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_ERROR,"Error: can not parse file in DOM, parser config error\n\t" + e.getMessage());
return false;
}
catch (SAXException e) {
// parsing error
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_ERROR,"Error: can not parse file in DOM, SAX error\n\t" + e.getMessage());
return false;
}
catch (IOException e) {
// i/o error
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_ERROR,"Error: can not parse file in DOM, i/o error\n\t" + e.getMessage());
return false;
}
}
public void copyFile(String inputFile, String outputFile){
try{
// Create channel on the source
FileChannel srcChannel = new FileInputStream(inputFile).getChannel();
// Create channel on the destination
FileChannel dstChannel = new FileOutputStream(outputFile).getChannel();
// Copy file contents from source to destination
dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
// Close the channels
srcChannel.close();
dstChannel.close();
}
catch (FileNotFoundException e){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_ERROR,"Error: can not find file to copy to destination\n\t" + e.getMessage());
}
catch (IOException e){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_ERROR,"Error: can not copy file, i/o error\n\t" + e.getMessage());
}
}
// Sends file to printer device
public boolean printFile(File file, Node props) throws TransformerException, URISyntaxException, FileNotFoundException, Exception {
String printername;
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Starting printing");
if (((Text)XPathAPI.selectSingleNode(props,"./format/text()")).getNodeValue().equals("ps")){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Printing PostScript file");
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Reading printer name");
try{
printername = ((Text)XPathAPI.selectSingleNode(props,"./location/text()")).getNodeValue();
}
catch (Exception e){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_ERROR,"Error Reading printer name");
throw new Exception("Error reading printer name "+e.getMessage());
}
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Printer name: "+printername);
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Adjusting PS file: "+file.getPath());
File adjustedFile = adjustPSFile(file, props);
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Opening PS file: "+adjustedFile.getPath());
FileInputStream inFile=new FileInputStream(adjustedFile);
int size=(int)adjustedFile.length ();
DataInputStream input =new DataInputStream(inFile);
byte type[]=new byte[size];
input.read(type);
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Creating output stream");
FileOutputStream os = new FileOutputStream(printername);
PrintStream ps = new PrintStream(os);
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Printing!");
ps.write (type);
if(ps.checkError ()==true)
return false;
ps.print("\f");
ps.close();
input.close ();
adjustedFile.delete();
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Printing done");
/*--- javax.print part, not working for now
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Printing PostScript file");
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Initialize print service and job");
DocFlavor flavor = INPUT_STREAM.POSTSCRIPT;
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Setting printer to "+ printername);
aset.add(new Destination(new URI("file:"+printername)));
PrintService[] service = PrintServiceLookup.lookupPrintServices(flavor,aset);
PrintService s = service[0];
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Found printer service "+ s.getName());
DocPrintJob job = s.createPrintJob();
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Opening file input stream from "+file.getPath());
FileInputStream f = new FileInputStream(file);
DocAttributeSet das = new HashDocAttributeSet();
Doc doc = new SimpleDoc(f, flavor, das);
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Sending document to printer the document");
job.print(doc, aset);
*/
}
return true;
}
// Edits the resulting PostScript file to add tray and duplex instructions
public File adjustPSFile(File input,Node props) throws Exception{
boolean duplex = false;
try{
if (XPathAPI.selectSingleNode(props,"./duplex")!=null)
if (((Text)XPathAPI.selectSingleNode(props,"./duplex/text()")).getNodeValue().equals("yes")) duplex = true;
}
catch (TransformerException e){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_ERROR,"Error Reading duplex param");
throw new Exception("Error reading printer name "+e.getMessage());
}
int tray = 0;
try{
if (XPathAPI.selectSingleNode(props,"./tray")!= null)
tray = Integer.parseInt(((Text)XPathAPI.selectSingleNode(props,"./tray/text()")).getNodeValue());
}
catch (TransformerException e){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_ERROR,"Error Reading duplex param");
throw new Exception("Error reading printer name "+e.getMessage());
}
boolean propertiesAdded = false;
String str;
String previousline = " ";
File output = new File(input.getPath()+".spool");
BufferedReader in = new BufferedReader(new FileReader(input));
BufferedWriter out = new BufferedWriter(new FileWriter(output));
while ((str=in.readLine())!=null){
if (!propertiesAdded && !str.substring(0,2).equals("%%") && previousline.substring(0,2).equals("%%"))
{
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Found end of comments");
propertiesAdded = true;
if (duplex){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Adding duplex command");
out.write("<< /Duplex true >> setpagedevice");
out.newLine();
}
if (tray > 1){
WrapperManager.log(WrapperManager.WRAPPER_LOG_LEVEL_DEBUG,"Setting tray to "+tray);
out.write("<< /ManualFeed false /MediaPosition null >> setpagedevice");
out.newLine();
out.write("userdict /lms");
out.newLine();
out.write("currentpagedevice /InputAttributes get "+(tray-1)+" known { "+(tray-1)+" }{ 0 }ifelse put");
out.newLine();
out.write("currentpagedevice /InputAttributes get lms get setpagedevice");
out.newLine();
out.write("<< /InputAttributes << /Priority [lms] >> >> setpagedevice");
out.newLine();
out.write("<< /Policies << /PageSize 7 >> >> setpagedevice");
out.newLine();
}
}
out.write(str);
out.newLine();
previousline = str;
}
in.close();
out.close();
return output;
}
}