update
This commit is contained in:
parent
32dfa62505
commit
b7d1313dbc
5 changed files with 268 additions and 1 deletions
|
|
@ -236,6 +236,13 @@
|
|||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Apache PDFBox -->
|
||||
<dependency>
|
||||
<groupId>org.apache.pdfbox</groupId>
|
||||
<artifactId>pdfbox</artifactId>
|
||||
<version>2.0.19</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -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.
|
||||
* <p>
|
||||
* 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<String> 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<String, PDComplexFileSpecification> names) throws IOException {
|
||||
for (Map.Entry<String, PDComplexFileSpecification> 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<String, PDComplexFileSpecification> names = efTree.getNames();
|
||||
if (names != null) {
|
||||
result = extractFirstXMLFile(names);
|
||||
} else {
|
||||
List<PDNameTreeNode<PDComplexFileSpecification>> kids = efTree.getKids();
|
||||
for (PDNameTreeNode<PDComplexFileSpecification> 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();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
|
||||
bean-discovery-mode="all" version="2.0">
|
||||
</beans>
|
||||
2
pom.xml
2
pom.xml
|
|
@ -29,7 +29,7 @@
|
|||
<org.imixs.marty.version>4.1.8</org.imixs.marty.version>
|
||||
<org.imixs.office.version>4.4.0</org.imixs.office.version>
|
||||
<org.imixs.adapters.version>2.2.3</org.imixs.adapters.version>
|
||||
<org.imixs.archive.version>2.2.4</org.imixs.archive.version>
|
||||
<org.imixs.archive.version>2.2.7</org.imixs.archive.version>
|
||||
<org.imixs.melman.version>1.0.19</org.imixs.melman.version>
|
||||
<org.imixs.ml.version>1.0.1</org.imixs.ml.version>
|
||||
<microprofile.version>2.2</microprofile.version>
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
</bpmn2:extensionElements>
|
||||
<bpmn2:signal id="Signal_1" name="org.imixs.archive.documents.OCRDocumentAdapter"/>
|
||||
<bpmn2:signal id="Signal_2" name="org.imixs.ml.workflow.MLAdapter"/>
|
||||
<bpmn2:signal id="Signal_3" name="com.alexanderlogistics.XMLPDFAdapter"/>
|
||||
<bpmn2:collaboration id="Collaboration_1" name="Default Collaboration">
|
||||
<bpmn2:participant id="Participant_1" name="Posteingang" processRef="Process_1"/>
|
||||
<bpmn2:textAnnotation id="TextAnnotation_1">
|
||||
|
|
@ -92,6 +93,7 @@ Possible ImageTypes are:
|
|||
<bpmn2:flowNodeRef>StartEvent_1</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>IntermediateCatchEvent_8</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>EndEvent_1</bpmn2:flowNodeRef>
|
||||
<bpmn2:flowNodeRef>IntermediateCatchEvent_1</bpmn2:flowNodeRef>
|
||||
</bpmn2:lane>
|
||||
</bpmn2:laneSet>
|
||||
<bpmn2:task id="Task_1" imixs:processid="100" name="Erfassung">
|
||||
|
|
@ -122,6 +124,7 @@ Possible ImageTypes are:
|
|||
</bpmn2:extensionElements>
|
||||
<bpmn2:documentation id="Documentation_3"><![CDATA[<textblock><itemvalue>$workflowgroup</itemvalue> - <itemvalue>$workflowstatus</itemvalue></textblock>]]></bpmn2:documentation>
|
||||
<bpmn2:incoming>SequenceFlow_13</bpmn2:incoming>
|
||||
<bpmn2:incoming>SequenceFlow_26</bpmn2:incoming>
|
||||
<bpmn2:outgoing>SequenceFlow_3</bpmn2:outgoing>
|
||||
</bpmn2:task>
|
||||
<bpmn2:exclusiveGateway id="ExclusiveGateway_1" gatewayDirection="Diverging">
|
||||
|
|
@ -1124,6 +1127,26 @@ Betrag: <itemvalue>_amount</itemvalue> (Brutto € <itemvalue>_amount_brutto</it
|
|||
<bpmn2:sequenceFlow id="SequenceFlow_2" sourceRef="BoundaryEvent_1" targetRef="IntermediateCatchEvent_3"/>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_8" sourceRef="BoundaryEvent_2" targetRef="IntermediateCatchEvent_8"/>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_25" sourceRef="BoundaryEvent_3" targetRef="IntermediateCatchEvent_10"/>
|
||||
<bpmn2:intermediateCatchEvent id="IntermediateCatchEvent_1" imixs:activityid="50" name="XML Test">
|
||||
<bpmn2:extensionElements>
|
||||
<imixs:item name="txtactivityresult" type="CDATA">
|
||||
<imixs:value><![CDATA[ <item name="PDFXMLExtractor">
|
||||
<filename>*.xml</filename>
|
||||
<report>myReport</report>
|
||||
</item>]]></imixs:value>
|
||||
</imixs:item>
|
||||
</bpmn2:extensionElements>
|
||||
<bpmn2:outgoing>SequenceFlow_26</bpmn2:outgoing>
|
||||
<bpmn2:dataOutput id="DataOutput_7" name="Signal_7_Output"/>
|
||||
<bpmn2:dataOutputAssociation id="DataOutputAssociation_7">
|
||||
<bpmn2:sourceRef>DataOutput_7</bpmn2:sourceRef>
|
||||
</bpmn2:dataOutputAssociation>
|
||||
<bpmn2:outputSet id="OutputSet_7" name="Output Set 7">
|
||||
<bpmn2:dataOutputRefs>DataOutput_7</bpmn2:dataOutputRefs>
|
||||
</bpmn2:outputSet>
|
||||
<bpmn2:signalEventDefinition id="SignalEventDefinition_7" signalRef="Signal_3"/>
|
||||
</bpmn2:intermediateCatchEvent>
|
||||
<bpmn2:sequenceFlow id="SequenceFlow_26" sourceRef="IntermediateCatchEvent_1" targetRef="Task_1"/>
|
||||
</bpmn2:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1" name="Default Collaboration Diagram">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1">
|
||||
|
|
@ -1285,6 +1308,12 @@ Betrag: <itemvalue>_amount</itemvalue> (Brutto € <itemvalue>_amount_brutto</it
|
|||
<dc:Bounds height="315.0" width="529.0" x="446.0" y="600.0"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="BPMNShape_IntermediateCatchEvent_1" bpmnElement="IntermediateCatchEvent_1">
|
||||
<dc:Bounds height="36.0" width="36.0" x="242.0" y="182.0"/>
|
||||
<bpmndi:BPMNLabel id="BPMNLabel_54">
|
||||
<dc:Bounds height="14.0" width="50.0" x="235.0" y="218.0"/>
|
||||
</bpmndi:BPMNLabel>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_1" bpmnElement="SequenceFlow_1" sourceElement="BPMNShape_ExclusiveGateway_1" targetElement="BPMNShape_IntermediateCatchEvent_2">
|
||||
<di:waypoint xsi:type="dc:Point" x="426.0" y="296.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="426.0" y="188.0"/>
|
||||
|
|
@ -1438,6 +1467,12 @@ Betrag: <itemvalue>_amount</itemvalue> (Brutto € <itemvalue>_amount_brutto</it
|
|||
<di:waypoint xsi:type="dc:Point" x="739.0" y="438.0"/>
|
||||
<bpmndi:BPMNLabel id="BPMNLabel_52"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="BPMNEdge_SequenceFlow_26" bpmnElement="SequenceFlow_26" sourceElement="BPMNShape_IntermediateCatchEvent_1" targetElement="BPMNShape_Task_1">
|
||||
<di:waypoint xsi:type="dc:Point" x="278.0" y="200.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="296.0" y="200.0"/>
|
||||
<di:waypoint xsi:type="dc:Point" x="296.0" y="296.0"/>
|
||||
<bpmndi:BPMNLabel id="BPMNLabel_55"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
<bpmndi:BPMNLabelStyle id="BPMNLabelStyle_1">
|
||||
<dc:Font name="arial" size="9.0"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue