From b7d1313dbcc9dde110deef5b6dd4a2d4ed28c135 Mon Sep 17 00:00:00 2001 From: Ralph Soika Date: Tue, 17 Nov 2020 11:57:38 +0100 Subject: [PATCH] update --- office-alexander-logistics-app/pom.xml | 7 + .../com/alexanderlogistics/XMLPDFAdapter.java | 219 ++++++++++++++++++ .../src/main/webapp/WEB-INF/beans.xml | 6 + pom.xml | 2 +- workflow/posteingang-de-1.0.0.bpmn | 35 +++ 5 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 office-alexander-logistics-app/src/main/java/com/alexanderlogistics/XMLPDFAdapter.java create mode 100644 office-alexander-logistics-app/src/main/webapp/WEB-INF/beans.xml diff --git a/office-alexander-logistics-app/pom.xml b/office-alexander-logistics-app/pom.xml index f89dca6..da13f76 100644 --- a/office-alexander-logistics-app/pom.xml +++ b/office-alexander-logistics-app/pom.xml @@ -236,6 +236,13 @@ compile + + + org.apache.pdfbox + pdfbox + 2.0.19 + compile + \ No newline at end of file diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/XMLPDFAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/XMLPDFAdapter.java new file mode 100644 index 0000000..41e46aa --- /dev/null +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/XMLPDFAdapter.java @@ -0,0 +1,219 @@ +package com.alexanderlogistics; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +import javax.inject.Inject; + +import org.apache.pdfbox.cos.COSInputStream; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary; +import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; +import org.apache.pdfbox.pdmodel.common.PDNameTreeNode; +import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; +import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; +import org.imixs.archive.core.SnapshotService; +import org.imixs.workflow.FileData; +import org.imixs.workflow.ItemCollection; +import org.imixs.workflow.SignalAdapter; +import org.imixs.workflow.engine.WorkflowService; +import org.imixs.workflow.exceptions.AdapterException; +import org.imixs.workflow.exceptions.PluginException; + +/** + * The + * + * @version 1.0 + * @author rsoika + */ +public class XMLPDFAdapter implements SignalAdapter { + + public static final String FILE_PATTERN_PDF = ".[pP][dD][fF]"; + public static final String FILE_PATTERN_XML = ".[xX][mM][lL]"; + + private static Logger logger = Logger.getLogger(XMLPDFAdapter.class.getName()); + + + @Inject + WorkflowService workflowService; + + @Inject + SnapshotService snapshotService; + + /** + * This method posts a text from an attachment to the Imixs-ML Analyse service + * endpoint + */ + @SuppressWarnings("unchecked") + @Override + public ItemCollection execute(ItemCollection document, ItemCollection event) throws AdapterException { + + logger.info("......starting xml extraction..." ); + try { + byte[] xmlData = getXMLFile(document, FILE_PATTERN_PDF); + + + } catch (PluginException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return document; + } + + + + /** + * This method searches attached PDF files of a workitem and extracts an + * embedded XML file. + *

+ * The method only returns the first embedded xml file and does not support + * multiple xml files embedded in one pdf file. + * + * @param document + * @param filePattern + * @return + * @throws PluginException + */ + public static byte[] getXMLFile(ItemCollection document, String file_pattern) throws PluginException { + + // verify all attached PDF files + List filenames = document.getFileNames(); + for (String filename : filenames) { + + if (Pattern.compile(file_pattern).matcher(filename).find()) { + + logger.info("...extract embedded XML from '" + filename + "'"); + + // we only support the first embedded XML file here! + FileData pdfFileData = document.getFileData(filename); + return getFirstEmbeddedXML(pdfFileData.getContent()); + + } + } + + // no data found + return null; + } + + /** + * Helper method to extract the first XML file from a list of files + * + * @param names + * @return + * @throws IOException + */ + private static byte[] extractFirstXMLFile(Map names) throws IOException { + for (Map.Entry entry : names.entrySet()) { + PDComplexFileSpecification fileSpec = entry.getValue(); + String filename = fileSpec.getFile(); + + // test if file is a xml file + if (Pattern.compile(FILE_PATTERN_XML).matcher(filename).find()) { + // we found an xml file! + PDEmbeddedFile embeddedFile = getEmbeddedFile(fileSpec); + COSInputStream inStream = embeddedFile.createInputStream(); + + return streamToByteArray(inStream); + + } + } + + // no XML file found + return null; + } + + /** + * This method extract the first XML file form a pdf file content + * + * @param content + * @return a byte array with the xml data or null if no xml file was found in + * the pdf file. + */ + private static byte[] getFirstEmbeddedXML(byte[] content) { + PDDocument doc = null; + byte[] result = null; + try { + + doc = PDDocument.load(content); + + PDDocumentNameDictionary namesDictionary = new PDDocumentNameDictionary(doc.getDocumentCatalog()); + PDEmbeddedFilesNameTreeNode efTree = namesDictionary.getEmbeddedFiles(); + if (efTree != null) { + Map names = efTree.getNames(); + if (names != null) { + result = extractFirstXMLFile(names); + } else { + List> kids = efTree.getKids(); + for (PDNameTreeNode node : kids) { + names = node.getNames(); + result = extractFirstXMLFile(names); + } + } + } + } catch (IOException e) { + logger.warning("unable to load embedded xml : " + e.getMessage()); + + } finally { + if (doc != null) { + try { + doc.close(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + } + + return result; + } + + /** + * Helper method to extract platform specific embedded file format. + * + * @param fileSpec + * @return + */ + private static PDEmbeddedFile getEmbeddedFile(PDComplexFileSpecification fileSpec) { + PDEmbeddedFile embeddedFile = null; + if (fileSpec != null) { + embeddedFile = fileSpec.getEmbeddedFileUnicode(); + if (embeddedFile == null) { + embeddedFile = fileSpec.getEmbeddedFileDos(); + } + if (embeddedFile == null) { + embeddedFile = fileSpec.getEmbeddedFileMac(); + } + if (embeddedFile == null) { + embeddedFile = fileSpec.getEmbeddedFileUnix(); + } + if (embeddedFile == null) { + embeddedFile = fileSpec.getEmbeddedFile(); + } + } + return embeddedFile; + } + + /** + * This method converts a inputStream into a byte array. + * + * @param ins + * @return + * @throws IOException + */ + public static byte[] streamToByteArray(InputStream ins) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] byteBuffer = new byte[1024]; + int len; + while ((len = ins.read(byteBuffer)) > -1) { + baos.write(byteBuffer, 0, len); + } + baos.flush(); + return baos.toByteArray(); + } +} \ No newline at end of file diff --git a/office-alexander-logistics-app/src/main/webapp/WEB-INF/beans.xml b/office-alexander-logistics-app/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 0000000..51e8caf --- /dev/null +++ b/office-alexander-logistics-app/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 9b1e5e9..a8a814d 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 4.1.8 4.4.0 2.2.3 - 2.2.4 + 2.2.7 1.0.19 1.0.1 2.2 diff --git a/workflow/posteingang-de-1.0.0.bpmn b/workflow/posteingang-de-1.0.0.bpmn index 4988e27..86aa736 100644 --- a/workflow/posteingang-de-1.0.0.bpmn +++ b/workflow/posteingang-de-1.0.0.bpmn @@ -39,6 +39,7 @@ + @@ -92,6 +93,7 @@ Possible ImageTypes are: StartEvent_1 IntermediateCatchEvent_8 EndEvent_1 + IntermediateCatchEvent_1 @@ -122,6 +124,7 @@ Possible ImageTypes are: $workflowgroup - $workflowstatus]]> SequenceFlow_13 + SequenceFlow_26 SequenceFlow_3 @@ -1124,6 +1127,26 @@ Betrag: _amount (Brutto € _amount_brutto + + + + + *.xml + myReport +]]> + + + SequenceFlow_26 + + + DataOutput_7 + + + DataOutput_7 + + + + @@ -1285,6 +1308,12 @@ Betrag: _amount (Brutto € _amount_brutto + + + + + + @@ -1438,6 +1467,12 @@ Betrag: _amount (Brutto € _amount_brutto + + + + + +