Merge pull request #393 from phax/master

Support for Jakarta and PDFBox 3.x
This commit is contained in:
Jochen Staerk
2024-06-24 13:54:22 +02:00
committed by GitHub
43 changed files with 4691 additions and 455 deletions

View File

@@ -3,14 +3,14 @@
<parent> <parent>
<groupId>org.mustangproject</groupId> <groupId>org.mustangproject</groupId>
<artifactId>core</artifactId> <artifactId>core</artifactId>
<version>2.11.1-SNAPSHOT</version> <version>3.0.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.mustangproject</groupId> <groupId>org.mustangproject</groupId>
<artifactId>Mustang-CLI</artifactId> <artifactId>Mustang-CLI</artifactId>
<name>e-invoices commandline tool, allowing to create(embed), split and validate Factur-X/ZUGFeRD files. Validation should also work for XRechnung/CII. </name> <name>e-invoices commandline tool, allowing to create(embed), split and validate Factur-X/ZUGFeRD files. Validation should also work for XRechnung/CII. </name>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>2.11.1-SNAPSHOT</version> <version>3.0.0-SNAPSHOT</version>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.compilerVersion>8</maven.compiler.compilerVersion> <maven.compiler.compilerVersion>8</maven.compiler.compilerVersion>
@@ -21,7 +21,7 @@
<dependency> <dependency>
<groupId>org.mustangproject</groupId> <groupId>org.mustangproject</groupId>
<artifactId>validator</artifactId> <artifactId>validator</artifactId>
<version>2.11.1-SNAPSHOT</version> <version>3.0.0-SNAPSHOT</version>
<!-- prototypes of new mustangproject versions can be installed by referring to them and installed to the local repo from a jar file with <!-- prototypes of new mustangproject versions can be installed by referring to them and installed to the local repo from a jar file with
mvn install:install-file -Dfile=mustang-1.5.4-SNAPSHOT.jar -DgroupId=org.mustangproject.ZUGFeRD -DartifactId=mustang -Dversion=1.5.4 -Dpackaging=jar -DgeneratePom=true mvn install:install-file -Dfile=mustang-1.5.4-SNAPSHOT.jar -DgroupId=org.mustangproject.ZUGFeRD -DartifactId=mustang -Dversion=1.5.4 -Dpackaging=jar -DgeneratePom=true
--> -->
@@ -30,24 +30,24 @@
<dependency><!-- apache commons cli to parse command line --> <dependency><!-- apache commons cli to parse command line -->
<groupId>commons-cli</groupId> <groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId> <artifactId>commons-cli</artifactId>
<version>1.5.0</version> <version>1.8.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.riversun</groupId> <groupId>org.riversun</groupId>
<artifactId>bigdoc</artifactId> <artifactId>bigdoc</artifactId>
<version>0.3.0</version> <version>0.4.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId> <artifactId>junit-jupiter-api</artifactId>
<version>5.9.1</version> <version>5.10.2</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.junit.vintage</groupId> <groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId> <artifactId>junit-vintage-engine</artifactId>
<version>5.9.1</version> <version>5.10.2</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- for directory validation: --> <!-- for directory validation: -->
@@ -59,7 +59,7 @@
<dependency> <dependency>
<groupId>org.xmlunit</groupId> <groupId>org.xmlunit</groupId>
<artifactId>xmlunit-assertj</artifactId> <artifactId>xmlunit-assertj</artifactId>
<version>2.9.1</version> <version>2.10.0</version>
</dependency> </dependency>
<!-- /directory validation: --> <!-- /directory validation: -->

View File

@@ -3,13 +3,13 @@
<parent> <parent>
<groupId>org.mustangproject</groupId> <groupId>org.mustangproject</groupId>
<artifactId>core</artifactId> <artifactId>core</artifactId>
<version>2.11.1-SNAPSHOT</version> <version>3.0.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.mustangproject</groupId> <groupId>org.mustangproject</groupId>
<artifactId>library</artifactId> <artifactId>library</artifactId>
<version>2.11.1-SNAPSHOT</version> <version>3.0.0-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>Library to write, read and validate e-invoices (Factur-X, ZUGFeRD, Order-X, XRechnung/CII)</name> <name>Library to write, read and validate e-invoices (Factur-X, ZUGFeRD, Order-X, XRechnung/CII)</name>
<description>FOSS Java library to read, write and validate european electronic invoices and orders in the UN/CEFACT Cross Industry Invoice based formats Factur-X/ZUGFeRD, XRechnung and Order-X in your invoice PDFs. <description>FOSS Java library to read, write and validate european electronic invoices and orders in the UN/CEFACT Cross Industry Invoice based formats Factur-X/ZUGFeRD, XRechnung and Order-X in your invoice PDFs.
@@ -56,12 +56,12 @@
<dependency> <dependency>
<groupId>net.sf.saxon</groupId> <groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId> <artifactId>Saxon-HE</artifactId>
<version>9.9.0-1</version> <version>12.4</version>
</dependency><!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> </dependency><!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>2.14.2</version> <version>2.17.1</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.apache.xmlgraphics/fop --> <!-- https://mvnrepository.com/artifact/org.apache.xmlgraphics/fop -->
<dependency> <dependency>
@@ -71,36 +71,41 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.activation</groupId> <groupId>jakarta.xml.bind</groupId>
<artifactId>activation</artifactId> <artifactId>jakarta.xml.bind-api</artifactId>
<version>1.1.1</version> <version>4.0.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.angus</groupId>
<artifactId>angus-activation</artifactId>
<version>2.0.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.pdfbox</groupId> <groupId>org.apache.pdfbox</groupId>
<artifactId>preflight</artifactId> <artifactId>preflight</artifactId>
<version>2.0.27</version> <version>3.0.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.pdfbox</groupId> <groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId> <artifactId>pdfbox</artifactId>
<version>2.0.27</version> <version>3.0.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.dom4j</groupId> <groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId> <artifactId>dom4j</artifactId>
<version>2.1.3</version> <version>2.1.4</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId> <artifactId>junit-jupiter-api</artifactId>
<version>5.9.1</version> <version>5.10.2</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.junit.vintage</groupId> <groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId> <artifactId>junit-vintage-engine</artifactId>
<version>5.9.1</version> <version>5.10.2</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
@@ -108,13 +113,13 @@
<dependency> <dependency>
<groupId>com.helger</groupId> <groupId>com.helger</groupId>
<artifactId>en16931-cii2ubl</artifactId> <artifactId>en16931-cii2ubl</artifactId>
<version>1.4.10</version> <version>2.2.4</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime --> <!-- https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime -->
<dependency> <dependency>
<groupId>org.glassfish.jaxb</groupId> <groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId> <artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version> <version>4.0.5</version>
</dependency> </dependency>
<dependency> <dependency>
@@ -127,16 +132,15 @@
<dependency> <dependency>
<groupId>org.xmlunit</groupId> <groupId>org.xmlunit</groupId>
<artifactId>xmlunit-assertj</artifactId> <artifactId>xmlunit-assertj</artifactId>
<version>2.9.1</version> <version>2.10.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- API -->
<dependency> <dependency>
<groupId>jakarta.xml.bind</groupId> <groupId>org.slf4j</groupId>
<artifactId>jakarta.xml.bind-api</artifactId> <artifactId>slf4j-simple</artifactId>
<version>2.3.3</version> <version>2.0.9</version>
<scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>

View File

