In my previous post (see here) I mentioned that I couldn’t add a pre-processor to a Pentaho report using the report designer. So, I’ve written a short Java program that does just that.
Note that I use a neat open source library called Zip4J (you can get it here).
package com.tona.rprt; import java.io.File; import java.io.FileWriter; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import net.lingala.zip4j.core.ZipFile; import net.lingala.zip4j.model.ZipParameters; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; public class Main { private static final String CONFIG_FILE_NAME = "layout.xml"; public static void main(String[] args) throws Exception { ZipFile reportFile = new ZipFile(""); File tempDirectory = createTempDirectory(); String path = tempDirectory.getAbsolutePath(); reportFile.extractFile(CONFIG_FILE_NAME, path); System.out.println("Extraced file to " + path); File updatedFile = new File(path + File.separator + CONFIG_FILE_NAME); // Update the file DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(updatedFile); System.out.println("Parsed document"); Element layoutNode = doc.getDocumentElement(); Element preProcessorElement = doc.createElement("preprocessor"); preProcessorElement.setAttribute("class", "com.tona.report.infra.TonaWizardProcessor"); Node firstLayoutChild = layoutNode.getFirstChild(); layoutNode.insertBefore(preProcessorElement, firstLayoutChild); System.out.println("Added child"); FileWriter output = new FileWriter(updatedFile); javax.xml.transform.stream.StreamResult result = new javax.xml.transform.stream.StreamResult(output); TransformerFactory tf = TransformerFactory.newInstance(); Transformer t = tf.newTransformer(); t.transform(new DOMSource(doc), result); System.out.println("Updated XML file"); ZipParameters parameters = new ZipParameters(); reportFile.removeFile(CONFIG_FILE_NAME); reportFile.addFile(updatedFile, parameters); System.out.println("Update ZIP file"); tempDirectory.delete(); System.out.println("Removed temporary directory"); } private static File createTempDirectory() throws Exception { File temp = File.createTempFile("temp", Long.toString(System.nanoTime())); if(!(temp.delete())) { throw new Exception("Could not delete temp file: " + temp.getAbsolutePath()); } if(!(temp.mkdir())) { throw new Exception("Could not create temp directory: " + temp.getAbsolutePath()); } return temp; } }