@@ -5,9 +5,9 @@ import java.io.Serializable;
import com.helger.commons.error.list.ErrorList; import com.helger.commons.error.list.ErrorList;
import com.helger.en16931.cii2ubl.CIIToUBL23Converter; import com.helger.en16931.cii2ubl.CIIToUBL23Converter;
import com.helger.ubl21.UBL21Writer; import com.helger.ubl21.UBL21Marshaller;
import com.helger.ubl22.UBL22Writer; import com.helger.ubl22.UBL22Marshaller;
import com.helger.ubl23.UBL23Writer; import com.helger.ubl23.UBL23Marshaller;
/*** /***
* converts a Cross Industry Invoice XML file to a UBL XML file * converts a Cross Industry Invoice XML file to a UBL XML file
@@ -25,37 +25,37 @@ public class CIIToUBL {
final Serializable aUBL = cc.convertCIItoUBL(input, occurred); final Serializable aUBL = cc.convertCIItoUBL(input, occurred);
if (aUBL instanceof oasis.names.specification.ubl.schema.xsd.invoice_21.InvoiceType) if (aUBL instanceof oasis.names.specification.ubl.schema.xsd.invoice_21.InvoiceType)
{ {
UBL21Writer.invoice () UBL21Marshaller.invoice ()
.setFormattedOutput (true) .setFormattedOutput (true)
.write ((oasis.names.specification.ubl.schema.xsd.invoice_21.InvoiceType) aUBL, output); .write ((oasis.names.specification.ubl.schema.xsd.invoice_21.InvoiceType) aUBL, output);
} }
else if (aUBL instanceof oasis.names.specification.ubl.schema.xsd.creditnote_21.CreditNoteType) else if (aUBL instanceof oasis.names.specification.ubl.schema.xsd.creditnote_21.CreditNoteType)
{ {
UBL21Writer.creditNote () UBL21Marshaller.creditNote ()
.setFormattedOutput (true) .setFormattedOutput (true)
.write ((oasis.names.specification.ubl.schema.xsd.creditnote_21.CreditNoteType) aUBL, output); .write ((oasis.names.specification.ubl.schema.xsd.creditnote_21.CreditNoteType) aUBL, output);
} }
else if (aUBL instanceof oasis.names.specification.ubl.schema.xsd.invoice_22.InvoiceType) else if (aUBL instanceof oasis.names.specification.ubl.schema.xsd.invoice_22.InvoiceType)
{ {
UBL22Writer.invoice () UBL22Marshaller.invoice ()
.setFormattedOutput (true) .setFormattedOutput (true)
.write ((oasis.names.specification.ubl.schema.xsd.invoice_22.InvoiceType) aUBL, output); .write ((oasis.names.specification.ubl.schema.xsd.invoice_22.InvoiceType) aUBL, output);
} }
else if (aUBL instanceof oasis.names.specification.ubl.schema.xsd.creditnote_22.CreditNoteType) else if (aUBL instanceof oasis.names.specification.ubl.schema.xsd.creditnote_22.CreditNoteType)
{ {
UBL22Writer.creditNote () UBL22Marshaller.creditNote ()
.setFormattedOutput (true) .setFormattedOutput (true)
.write ((oasis.names.specification.ubl.schema.xsd.creditnote_22.CreditNoteType) aUBL, output); .write ((oasis.names.specification.ubl.schema.xsd.creditnote_22.CreditNoteType) aUBL, output);
} }
else if (aUBL instanceof oasis.names.specification.ubl.schema.xsd.invoice_23.InvoiceType) else if (aUBL instanceof oasis.names.specification.ubl.schema.xsd.invoice_23.InvoiceType)
{ {
UBL23Writer.invoice () UBL23Marshaller.invoice ()
.setFormattedOutput (true) .setFormattedOutput (true)
.write ((oasis.names.specification.ubl.schema.xsd.invoice_23.InvoiceType) aUBL, output); .write ((oasis.names.specification.ubl.schema.xsd.invoice_23.InvoiceType) aUBL, output);
} }
else if (aUBL instanceof oasis.names.specification.ubl.schema.xsd.creditnote_23.CreditNoteType) else if (aUBL instanceof oasis.names.specification.ubl.schema.xsd.creditnote_23.CreditNoteType)
{ {
UBL23Writer.creditNote () UBL23Marshaller.creditNote ()
.setFormattedOutput (true) .setFormattedOutput (true)
.write ((oasis.names.specification.ubl.schema.xsd.creditnote_23.CreditNoteType) aUBL, output); .write ((oasis.names.specification.ubl.schema.xsd.creditnote_23.CreditNoteType) aUBL, output);
} }

View File

@@ -28,7 +28,10 @@ import java.util.Optional;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.mustangproject.*; import org.mustangproject.EStandard;
import org.mustangproject.FileAttachment;
import org.mustangproject.Invoice;
import org.mustangproject.XMLTools;
public class DAPullProvider extends ZUGFeRD2PullProvider implements IXMLProvider { public class DAPullProvider extends ZUGFeRD2PullProvider implements IXMLProvider {

View File

@@ -19,13 +19,15 @@
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import java.io.IOException;
import java.io.InputStream;
import org.apache.pdfbox.preflight.PreflightDocument; import org.apache.pdfbox.preflight.PreflightDocument;
import org.apache.pdfbox.preflight.ValidationResult;
import org.apache.pdfbox.preflight.exception.ValidationException; import org.apache.pdfbox.preflight.exception.ValidationException;
import org.apache.pdfbox.preflight.parser.PreflightParser; import org.apache.pdfbox.preflight.parser.PreflightParser;
import javax.activation.DataSource; import jakarta.activation.DataSource;
import java.io.IOException;
import java.io.InputStream;
public class DXExporterFromA1 extends DXExporterFromA3 implements IZUGFeRDExporter { public class DXExporterFromA1 extends DXExporterFromA3 implements IZUGFeRDExporter {
protected boolean ignorePDFAErrors = false; protected boolean ignorePDFAErrors = false;
@@ -36,7 +38,7 @@ public class DXExporterFromA1 extends DXExporterFromA3 implements IZUGFeRDExport
} }
private static boolean isValidA1(DataSource dataSource) throws IOException { private static boolean isValidA1(DataSource dataSource) throws IOException {
return getPDFAParserValidationResult(new PreflightParser(dataSource)); return getPDFAParserValidationResult(PreflightParserHelper.createPreflightParser (dataSource));
} }
/*** /***
* internal helper function: get namespace for order-x * internal helper function: get namespace for order-x
@@ -65,19 +67,19 @@ public class DXExporterFromA1 extends DXExporterFromA3 implements IZUGFeRDExport
* NonSequentialParser. Some additional controls are present to check a set of * NonSequentialParser. Some additional controls are present to check a set of
* PDF/A requirements. (Stream length consistency, EOL after some Keyword...) * PDF/A requirements. (Stream length consistency, EOL after some Keyword...)
*/ */
parser.parse();// might add a Format.PDF_A1A as parameter and iterate through A1 and A3 // might add a Format.PDF_A1A as parameter and iterate through A1 and A3
try (PreflightDocument document = parser.getPreflightDocument()) { try (PreflightDocument document = (PreflightDocument) parser.parse()) {
/* /*
* Once the syntax validation is done, the parser can provide a * Once the syntax validation is done, the parser can provide a
* PreflightDocument (that inherits from PDDocument) This document process the * PreflightDocument (that inherits from PDDocument) This document process the
* end of PDF/A validation. * end of PDF/A validation.
*/ */
document.validate(); ValidationResult res = document.validate();
// Get validation result // Get validation result
return document.getResult().isValid(); return res.isValid();
} catch (ValidationException e) { } catch (ValidationException e) {
/* /*
* the parse method can throw a SyntaxValidationException if the PDF file can't * the parse method can throw a SyntaxValidationException if the PDF file can't

View File

@@ -20,16 +20,38 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import org.apache.pdfbox.cos.*; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import javax.xml.transform.TransformerException;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSObject;
import org.apache.pdfbox.io.IOUtils; import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.pdmodel.*; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary;
import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode;
import org.apache.pdfbox.pdmodel.common.PDMetadata; import org.apache.pdfbox.pdmodel.common.PDMetadata;
import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification;
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDMarkInfo; import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDMarkInfo;
import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureTreeRoot; import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureTreeRoot;
import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent; import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent;
import org.apache.pdfbox.preflight.utils.ByteArrayDataSource;
import org.apache.xmpbox.XMPMetadata; import org.apache.xmpbox.XMPMetadata;
import org.apache.xmpbox.schema.AdobePDFSchema; import org.apache.xmpbox.schema.AdobePDFSchema;
import org.apache.xmpbox.schema.DublinCoreSchema; import org.apache.xmpbox.schema.DublinCoreSchema;
@@ -43,11 +65,8 @@ import org.apache.xmpbox.xml.XmpSerializer;
import org.mustangproject.EStandard; import org.mustangproject.EStandard;
import org.mustangproject.FileAttachment; import org.mustangproject.FileAttachment;
import javax.activation.DataSource; import jakarta.activation.DataSource;
import javax.activation.FileDataSource; import jakarta.activation.FileDataSource;
import javax.xml.transform.TransformerException;
import java.io.*;
import java.util.*;
public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 { public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
@@ -163,7 +182,7 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
*/ */
public DXExporterFromA3 load(byte[] pdfBinary) throws IOException { public DXExporterFromA3 load(byte[] pdfBinary) throws IOException {
ensurePDFIsValid(new ByteArrayDataSource(new ByteArrayInputStream(pdfBinary))); ensurePDFIsValid(new ByteArrayDataSource(new ByteArrayInputStream(pdfBinary)));
doc = PDDocument.load(pdfBinary); doc = Loader.loadPDF(pdfBinary);
return this; return this;
} }
@@ -542,13 +561,13 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
} }
protected PDFAIdentificationSchema getPDFAIdentificationSchema(XMPMetadata xmp) { protected PDFAIdentificationSchema getPDFAIdentificationSchema(XMPMetadata xmp) {
PDFAIdentificationSchema pdfaid = xmp.getPDFIdentificationSchema(); PDFAIdentificationSchema pdfaid = xmp.getPDFAIdentificationSchema();
if (pdfaid != null) if (pdfaid != null)
if (overwrite) if (overwrite)
xmp.removeSchema(pdfaid); xmp.removeSchema(pdfaid);
else else
return pdfaid; return pdfaid;
return xmp.createAndAddPFAIdentificationSchema(); return xmp.createAndAddPDFAIdentificationSchema();
} }
protected void writeDublinCoreSchema(XMPMetadata xmp) { protected void writeDublinCoreSchema(XMPMetadata xmp) {

View File

@@ -20,31 +20,10 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import org.apache.pdfbox.cos.*; import java.io.File;
import org.apache.pdfbox.io.IOUtils; import java.io.FileOutputStream;
import org.apache.pdfbox.pdmodel.*; import java.io.IOException;
import org.apache.pdfbox.pdmodel.common.PDMetadata; import java.io.OutputStream;
import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification;
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
import org.apache.pdfbox.preflight.PreflightDocument;
import org.apache.pdfbox.preflight.exception.ValidationException;
import org.apache.pdfbox.preflight.parser.PreflightParser;
import org.apache.pdfbox.preflight.utils.ByteArrayDataSource;
import org.apache.xmpbox.XMPMetadata;
import org.apache.xmpbox.schema.AdobePDFSchema;
import org.apache.xmpbox.schema.DublinCoreSchema;
import org.apache.xmpbox.schema.PDFAIdentificationSchema;
import org.apache.xmpbox.schema.XMPBasicSchema;
import org.apache.xmpbox.type.BadFieldValueException;
import org.apache.xmpbox.xml.XmpSerializer;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.xml.transform.TransformerException;
import java.io.*;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
public class EinLieferscheinExporter implements IExporter { public class EinLieferscheinExporter implements IExporter {
IXMLProvider xmlProvider; IXMLProvider xmlProvider;

View File

@@ -18,7 +18,6 @@
*********************************************************************** */ *********************************************************************** */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;

View File

@@ -15,10 +15,10 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants;
import java.math.BigDecimal; import java.math.BigDecimal;
import org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants;
/** /**
* The interface for allowances or charges, to be used by the pullprovider * The interface for allowances or charges, to be used by the pullprovider
* @author AlexanderSchmidt * @author AlexanderSchmidt

View File

@@ -1,7 +1,5 @@
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import org.mustangproject.XMLTools;
public interface IZUGFeRDCashDiscount { public interface IZUGFeRDCashDiscount {

View File

@@ -26,12 +26,13 @@ package org.mustangproject.ZUGFeRD;
* @author jstaerk * @author jstaerk
* */ * */
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.mustangproject.Item;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import org.mustangproject.Item;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
@JsonDeserialize(as = Item.class) @JsonDeserialize(as = Item.class)
public interface IZUGFeRDExportableItem extends IAbsoluteValueProvider{ public interface IZUGFeRDExportableItem extends IAbsoluteValueProvider{
IZUGFeRDExportableProduct getProduct(); IZUGFeRDExportableProduct getProduct();

View File

@@ -20,8 +20,6 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import org.mustangproject.TradeParty;
/** /**
* Mustangproject's ZUGFeRD implementation neccessary interface for ZUGFeRD exporter Licensed under the APLv2 * Mustangproject's ZUGFeRD implementation neccessary interface for ZUGFeRD exporter Licensed under the APLv2
* *

View File

@@ -18,11 +18,12 @@
*********************************************************************** */ *********************************************************************** */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import javax.activation.DataSource;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import jakarta.activation.DataSource;
public interface IZUGFeRDExporter extends Closeable, IExporter { public interface IZUGFeRDExporter extends Closeable, IExporter {
/** /**
* factory: loads a PDF file and returns an appropriate exporter * factory: loads a PDF file and returns an appropriate exporter

View File

@@ -18,11 +18,6 @@
*********************************************************************** */ *********************************************************************** */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import javax.activation.DataSource;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
public interface IZUGFeRDLegalOrganisation { public interface IZUGFeRDLegalOrganisation {
/*** /***

View File

@@ -19,13 +19,15 @@
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import java.io.IOException;
import java.io.InputStream;
import org.apache.pdfbox.preflight.PreflightDocument; import org.apache.pdfbox.preflight.PreflightDocument;
import org.apache.pdfbox.preflight.ValidationResult;
import org.apache.pdfbox.preflight.exception.ValidationException; import org.apache.pdfbox.preflight.exception.ValidationException;
import org.apache.pdfbox.preflight.parser.PreflightParser; import org.apache.pdfbox.preflight.parser.PreflightParser;
import javax.activation.DataSource; import jakarta.activation.DataSource;
import java.io.IOException;
import java.io.InputStream;
public class OXExporterFromA1 extends OXExporterFromA3 implements IZUGFeRDExporter { public class OXExporterFromA1 extends OXExporterFromA3 implements IZUGFeRDExporter {
protected boolean ignorePDFAErrors = false; protected boolean ignorePDFAErrors = false;
@@ -36,7 +38,7 @@ public class OXExporterFromA1 extends OXExporterFromA3 implements IZUGFeRDExport
} }
private static boolean isValidA1(DataSource dataSource) throws IOException { private static boolean isValidA1(DataSource dataSource) throws IOException {
return getPDFAParserValidationResult(new PreflightParser(dataSource)); return getPDFAParserValidationResult(PreflightParserHelper.createPreflightParser(dataSource));
} }
/*** /***
* internal helper function: get namespace for order-x * internal helper function: get namespace for order-x
@@ -61,19 +63,19 @@ public class OXExporterFromA1 extends OXExporterFromA3 implements IZUGFeRDExport
* NonSequentialParser. Some additional controls are present to check a set of * NonSequentialParser. Some additional controls are present to check a set of
* PDF/A requirements. (Stream length consistency, EOL after some Keyword...) * PDF/A requirements. (Stream length consistency, EOL after some Keyword...)
*/ */
parser.parse();// might add a Format.PDF_A1A as parameter and iterate through A1 and A3 // might add a Format.PDF_A1A as parameter and iterate through A1 and A3
try (PreflightDocument document = parser.getPreflightDocument()) { try (PreflightDocument document = (PreflightDocument) parser.parse()) {
/* /*
* Once the syntax validation is done, the parser can provide a * Once the syntax validation is done, the parser can provide a
* PreflightDocument (that inherits from PDDocument) This document process the * PreflightDocument (that inherits from PDDocument) This document process the
* end of PDF/A validation. * end of PDF/A validation.
*/ */
document.validate(); ValidationResult res = document.validate();
// Get validation result // Get validation result
return document.getResult().isValid(); return res.isValid();
} catch (ValidationException e) { } catch (ValidationException e) {
/* /*
* the parse method can throw a SyntaxValidationException if the PDF file can't * the parse method can throw a SyntaxValidationException if the PDF file can't

View File

@@ -20,20 +20,38 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import org.apache.pdfbox.cos.*; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import javax.xml.transform.TransformerException;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSObject;
import org.apache.pdfbox.io.IOUtils; import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.pdmodel.*; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary;
import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode;
import org.apache.pdfbox.pdmodel.common.PDMetadata; import org.apache.pdfbox.pdmodel.common.PDMetadata;
import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification;
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDMarkInfo; import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDMarkInfo;
import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureTreeRoot; import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureTreeRoot;
import org.apache.pdfbox.pdmodel.font.PDCIDFontType2;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDFontDescriptor;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent; import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent;
import org.apache.pdfbox.preflight.utils.ByteArrayDataSource;
import org.apache.xmpbox.XMPMetadata; import org.apache.xmpbox.XMPMetadata;
import org.apache.xmpbox.schema.AdobePDFSchema; import org.apache.xmpbox.schema.AdobePDFSchema;
import org.apache.xmpbox.schema.DublinCoreSchema; import org.apache.xmpbox.schema.DublinCoreSchema;
@@ -47,11 +65,8 @@ import org.apache.xmpbox.xml.XmpSerializer;
import org.mustangproject.EStandard; import org.mustangproject.EStandard;
import org.mustangproject.FileAttachment; import org.mustangproject.FileAttachment;
import javax.activation.DataSource; import jakarta.activation.DataSource;
import javax.activation.FileDataSource; import jakarta.activation.FileDataSource;
import javax.xml.transform.TransformerException;
import java.io.*;
import java.util.*;
public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 { public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
@@ -167,7 +182,7 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
*/ */
public OXExporterFromA3 load(byte[] pdfBinary) throws IOException { public OXExporterFromA3 load(byte[] pdfBinary) throws IOException {
ensurePDFIsValid(new ByteArrayDataSource(new ByteArrayInputStream(pdfBinary))); ensurePDFIsValid(new ByteArrayDataSource(new ByteArrayInputStream(pdfBinary)));
doc = PDDocument.load(pdfBinary); doc = Loader.loadPDF(pdfBinary);
return this; return this;
} }
@@ -536,13 +551,13 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
} }
protected PDFAIdentificationSchema getPDFAIdentificationSchema(XMPMetadata xmp) { protected PDFAIdentificationSchema getPDFAIdentificationSchema(XMPMetadata xmp) {
PDFAIdentificationSchema pdfaid = xmp.getPDFIdentificationSchema(); PDFAIdentificationSchema pdfaid = xmp.getPDFAIdentificationSchema();
if (pdfaid != null) if (pdfaid != null)
if (overwrite) if (overwrite)
xmp.removeSchema(pdfaid); xmp.removeSchema(pdfaid);
else else
return pdfaid; return pdfaid;
return xmp.createAndAddPFAIdentificationSchema(); return xmp.createAndAddPDFAIdentificationSchema();
} }
protected void writeDublinCoreSchema(XMPMetadata xmp) { protected void writeDublinCoreSchema(XMPMetadata xmp) {

View File

@@ -27,18 +27,14 @@ import static org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants.CATE
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Base64; import java.util.Base64;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.stream.Collectors;
import org.mustangproject.EStandard; import org.mustangproject.EStandard;
import org.mustangproject.FileAttachment; import org.mustangproject.FileAttachment;
import org.mustangproject.IncludedNote;
import org.mustangproject.XMLTools; import org.mustangproject.XMLTools;
public class OXPullProvider extends ZUGFeRD2PullProvider implements IXMLProvider { public class OXPullProvider extends ZUGFeRD2PullProvider implements IXMLProvider {

View File

@@ -0,0 +1,105 @@
package org.mustangproject.ZUGFeRD;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.io.RandomAccessRead;
import org.apache.pdfbox.io.RandomAccessReadBuffer;
import org.apache.pdfbox.preflight.parser.PreflightParser;
import jakarta.activation.DataSource;
// Copied from PDFBox preflight 2.0.x
final class ByteArrayDataSource implements DataSource
{
private ByteArrayOutputStream data;
private String type = null;
private String name = null;
public ByteArrayDataSource (InputStream is) throws IOException
{
data = new ByteArrayOutputStream ();
IOUtils.copy (is, data);
IOUtils.closeQuietly (is);
}
public String getContentType ()
{
return this.type;
}
/**
* @param type
* the type to set
*/
public void setType (String type)
{
this.type = type;
}
/**
* @param name
* the name to set
*/
public void setName (String name)
{
this.name = name;
}
public InputStream getInputStream () throws IOException
{
return new ByteArrayInputStream (data.toByteArray ());
}
public String getName ()
{
return this.name;
}
public OutputStream getOutputStream () throws IOException
{
this.data = new ByteArrayOutputStream ();
return data;
}
}
// Try to create an API similar to the 2.x one
final class PreflightParserHelper
{
private static File createTmpFile (InputStream input) throws IOException
{
FileOutputStream fos = null;
try
{
File tmpFile = File.createTempFile ("mustang-pdf", ".pdf");
fos = new FileOutputStream (tmpFile);
IOUtils.copy (input, fos);
return tmpFile;
}
finally
{
IOUtils.closeQuietly (input);
IOUtils.closeQuietly (fos);
}
}
public static PreflightParser createPreflightParser (DataSource dataSource) throws IOException
{
return new PreflightParser (createTmpFile (dataSource.getInputStream ()));
}
}
final class PDFBoxUpdateMitigation
{
// Dummy for the name only
}

View File

@@ -20,12 +20,12 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import org.mustangproject.EStandard;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.mustangproject.EStandard;
public class Profiles { public class Profiles {
static Map<String, Profile> zf2Map = Stream.of(new Object[][]{ static Map<String, Profile> zf2Map = Stream.of(new Object[][]{
{"MINIMUM", new Profile("MINIMUM", "urn:factur-x.eu:1p0:minimum")}, {"MINIMUM", new Profile("MINIMUM", "urn:factur-x.eu:1p0:minimum")},

View File

@@ -20,32 +20,22 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.DocumentException; import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper; import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat; import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter; import org.dom4j.io.XMLWriter;
import org.mustangproject.EStandard; import org.mustangproject.EStandard;
import org.mustangproject.FileAttachment;
import org.mustangproject.TradeParty;
import org.mustangproject.XMLTools; import org.mustangproject.XMLTools;
import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat.DATE;
import static org.mustangproject.ZUGFeRD.model.DocumentCodeTypeConstants.CORRECTEDINVOICE;
import static org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants.CATEGORY_CODES_WITH_EXEMPTION_REASON;
public class UBLDAPullProvider implements IXMLProvider { public class UBLDAPullProvider implements IXMLProvider {
protected IExportableTransaction trans; protected IExportableTransaction trans;

View File

@@ -1,9 +1,20 @@
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import javax.xml.transform.*; import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource; import javax.xml.transform.stream.StreamSource;
import java.io.*;
/*** /***

View File

@@ -30,7 +30,15 @@ package org.mustangproject.ZUGFeRD;
import org.apache.xmpbox.XMPMetadata; import org.apache.xmpbox.XMPMetadata;
import org.apache.xmpbox.XmpConstants; import org.apache.xmpbox.XmpConstants;
import org.apache.xmpbox.schema.PDFAExtensionSchema; import org.apache.xmpbox.schema.PDFAExtensionSchema;
import org.apache.xmpbox.type.*; import org.apache.xmpbox.type.ArrayProperty;
import org.apache.xmpbox.type.Attribute;
import org.apache.xmpbox.type.Cardinality;
import org.apache.xmpbox.type.ChoiceType;
import org.apache.xmpbox.type.DefinedStructuredType;
import org.apache.xmpbox.type.PDFAPropertyType;
import org.apache.xmpbox.type.PDFASchemaType;
import org.apache.xmpbox.type.StructuredType;
import org.apache.xmpbox.type.TextType;
import org.mustangproject.EStandard; import org.mustangproject.EStandard;
/** /**

View File

@@ -20,31 +20,10 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import org.apache.pdfbox.cos.*; import java.io.File;
import org.apache.pdfbox.io.IOUtils; import java.io.FileOutputStream;
import org.apache.pdfbox.pdmodel.*; import java.io.IOException;
import org.apache.pdfbox.pdmodel.common.PDMetadata; import java.io.OutputStream;
import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification;
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
import org.apache.pdfbox.preflight.PreflightDocument;
import org.apache.pdfbox.preflight.exception.ValidationException;
import org.apache.pdfbox.preflight.parser.PreflightParser;
import org.apache.pdfbox.preflight.utils.ByteArrayDataSource;
import org.apache.xmpbox.XMPMetadata;
import org.apache.xmpbox.schema.AdobePDFSchema;
import org.apache.xmpbox.schema.DublinCoreSchema;
import org.apache.xmpbox.schema.PDFAIdentificationSchema;
import org.apache.xmpbox.schema.XMPBasicSchema;
import org.apache.xmpbox.type.BadFieldValueException;
import org.apache.xmpbox.xml.XmpSerializer;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.xml.transform.TransformerException;
import java.io.*;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
public class XRExporter implements IExporter { public class XRExporter implements IExporter {
IXMLProvider xmlProvider; IXMLProvider xmlProvider;

View File

@@ -1,8 +1,5 @@
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import org.mustangproject.XMLTools;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Files; import java.nio.file.Files;
@@ -10,6 +7,8 @@ import java.nio.file.Paths;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.mustangproject.XMLTools;
public class XRechnungImporter extends ZUGFeRDImporter { public class XRechnungImporter extends ZUGFeRDImporter {
public XRechnungImporter(byte[] rawXml) { public XRechnungImporter(byte[] rawXml) {

View File

@@ -19,14 +19,16 @@
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import java.io.IOException;
import java.io.InputStream;
import org.apache.pdfbox.preflight.PreflightDocument; import org.apache.pdfbox.preflight.PreflightDocument;
import org.apache.pdfbox.preflight.ValidationResult;
import org.apache.pdfbox.preflight.exception.ValidationException; import org.apache.pdfbox.preflight.exception.ValidationException;
import org.apache.pdfbox.preflight.parser.PreflightParser; import org.apache.pdfbox.preflight.parser.PreflightParser;
import org.mustangproject.EStandard; import org.mustangproject.EStandard;
import javax.activation.DataSource; import jakarta.activation.DataSource;
import java.io.IOException;
import java.io.InputStream;
public class ZUGFeRDExporterFromA1 extends ZUGFeRDExporterFromA3 implements IZUGFeRDExporter { public class ZUGFeRDExporterFromA1 extends ZUGFeRDExporterFromA3 implements IZUGFeRDExporter {
protected boolean ignorePDFAErrors = false; protected boolean ignorePDFAErrors = false;
@@ -37,7 +39,7 @@ public class ZUGFeRDExporterFromA1 extends ZUGFeRDExporterFromA3 implements IZUG
} }
private static boolean isValidA1(DataSource dataSource) throws IOException { private static boolean isValidA1(DataSource dataSource) throws IOException {
return getPDFAParserValidationResult(new PreflightParser(dataSource)); return getPDFAParserValidationResult(PreflightParserHelper.createPreflightParser(dataSource));
} }
private static boolean getPDFAParserValidationResult(PreflightParser parser) throws IOException { private static boolean getPDFAParserValidationResult(PreflightParser parser) throws IOException {
@@ -46,19 +48,19 @@ public class ZUGFeRDExporterFromA1 extends ZUGFeRDExporterFromA3 implements IZUG
* NonSequentialParser. Some additional controls are present to check a set of * NonSequentialParser. Some additional controls are present to check a set of
* PDF/A requirements. (Stream length consistency, EOL after some Keyword...) * PDF/A requirements. (Stream length consistency, EOL after some Keyword...)
*/ */
parser.parse();// might add a Format.PDF_A1A as parameter and iterate through A1 and A3 // might add a Format.PDF_A1A as parameter and iterate through A1 and A3
try (PreflightDocument document = parser.getPreflightDocument()) { try (PreflightDocument document = (PreflightDocument) parser.parse()) {
/* /*
* Once the syntax validation is done, the parser can provide a * Once the syntax validation is done, the parser can provide a
* PreflightDocument (that inherits from PDDocument) This document process the * PreflightDocument (that inherits from PDDocument) This document process the
* end of PDF/A validation. * end of PDF/A validation.
*/ */
document.validate(); ValidationResult res = document.validate();
// Get validation result // Get validation result
return document.getResult().isValid(); return res.isValid();
} catch (ValidationException e) { } catch (ValidationException e) {
/* /*
* the parse method can throw a SyntaxValidationException if the PDF file can't * the parse method can throw a SyntaxValidationException if the PDF file can't

View File

@@ -20,9 +20,36 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import org.apache.pdfbox.cos.*; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import javax.xml.transform.TransformerException;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSObject;
import org.apache.pdfbox.io.IOUtils; import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.pdmodel.*; import org.apache.pdfbox.pdfwriter.compress.CompressParameters;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary;
import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.common.PDMetadata; import org.apache.pdfbox.pdmodel.common.PDMetadata;
import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification; import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification;
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
@@ -33,7 +60,6 @@ import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDFontDescriptor; import org.apache.pdfbox.pdmodel.font.PDFontDescriptor;
import org.apache.pdfbox.pdmodel.font.PDType0Font; import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent; import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent;
import org.apache.pdfbox.preflight.utils.ByteArrayDataSource;
import org.apache.xmpbox.XMPMetadata; import org.apache.xmpbox.XMPMetadata;
import org.apache.xmpbox.schema.AdobePDFSchema; import org.apache.xmpbox.schema.AdobePDFSchema;
import org.apache.xmpbox.schema.DublinCoreSchema; import org.apache.xmpbox.schema.DublinCoreSchema;
@@ -47,11 +73,8 @@ import org.apache.xmpbox.xml.XmpSerializer;
import org.mustangproject.EStandard; import org.mustangproject.EStandard;
import org.mustangproject.FileAttachment; import org.mustangproject.FileAttachment;
import javax.activation.DataSource; import jakarta.activation.DataSource;
import javax.activation.FileDataSource; import jakarta.activation.FileDataSource;
import javax.xml.transform.TransformerException;
import java.io.*;
import java.util.*;
public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporter, IExporter, Closeable { public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporter, IExporter, Closeable {
private boolean isFacturX = true; private boolean isFacturX = true;
@@ -258,7 +281,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
*/ */
public ZUGFeRDExporterFromA3 load(byte[] pdfBinary) throws IOException { public ZUGFeRDExporterFromA3 load(byte[] pdfBinary) throws IOException {
ensurePDFIsValid(new ByteArrayDataSource(new ByteArrayInputStream(pdfBinary))); ensurePDFIsValid(new ByteArrayDataSource(new ByteArrayInputStream(pdfBinary)));
doc = PDDocument.load(pdfBinary); doc = Loader.loadPDF(pdfBinary);
return this; return this;
} }
@@ -290,7 +313,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
throw new IOException( throw new IOException(
"File must be attached (usually with setTransaction) before perfoming this operation"); "File must be attached (usually with setTransaction) before perfoming this operation");
} }
doc.save(ZUGFeRDfilename); doc.save(ZUGFeRDfilename, CompressParameters.NO_COMPRESSION);
if (!disableAutoClose) { if (!disableAutoClose) {
close(); close();
} }
@@ -317,7 +340,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
throw new IOException( throw new IOException(
"File must be attached (usually with setTransaction) before perfoming this operation"); "File must be attached (usually with setTransaction) before perfoming this operation");
} }
doc.save(output); doc.save(output, CompressParameters.NO_COMPRESSION);
if (!disableAutoClose) { if (!disableAutoClose) {
close(); close();
} }
@@ -713,13 +736,13 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
} }
protected PDFAIdentificationSchema getPDFAIdentificationSchema(XMPMetadata xmp) { protected PDFAIdentificationSchema getPDFAIdentificationSchema(XMPMetadata xmp) {
PDFAIdentificationSchema pdfaid = xmp.getPDFIdentificationSchema(); PDFAIdentificationSchema pdfaid = xmp.getPDFAIdentificationSchema();
if (pdfaid != null) if (pdfaid != null)
if (overwrite) if (overwrite)
xmp.removeSchema(pdfaid); xmp.removeSchema(pdfaid);
else else
return pdfaid; return pdfaid;
return xmp.createAndAddPFAIdentificationSchema(); return xmp.createAndAddPDFAIdentificationSchema();
} }
protected void writeDublinCoreSchema(XMPMetadata xmp) { protected void writeDublinCoreSchema(XMPMetadata xmp) {

View File

@@ -20,6 +20,13 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog; import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.common.PDMetadata; import org.apache.pdfbox.pdmodel.common.PDMetadata;
@@ -30,8 +37,7 @@ import org.apache.xmpbox.xml.XmpParsingException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.activation.DataSource; import jakarta.activation.DataSource;
import java.io.*;
/*** /***
* Auto-detects the source PDF-A-Version and acts accordingly * Auto-detects the source PDF-A-Version and acts accordingly
@@ -79,7 +85,7 @@ public class ZUGFeRDExporterFromPDFA implements IZUGFeRDExporter {
* @throws IOException * @throws IOException
*/ */
private int getPDFAVersion(byte[] byteArrayInputStream) throws IOException { private int getPDFAVersion(byte[] byteArrayInputStream) throws IOException {
PDDocument document = PDDocument.load(byteArrayInputStream); PDDocument document = Loader.loadPDF(byteArrayInputStream);
PDDocumentCatalog catalog = document.getDocumentCatalog(); PDDocumentCatalog catalog = document.getDocumentCatalog();
PDMetadata metadata = catalog.getMetadata(); PDMetadata metadata = catalog.getMetadata();
// the PDF version we could get through the document but we want the PDF-A version, // the PDF version we could get through the document but we want the PDF-A version,
@@ -89,7 +95,7 @@ public class ZUGFeRDExporterFromPDFA implements IZUGFeRDExporter {
DomXmpParser xmpParser = new DomXmpParser(); DomXmpParser xmpParser = new DomXmpParser();
XMPMetadata xmp = xmpParser.parse(metadata.createInputStream()); XMPMetadata xmp = xmpParser.parse(metadata.createInputStream());
PDFAIdentificationSchema pdfaSchema = xmp.getPDFIdentificationSchema(); PDFAIdentificationSchema pdfaSchema = xmp.getPDFAIdentificationSchema();
if (pdfaSchema != null) { if (pdfaSchema != null) {
return pdfaSchema.getPart(); return pdfaSchema.getPart();
} }

View File

@@ -23,7 +23,13 @@ import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -36,6 +42,8 @@ import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathFactory;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary; import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary;
import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode; import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode;
@@ -115,7 +123,7 @@ public class ZUGFeRDImporter {
if (Arrays.equals(pad, pdfSignature)) { // we have a pdf if (Arrays.equals(pad, pdfSignature)) { // we have a pdf
try (PDDocument doc = PDDocument.load(pdfStream)) { try (PDDocument doc = Loader.loadPDF(IOUtils.toByteArray (pdfStream))) {
// PDDocumentInformation info = doc.getDocumentInformation(); // PDDocumentInformation info = doc.getDocumentInformation();
final PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog()); final PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog());
//start //start

View File

@@ -3,11 +3,9 @@ package org.mustangproject.ZUGFeRD;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import javax.xml.xpath.XPath; import javax.xml.xpath.XPath;
@@ -16,7 +14,14 @@ import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathFactory;
import org.mustangproject.*; import org.mustangproject.Allowance;
import org.mustangproject.BankDetails;
import org.mustangproject.Charge;
import org.mustangproject.EStandard;
import org.mustangproject.Invoice;
import org.mustangproject.Item;
import org.mustangproject.TradeParty;
import org.mustangproject.XMLTools;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.w3c.dom.Node; import org.w3c.dom.Node;

View File

@@ -20,30 +20,50 @@
*/ */
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import org.apache.fop.apps.*; import java.io.BufferedOutputStream;
import org.apache.fop.apps.io.ResourceResolverFactory; import java.io.ByteArrayInputStream;
import org.apache.fop.configuration.Configuration; import java.io.ByteArrayOutputStream;
import org.apache.fop.configuration.ConfigurationException; import java.io.File;
import org.apache.fop.configuration.DefaultConfigurationBuilder; import java.io.FileInputStream;
import org.apache.xmlgraphics.util.MimeConstants; import java.io.FileNotFoundException;
import org.mustangproject.CII.CIIToUBL; import java.io.FileOutputStream;
import org.mustangproject.ClasspathResolverURIAdapter; import java.io.IOException;
import org.xml.sax.SAXException; import java.io.InputStream;
import java.io.OutputStream;
import javax.xml.transform.*; import java.io.PipedInputStream;
import javax.xml.transform.sax.SAXResult; import java.io.PipedOutputStream;
import javax.xml.transform.stream.StreamResult; import java.io.UnsupportedEncodingException;
import javax.xml.transform.stream.StreamSource;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.fop.apps.FOPException;
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.io.ResourceResolverFactory;
import org.apache.fop.configuration.Configuration;
import org.apache.fop.configuration.ConfigurationException;
import org.apache.fop.configuration.DefaultConfigurationBuilder;
import org.apache.xmlgraphics.util.MimeConstants;
import org.mustangproject.ClasspathResolverURIAdapter;
import org.mustangproject.CII.CIIToUBL;
public class ZUGFeRDVisualizer { public class ZUGFeRDVisualizer {
public enum Language { public enum Language {

View File

@@ -21,6 +21,7 @@ package org.mustangproject.ZUGFeRD;
import junit.framework.Test; import junit.framework.Test;
import junit.framework.TestSuite; import junit.framework.TestSuite;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.common.PDMetadata; import org.apache.pdfbox.pdmodel.common.PDMetadata;
import org.apache.xmpbox.XMPMetadata; import org.apache.xmpbox.XMPMetadata;
@@ -252,7 +253,7 @@ public class MustangReaderWriterEdgeTest extends MustangReaderTestCase {
setupPdfUnderTest(SOURCE_PDF, TARGET_PDF); setupPdfUnderTest(SOURCE_PDF, TARGET_PDF);
// now check the contents // now check the contents
PDDocument doc = PDDocument.load(new File(TARGET_PDF)); PDDocument doc = Loader.loadPDF(new File(TARGET_PDF));
PDMetadata meta = doc.getDocumentCatalog().getMetadata(); PDMetadata meta = doc.getDocumentCatalog().getMetadata();
assertNotNull("The pdf must contain XMPMetadata", meta); assertNotNull("The pdf must contain XMPMetadata", meta);
@@ -262,7 +263,7 @@ public class MustangReaderWriterEdgeTest extends MustangReaderTestCase {
DomXmpParser xmpParser = new DomXmpParser(); DomXmpParser xmpParser = new DomXmpParser();
XMPMetadata xmp = xmpParser.parse(xmpBytes); XMPMetadata xmp = xmpParser.parse(xmpBytes);
PDFAIdentificationSchema pdfai = xmp.getPDFIdentificationSchema(); PDFAIdentificationSchema pdfai = xmp.getPDFAIdentificationSchema();
assertNotNull("The pdf must contain a PDFIdentificationSchema", pdfai); assertNotNull("The pdf must contain a PDFIdentificationSchema", pdfai);
assertTrue("The PDF/A conformance must be A, B or U", assertTrue("The PDF/A conformance must be A, B or U",

View File

@@ -21,6 +21,7 @@ package org.mustangproject.ZUGFeRD;
import junit.framework.Test; import junit.framework.Test;
import junit.framework.TestSuite; import junit.framework.TestSuite;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.common.PDMetadata; import org.apache.pdfbox.pdmodel.common.PDMetadata;
import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException; import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException;
@@ -328,13 +329,13 @@ public class MustangReaderWriterTest extends MustangReaderTestCase {
} }
private void checkPdfA3B(File tempFile) throws IOException, InvalidPasswordException { private void checkPdfA3B(File tempFile) throws IOException, InvalidPasswordException {
try (PDDocument doc = PDDocument.load(tempFile)) { try (PDDocument doc = Loader.loadPDF(tempFile)) {
PDMetadata metadata = doc.getDocumentCatalog().getMetadata(); PDMetadata metadata = doc.getDocumentCatalog().getMetadata();
InputStream exportXMPMetadata = metadata.exportXMPMetadata(); InputStream exportXMPMetadata = metadata.exportXMPMetadata();
byte[] xmpBytes = new byte[exportXMPMetadata.available()]; byte[] xmpBytes = new byte[exportXMPMetadata.available()];
exportXMPMetadata.read(xmpBytes); exportXMPMetadata.read(xmpBytes);
final XMPMetadata xmp = new DomXmpParser().parse(xmpBytes); final XMPMetadata xmp = new DomXmpParser().parse(xmpBytes);
PDFAIdentificationSchema pdfaid = xmp.getPDFIdentificationSchema(); PDFAIdentificationSchema pdfaid = xmp.getPDFAIdentificationSchema();
assertEquals(pdfaid.getPart().intValue(), 3); assertEquals(pdfaid.getPart().intValue(), 3);
assertEquals(pdfaid.getConformance(), "U"); assertEquals(pdfaid.getConformance(), "U");
} catch (XmpParsingException e) { } catch (XmpParsingException e) {

View File

@@ -1,6 +1,8 @@
package org.mustangproject.ZUGFeRD; package org.mustangproject.ZUGFeRD;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.junit.Ignore;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -9,6 +11,7 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@Ignore
public class ResourceCase extends TestCase { public class ResourceCase extends TestCase {
private static final Logger LOGGER = LoggerFactory.getLogger(ResourceCase.class.getCanonicalName()); // log output is private static final Logger LOGGER = LoggerFactory.getLogger(ResourceCase.class.getCanonicalName()); // log output is

View File

@@ -80,10 +80,10 @@ public class VisualizationTest extends ResourceCase {
/* remove file endings so that tests can also pass after checking /* remove file endings so that tests can also pass after checking
out from git with arbitrary options (which may include CSRF changes) out from git with arbitrary options (which may include CSRF changes)
*/ */
result = zvi.visualize(UBLinputFile.getAbsolutePath(),ZUGFeRDVisualizer.Language.EN).replace("\r","").replace("\n",""); result = zvi.visualize(UBLinputFile.getAbsolutePath(),ZUGFeRDVisualizer.Language.EN).replace("\r","").replace("\n","").replace(" ","").replace("\t","");
File expectedResult=getResourceAsFile("factur-x-vis-ubl-creditnote.en.html"); File expectedResult=getResourceAsFile("factur-x-vis-ubl-creditnote.en.html");
expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8).replace("\r","").replace("\n",""); expected = new String(Files.readAllBytes(expectedResult.toPath()), StandardCharsets.UTF_8).replace("\r","").replace("\n","").replace(" ","").replace("\t","");
// remove linebreaks as well... // remove linebreaks as well...
} catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) {

View File

@@ -1,7 +1,7 @@
<html xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xr="urn:ce.eu:en16931:2017:xoev-de:kosit:standard:xrechnung-1" xmlns:xrv="http://www.example.org/XRechnung-Viewer" lang="de"> <!DOCTYPE HTML>
<html xmlns:xr="urn:ce.eu:en16931:2017:xoev-de:kosit:standard:xrechnung-1" xmlns:xrv="http://www.example.org/XRechnung-Viewer" xmlns:xs="http://www.w3.org/2001/XMLSchema" lang="de">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<title>XRechnung</title> <title>XRechnung</title>
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0"> <meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
<style> <style>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?><Invoice xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:cec="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2">
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:cec="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2">
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID> <cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID>
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID> <cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
<cbc:ID>RE-20201121/508</cbc:ID> <cbc:ID>RE-20201121/508</cbc:ID>
@@ -12,9 +9,6 @@
<cbc:BuyerReference>AB321</cbc:BuyerReference> <cbc:BuyerReference>AB321</cbc:BuyerReference>
<cac:AccountingSupplierParty> <cac:AccountingSupplierParty>
<cac:Party> <cac:Party>
<cac:PartyName>
<cbc:Name>Bei Spiel GmbH</cbc:Name>
</cac:PartyName>
<cac:PostalAddress> <cac:PostalAddress>
<cbc:StreetName>Ecke 12</cbc:StreetName> <cbc:StreetName>Ecke 12</cbc:StreetName>
<cbc:CityName>Stadthausen</cbc:CityName> <cbc:CityName>Stadthausen</cbc:CityName>
@@ -39,9 +33,6 @@
<cac:PartyIdentification> <cac:PartyIdentification>
<cbc:ID>2</cbc:ID> <cbc:ID>2</cbc:ID>
</cac:PartyIdentification> </cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>Theodor Est</cbc:Name>
</cac:PartyName>
<cac:PostalAddress> <cac:PostalAddress>
<cbc:StreetName>Bahnstr. 42</cbc:StreetName> <cbc:StreetName>Bahnstr. 42</cbc:StreetName>
<cbc:CityName>Spielkreis</cbc:CityName> <cbc:CityName>Spielkreis</cbc:CityName>
@@ -124,6 +115,11 @@
<cac:Price> <cac:Price>
<cbc:PriceAmount currencyID="EUR">160</cbc:PriceAmount> <cbc:PriceAmount currencyID="EUR">160</cbc:PriceAmount>
<cbc:BaseQuantity unitCode="HUR">1</cbc:BaseQuantity> <cbc:BaseQuantity unitCode="HUR">1</cbc:BaseQuantity>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:Amount currencyID="EUR">0</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">160</cbc:BaseAmount>
</cac:AllowanceCharge>
</cac:Price> </cac:Price>
</cac:InvoiceLine> </cac:InvoiceLine>
<cac:InvoiceLine> <cac:InvoiceLine>
@@ -144,6 +140,11 @@
<cac:Price> <cac:Price>
<cbc:PriceAmount currencyID="EUR">0.79</cbc:PriceAmount> <cbc:PriceAmount currencyID="EUR">0.79</cbc:PriceAmount>
<cbc:BaseQuantity unitCode="H87">1</cbc:BaseQuantity> <cbc:BaseQuantity unitCode="H87">1</cbc:BaseQuantity>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:Amount currencyID="EUR">0</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">0.79</cbc:BaseAmount>
</cac:AllowanceCharge>
</cac:Price> </cac:Price>
</cac:InvoiceLine> </cac:InvoiceLine>
<cac:InvoiceLine> <cac:InvoiceLine>
@@ -163,6 +164,11 @@
<cac:Price> <cac:Price>
<cbc:PriceAmount currencyID="EUR">0.025</cbc:PriceAmount> <cbc:PriceAmount currencyID="EUR">0.025</cbc:PriceAmount>
<cbc:BaseQuantity unitCode="LTR">1</cbc:BaseQuantity> <cbc:BaseQuantity unitCode="LTR">1</cbc:BaseQuantity>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:Amount currencyID="EUR">0</cbc:Amount>
<cbc:BaseAmount currencyID="EUR">0.025</cbc:BaseAmount>
</cac:AllowanceCharge>
</cac:Price> </cac:Price>
</cac:InvoiceLine> </cac:InvoiceLine>
</Invoice> </Invoice>

10
pom.xml
View File

@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.mustangproject</groupId> <groupId>org.mustangproject</groupId>
<artifactId>core</artifactId> <artifactId>core</artifactId>
<version>2.11.1-SNAPSHOT</version> <version>3.0.0-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Mustang</name> <name>Mustang</name>
@@ -118,9 +118,9 @@
<github.global.server>github</github.global.server> <github.global.server>github</github.global.server>
<additionalparam>-Xdoclint:none</additionalparam> <additionalparam>-Xdoclint:none</additionalparam>
<!-- Skip error check for javadoc --> <!-- Skip error check for javadoc -->
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> <maven.compiler.compilerVersion>11</maven.compiler.compilerVersion>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>11</maven.compiler.target>
<maven.deploy.skip>true</maven.deploy.skip><!-- prevent this to be deployed to maven central as "core", <maven.deploy.skip>true</maven.deploy.skip><!-- prevent this to be deployed to maven central as "core",
we only want submodules, see also https://stackoverflow.com/questions/7446599/how-to-deploy-only-the-sub-modules-using-maven-deploy--> we only want submodules, see also https://stackoverflow.com/questions/7446599/how-to-deploy-only-the-sub-modules-using-maven-deploy-->
</properties> </properties>
@@ -199,7 +199,7 @@
<configuration> <configuration>
<toolchains> <toolchains>
<jdk> <jdk>
<version>8</version> <version>11</version>
<vendor>adopt</vendor> <vendor>adopt</vendor>
</jdk> </jdk>
</toolchains> </toolchains>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>org.mustangproject</groupId> <groupId>org.mustangproject</groupId>
<artifactId>core</artifactId> <artifactId>core</artifactId>
<version>2.11.1-SNAPSHOT</version> <version>3.0.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.mustangproject</groupId> <groupId>org.mustangproject</groupId>
@@ -11,7 +11,7 @@
<name>Library to validate e-invoices (ZUGFeRD, Factur-X and Xrechnung)</name> <name>Library to validate e-invoices (ZUGFeRD, Factur-X and Xrechnung)</name>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>2.11.1-SNAPSHOT</version> <version>3.0.0-SNAPSHOT</version>
<repositories> <repositories>
<repository> <repository>
<!-- for jargs --> <!-- for jargs -->
@@ -38,37 +38,24 @@
<dependency> <dependency>
<groupId>${project.groupId}</groupId> <groupId>${project.groupId}</groupId>
<artifactId>library</artifactId> <artifactId>library</artifactId>
<version>2.11.1-SNAPSHOT</version> <version>3.0.0-SNAPSHOT</version>
</dependency> </dependency>
<!-- for java9 -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
</dependency>
<!-- for xml pretty print -->
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.3</version>
</dependency>
<!-- for ph-schematron -->
<dependency> <dependency>
<groupId>ch.qos.logback</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId> <artifactId>logback-classic</artifactId>
<version>1.2.13</version> <version>1.5.6</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>ch.qos.logback</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId> <artifactId>logback-core</artifactId>
<version>1.2.13</version> <version>1.5.6</version>
</dependency> </dependency>
<dependency> <dependency>
<!-- This library is needed so that logback stderr output is sent to, well, stderr, otherwise it lands in stdout --> <!-- This library is needed so that logback stderr output is sent to, well, stderr, otherwise it lands in stdout -->
<groupId>org.codehaus.janino</groupId> <groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId> <artifactId>janino</artifactId>
<version>3.1.7</version> <version>3.1.8</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/com.googlecode.slf4j-maven-plugin-log/slf4j-maven-plugin-log --> <!-- https://mvnrepository.com/artifact/com.googlecode.slf4j-maven-plugin-log/slf4j-maven-plugin-log -->
<dependency> <dependency>
@@ -81,24 +68,14 @@
<!-- embedded verapdf --> <!-- embedded verapdf -->
<dependency> <dependency>
<groupId>org.verapdf</groupId> <groupId>org.verapdf</groupId>
<artifactId>validation-model</artifactId> <artifactId>validation-model-jakarta</artifactId>
<version>1.22.2</version> <version>1.26.1</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/com.helger/ph-schematron --> <!-- https://mvnrepository.com/artifact/com.helger/ph-schematron -->
<dependency> <dependency>
<groupId>com.helger.schematron</groupId> <groupId>com.helger.schematron</groupId>
<artifactId>ph-schematron-xslt</artifactId> <artifactId>ph-schematron-xslt</artifactId>
<version>6.3.3</version> <version>8.0.0</version>
</dependency>
<dependency>
<groupId>com.helger</groupId>
<artifactId>ph-jaxb</artifactId>
<version>9.5.5</version>
</dependency>
<dependency>
<groupId>org.mustangproject</groupId>
<artifactId>library</artifactId>
<version>2.11.1-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.xmlunit</groupId> <groupId>org.xmlunit</groupId>
@@ -115,18 +92,18 @@
<dependency> <dependency>
<groupId>org.riversun</groupId> <groupId>org.riversun</groupId>
<artifactId>bigdoc</artifactId> <artifactId>bigdoc</artifactId>
<version>0.3.0</version> <version>0.4.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId> <artifactId>junit-jupiter-api</artifactId>
<version>5.9.1</version> <version>5.10.2</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.junit.vintage</groupId> <groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId> <artifactId>junit-vintage-engine</artifactId>
<version>5.9.1</version> <version>5.10.2</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
@@ -328,7 +305,7 @@
<plugin> <plugin>
<groupId>com.helger.maven</groupId> <groupId>com.helger.maven</groupId>
<artifactId>ph-schematron-maven-plugin</artifactId> <artifactId>ph-schematron-maven-plugin</artifactId>
<version>5.6.0</version> <version>8.0.0</version>
<configuration> <configuration>
<schematronDirectory>${basedir}/src/main/resources/schematron</schematronDirectory> <schematronDirectory>${basedir}/src/main/resources/schematron</schematronDirectory>
<xsltDirectory>${basedir}/src/main/resources/xslt</xsltDirectory> <xsltDirectory>${basedir}/src/main/resources/xslt</xsltDirectory>

View File

@@ -129,10 +129,11 @@ public class PDFValidator extends Validator {
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
final Document docXMP; final Document docXMP;
if (xmp.length() == 0) { if (xmp == null || xmp.length() == 0) {
context.addResultItem(new ValidationResultItem(ESeverity.error, "Invalid XMP Metadata not found") context.addResultItem(new ValidationResultItem(ESeverity.error, "Invalid XMP Metadata not found")
.setSection(17).setPart(EPart.pdf)); .setSection(17).setPart(EPart.pdf));
} }
else
/* /*
* checking for sth like <zf:ConformanceLevel>EXTENDED</zf:ConformanceLevel> * checking for sth like <zf:ConformanceLevel>EXTENDED</zf:ConformanceLevel>
* <zf:DocumentType>INVOICE</zf:DocumentType> * <zf:DocumentType>INVOICE</zf:DocumentType>

View File

@@ -1,6 +1,12 @@
package org.mustangproject.validator; package org.mustangproject.validator;
import java.io.*; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@@ -11,7 +17,6 @@ import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
@@ -28,6 +33,8 @@ import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import jakarta.xml.bind.annotation.adapters.HexBinaryAdapter;
//abstract class //abstract class
public class ZUGFeRDValidator { public class ZUGFeRDValidator {
private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDValidator.class.getCanonicalName()); // log private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDValidator.class.getCanonicalName()); // log
@@ -322,6 +329,7 @@ public class ZUGFeRDValidator {
} }
} catch (IrrecoverableValidationError | IOException irx) { } catch (IrrecoverableValidationError | IOException irx) {
LOGGER.info(irx.getMessage()); LOGGER.info(irx.getMessage());
context.setInvalid ();
} finally { } finally {
finalStringResult.append(context.getXMLResult()); finalStringResult.append(context.getXMLResult());
finalStringResult.append("</validation>"); finalStringResult.append("</validation>");

View File

@@ -6,10 +6,13 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.junit.Ignore;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import junit.framework.TestCase; import junit.framework.TestCase;
@Ignore
public class ResourceCase extends TestCase { public class ResourceCase extends TestCase {
private static final Logger LOGGER = LoggerFactory.getLogger(ResourceCase.class.getCanonicalName()); // log output is private static final Logger LOGGER = LoggerFactory.getLogger(ResourceCase.class.getCanonicalName()); // log output is