Merge pull request #406 from phax/master

Misc optimizations
This commit is contained in:
Jochen Staerk
2024-07-10 10:42:33 +02:00
committed by GitHub
60 changed files with 869 additions and 950 deletions

View File

@@ -16,7 +16,7 @@ jobs:
- uses: actions/setup-java@v3 # the log states the default ~/.m2/toolchains.xml is being created pointing to the JDK
with:
distribution: 'adopt' # for latest JDKs use temurin https://blog.adoptopenjdk.net/2021/08/goodbye-adoptopenjdk-hello-adoptium/
java-version: '8'
java-version: '11'
cache: 'maven' #cache/restore any dependencies to improve the workflow execution time
- name: Build with Maven
run: mvn -B package --file pom.xml

View File

@@ -16,9 +16,9 @@
<version>2.12.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.compilerVersion>8</maven.compiler.compilerVersion>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.compilerVersion>11</maven.compiler.compilerVersion>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
@@ -36,11 +36,6 @@
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>org.riversun</groupId>
<artifactId>bigdoc</artifactId>
<version>0.4.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
@@ -100,7 +95,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<version>3.4.2</version>
<configuration>
<archive>
<manifest>
@@ -128,14 +123,14 @@
<!-- http://stackoverflow.com/questions/574594/how-can-i-create-an-executable-jar-with-dependencies-using-maven
mvn clean compile assembly:single -->
<!-- or whatever version you use -->
<source>8</source>
<target>8</target>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<version>3.5.3</version>
<configuration>
<transformers>
<transformer
@@ -218,7 +213,7 @@
<configuration>
<toolchains>
<jdk>
<version>8</version>
<version>11</version>
<vendor>adopt</vendor>
</jdk>
</toolchains>

View File

@@ -332,7 +332,7 @@ public class Main {
public static void main(String[] args) {
try {
CommandLine cmd;
CommandLineParser parser = new BasicParser();
CommandLineParser parser = new DefaultParser();
// create Options object
Options options = new Options();
@@ -427,7 +427,7 @@ public class Main {
performUBL(sourceName, outName);
optionsRecognized = true;
} else if ((action != null) && (action.equals("validate"))) {
optionsRecognized = performValidate(sourceName, noNotices != null && noNotices, cmd.getOptionValue("logAppend"));
optionsRecognized = performValidate(sourceName, noNotices, cmd.getOptionValue("logAppend"));
} else if ((action != null) && (action.equals("validateExpectValid"))) {
optionsRecognized = performValidateExpect(true, directoryName);
} else if ((action != null) && (action.equals("validateExpectInvalid"))) {
@@ -519,10 +519,11 @@ public class Main {
ensureFileNotExists(outName);
// All params are good! continue...
ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1().convertOnly().load(pdfName);
ze.export(outName);
System.out.println("Written to " + outName);
try (ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1()) {
ze.convertOnly().load(pdfName);
ze.export(outName);
System.out.println("Written to " + outName);
}
}
private static void performExtract(String pdfName, String xmlName) throws IOException {
@@ -585,7 +586,7 @@ public class Main {
if (attachmentFilenames == null) {
byte attachmentContents[] = null;
String attachmentFilename, attachmentMime, attachmentDescription;
String attachmentFilename, attachmentMime;
if (!noAttachments) {
attachmentFilename = getFilenameFromUser("Additional file attachments filename (empty for none)", "", "pdf", true, false);
if (attachmentFilename.length() != 0) {
@@ -842,13 +843,7 @@ public class Main {
} else {
zvi.toPDF(sourceName, outName);
}
} catch (FileNotFoundException e) {
LOGGER.error(e.getMessage(), e);
} catch (UnsupportedEncodingException e) {
LOGGER.error(e.getMessage(), e);
} catch (TransformerException e) {
LOGGER.error(e.getMessage(), e);
} catch (IOException e) {
} catch (TransformerException | IOException e) {
LOGGER.error(e.getMessage(), e);
}
System.out.println("Written to " + outName);
@@ -876,11 +871,8 @@ public class Main {
* @throws Exception e.g. if the specified resource does not exist at the specified location
*/
static public String ExportResource(String resourceName) throws Exception {
InputStream stream = null;
OutputStream resStreamOut = null;
String jarFolder;
try {
stream = Main.class.getResourceAsStream(resourceName);//note that each / is a directory down in the "jar tree" been the jar the root of the tree
try (InputStream stream = Main.class.getResourceAsStream(resourceName)) {//note that each / is a directory down in the "jar tree" been the jar the root of the tree
if (stream == null) {
throw new Exception("Cannot get resource \"" + resourceName + "\" from Jar file.");
}
@@ -888,15 +880,11 @@ public class Main {
int readBytes;
byte[] buffer = new byte[4096];
jarFolder = System.getProperty("user.dir");
resStreamOut = new FileOutputStream(jarFolder + resourceName);
while ((readBytes = stream.read(buffer)) > 0) {
resStreamOut.write(buffer, 0, readBytes);
try (FileOutputStream resStreamOut = new FileOutputStream(jarFolder + resourceName)) {
while ((readBytes = stream.read(buffer)) > 0) {
resStreamOut.write(buffer, 0, readBytes);
}
}
} catch (Exception ex) {
throw ex;
} finally {
stream.close();
resStreamOut.close();
}
return jarFolder + resourceName;
@@ -918,7 +906,8 @@ public class Main {
if (fileName == null)
return false;
File f = new File(fileName);
return f.exists();
// "exists" also returns true for directories
return f.isFile();
}
}

View File

@@ -14,9 +14,6 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmlunit.builder.Input;
import org.xmlunit.xpath.JAXPXPathEngine;
import org.xmlunit.xpath.XPathEngine;
import org.mustangproject.validator.ZUGFeRDValidator;
import static org.xmlunit.assertj.XmlAssert.assertThat;
@@ -50,25 +47,23 @@ public class ValidatorFileWalker
Date date = new Date();
String expectedString="valid";
if (!expectValid) {
expectedString="invalid";
}
expectedString="invalid";
}
if ((attr!=null)&&(attr.isRegularFile())) {
if (matcher.matches(file.getFileName())) {
boolean thisResultValid=true;
String thisResultString=" valid";
try {
assertThat(zul.validate(file.toAbsolutePath().toString())).valueByXPath("/validation/summary/@status")
.asString()
.isEqualTo(expectedString);
} catch (AssertionError ae) {
thisResultValid=false;
thisResultString="invalid";
allValid=false;
}
LOGGER.info(String.format("\n@%s Testing file %d: %s (%s)", dateFormat.format(date), fileCount++, thisResultString, file));
}
try {
assertThat(zul.validate(file.toAbsolutePath().toString())).valueByXPath("/validation/summary/@status")
.asString()
.isEqualTo(expectedString);
} catch (AssertionError ae) {
thisResultString="invalid";
allValid=false;
}
LOGGER.info(String.format("\n@%s Testing file %d: %s (%s)", dateFormat.format(date), fileCount++, thisResultString, file));
}
}
return FileVisitResult.CONTINUE;
}

View File

@@ -47,14 +47,19 @@
<github.global.server>github</github.global.server>
<additionalparam>-Xdoclint:none</additionalparam>
<!-- Skip error check for javadoc -->
<maven.compiler.compilerVersion>8</maven.compiler.compilerVersion>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.compilerVersion>11</maven.compiler.compilerVersion>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<maven.deploy.skip>true
</maven.deploy.skip><!-- do deploy to maven central, parent project does not and inherits -->
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.saxon/Saxon-HE -->
<dependency>
<groupId>net.sf.saxon</groupId>
@@ -71,6 +76,12 @@
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>fop</artifactId>
<version>2.9</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
@@ -157,7 +168,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<version>3.13.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
@@ -165,8 +176,8 @@
<!-- http://stackoverflow.com/questions/574594/how-can-i-create-an-executable-jar-with-dependencies-using-maven
mvn clean compile assembly:single -->
<!-- or whatever version you use -->
<source>8</source>
<target>8</target>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
@@ -207,7 +218,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<version>3.3.1</version>
<executions>
<execution>
<id>attach-sources</id>
@@ -220,7 +231,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<version>3.5.3</version>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<minimizeJar>false
@@ -309,7 +320,7 @@
<configuration>
<toolchains>
<jdk>
<version>8</version>
<version>11</version>
<vendor>adopt</vendor>
</jdk>
</toolchains>

View File

@@ -1,14 +1,11 @@
package org.mustangproject;
import org.mustangproject.ZUGFeRD.IExportableTransaction;
import org.mustangproject.ZUGFeRD.IZUGFeRDAllowanceCharge;
import java.math.BigDecimal;
/***
* (absolute) allowances on item and document level
*/
public class Allowance extends Charge implements IZUGFeRDAllowanceCharge {
public class Allowance extends Charge {
/***
* bean constructor

View File

@@ -5,8 +5,6 @@ import java.io.Serializable;
import com.helger.commons.error.list.ErrorList;
import com.helger.en16931.cii2ubl.CIIToUBL23Converter;
import com.helger.ubl21.UBL21Marshaller;
import com.helger.ubl22.UBL22Marshaller;
import com.helger.ubl23.UBL23Marshaller;
/***
@@ -23,31 +21,7 @@ public class CIIToUBL {
final ErrorList occurred=new ErrorList();
final CIIToUBL23Converter cc=new CIIToUBL23Converter();
final Serializable aUBL = cc.convertCIItoUBL(input, occurred);
if (aUBL instanceof oasis.names.specification.ubl.schema.xsd.invoice_21.InvoiceType)
{
UBL21Marshaller.invoice ()
.setFormattedOutput (true)
.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)
{
UBL21Marshaller.creditNote ()
.setFormattedOutput (true)
.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)
{
UBL22Marshaller.invoice ()
.setFormattedOutput (true)
.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)
{
UBL22Marshaller.creditNote ()
.setFormattedOutput (true)
.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)
if (aUBL instanceof oasis.names.specification.ubl.schema.xsd.invoice_23.InvoiceType)
{
UBL23Marshaller.invoice ()
.setFormattedOutput (true)

View File

@@ -1,9 +1,7 @@
package org.mustangproject;
import org.mustangproject.ZUGFeRD.IAbsoluteValueProvider;
import org.mustangproject.ZUGFeRD.IExportableTransaction;
import org.mustangproject.ZUGFeRD.IZUGFeRDAllowanceCharge;
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableItem;
import java.math.BigDecimal;

View File

@@ -547,7 +547,7 @@ public class Invoice implements IExportableTransaction {
return null;
}
return ((TradeParty) getSender()).getAsTradeSettlement();
return getSender().getAsTradeSettlement();
}

View File

@@ -1,7 +1,6 @@
package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.apache.fop.util.XMLUtil;
import org.mustangproject.ZUGFeRD.IReferencedDocument;
import org.mustangproject.ZUGFeRD.IZUGFeRDAllowanceCharge;
import org.mustangproject.ZUGFeRD.IZUGFeRDExportableItem;
@@ -12,7 +11,6 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/***
* describes any invoice line
@@ -28,8 +26,8 @@ public class Item implements IZUGFeRDExportableItem {
protected Product product;
protected ArrayList<String> notes = null;
protected ArrayList<ReferencedDocument> referencedDocuments = null;
protected ArrayList<IZUGFeRDAllowanceCharge> Allowances = new ArrayList<IZUGFeRDAllowanceCharge>(),
Charges = new ArrayList<IZUGFeRDAllowanceCharge>();
protected ArrayList<IZUGFeRDAllowanceCharge> Allowances = new ArrayList<>(),
Charges = new ArrayList<>();
/***
* default constructor
@@ -138,7 +136,7 @@ public class Item implements IZUGFeRDExportableItem {
ReferencedDocument rd = new ReferencedDocument(IssuerAssignedID, TypeCode,
ReferenceTypeCode);
if (rdocs == null) {
rdocs = new ArrayList<ReferencedDocument>();
rdocs = new ArrayList<>();
}
rdocs.add(rd);
@@ -428,7 +426,7 @@ public class Item implements IZUGFeRDExportableItem {
*/
public Item addNote(String text) {
if (notes == null) {
notes = new ArrayList<String>();
notes = new ArrayList<>();
}
notes.add(text);
return this;
@@ -441,7 +439,7 @@ public class Item implements IZUGFeRDExportableItem {
*/
public Item addReferencedDocument(ReferencedDocument doc) {
if (referencedDocuments == null) {
referencedDocuments = new ArrayList<ReferencedDocument>();
referencedDocuments = new ArrayList<>();
}
referencedDocuments.add(doc);
return this;

View File

@@ -2,13 +2,6 @@ package org.mustangproject;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.mustangproject.ZUGFeRD.*;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/***
* A organisation, i.e. usually a company

View File

@@ -66,15 +66,15 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
//nodes.item(i).getTextContent())) {
Node currentItemNode = nodes.item(nodeIndex);
if (nodes.item(nodeIndex).getLocalName() != null) {
String debcurrentChild = nodes.item(nodeIndex).getLocalName();
if (nodes.item(nodeIndex).getLocalName().equals("Party")) {
if (currentItemNode.getLocalName() != null) {
String debcurrentChild = currentItemNode.getLocalName();
if (debcurrentChild.equals("Party")) {
NodeList party = nodes.item(nodeIndex).getChildNodes();
NodeList party = currentItemNode.getChildNodes();
for (int partyIndex = 0; partyIndex < party.getLength(); partyIndex++) {
if (party.item(partyIndex).getLocalName() != null) {
String debCN = party.item(partyIndex).getLocalName();
if (party.item(partyIndex).getLocalName().equals("PartyName")) {
if (debCN.equals("PartyName")) {
NodeList partyName = party.item(partyIndex).getChildNodes();
for (int partyNameIndex = 0; partyNameIndex < partyName.getLength(); partyNameIndex++) {
@@ -87,7 +87,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
}
}
}
if (party.item(partyIndex).getLocalName().equals("PostalAddress")) {
if (debCN.equals("PostalAddress")) {
NodeList postal = party.item(partyIndex).getChildNodes();
for (int postalChildIndex = 0; postalChildIndex < postal.getLength(); postalChildIndex++) {
@@ -145,7 +145,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
}
}
if (party.item(partyIndex).getLocalName().equals("Contact")) {
if (debCN.equals("Contact")) {
NodeList contact = party.item(partyIndex).getChildNodes();
setContact(new Contact(contact));
@@ -156,19 +156,19 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
}
if (nodes.item(nodeIndex).getLocalName().equals("GlobalID")) {
if (debcurrentChild.equals("GlobalID")) {
if (nodes.item(nodeIndex).getAttributes().getNamedItem("schemeID") != null) {
SchemedID gid = new SchemedID().setScheme(nodes.item(nodeIndex).getAttributes().getNamedItem("schemeID").getNodeValue()).setId(nodes.item(nodeIndex).getTextContent());
addGlobalID(gid);
}
}
if (nodes.item(nodeIndex).getLocalName().equals("DefinedTradeContact")) {
if (debcurrentChild.equals("DefinedTradeContact")) {
NodeList contact = nodes.item(nodeIndex).getChildNodes();
setContact(new Contact(contact));
}
if (nodes.item(nodeIndex).getLocalName().equals("PostalTradeAddress")) {
if (debcurrentChild.equals("PostalTradeAddress")) {
NodeList postal = nodes.item(nodeIndex).getChildNodes();
for (int postalChildIndex = 0; postalChildIndex < postal.getLength(); postalChildIndex++) {
if (postal.item(postalChildIndex).getLocalName() != null) {
@@ -196,7 +196,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
}
if (nodes.item(nodeIndex).getLocalName().equals("SpecifiedTaxRegistration")) {
if (debcurrentChild.equals("SpecifiedTaxRegistration")) {
NodeList taxChilds = nodes.item(nodeIndex).getChildNodes();
for (int taxChildIndex = 0; taxChildIndex < taxChilds.getLength(); taxChildIndex++) {
if (taxChilds.item(taxChildIndex).getLocalName() != null) {
@@ -290,7 +290,7 @@ public class TradeParty implements IZUGFeRDExportableTradeParty {
for (int nodeIndex = 0; nodeIndex < nodes.getLength(); nodeIndex++) {
//nodes.item(i).getTextContent())) {
String debLN = nodes.item(nodeIndex).getLocalName();
if (nodes.item(nodeIndex).getLocalName().equals("Party")) {
if (debLN.equals("Party")) {
// take one step back and parse from top
parseFromUBL(nodes);
return;

View File

@@ -1,7 +1,5 @@
package org.mustangproject;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
@@ -11,6 +9,7 @@ import java.util.Collections;
import java.util.List;
import java.util.RandomAccess;
import org.apache.commons.io.IOUtils;
import org.dom4j.io.XMLWriter;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@@ -40,11 +39,13 @@ public class XMLTools extends XMLWriter {
list = l;
}
public Node get(int index) {
@Override
public Node get(int index) {
return list.item(index);
}
public int size() {
@Override
public int size() {
return list.getLength();
}
}
@@ -127,6 +128,7 @@ public class XMLTools extends XMLWriter {
*/
public static byte[] removeBOM(byte[] zugferdRaw) {
final byte[] zugferdData;
// This handles the UTF-8 BOM
if ((zugferdRaw[0] == (byte) 0xEF) && (zugferdRaw[1] == (byte) 0xBB) && (zugferdRaw[2] == (byte) 0xBF)) {
// I don't like BOMs, lets remove it
zugferdData = new byte[zugferdRaw.length - 3];
@@ -138,20 +140,7 @@ public class XMLTools extends XMLWriter {
}
public static byte[] getBytesFromStream(InputStream fileinput) throws IOException {
// we're on java 8 so we cant use inputstream.readallbytes
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
BufferedInputStream bufferedInput=new BufferedInputStream(fileinput);
while ((nRead = bufferedInput.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
return buffer.toByteArray();
// end of polyfill
return IOUtils.toByteArray (fileinput);
}
}

View File

@@ -22,21 +22,18 @@ package org.mustangproject.ZUGFeRD;
import static org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat.DATE;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;
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 {
protected IExportableTransaction trans;
private String paymentTermsDescription;
protected Profile profile = Profiles.getByName(EStandard.despatchadvice,"pilot", 1);
@@ -252,13 +249,9 @@ public class DAPullProvider extends ZUGFeRD2PullProvider implements IXMLProvider
+ "</SCRDMCCBDACIDAMessageStructure>";
final byte[] zugferdRaw;
try {
zugferdRaw = xml.getBytes("UTF-8");
zugferdRaw = xml.getBytes(StandardCharsets.UTF_8);
zugferdData = XMLTools.removeBOM(zugferdRaw);
} catch (final UnsupportedEncodingException e) {
Logger.getLogger(OXPullProvider.class.getName()).log(Level.SEVERE, null, e);
}
zugferdData = XMLTools.removeBOM(zugferdRaw);
}

View File

@@ -29,10 +29,11 @@ import org.apache.pdfbox.preflight.parser.PreflightParser;
import jakarta.activation.DataSource;
public class DXExporterFromA1 extends DXExporterFromA3 implements IZUGFeRDExporter {
public class DXExporterFromA1 extends DXExporterFromA3 {
protected boolean ignorePDFAErrors = false;
public DXExporterFromA1 ignorePDFAErrors() {
@Override
public DXExporterFromA1 ignorePDFAErrors() {
this.ignorePDFAErrors = true;
return this;
}
@@ -45,7 +46,8 @@ public class DXExporterFromA1 extends DXExporterFromA3 implements IZUGFeRDExport
* @param ver the delivery-x version
* @return the URN of the namespace
*/
public String getNamespaceForVersion(int ver) {
@Override
public String getNamespaceForVersion(int ver) {
// As of late 2022 the Delivery-X standard is not yet published. See specification:
// Die digitale Ablösung des Papier-Lieferscheins, Version 1.1, April 2022
// Chapter 7.1 XMP-Erweiterungsschema für PDF/A-3
@@ -57,7 +59,8 @@ public class DXExporterFromA1 extends DXExporterFromA3 implements IZUGFeRDExport
* @param ver the ox version
* @return the namespace prefix as string, without colon
*/
public String getPrefixForVersion(int ver) {
@Override
public String getPrefixForVersion(int ver) {
return "fx";
}
@@ -91,14 +94,17 @@ public class DXExporterFromA1 extends DXExporterFromA3 implements IZUGFeRDExport
}
public DXExporterFromA1 setProfile(Profile p) {
@Override
public DXExporterFromA1 setProfile(Profile p) {
return (DXExporterFromA1)super.setProfile(p);
}
public DXExporterFromA1 setProfile(String profileName) {
@Override
public DXExporterFromA1 setProfile(String profileName) {
return (DXExporterFromA1)super.setProfile(profileName);
}
public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException {
@Override
public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException {
if (!ignorePDFAErrors && !isValidA1(dataSource)) {
throw new IOException("File is not a valid PDF/A input file");
}
@@ -110,32 +116,41 @@ public class DXExporterFromA1 extends DXExporterFromA3 implements IZUGFeRDExport
}
public DXExporterFromA1 load(String pdfFilename) throws IOException {
@Override
public DXExporterFromA1 load(String pdfFilename) throws IOException {
return (DXExporterFromA1) super.load(pdfFilename);
}
public DXExporterFromA1 load(byte[] pdfBinary) throws IOException {
@Override
public DXExporterFromA1 load(byte[] pdfBinary) throws IOException {
return (DXExporterFromA1) super.load(pdfBinary);
}
public DXExporterFromA1 load(InputStream pdfSource) throws IOException{
@Override
public DXExporterFromA1 load(InputStream pdfSource) throws IOException{
return (DXExporterFromA1) super.load(pdfSource);
}
public DXExporterFromA1 setCreator(String creator) {
@Override
public DXExporterFromA1 setCreator(String creator) {
return (DXExporterFromA1) super.setCreator(creator);
}
public DXExporterFromA1 setConformanceLevel(PDFAConformanceLevel newLevel) {
@Override
public DXExporterFromA1 setConformanceLevel(PDFAConformanceLevel newLevel) {
return (DXExporterFromA1) super.setConformanceLevel(newLevel);
}
public DXExporterFromA1 setProducer(String producer){
@Override
public DXExporterFromA1 setProducer(String producer){
return (DXExporterFromA1) super.setProducer(producer);
}
public DXExporterFromA1 setZUGFeRDVersion(int version){
@Override
public DXExporterFromA1 setZUGFeRDVersion(int version){
return (DXExporterFromA1) super.setZUGFeRDVersion(version);
}
public DXExporterFromA1 setXML(byte[] zugferdData) throws IOException{
@Override
public DXExporterFromA1 setXML(byte[] zugferdData) throws IOException{
return (DXExporterFromA1) super.setXML(zugferdData);
}
public DXExporterFromA1 disableAutoClose(boolean disableAutoClose){
@Override
public DXExporterFromA1 disableAutoClose(boolean disableAutoClose){
return (DXExporterFromA1) super.disableAutoClose(disableAutoClose);
}
public DXExporterFromA1 convertOnly() {

View File

@@ -71,7 +71,7 @@ import jakarta.activation.FileDataSource;
public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
protected PDFAConformanceLevel conformanceLevel = PDFAConformanceLevel.UNICODE;
protected ArrayList<FileAttachment> fileAttachments = new ArrayList<FileAttachment>();
protected ArrayList<FileAttachment> fileAttachments = new ArrayList<>();
/**
* This flag controls whether or not the metadata is overwritten, or kind of merged.
@@ -127,9 +127,6 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
protected String despatchAdviceDocumentType = "DESPATCHADVICE";
private HashMap<String, byte[]> additionalXMLs = new HashMap<String, byte[]>();
private boolean attachZUGFeRDHeaders = true;
/**
@@ -138,7 +135,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
*
* @param pdfFilename filename of an PDF/A1 compliant document
*/
public DXExporterFromA3 load(String pdfFilename) throws IOException {
@Override
public DXExporterFromA3 load(String pdfFilename) throws IOException {
ensurePDFIsValid(new FileDataSource(pdfFilename));
try (FileInputStream pdf = new FileInputStream(pdfFilename)) {
@@ -146,11 +144,13 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
}
}
public IXMLProvider getProvider() {
@Override
public IXMLProvider getProvider() {
return xmlProvider;
}
public DXExporterFromA3 setProfile(Profile p) {
@Override
public DXExporterFromA3 setProfile(Profile p) {
this.profile = p;
if (xmlProvider != null) {
xmlProvider.setProfile(p);
@@ -158,7 +158,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
return this;
}
public DXExporterFromA3 setProfile(String profilename) {
@Override
public DXExporterFromA3 setProfile(String profilename) {
this.profile = Profiles.getByName(profilename);
if (xmlProvider != null) {
@@ -167,7 +168,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
return this;
}
public DXExporterFromA3 addAdditionalFile(String name, byte[] content) {
@Override
public DXExporterFromA3 addAdditionalFile(String name, byte[] content) {
fileAttachments.add(new FileAttachment(name, "text/xml", "Supplement", content).setDescription("ZUGFeRD extension/additional data"));
return this;
}
@@ -180,7 +182,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
*
* @param pdfBinary binary of a PDF/A1 compliant document
*/
public DXExporterFromA3 load(byte[] pdfBinary) throws IOException {
@Override
public DXExporterFromA3 load(byte[] pdfBinary) throws IOException {
ensurePDFIsValid(new ByteArrayDataSource(new ByteArrayInputStream(pdfBinary)));
doc = Loader.loadPDF(pdfBinary);
return this;
@@ -190,11 +193,13 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
super();
}
public void attachFile(FileAttachment file) {
@Override
public void attachFile(FileAttachment file) {
fileAttachments.add(file);
}
public void attachFile(String filename, byte[] data, String mimetype, String relation) {
@Override
public void attachFile(String filename, byte[] data, String mimetype, String relation) {
FileAttachment fa = new FileAttachment(filename, mimetype, relation, data);
fileAttachments.add(fa);
}
@@ -204,7 +209,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* @param ZUGFeRDfilename the pdf file name
* @throws IOException if anything is wrong in the target location
*/
public void export(String ZUGFeRDfilename) throws IOException {
@Override
public void export(String ZUGFeRDfilename) throws IOException {
if (!documentPrepared) {
prepareDocument();
}
@@ -231,7 +237,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* @param output the OutputStream
* @throws IOException if anything is wrong in the OutputStream
*/
public void export(OutputStream output) throws IOException {
@Override
public void export(OutputStream output) throws IOException {
if (!documentPrepared) {
prepareDocument();
}
@@ -257,7 +264,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* @param data the binary data of the file/attachment
* @throws IOException if anything is wrong with filename
*/
public void PDFAttachGenericFile(String filename, String relationship, String description,
@Override
public void PDFAttachGenericFile(String filename, String relationship, String description,
String subType, byte[] data) throws IOException {
PDFAttachGenericFile(this.doc, filename, relationship, description, subType, data);
}
@@ -274,7 +282,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* @param data the binary data of the file/attachment
* @throws IOException if anything is wrong with filename
*/
public void PDFAttachGenericFile(PDDocument doc, String filename, String relationship, String description,
@Override
public void PDFAttachGenericFile(PDDocument doc, String filename, String relationship, String description,
String subType, byte[] data) throws IOException {
fileAttached = true;
@@ -293,7 +302,7 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
ef.setSize(data.length);
ef.setCreationDate(new GregorianCalendar());
ef.setModDate(GregorianCalendar.getInstance());
ef.setModDate(Calendar.getInstance());
fs.setEmbeddedFile(ef);
@@ -325,7 +334,7 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
doc.getDocumentCatalog().setNames(names);
// AF entry (Array) in catalog with the FileSpec
COSBase AFEntry = (COSBase) doc.getDocumentCatalog().getCOSObject().getItem("AF");
COSBase AFEntry = doc.getDocumentCatalog().getCOSObject().getItem("AF");
if ((AFEntry == null)) {
COSArray cosArray = new COSArray();
cosArray.add(fs);
@@ -351,7 +360,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* @param zugferdData XML data to be set as a byte array (XML file in raw form).
* @throws IOException (should not happen)
*/
public DXExporterFromA3 setXML(byte[] zugferdData) throws IOException {
@Override
public DXExporterFromA3 setXML(byte[] zugferdData) throws IOException {
CustomXMLProvider cus = new CustomXMLProvider();
// As of late 2022 the Delivery-X standard is not yet published. See specification:
// Die digitale Ablösung des Papier-Lieferscheins, Version 1.1, April 2022
@@ -372,11 +382,13 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
*
* @param pdfSource source to read a PDF/A1 compliant document from
*/
public DXExporterFromA3 load(InputStream pdfSource) throws IOException {
@Override
public DXExporterFromA3 load(InputStream pdfSource) throws IOException {
return load(readAllBytes(pdfSource));
}
public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException {
@Override
public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException {
return true;
}
@@ -399,23 +411,27 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* <p>
* Feel free to pass "A" as new level if you know what you are doing :-)
*/
public DXExporterFromA3 setConformanceLevel(PDFAConformanceLevel newLevel) {
@Override
public DXExporterFromA3 setConformanceLevel(PDFAConformanceLevel newLevel) {
conformanceLevel = newLevel;
return this;
}
public DXExporterFromA3 setCreator(String creator) {
@Override
public DXExporterFromA3 setCreator(String creator) {
this.creator = creator;
return this;
}
public DXExporterFromA3 setCreatorTool(String creatorTool) {
@Override
public DXExporterFromA3 setCreatorTool(String creatorTool) {
this.creatorTool = creatorTool;
return this;
}
public DXExporterFromA3 setProducer(String producer) {
@Override
public DXExporterFromA3 setProducer(String producer) {
this.producer = producer;
return this;
}
@@ -434,7 +450,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
return this;
}
protected DXExporterFromA3 setAttachZUGFeRDHeaders(boolean attachHeaders) {
@Override
protected DXExporterFromA3 setAttachZUGFeRDHeaders(boolean attachHeaders) {
this.attachZUGFeRDHeaders = attachHeaders;
return this;
}
@@ -447,7 +464,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
*
* @param metadata the PDFbox XMPMetadata object
*/
protected void addXMP(XMPMetadata metadata) {
@Override
protected void addXMP(XMPMetadata metadata) {
if (attachZUGFeRDHeaders) {
// As of late 2022 the Delivery-X standard is not yet published. See specification:
@@ -478,12 +496,14 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* <code>setZUGFeRDXMLData(byte[] zugferdData)</code>
* @throws IOException if anything is wrong with already loaded PDF
*/
public IExporter setTransaction(IExportableTransaction trans) throws IOException {
@Override
public IExporter setTransaction(IExportableTransaction trans) throws IOException {
this.trans = trans;
return prepare();
}
public IExporter prepare() throws IOException {
@Override
public IExporter prepare() throws IOException {
prepareDocument();
xmlProvider.generateXML(trans);
String filename = "cida.xml";
@@ -502,7 +522,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* Reads the XMPMetadata from the PDDocument, if it exists.
* Otherwise creates XMPMetadata.
*/
protected XMPMetadata getXmpMetadata() throws IOException {
@Override
protected XMPMetadata getXmpMetadata() throws IOException {
PDMetadata meta = doc.getDocumentCatalog().getMetadata();
if ((meta != null) && (meta.getLength() > 0)) {
try {
@@ -515,7 +536,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
return XMPMetadata.createXMPMetadata();
}
protected byte[] serializeXmpMetadata(XMPMetadata xmpMetadata) throws TransformerException {
@Override
protected byte[] serializeXmpMetadata(XMPMetadata xmpMetadata) throws TransformerException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
new XmpSerializer().serialize(xmpMetadata, buffer, true); // see https://github.com/ZUGFeRD/mustangproject/issues/44
return buffer.toByteArray();
@@ -525,7 +547,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* Sets the producer if the overwrite flag is set or the producer is not already set.
* Sets the PDFVersion to 1.4 if the field is empty.
*/
protected void writeAdobePDFSchema(XMPMetadata xmp) {
@Override
protected void writeAdobePDFSchema(XMPMetadata xmp) {
AdobePDFSchema pdf = getAdobePDFSchema(xmp);
if (overwrite || isEmpty(pdf.getProducer()))
pdf.setProducer(producer);
@@ -535,7 +558,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* Returns the AdobePDFSchema from the XMPMetadata if it exists.
* If the overwrite flag is set or no AdobePDFSchema exists in the XMPMetadata, it is created, added and returned.
*/
protected AdobePDFSchema getAdobePDFSchema(XMPMetadata xmp) {
@Override
protected AdobePDFSchema getAdobePDFSchema(XMPMetadata xmp) {
AdobePDFSchema pdf = xmp.getAdobePDFSchema();
if (pdf != null)
if (overwrite)
@@ -545,7 +569,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
return xmp.createAndAddAdobePDFSchema();
}
protected void writePDFAIdentificationSchema(XMPMetadata xmp) {
@Override
protected void writePDFAIdentificationSchema(XMPMetadata xmp) {
PDFAIdentificationSchema pdfaid = getPDFAIdentificationSchema(xmp);
if (overwrite || isEmpty(pdfaid.getConformance())) {
try {
@@ -560,7 +585,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
pdfaid.setPart(3);
}
protected PDFAIdentificationSchema getPDFAIdentificationSchema(XMPMetadata xmp) {
@Override
protected PDFAIdentificationSchema getPDFAIdentificationSchema(XMPMetadata xmp) {
PDFAIdentificationSchema pdfaid = xmp.getPDFAIdentificationSchema();
if (pdfaid != null)
if (overwrite)
@@ -570,7 +596,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
return xmp.createAndAddPDFAIdentificationSchema();
}
protected void writeDublinCoreSchema(XMPMetadata xmp) {
@Override
protected void writeDublinCoreSchema(XMPMetadata xmp) {
DublinCoreSchema dc = getDublinCoreSchema(xmp);
if (dc.getFormat() == null)
dc.setFormat("application/pdf");
@@ -593,7 +620,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
}
}
protected DublinCoreSchema getDublinCoreSchema(XMPMetadata xmp) {
@Override
protected DublinCoreSchema getDublinCoreSchema(XMPMetadata xmp) {
DublinCoreSchema dc = xmp.getDublinCoreSchema();
if (dc != null)
if (overwrite)
@@ -603,15 +631,17 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
return xmp.createAndAddDublinCoreSchema();
}
protected void writeXMLBasicSchema(XMPMetadata xmp) {
@Override
protected void writeXMLBasicSchema(XMPMetadata xmp) {
XMPBasicSchema xsb = getXmpBasicSchema(xmp);
if (overwrite || isEmpty(xsb.getCreatorTool()) || "UnknownApplication".equals(xsb.getCreatorTool()))
xsb.setCreatorTool(creatorTool);
if (overwrite || xsb.getCreateDate() == null)
xsb.setCreateDate(GregorianCalendar.getInstance());
xsb.setCreateDate(Calendar.getInstance());
}
protected XMPBasicSchema getXmpBasicSchema(XMPMetadata xmp) {
@Override
protected XMPBasicSchema getXmpBasicSchema(XMPMetadata xmp) {
XMPBasicSchema xsb = xmp.getXMPBasicSchema();
if (xsb != null)
if (overwrite)
@@ -621,7 +651,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
return xmp.createAndAddXMPBasicSchema();
}
protected void writeDocumentInformation() {
@Override
protected void writeDocumentInformation() {
String fullProducer = producer + " (via mustangproject.org " + Version.VERSION + ")";
PDDocumentInformation info = doc.getDocumentInformation();
if (overwrite || info.getCreationDate() == null)
@@ -643,7 +674,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
/**
* Adds an OutputIntent and the sRGB color profile if no OutputIntent exist
*/
protected void addSRGBOutputIntend() throws IOException {
@Override
protected void addSRGBOutputIntend() throws IOException {
if (!doc.getDocumentCatalog().getOutputIntents().isEmpty()) {
return;
}
@@ -666,7 +698,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
/**
* Adds a MarkInfo element to the PDF if it doesn't already exist and sets it as marked.
*/
protected void setMarked() {
@Override
protected void setMarked() {
PDDocumentCatalog catalog = doc.getDocumentCatalog();
if (catalog.getMarkInfo() == null) {
catalog.setMarkInfo(new PDMarkInfo(doc.getPages().getCOSObject()));
@@ -677,7 +710,8 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
/**
* Adds a StructureTreeRoot element to the PDF if it doesn't already exist.
*/
protected void addStructureTreeRoot() {
@Override
protected void addStructureTreeRoot() {
if (doc.getDocumentCatalog().getStructureTreeRoot() == null) {
doc.getDocumentCatalog().setStructureTreeRoot(new PDStructureTreeRoot());
}
@@ -687,19 +721,22 @@ public class DXExporterFromA3 extends ZUGFeRDExporterFromA3 {
/**
* @return if pdf file will be automatically closed after adding ZF
*/
public boolean isAutoCloseDisabled() {
@Override
public boolean isAutoCloseDisabled() {
return disableAutoClose;
}
/**
* @param disableAutoClose prevent PDF file from being closed after adding ZF
*/
public DXExporterFromA3 disableAutoClose(boolean disableAutoClose) {
@Override
public DXExporterFromA3 disableAutoClose(boolean disableAutoClose) {
this.disableAutoClose = disableAutoClose;
return this;
}
protected void setXMLProvider(IXMLProvider p) {
@Override
protected void setXMLProvider(IXMLProvider p) {
this.xmlProvider = p;
if (profile != null) {
xmlProvider.setProfile(profile);

View File

@@ -141,6 +141,6 @@ public interface IZUGFeRDExportableItem extends IAbsoluteValueProvider{
*/
default IZUGFeRDAllowanceCharge[] getItemTotalAllowances() {
return null;
};
}
}

View File

@@ -1,6 +1,7 @@
package org.mustangproject.ZUGFeRD;
import java.math.BigDecimal;
import java.math.RoundingMode;
/***
* the linecalculator does the math within an item line, and e.g. calculates quantity*price.
@@ -40,7 +41,7 @@ public class LineCalculator {
priceGross = currentItem.getPrice(); // see https://github.com/ZUGFeRD/mustangproject/issues/159
price = priceGross.subtract(allowance).add(charge);
itemTotalNetAmount = currentItem.getQuantity().multiply(getPrice()).divide(currentItem.getBasisQuantity())
.subtract(allowanceItemTotal).setScale(2, BigDecimal.ROUND_HALF_UP);
.subtract(allowanceItemTotal).setScale(2, RoundingMode.HALF_UP);
itemTotalVATAmount = itemTotalNetAmount.multiply(multiplicator);
}

View File

@@ -29,10 +29,11 @@ import org.apache.pdfbox.preflight.parser.PreflightParser;
import jakarta.activation.DataSource;
public class OXExporterFromA1 extends OXExporterFromA3 implements IZUGFeRDExporter {
public class OXExporterFromA1 extends OXExporterFromA3 {
protected boolean ignorePDFAErrors = false;
public OXExporterFromA1 ignorePDFAErrors() {
@Override
public OXExporterFromA1 ignorePDFAErrors() {
this.ignorePDFAErrors = true;
return this;
}
@@ -45,7 +46,8 @@ public class OXExporterFromA1 extends OXExporterFromA3 implements IZUGFeRDExport
* @param ver the order-x version
* @return the URN of the namespace
*/
public String getNamespaceForVersion(int ver) {
@Override
public String getNamespaceForVersion(int ver) {
return "urn:factur-x:pdfa:CrossIndustryDocument:1p0#";
}
/***
@@ -53,7 +55,8 @@ public class OXExporterFromA1 extends OXExporterFromA3 implements IZUGFeRDExport
* @param ver the ox version
* @return the namespace prefix as string, without colon
*/
public String getPrefixForVersion(int ver) {
@Override
public String getPrefixForVersion(int ver) {
return "fx";
}
@@ -87,14 +90,17 @@ public class OXExporterFromA1 extends OXExporterFromA3 implements IZUGFeRDExport
}
public OXExporterFromA1 setProfile(Profile p) {
@Override
public OXExporterFromA1 setProfile(Profile p) {
return (OXExporterFromA1)super.setProfile(p);
}
public OXExporterFromA1 setProfile(String profileName) {
@Override
public OXExporterFromA1 setProfile(String profileName) {
return (OXExporterFromA1)super.setProfile(profileName);
}
public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException {
@Override
public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException {
if (!ignorePDFAErrors && !isValidA1(dataSource)) {
throw new IOException("File is not a valid PDF/A input file");
}
@@ -106,32 +112,41 @@ public class OXExporterFromA1 extends OXExporterFromA3 implements IZUGFeRDExport
}
public OXExporterFromA1 load(String pdfFilename) throws IOException {
@Override
public OXExporterFromA1 load(String pdfFilename) throws IOException {
return (OXExporterFromA1) super.load(pdfFilename);
}
public OXExporterFromA1 load(byte[] pdfBinary) throws IOException {
@Override
public OXExporterFromA1 load(byte[] pdfBinary) throws IOException {
return (OXExporterFromA1) super.load(pdfBinary);
}
public OXExporterFromA1 load(InputStream pdfSource) throws IOException{
@Override
public OXExporterFromA1 load(InputStream pdfSource) throws IOException{
return (OXExporterFromA1) super.load(pdfSource);
}
public OXExporterFromA1 setCreator(String creator) {
@Override
public OXExporterFromA1 setCreator(String creator) {
return (OXExporterFromA1) super.setCreator(creator);
}
public OXExporterFromA1 setConformanceLevel(PDFAConformanceLevel newLevel) {
@Override
public OXExporterFromA1 setConformanceLevel(PDFAConformanceLevel newLevel) {
return (OXExporterFromA1) super.setConformanceLevel(newLevel);
}
public OXExporterFromA1 setProducer(String producer){
@Override
public OXExporterFromA1 setProducer(String producer){
return (OXExporterFromA1) super.setProducer(producer);
}
public OXExporterFromA1 setZUGFeRDVersion(int version){
@Override
public OXExporterFromA1 setZUGFeRDVersion(int version){
return (OXExporterFromA1) super.setZUGFeRDVersion(version);
}
public OXExporterFromA1 setXML(byte[] zugferdData) throws IOException{
@Override
public OXExporterFromA1 setXML(byte[] zugferdData) throws IOException{
return (OXExporterFromA1) super.setXML(zugferdData);
}
public OXExporterFromA1 disableAutoClose(boolean disableAutoClose){
@Override
public OXExporterFromA1 disableAutoClose(boolean disableAutoClose){
return (OXExporterFromA1) super.disableAutoClose(disableAutoClose);
}
public OXExporterFromA1 convertOnly() {

View File

@@ -71,7 +71,7 @@ import jakarta.activation.FileDataSource;
public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
protected PDFAConformanceLevel conformanceLevel = PDFAConformanceLevel.UNICODE;
protected ArrayList<FileAttachment> fileAttachments = new ArrayList<FileAttachment>();
protected ArrayList<FileAttachment> fileAttachments = new ArrayList<>();
/**
* This flag controls whether or not the metadata is overwritten, or kind of merged.
@@ -127,9 +127,6 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
protected String orderXDocumentType = "ORDER";
private HashMap<String, byte[]> additionalXMLs = new HashMap<String, byte[]>();
private boolean attachZUGFeRDHeaders = true;
/**
@@ -138,7 +135,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
*
* @param pdfFilename filename of an PDF/A1 compliant document
*/
public OXExporterFromA3 load(String pdfFilename) throws IOException {
@Override
public OXExporterFromA3 load(String pdfFilename) throws IOException {
ensurePDFIsValid(new FileDataSource(pdfFilename));
try (FileInputStream pdf = new FileInputStream(pdfFilename)) {
@@ -146,11 +144,13 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
}
}
public IXMLProvider getProvider() {
@Override
public IXMLProvider getProvider() {
return xmlProvider;
}
public OXExporterFromA3 setProfile(Profile p) {
@Override
public OXExporterFromA3 setProfile(Profile p) {
this.profile = p;
if (xmlProvider != null) {
xmlProvider.setProfile(p);
@@ -158,7 +158,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
return this;
}
public OXExporterFromA3 setProfile(String profilename) {
@Override
public OXExporterFromA3 setProfile(String profilename) {
this.profile = Profiles.getByName(profilename);
if (xmlProvider != null) {
@@ -167,7 +168,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
return this;
}
public OXExporterFromA3 addAdditionalFile(String name, byte[] content) {
@Override
public OXExporterFromA3 addAdditionalFile(String name, byte[] content) {
fileAttachments.add(new FileAttachment(name, "text/xml", "Supplement", content).setDescription("ZUGFeRD extension/additional data"));
return this;
}
@@ -180,7 +182,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
*
* @param pdfBinary binary of a PDF/A1 compliant document
*/
public OXExporterFromA3 load(byte[] pdfBinary) throws IOException {
@Override
public OXExporterFromA3 load(byte[] pdfBinary) throws IOException {
ensurePDFIsValid(new ByteArrayDataSource(new ByteArrayInputStream(pdfBinary)));
doc = Loader.loadPDF(pdfBinary);
return this;
@@ -190,11 +193,13 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
super();
}
public void attachFile(FileAttachment file) {
@Override
public void attachFile(FileAttachment file) {
fileAttachments.add(file);
}
public void attachFile(String filename, byte[] data, String mimetype, String relation) {
@Override
public void attachFile(String filename, byte[] data, String mimetype, String relation) {
FileAttachment fa = new FileAttachment(filename, mimetype, relation, data);
fileAttachments.add(fa);
}
@@ -204,7 +209,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* @param ZUGFeRDfilename the pdf file name
* @throws IOException if anything is wrong in the target location
*/
public void export(String ZUGFeRDfilename) throws IOException {
@Override
public void export(String ZUGFeRDfilename) throws IOException {
if (!documentPrepared) {
prepareDocument();
}
@@ -231,7 +237,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* @param output the OutputStream
* @throws IOException if anything is wrong in the OutputStream
*/
public void export(OutputStream output) throws IOException {
@Override
public void export(OutputStream output) throws IOException {
if (!documentPrepared) {
prepareDocument();
}
@@ -257,7 +264,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* @param data the binary data of the file/attachment
* @throws java.io.IOException if anything is wrong with filename
*/
public void PDFAttachGenericFile(String filename, String relationship, String description,
@Override
public void PDFAttachGenericFile(String filename, String relationship, String description,
String subType, byte[] data) throws IOException {
PDFAttachGenericFile(this.doc, filename, relationship, description, subType, data);
}
@@ -274,7 +282,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* @param data the binary data of the file/attachment
* @throws IOException if anything is wrong with filename
*/
public void PDFAttachGenericFile(PDDocument doc, String filename, String relationship, String description,
@Override
public void PDFAttachGenericFile(PDDocument doc, String filename, String relationship, String description,
String subType, byte[] data) throws IOException {
fileAttached = true;
@@ -293,7 +302,7 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
ef.setSize(data.length);
ef.setCreationDate(new GregorianCalendar());
ef.setModDate(GregorianCalendar.getInstance());
ef.setModDate(Calendar.getInstance());
fs.setEmbeddedFile(ef);
@@ -325,7 +334,7 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
doc.getDocumentCatalog().setNames(names);
// AF entry (Array) in catalog with the FileSpec
COSBase AFEntry = (COSBase) doc.getDocumentCatalog().getCOSObject().getItem("AF");
COSBase AFEntry = doc.getDocumentCatalog().getCOSObject().getItem("AF");
if ((AFEntry == null)) {
COSArray cosArray = new COSArray();
cosArray.add(fs);
@@ -351,7 +360,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* @param zugferdData XML data to be set as a byte array (XML file in raw form).
* @throws IOException (should not happen)
*/
public OXExporterFromA3 setXML(byte[] zugferdData) throws IOException {
@Override
public OXExporterFromA3 setXML(byte[] zugferdData) throws IOException {
CustomXMLProvider cus = new CustomXMLProvider();
cus.setXML(zugferdData);
this.setXMLProvider(cus);
@@ -366,11 +376,13 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
*
* @param pdfSource source to read a PDF/A1 compliant document from
*/
public OXExporterFromA3 load(InputStream pdfSource) throws IOException {
@Override
public OXExporterFromA3 load(InputStream pdfSource) throws IOException {
return load(readAllBytes(pdfSource));
}
public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException {
@Override
public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException {
return true;
}
@@ -393,23 +405,27 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* <p>
* Feel free to pass "A" as new level if you know what you are doing :-)
*/
public OXExporterFromA3 setConformanceLevel(PDFAConformanceLevel newLevel) {
@Override
public OXExporterFromA3 setConformanceLevel(PDFAConformanceLevel newLevel) {
conformanceLevel = newLevel;
return this;
}
public OXExporterFromA3 setCreator(String creator) {
@Override
public OXExporterFromA3 setCreator(String creator) {
this.creator = creator;
return this;
}
public OXExporterFromA3 setCreatorTool(String creatorTool) {
@Override
public OXExporterFromA3 setCreatorTool(String creatorTool) {
this.creatorTool = creatorTool;
return this;
}
public OXExporterFromA3 setProducer(String producer) {
@Override
public OXExporterFromA3 setProducer(String producer) {
this.producer = producer;
return this;
}
@@ -428,7 +444,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
return this;
}
protected OXExporterFromA3 setAttachZUGFeRDHeaders(boolean attachHeaders) {
@Override
protected OXExporterFromA3 setAttachZUGFeRDHeaders(boolean attachHeaders) {
this.attachZUGFeRDHeaders = attachHeaders;
return this;
}
@@ -441,7 +458,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
*
* @param metadata the PDFbox XMPMetadata object
*/
protected void addXMP(XMPMetadata metadata) {
@Override
protected void addXMP(XMPMetadata metadata) {
if (attachZUGFeRDHeaders) {
XMPSchemaZugferd zf = new XMPSchemaZugferd(metadata, 1, true, xmlProvider.getProfile(),
@@ -468,12 +486,14 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* <code>setZUGFeRDXMLData(byte[] zugferdData)</code>
* @throws IOException if anything is wrong with already loaded PDF
*/
public IExporter setTransaction(IExportableTransaction trans) throws IOException {
@Override
public IExporter setTransaction(IExportableTransaction trans) throws IOException {
this.trans = trans;
return prepare();
}
public IExporter prepare() throws IOException {
@Override
public IExporter prepare() throws IOException {
prepareDocument();
xmlProvider.generateXML(trans);
String filename = "order-x.xml";
@@ -492,7 +512,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* Reads the XMPMetadata from the PDDocument, if it exists.
* Otherwise creates XMPMetadata.
*/
protected XMPMetadata getXmpMetadata() throws IOException {
@Override
protected XMPMetadata getXmpMetadata() throws IOException {
PDMetadata meta = doc.getDocumentCatalog().getMetadata();
if ((meta != null) && (meta.getLength() > 0)) {
try {
@@ -505,7 +526,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
return XMPMetadata.createXMPMetadata();
}
protected byte[] serializeXmpMetadata(XMPMetadata xmpMetadata) throws TransformerException {
@Override
protected byte[] serializeXmpMetadata(XMPMetadata xmpMetadata) throws TransformerException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
new XmpSerializer().serialize(xmpMetadata, buffer, true); // see https://github.com/ZUGFeRD/mustangproject/issues/44
return buffer.toByteArray();
@@ -515,7 +537,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* Sets the producer if the overwrite flag is set or the producer is not already set.
* Sets the PDFVersion to 1.4 if the field is empty.
*/
protected void writeAdobePDFSchema(XMPMetadata xmp) {
@Override
protected void writeAdobePDFSchema(XMPMetadata xmp) {
AdobePDFSchema pdf = getAdobePDFSchema(xmp);
if (overwrite || isEmpty(pdf.getProducer()))
pdf.setProducer(producer);
@@ -525,7 +548,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
* Returns the AdobePDFSchema from the XMPMetadata if it exists.
* If the overwrite flag is set or no AdobePDFSchema exists in the XMPMetadata, it is created, added and returned.
*/
protected AdobePDFSchema getAdobePDFSchema(XMPMetadata xmp) {
@Override
protected AdobePDFSchema getAdobePDFSchema(XMPMetadata xmp) {
AdobePDFSchema pdf = xmp.getAdobePDFSchema();
if (pdf != null)
if (overwrite)
@@ -535,7 +559,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
return xmp.createAndAddAdobePDFSchema();
}
protected void writePDFAIdentificationSchema(XMPMetadata xmp) {
@Override
protected void writePDFAIdentificationSchema(XMPMetadata xmp) {
PDFAIdentificationSchema pdfaid = getPDFAIdentificationSchema(xmp);
if (overwrite || isEmpty(pdfaid.getConformance())) {
try {
@@ -550,7 +575,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
pdfaid.setPart(3);
}
protected PDFAIdentificationSchema getPDFAIdentificationSchema(XMPMetadata xmp) {
@Override
protected PDFAIdentificationSchema getPDFAIdentificationSchema(XMPMetadata xmp) {
PDFAIdentificationSchema pdfaid = xmp.getPDFAIdentificationSchema();
if (pdfaid != null)
if (overwrite)
@@ -560,7 +586,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
return xmp.createAndAddPDFAIdentificationSchema();
}
protected void writeDublinCoreSchema(XMPMetadata xmp) {
@Override
protected void writeDublinCoreSchema(XMPMetadata xmp) {
DublinCoreSchema dc = getDublinCoreSchema(xmp);
if (dc.getFormat() == null)
dc.setFormat("application/pdf");
@@ -583,7 +610,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
}
}
protected DublinCoreSchema getDublinCoreSchema(XMPMetadata xmp) {
@Override
protected DublinCoreSchema getDublinCoreSchema(XMPMetadata xmp) {
DublinCoreSchema dc = xmp.getDublinCoreSchema();
if (dc != null)
if (overwrite)
@@ -593,15 +621,17 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
return xmp.createAndAddDublinCoreSchema();
}
protected void writeXMLBasicSchema(XMPMetadata xmp) {
@Override
protected void writeXMLBasicSchema(XMPMetadata xmp) {
XMPBasicSchema xsb = getXmpBasicSchema(xmp);
if (overwrite || isEmpty(xsb.getCreatorTool()) || "UnknownApplication".equals(xsb.getCreatorTool()))
xsb.setCreatorTool(creatorTool);
if (overwrite || xsb.getCreateDate() == null)
xsb.setCreateDate(GregorianCalendar.getInstance());
xsb.setCreateDate(Calendar.getInstance());
}
protected XMPBasicSchema getXmpBasicSchema(XMPMetadata xmp) {
@Override
protected XMPBasicSchema getXmpBasicSchema(XMPMetadata xmp) {
XMPBasicSchema xsb = xmp.getXMPBasicSchema();
if (xsb != null)
if (overwrite)
@@ -611,7 +641,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
return xmp.createAndAddXMPBasicSchema();
}
protected void writeDocumentInformation() {
@Override
protected void writeDocumentInformation() {
String fullProducer = producer + " (via mustangproject.org " + Version.VERSION + ")";
PDDocumentInformation info = doc.getDocumentInformation();
if (overwrite || info.getCreationDate() == null)
@@ -633,7 +664,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
/**
* Adds an OutputIntent and the sRGB color profile if no OutputIntent exist
*/
protected void addSRGBOutputIntend() throws IOException {
@Override
protected void addSRGBOutputIntend() throws IOException {
if (!doc.getDocumentCatalog().getOutputIntents().isEmpty()) {
return;
}
@@ -656,7 +688,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
/**
* Adds a MarkInfo element to the PDF if it doesn't already exist and sets it as marked.
*/
protected void setMarked() {
@Override
protected void setMarked() {
PDDocumentCatalog catalog = doc.getDocumentCatalog();
if (catalog.getMarkInfo() == null) {
catalog.setMarkInfo(new PDMarkInfo(doc.getPages().getCOSObject()));
@@ -667,7 +700,8 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
/**
* Adds a StructureTreeRoot element to the PDF if it doesn't already exist.
*/
protected void addStructureTreeRoot() {
@Override
protected void addStructureTreeRoot() {
if (doc.getDocumentCatalog().getStructureTreeRoot() == null) {
doc.getDocumentCatalog().setStructureTreeRoot(new PDStructureTreeRoot());
}
@@ -677,19 +711,22 @@ public class OXExporterFromA3 extends ZUGFeRDExporterFromA3 {
/**
* @return if pdf file will be automatically closed after adding ZF
*/
public boolean isAutoCloseDisabled() {
@Override
public boolean isAutoCloseDisabled() {
return disableAutoClose;
}
/**
* @param disableAutoClose prevent PDF file from being closed after adding ZF
*/
public OXExporterFromA3 disableAutoClose(boolean disableAutoClose) {
@Override
public OXExporterFromA3 disableAutoClose(boolean disableAutoClose) {
this.disableAutoClose = disableAutoClose;
return this;
}
protected void setXMLProvider(IXMLProvider p) {
@Override
protected void setXMLProvider(IXMLProvider p) {
this.xmlProvider = p;
if (profile != null) {
xmlProvider.setProfile(profile);

View File

@@ -22,22 +22,19 @@ package org.mustangproject.ZUGFeRD;
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;
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 org.mustangproject.EStandard;
import org.mustangproject.FileAttachment;
import org.mustangproject.XMLTools;
public class OXPullProvider extends ZUGFeRD2PullProvider implements IXMLProvider {
public class OXPullProvider extends ZUGFeRD2PullProvider {
protected IExportableTransaction trans;
protected TransactionCalculator calc;
@@ -329,17 +326,19 @@ public class OXPullProvider extends ZUGFeRD2PullProvider implements IXMLProvider
}
}
}
if ((trans.getDocumentCode() == CORRECTEDINVOICE)/*||(trans.getDocumentCode() == DocumentCodeTypeConstants.CREDITNOTE)*/) {
hasDueDate = false;
if (trans.getDocumentCode() != null) {
if ((trans.getDocumentCode().equals(CORRECTEDINVOICE))/*||(trans.getDocumentCode().equals (DocumentCodeTypeConstants.CREDITNOTE))*/) {
hasDueDate = false;
}
}
final Map<BigDecimal, VATAmount> VATPercentAmountMap = calc.getVATPercentAmountMap();
for (final BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) {
final VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
if (amount != null) {
final String amountCategoryCode = amount.getCategoryCode();
/*final String amountCategoryCode = amount.getCategoryCode();
final boolean displayExemptionReason = CATEGORY_CODES_WITH_EXEMPTION_REASON.contains(amountCategoryCode);
/* xml += "<ram:ApplicableTradeTax>\n"
xml += "<ram:ApplicableTradeTax>\n"
+ "<ram:CalculatedAmount>" + currencyFormat(amount.getCalculated())
+ "</ram:CalculatedAmount>\n" //currencyID=\"EUR\"
+ "<ram:TypeCode>VAT</ram:TypeCode>\n"
@@ -475,13 +474,9 @@ public class OXPullProvider extends ZUGFeRD2PullProvider implements IXMLProvider
+ "</rsm:SCRDMCCBDACIOMessageStructure>";
final byte[] zugferdRaw;
try {
zugferdRaw = xml.getBytes("UTF-8");
zugferdRaw = xml.getBytes(StandardCharsets.UTF_8);
zugferdData = XMLTools.removeBOM(zugferdRaw);
} catch (final UnsupportedEncodingException e) {
Logger.getLogger(OXPullProvider.class.getName()).log(Level.SEVERE, null, e);
}
zugferdData = XMLTools.removeBOM(zugferdRaw);
}

View File

@@ -2,19 +2,13 @@ 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;

View File

@@ -22,7 +22,6 @@ 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;
@@ -86,13 +85,9 @@ public class UBLDAPullProvider implements IXMLProvider {
}
xml += "</DespatchAdvice>\n";
final byte[] ublRaw;
try {
ublRaw = xml.getBytes("UTF-8");
ublRaw = xml.getBytes(StandardCharsets.UTF_8);
ublData = XMLTools.removeBOM(ublRaw);
} catch (final UnsupportedEncodingException e) {
Logger.getLogger(UBLDAPullProvider.class.getName()).log(Level.SEVERE, null, e);
}
ublData = XMLTools.removeBOM(ublRaw);
}
public String getPartyXML(IZUGFeRDExportableTradeParty tp) {

View File

@@ -5,7 +5,7 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
@@ -42,9 +42,8 @@ public class XMLUpgrader {
* @return String the updated XML
* @throws FileNotFoundException if the source could not be found
* @throws TransformerException if the source could not be transformed
* @throws UnsupportedEncodingException if the source was not utf8
*/
public String migrateFromV1ToV2(String xmlFilename) throws FileNotFoundException, TransformerException, UnsupportedEncodingException {
public String migrateFromV1ToV2(String xmlFilename) throws FileNotFoundException, TransformerException {
/**
* *
* http://www.unece.org/fileadmin/DAM/cefact/xml/XML-Naming-And-Design-Rules-V2_1.pdf
@@ -56,7 +55,7 @@ public class XMLUpgrader {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
applySchematronXsl(new FileInputStream(xmlFilename), baos);
String res = null;
res = baos.toString("UTF-8");
res = baos.toString(StandardCharsets.UTF_8);
return res;
}

View File

@@ -40,7 +40,7 @@ import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.mustangproject.XMLTools;
public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLProvider {
public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider {
//// MAIN CLASS
@@ -100,7 +100,7 @@ public class ZUGFeRD1PullProvider extends ZUGFeRD2PullProvider implements IXMLPr
format.setTrimText(false);
final XMLWriter writer = new XMLWriter(sw, format);
writer.write(document);
res = sw.toString().getBytes("UTF-8");
res = sw.toString().getBytes(StandardCharsets.UTF_8);
} catch (final IOException e) {
Logger.getLogger(ZUGFeRD1PullProvider.class.getName()).log(Level.SEVERE, null, e);

View File

@@ -25,7 +25,6 @@ import static org.mustangproject.ZUGFeRD.model.TaxCategoryCodeTypeConstants.CATE
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;
@@ -756,13 +755,9 @@ public class ZUGFeRD2PullProvider implements IXMLProvider {
+ "</rsm:CrossIndustryInvoice>";
final byte[] zugferdRaw;
try {
zugferdRaw = xml.getBytes("UTF-8");
zugferdRaw = xml.getBytes(StandardCharsets.UTF_8);
zugferdData = XMLTools.removeBOM(zugferdRaw);
} catch (final UnsupportedEncodingException e) {
Logger.getLogger(ZUGFeRD2PullProvider.class.getName()).log(Level.SEVERE, null, e);
}
zugferdData = XMLTools.removeBOM(zugferdRaw);
}
protected String buildItemNotes(IZUGFeRDExportableItem currentItem) {

View File

@@ -30,7 +30,7 @@ import org.mustangproject.EStandard;
import jakarta.activation.DataSource;
public class ZUGFeRDExporterFromA1 extends ZUGFeRDExporterFromA3 implements IZUGFeRDExporter {
public class ZUGFeRDExporterFromA1 extends ZUGFeRDExporterFromA3 {
private static boolean isValidA1(DataSource dataSource) throws IOException {
return getPDFAParserValidationResult(PreflightParserHelper.createPreflightParser(dataSource));
@@ -66,14 +66,17 @@ public class ZUGFeRDExporterFromA1 extends ZUGFeRDExporterFromA3 implements IZUG
}
public ZUGFeRDExporterFromA1 setProfile(Profile p) {
@Override
public ZUGFeRDExporterFromA1 setProfile(Profile p) {
return (ZUGFeRDExporterFromA1)super.setProfile(p);
}
public ZUGFeRDExporterFromA1 setProfile(String profileName) {
@Override
public ZUGFeRDExporterFromA1 setProfile(String profileName) {
return (ZUGFeRDExporterFromA1)super.setProfile(profileName);
}
public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException {
@Override
public boolean ensurePDFIsValid(final DataSource dataSource) throws IOException {
if (!ignorePDFAErrors && !isValidA1(dataSource)) {
throw new IOException("File is not a valid PDF/A-1 input file");
}
@@ -81,35 +84,45 @@ public class ZUGFeRDExporterFromA1 extends ZUGFeRDExporterFromA3 implements IZUG
}
public ZUGFeRDExporterFromA1 load(String pdfFilename) throws IOException {
@Override
public ZUGFeRDExporterFromA1 load(String pdfFilename) throws IOException {
return (ZUGFeRDExporterFromA1) super.load(pdfFilename);
}
public ZUGFeRDExporterFromA1 load(byte[] pdfBinary) throws IOException {
@Override
public ZUGFeRDExporterFromA1 load(byte[] pdfBinary) throws IOException {
return (ZUGFeRDExporterFromA1) super.load(pdfBinary);
}
public ZUGFeRDExporterFromA1 load(InputStream pdfSource) throws IOException{
@Override
public ZUGFeRDExporterFromA1 load(InputStream pdfSource) throws IOException{
return (ZUGFeRDExporterFromA1) super.load(pdfSource);
}
public ZUGFeRDExporterFromA1 setCreator(String creator) {
@Override
public ZUGFeRDExporterFromA1 setCreator(String creator) {
return (ZUGFeRDExporterFromA1) super.setCreator(creator);
}
public ZUGFeRDExporterFromA1 setConformanceLevel(PDFAConformanceLevel newLevel) {
@Override
public ZUGFeRDExporterFromA1 setConformanceLevel(PDFAConformanceLevel newLevel) {
return (ZUGFeRDExporterFromA1) super.setConformanceLevel(newLevel);
}
public ZUGFeRDExporterFromA1 setProducer(String producer){
@Override
public ZUGFeRDExporterFromA1 setProducer(String producer){
return (ZUGFeRDExporterFromA1) super.setProducer(producer);
}
public ZUGFeRDExporterFromA1 setZUGFeRDVersion(EStandard est, int version){
@Override
public ZUGFeRDExporterFromA1 setZUGFeRDVersion(EStandard est, int version){
return (ZUGFeRDExporterFromA1) super.setZUGFeRDVersion(est, version);
}
public ZUGFeRDExporterFromA1 setZUGFeRDVersion(int version){
@Override
public ZUGFeRDExporterFromA1 setZUGFeRDVersion(int version){
return (ZUGFeRDExporterFromA1) super.setZUGFeRDVersion(version);
}
public ZUGFeRDExporterFromA1 setXML(byte[] zugferdData) throws IOException{
@Override
public ZUGFeRDExporterFromA1 setXML(byte[] zugferdData) throws IOException{
return (ZUGFeRDExporterFromA1) super.setXML(zugferdData);
}
public ZUGFeRDExporterFromA1 disableAutoClose(boolean disableAutoClose){
@Override
public ZUGFeRDExporterFromA1 disableAutoClose(boolean disableAutoClose){
return (ZUGFeRDExporterFromA1) super.disableAutoClose(disableAutoClose);
}
public ZUGFeRDExporterFromA1 convertOnly() {

View File

@@ -22,7 +22,6 @@ package org.mustangproject.ZUGFeRD;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -76,7 +75,7 @@ import org.mustangproject.FileAttachment;
import jakarta.activation.DataSource;
import jakarta.activation.FileDataSource;
public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporter, IExporter, Closeable {
public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporter {
private boolean isFacturX = true;
public static final int DefaultZUGFeRDVersion = 2;
@@ -87,7 +86,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
return this;
}
protected PDFAConformanceLevel conformanceLevel = PDFAConformanceLevel.UNICODE;
protected ArrayList<FileAttachment> fileAttachments = new ArrayList<FileAttachment>();
protected ArrayList<FileAttachment> fileAttachments = new ArrayList<>();
/**
* This flag controls whether or not the metadata is overwritten, or kind of merged.
@@ -139,9 +138,6 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
protected PDDocument doc;
private HashMap<String, byte[]> additionalXMLs = new HashMap<String, byte[]>();
protected int ZFVersion = DefaultZUGFeRDVersion;
private boolean attachZUGFeRDHeaders = true;
@@ -248,9 +244,10 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
* Generate ZF2.1 files with filename factur-x.xml
*
* @return this (fluent setter)
* @deprecated
* @deprecated It's now the default anyway
*/
public ZUGFeRDExporterFromA3 setFacturX() {
@Deprecated
public ZUGFeRDExporterFromA3 setFacturX() {
isFacturX = true;
return this;
}
@@ -310,7 +307,8 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
* @param ZUGFeRDfilename the pdf file name
* @throws IOException if anything is wrong in the target location
*/
public void export(String ZUGFeRDfilename) throws IOException {
@Override
public void export(String ZUGFeRDfilename) throws IOException {
if (!documentPrepared) {
prepareDocument();
}
@@ -337,7 +335,8 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
* @param output the OutputStream
* @throws IOException if anything is wrong in the OutputStream
*/
public void export(OutputStream output) throws IOException {
@Override
public void export(OutputStream output) throws IOException {
if (!documentPrepared) {
prepareDocument();
}
@@ -399,7 +398,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
ef.setSize(data.length);
ef.setCreationDate(new GregorianCalendar());
ef.setModDate(GregorianCalendar.getInstance());
ef.setModDate(Calendar.getInstance());
fs.setEmbeddedFile(ef);
@@ -431,7 +430,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
doc.getDocumentCatalog().setNames(names);
// AF entry (Array) in catalog with the FileSpec
COSBase AFEntry = (COSBase) doc.getDocumentCatalog().getCOSObject().getItem("AF");
COSBase AFEntry = doc.getDocumentCatalog().getCOSObject().getItem("AF");
if ((AFEntry == null)) {
COSArray cosArray = new COSArray();
cosArray.add(fs);
@@ -557,7 +556,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
metadata.addSchema(pdfaex);
}
private void removeCidSet(PDDocumentCatalog catalog, PDDocument doc)
private void removeCidSet(PDDocument doc)
throws IOException
{
// https://github.com/ZUGFeRD/mustangproject/issues/249
@@ -578,7 +577,8 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
PDType0Font typedFont = (PDType0Font) pdFont;
if (typedFont.getDescendantFont() instanceof PDCIDFontType2) {
PDCIDFontType2 f = (PDCIDFontType2) typedFont.getDescendantFont();
@SuppressWarnings ("unused")
PDCIDFontType2 f = (PDCIDFontType2) typedFont.getDescendantFont();
PDFontDescriptor fontDescriptor = pdFont.getFontDescriptor();
fontDescriptor.getCOSObject().removeItem(cidSet);
@@ -599,7 +599,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
metadata = new PDMetadata(doc);
cat.setMetadata(metadata);
removeCidSet(cat, doc);
removeCidSet(doc);
xmp = getXmpMetadata();
writeAdobePDFSchema(xmp);
writePDFAIdentificationSchema(xmp);
@@ -636,7 +636,8 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
* <code>setZUGFeRDXMLData(byte[] zugferdData)</code>
* @throws IOException if anything is wrong with already loaded PDF
*/
public IExporter setTransaction(IExportableTransaction trans) throws IOException {
@Override
public IExporter setTransaction(IExportableTransaction trans) throws IOException {
this.trans = trans;
return prepare();
}
@@ -788,7 +789,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
if (overwrite || isEmpty(xsb.getCreatorTool()) || "UnknownApplication".equals(xsb.getCreatorTool()))
xsb.setCreatorTool(creatorTool);
if (overwrite || xsb.getCreateDate() == null)
xsb.setCreateDate(GregorianCalendar.getInstance());
xsb.setCreateDate(Calendar.getInstance());
}
protected XMPBasicSchema getXmpBasicSchema(XMPMetadata xmp) {

View File

@@ -168,7 +168,7 @@ public class ZUGFeRDExporterFromPDFA implements IZUGFeRDExporter {
}
public IZUGFeRDExporter setProfile(Profile p) {
return (IZUGFeRDExporter) getExporter().setProfile(p);
return getExporter().setProfile(p);
}
public IZUGFeRDExporter setProfile(String profileName) {
@@ -176,7 +176,7 @@ public class ZUGFeRDExporterFromPDFA implements IZUGFeRDExporter {
if (p==null) {
throw new RuntimeException("Profile not found.");
}
return (IZUGFeRDExporter) getExporter().setProfile(p);
return getExporter().setProfile(p);
}
public IZUGFeRDExporter setConformanceLevel(PDFAConformanceLevel newLevel) {

View File

@@ -19,6 +19,7 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
@@ -785,9 +786,10 @@ public class ZUGFeRDImporter {
static String convertStreamToString(java.io.InputStream is) {
// TODO wouldn't we use IOUtils.toByteArray nowadays???
// source https://stackoverflow.com/questions/309424/how-do-i-read-convert-an-inputstream-into-a-string-in-java referring to
// https://community.oracle.com/blogs/pat/2004/10/23/stupid-scanner-tricks
final Scanner s = new Scanner(is, "UTF-8").useDelimiter("\\A");
final Scanner s = new Scanner(is, StandardCharsets.UTF_8).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}

View File

@@ -32,7 +32,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
@@ -62,7 +61,6 @@ 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 {
@@ -100,7 +98,7 @@ public class ZUGFeRDVisualizer {
}
public String visualize(String xmlFilename, Language lang)
throws FileNotFoundException, TransformerException, UnsupportedEncodingException {
throws FileNotFoundException, TransformerException {
try {
if (mXsltXRTemplate == null) {
@@ -202,11 +200,11 @@ public class ZUGFeRDVisualizer {
}
return baos.toString("UTF-8");
return baos.toString(StandardCharsets.UTF_8);
}
protected String toFOP(String xmlFilename)
throws FileNotFoundException, TransformerException, UnsupportedEncodingException {
throws FileNotFoundException, TransformerException {
try {
if (mXsltXRTemplate == null) {
@@ -222,9 +220,8 @@ public class ZUGFeRDVisualizer {
}
FileInputStream fis = new FileInputStream(xmlFilename);
String fileContent = "";
try {
fileContent = new String(Files.readAllBytes(Paths.get(xmlFilename)), StandardCharsets.UTF_8);
new String(Files.readAllBytes(Paths.get(xmlFilename)), StandardCharsets.UTF_8);
} catch (IOException e2) {
LOG.log(Level.SEVERE, null, e2);
}
@@ -270,17 +267,14 @@ public class ZUGFeRDVisualizer {
}
return baos.toString("UTF-8");
return baos.toString(StandardCharsets.UTF_8);
}
public void toPDF(String xmlFilename, String pdfFilename) {
// the writing part
CIIToUBL c2u = new CIIToUBL();
String sourceFilename = "factur-x.xml";
File CIIinputFile = new File(xmlFilename);
String expected = null;
String result = null;
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
@@ -289,11 +283,7 @@ public class ZUGFeRDVisualizer {
*/
try {
result = zvi.toFOP(CIIinputFile.getAbsolutePath());
} catch (FileNotFoundException e) {
Logger.getLogger(ZUGFeRDVisualizer.class.getName()).log(Level.SEVERE, null, e);
} catch (TransformerException e) {
Logger.getLogger(ZUGFeRDVisualizer.class.getName()).log(Level.SEVERE, null, e);
} catch (UnsupportedEncodingException e) {
} catch (FileNotFoundException | TransformerException e) {
Logger.getLogger(ZUGFeRDVisualizer.class.getName()).log(Level.SEVERE, null, e);
}
/*

View File

@@ -22,6 +22,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
@@ -65,7 +66,7 @@ public class BackwardCompatibilityTest extends TestCase implements IExportableTr
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ze.export(baos);
ze.close();
String pdfContent = baos.toString("UTF-8");
String pdfContent = baos.toString(StandardCharsets.UTF_8);
assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1);
// check for pdf-a schema extension
// assertFalse(pdfContent.indexOf("<zf:ConformanceLevel>EN 16931</zf:ConformanceLevel>") == -1);
@@ -105,7 +106,7 @@ public class BackwardCompatibilityTest extends TestCase implements IExportableTr
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ze.export(baos);
ze.close();
String pdfContent = baos.toString("UTF-8");
String pdfContent = baos.toString(StandardCharsets.UTF_8);
assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1);
// check for pdf-a schema extension
// assertFalse(pdfContent.indexOf("<zf:ConformanceLevel>EN 16931</zf:ConformanceLevel>") == -1);
@@ -143,7 +144,7 @@ public class BackwardCompatibilityTest extends TestCase implements IExportableTr
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ze.export(baos);
ze.close();
String pdfContent = baos.toString("UTF-8");
String pdfContent = baos.toString(StandardCharsets.UTF_8);
assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1);
// check for pdf-a schema extension
// assertFalse(pdfContent.indexOf("<zf:ConformanceLevel>EN 16931</zf:ConformanceLevel>") == -1);
@@ -316,7 +317,7 @@ public class BackwardCompatibilityTest extends TestCase implements IExportableTr
//
public IZUGFeRDTradeSettlementPayment[] getTradeSettlementPayment() {
public IZUGFeRDTradeSettlementPayment[] getTradeSettlementPayment() {
Payment P = new Payment();
IZUGFeRDTradeSettlementPayment[] allP = new Payment[1];
allP[0] = P;

View File

@@ -22,16 +22,7 @@ import junit.framework.Test;
import junit.framework.TestSuite;
import junit.framework.TestCase;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import org.mustangproject.XMLTools;
public class BaseTest extends TestCase {

View File

@@ -45,7 +45,7 @@ import java.util.GregorianCalendar;
import static org.xmlunit.assertj.XmlAssert.assertThat;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class DXTest extends MustangReaderTestCase implements IExportableTransaction {
public class DXTest extends MustangReaderTestCase {
final String TARGET_PDF = "./target/testout-DX.pdf";
final String TARGET_XML = "./target/testout-DX.xml";

View File

@@ -21,12 +21,9 @@
*/
package org.mustangproject.ZUGFeRD;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import junit.framework.TestCase;
import org.assertj.core.util.Lists;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import org.mustangproject.*;

View File

@@ -256,13 +256,13 @@ public class MustangReaderWriterCustomXMLTest extends TestCase {
"</ram:ApplicableHeaderTradeSettlement>\n" +
"</rsm:SupplyChainTradeTransaction>\n" +
"</rsm:CrossIndustryInvoice>";
zea1.setXML(ownZUGFeRDXML.getBytes("UTF-8"));
zea1.setXML(ownZUGFeRDXML.getBytes(StandardCharsets.UTF_8));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
zea1.disableAutoClose(true);
zea1.export(TARGET_PDF);
zea1.export(baos);
zea1.close();
String pdfContent = baos.toString("UTF-8");
String pdfContent = baos.toString(StandardCharsets.UTF_8);
assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1);
assertFalse(pdfContent.indexOf("<fx:ConformanceLevel>EN 16931</fx:ConformanceLevel>") == -1);
@@ -437,14 +437,14 @@ public class MustangReaderWriterCustomXMLTest extends TestCase {
+ "<ram:Name>Heiße Luft pro Liter</ram:Name>\n" + "<ram:Description/>\n"
+ "</ram:SpecifiedTradeProduct>\n" + "</ram:IncludedSupplyChainTradeLineItem>\n"
+ "</rsm:SpecifiedSupplyChainTradeTransaction>\n" + "</rsm:CrossIndustryDocument>";
zea1.setXML(ownZUGFeRDXML.getBytes("UTF-8"));
zea1.setXML(ownZUGFeRDXML.getBytes(StandardCharsets.UTF_8));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
zea1.disableAutoClose(true);
zea1.export(TARGET_PDF);
zea1.export(baos);
zea1.close();
String pdfContent = baos.toString("UTF-8");
String pdfContent = baos.toString(StandardCharsets.UTF_8);
assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1);
assertFalse(pdfContent.indexOf("<zf:ConformanceLevel>BASIC</zf:ConformanceLevel>") == -1);

View File

@@ -43,7 +43,7 @@ import java.util.GregorianCalendar;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MustangReaderWriterEdgeTest extends MustangReaderTestCase {
protected class EasyRecipientTradeParty extends RecipientTradeParty implements IZUGFeRDExportableTradeParty {
protected class EasyRecipientTradeParty extends RecipientTradeParty {
// Not testing extended profile here, lineThree not possible
@Override
public String getAdditionalAddressExtension() {

View File

@@ -39,6 +39,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
@@ -368,7 +369,7 @@ public class MustangReaderWriterTest extends MustangReaderTestCase {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ze.export(baos);
ze.close();
String pdfContent = baos.toString("UTF-8");
String pdfContent = baos.toString(StandardCharsets.UTF_8);
assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1);
// check for pdf-a schema extension
// assertFalse(pdfContent.indexOf("<zf:ConformanceLevel>EN 16931</zf:ConformanceLevel>") == -1);
@@ -412,7 +413,7 @@ public class MustangReaderWriterTest extends MustangReaderTestCase {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ze.export(baos);
ze.close();
String pdfContent = baos.toString("UTF-8");
String pdfContent = baos.toString(StandardCharsets.UTF_8);
assertFalse(pdfContent.indexOf(DocumentContextParameterTypeConstants.BASIC) >= 0);
assertFalse(pdfContent.indexOf(DocumentContextParameterTypeConstants.EXTENDED) >= 0);
assertTrue(pdfContent.indexOf(DocumentContextParameterTypeConstants.COMFORT) >= 0);
@@ -448,7 +449,7 @@ public class MustangReaderWriterTest extends MustangReaderTestCase {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ze.export(baos);
ze.close();
String pdfContent = baos.toString("UTF-8");
String pdfContent = baos.toString(StandardCharsets.UTF_8);
assertFalse(pdfContent.indexOf("(via mustangproject.org") == -1);
// check for pdf-a schema extension
assertFalse(pdfContent.indexOf("<fx:ConformanceLevel>EN 16931</fx:ConformanceLevel>") == -1);

View File

@@ -28,7 +28,6 @@ import org.junit.runners.MethodSorters;
import org.mustangproject.*;
import javax.xml.xpath.XPathExpressionException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
@@ -42,7 +41,7 @@ import java.util.Date;
import java.util.GregorianCalendar;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class OXTest extends MustangReaderTestCase implements IExportableTransaction {
public class OXTest extends MustangReaderTestCase {
final String TARGET_PDF = "./target/testout-OX.pdf";
final String TARGET_PDF_EDGE = "./target/testout-OX-edge.pdf";
final String TARGET_XML = "./target/testout-OX.xml";

View File

@@ -23,13 +23,10 @@ package org.mustangproject.ZUGFeRD;
import junit.framework.TestCase;
import org.mustangproject.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
/***
* This is a test to confirm the minimum steps to implement a interface are still sufficient

View File

@@ -90,7 +90,7 @@ public class UBLTest extends ResourceCase {
final ByteArrayOutputStream baos=new ByteArrayOutputStream();
oe.export(baos);
final String theXML = baos.toString("UTF-8");
final String theXML = baos.toString(StandardCharsets.UTF_8);
assertTrue(theXML.contains("<DespatchAdvice"));
Files.write(Paths.get(TARGET_XML), theXML.getBytes(StandardCharsets.UTF_8));
} catch (final IOException e) {

View File

@@ -19,24 +19,9 @@
*********************************************************************** */
package org.mustangproject.ZUGFeRD;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import org.mustangproject.Contact;
import org.mustangproject.Invoice;
import org.mustangproject.Item;
import org.mustangproject.Product;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class UXTest extends TestCase {

View File

@@ -21,7 +21,6 @@ package org.mustangproject.ZUGFeRD;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import org.mustangproject.CII.CIIToUBL;
import javax.xml.transform.*;
import java.io.*;
@@ -69,8 +68,6 @@ public class VisualizationTest extends ResourceCase {
public void testUBLCreditNoteVisualizationBasic() {
// the writing part
CIIToUBL c2u = new CIIToUBL();
String sourceFilename = "factur-x.xml";
File UBLinputFile = getResourceAsFile("ubl-creditnote.xml");
String expected = null;
@@ -105,8 +102,6 @@ public class VisualizationTest extends ResourceCase {
public void testUBLVisualizationBasic() {
// the writing part
CIIToUBL c2u = new CIIToUBL();
String sourceFilename = "factur-x.xml";
File UBLinputFile = getResourceAsFile("ubl/01.01a-INVOICE.ubl.xml");
String expected = null;

View File

@@ -32,9 +32,6 @@ import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import static org.xmlunit.assertj.XmlAssert.assertThat;

View File

@@ -37,7 +37,7 @@ import junit.framework.Test;
import junit.framework.TestSuite;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ZF2EdgeTest extends MustangReaderTestCase implements IExportableTransaction {
public class ZF2EdgeTest extends MustangReaderTestCase {
final String TARGET_PDF = "./target/testout-ZF2newEdge.pdf";
protected class EdgeProduct implements IZUGFeRDExportableProduct {
@@ -325,7 +325,7 @@ public class ZF2EdgeTest extends MustangReaderTestCase implements IExportableTra
assertTrue(resultXML.contains("<ram:IssuerAssignedID>123</ram:IssuerAssignedID>"));
// Reading ZUGFeRD
assertEquals("337.60", zi.getAmount());;
assertEquals("337.60", zi.getAmount());
assertEquals(zi.getHolder(), getOwnOrganisationName());
assertEquals(zi.getForeignReference(), getNumber());
try {

View File

@@ -29,7 +29,6 @@ import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.mustangproject.*;
import org.junit.FixMethodOrder;
@@ -38,9 +37,6 @@ import org.junit.runners.MethodSorters;
import junit.framework.TestCase;
import org.mustangproject.ZUGFeRD.model.EventTimeCodeTypeConstants;
import org.xmlunit.builder.Input;
import org.xmlunit.xpath.JAXPXPathEngine;
import org.xmlunit.xpath.XPathEngine;
import javax.xml.xpath.XPathExpressionException;
@@ -138,7 +134,7 @@ public class ZF2PushTest extends TestCase {
byte[] b = {12, 13};
ze.attachFile("one.pdf", b, "application/pdf", "Alternative");
ze.attachFile("two.pdf", b, "application/pdf", "Alternative");
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID(taxID)).setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE4711").setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE"))).setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, new BigDecimal(1.0)))
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID(taxID).addVATID("DE0815")).setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE4711").setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE"))).setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, new BigDecimal(1.0)))
);
String theXML = new String(ze.getProvider().getXML());
@@ -186,7 +182,7 @@ public class ZF2PushTest extends TestCase {
String IBAN = "DE999888777";
String BIC = "COBADEFXXX";
BankDetails bd = new BankDetails(IBAN, BIC);
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addBankDetails(bd).addTaxID(taxID)).setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE4711").setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE"))).setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, new BigDecimal(1.0)))
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addBankDetails(bd).addTaxID(taxID).addVATID("DE0815")).setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE4711").setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE"))).setNumber(number).addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, new BigDecimal(1.0)))
);
String theXML = new String(ze.getProvider().getXML());
@@ -226,7 +222,7 @@ public class ZF2PushTest extends TestCase {
// .addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance().setPercent(new BigDecimal(50)))));
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE")).setOwnTaxID("4711").setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").setContact(new Contact("contact testname", "123456", "contact.testemail@example.org").setFax("0911623562"))).setNumber(number)
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815")).setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").setContact(new Contact("contact testname", "123456", "contact.testemail@example.org").setFax("0911623562"))).setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance(new BigDecimal("0.1"))))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance().setPercent(new BigDecimal(50))))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(2.0)).addCharge(new Charge(new BigDecimal(1))))
@@ -280,7 +276,7 @@ public class ZF2PushTest extends TestCase {
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date())
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addVATID("DE0815")).setOwnTaxID("4711")
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addVATID("DE0815").addTaxID ("4711"))
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE0816").setContact(new Contact("contact testname", "123456", "contact.testemail@example.org").setFax("0911623562")))
.setDeliveryAddress(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE0816"))
.setNumber(number)
@@ -335,7 +331,7 @@ public class ZF2PushTest extends TestCase {
// .addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)).addAllowance(new Allowance().setPercent(new BigDecimal(50)))));
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addVATID("DE0815")).setOwnTaxID("4711").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE0816").setContact(new Contact("contact testname", "123456", "contact.testemail@example.org").setFax("0911623562"))).setNumber(number)
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addVATID("DE0815").addTaxID("4711")).setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addVATID("DE0816").setContact(new Contact("contact testname", "123456", "contact.testemail@example.org").setFax("0911623562"))).setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)).setReverseCharge(), amount, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)).setReverseCharge(), amount, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)).setReverseCharge(), amount, new BigDecimal(2.0)))
@@ -384,7 +380,7 @@ public class ZF2PushTest extends TestCase {
ze.setProducer("My Application")
.setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile(Profiles.getByName("en16931"));
ze.setTransaction(new Invoice().setCurrency("CHF").setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE")).setOwnTaxID("4711").setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setNumber(number)
ze.setTransaction(new Invoice().setCurrency("CHF").setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815")).setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), amount, new BigDecimal(1.0)))
@@ -449,7 +445,7 @@ public class ZF2PushTest extends TestCase {
ze.setTransaction(new Invoice().setCurrency("CHF").addNote("document level 1/2").addNote("document level 2/2").setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date())
.setSellerOrderReferencedDocumentID("9384").setBuyerOrderReferencedDocumentID("28934")
.setDetailedDeliveryPeriod(new SimpleDateFormat("yyyyMMdd").parse(occurrenceFrom), new SimpleDateFormat("yyyyMMdd").parse(occurrenceTo))
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID(taxID).setEmail("sender@test.org").setID("0009845"))
.setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID(taxID).setEmail("sender@test.org").setID("0009845").addVATID("DE0815"))
.setDeliveryAddress(new TradeParty("just the other side of the street", "teststr.12a", "55232", "Entenhausen", "DE").addVATID("DE47110"))
.setContractReferencedDocument(contractID)
.setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE").addGlobalID(gln).setEmail("recipient@test.org").addVATID("DE4711").setContact(new Contact("Franz Müller", "01779999999", "franz@mueller.de", "teststr. 12", "55232", "Entenhausen", "DE").setFax("++49555123456")).setAdditionalAddress("Hinterhaus 3"))
@@ -457,7 +453,7 @@ public class ZF2PushTest extends TestCase {
.addCharge(new Charge(new BigDecimal(0.5)).setReason("quick delivery charge").setTaxPercent(new BigDecimal(16)))
.addAllowance(new Allowance(new BigDecimal(0.2)).setReason("discount").setTaxPercent(new BigDecimal(16)))
.addCashDiscount(new CashDiscount(new BigDecimal(2), 14))
.setDeliveryDate(sdf.parse("2020-11-02")).setOwnVATID("DE0815").setNumber(number).setVATDueDateTypeCode(EventTimeCodeTypeConstants.PAYMENT_DATE)
.setDeliveryDate(sdf.parse("2020-11-02")).setNumber(number).setVATDueDateTypeCode(EventTimeCodeTypeConstants.PAYMENT_DATE)
);
} catch (ParseException e) {
e.printStackTrace();
@@ -535,7 +531,7 @@ public class ZF2PushTest extends TestCase {
.setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile(Profiles.getByName("en16931"));
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE")).setOwnTaxID("4711").setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setNumber(number)
ze.setTransaction(new Invoice().setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815")).setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), new BigDecimal(500.0), qty).addAllowance(new Allowance(new BigDecimal(300)).setTaxPercent(new BigDecimal(19))))
.addAllowance(new Allowance(new BigDecimal(600)).setTaxPercent(new BigDecimal(19)))
@@ -582,7 +578,7 @@ public class ZF2PushTest extends TestCase {
ze.setProducer("My Application")
.setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile(Profiles.getByName("extended"));
ze.setTransaction(new Invoice().setCurrency("CHF").setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE")).setOwnTaxID("4711").setOwnVATID("DE0815").setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setNumber(number)
ze.setTransaction(new Invoice().setCurrency("CHF").setDueDate(new Date()).setIssueDate(new Date()).setDeliveryDate(new Date()).setSender(new TradeParty(orgname, "teststr", "55232", "teststadt", "DE").addTaxID("4711").addVATID("DE0815")).setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setNumber(number)
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, new BigDecimal(1.0)))
.addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), price, new BigDecimal(1.0)).addCharge(new Charge().setPercent(new BigDecimal(50)).setTaxPercent(new BigDecimal(19))))

View File

@@ -229,14 +229,14 @@ public class ZF2Test extends MustangReaderTestCase {
assertEquals(zi.getSellerTradePartyAddress().getCityName(), "Stadthausen");
final List<org.mustangproject.Item> li = zi.getLineItemList();
assertEquals(zi.getLineItemList().get(0).getId().toString(), "1");
assertEquals(zi.getLineItemList().get(0).getProduct().getBuyerAssignedID(), "");
assertEquals(zi.getLineItemList().get(0).getProduct().getSellerAssignedID(), "");
assertEquals(zi.getLineItemList().get(0).getLineTotalAmount().toString(), "160.00");
assertEquals(zi.getLineItemList().get(0).getQuantity().toString(), "1.0000");
assertEquals(zi.getLineItemList().get(0).getProduct().getVATPercent().toString(), "7.00");
assertEquals(zi.getLineItemList().get(0).getProduct().getName(), "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung");
assertEquals(zi.getLineItemList().get(0).getProduct().getDescription(), "");
assertEquals(li.get(0).getId().toString(), "1");
assertEquals(li.get(0).getProduct().getBuyerAssignedID(), "");
assertEquals(li.get(0).getProduct().getSellerAssignedID(), "");
assertEquals(li.get(0).getLineTotalAmount().toString(), "160.00");
assertEquals(li.get(0).getQuantity().toString(), "1.0000");
assertEquals(li.get(0).getProduct().getVATPercent().toString(), "7.00");
assertEquals(li.get(0).getProduct().getName(), "Künstlerische Gestaltung (Stunde): Einer Beispielrechnung");
assertEquals(li.get(0).getProduct().getDescription(), "");
try {
assertEquals(zi.getVersion(), 2);

View File

@@ -21,16 +21,8 @@
*/
package org.mustangproject.ZUGFeRD;
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
import org.mustangproject.Invoice;
import junit.framework.TestCase;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import java.io.*;
import java.math.BigDecimal;
@@ -39,7 +31,6 @@ import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Scanner;
/***

View File

@@ -29,9 +29,9 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.deploy.skip>false
</maven.deploy.skip><!-- do deploy to maven central, parent project does not and inherits -->
<maven.compiler.compilerVersion>8</maven.compiler.compilerVersion>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.compilerVersion>11</maven.compiler.compilerVersion>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
@@ -72,11 +72,6 @@
<version>2.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.riversun</groupId>
<artifactId>bigdoc</artifactId>
<version>0.4.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
@@ -89,6 +84,12 @@
<version>5.10.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
@@ -139,8 +140,8 @@
<!-- http://stackoverflow.com/questions/574594/how-can-i-create-an-executable-jar-with-dependencies-using-maven
mvn clean compile assembly:single -->
<!-- or whatever version you use -->
<source>8</source>
<target>8</target>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<!-- /ZUV -->
@@ -268,7 +269,7 @@
<configuration>
<toolchains>
<jdk>
<version>8</version>
<version>11</version>
<vendor>adopt</vendor>
</jdk>
</toolchains>

View File

@@ -5,24 +5,52 @@ public final class ByteArraySearcher {
private ByteArraySearcher() {
}
public static int indexOf(byte[] haystack, byte[] needle) {
if (needle.length > haystack.length) {
return -1;
}
// Any needle to search?
if (needle.length == 0) {
return -1;
}
for (int i = 0; i <= haystack.length - needle.length; i++) {
boolean found = true;
for (int j = 0; j < needle.length; j++) {
if (haystack[i + j] != needle[j]) {
found = false;
break;
}
}
if (found) {
return i;
}
}
return -1;
}
public static boolean contains(byte[] haystack, byte[] needle) {
if (needle.length > haystack.length) {
return false;
}
for (int i = 0; i <= haystack.length - needle.length; i++) {
boolean found = true;
for (int j = 0; j < needle.length; j++) {
if (haystack[i + j] != needle[j]) {
found = false;
break;
}
}
if (found) {
return true;
}
}
return false;
return indexOf (haystack, needle) >= 0;
}
public static boolean startsWith(byte[] haystack, byte[] needle) {
if (needle.length > haystack.length) {
return false;
}
// Any needle to search?
if (needle.length == 0) {
return false;
}
for (int j = 0; j < needle.length; j++) {
if (haystack[j] != needle[j]) {
return false;
}
}
return true;
}
}

View File

@@ -1,14 +1,16 @@
package org.mustangproject.validator;
import java.io.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -20,20 +22,16 @@ import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.mustangproject.ZUGFeRD.ZUGFeRDImporter;
import org.riversun.bigdoc.bin.BigFileSearcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.verapdf.core.VeraPDFException;
import org.verapdf.features.FeatureExtractorConfig;
import org.verapdf.features.FeatureFactory;
import org.verapdf.gf.foundry.VeraGreenfieldFoundryProvider;
import org.verapdf.metadata.fixer.FixerFactory;
import org.verapdf.metadata.fixer.MetadataFixerConfig;
import org.verapdf.gf.foundry.VeraGreenfieldFoundryProvider;
import org.verapdf.pdfa.flavours.PDFAFlavour;
import org.verapdf.pdfa.validation.validators.ValidatorConfig;
import org.verapdf.pdfa.validation.validators.ValidatorFactory;
import org.verapdf.processor.BatchProcessor;
import org.verapdf.processor.FormatOption;
import org.verapdf.processor.ItemProcessor;
import org.verapdf.processor.ProcessorConfig;
import org.verapdf.processor.ProcessorFactory;
@@ -76,7 +74,7 @@ public class PDFValidator extends Validator {
zfXML = null;
// file existence must have been checked before
if (!ByteArraySearcher.contains(fileContents, new byte[]{'%', 'P', 'D', 'F'})) {
if (!ByteArraySearcher.startsWith(fileContents, new byte[]{'%', 'P', 'D', 'F'})) {
context.addResultItem(
new ValidationResultItem(ESeverity.fatal, "Not a PDF file " + pdfFilename).setSection(20).setPart(EPart.pdf));
@@ -96,7 +94,7 @@ public class PDFValidator extends Validator {
// Default fixer config
final MetadataFixerConfig fixerConfig = FixerFactory.defaultConfig();
// Tasks configuring
final EnumSet tasks = EnumSet.noneOf(TaskType.class);
final EnumSet<TaskType> tasks = EnumSet.noneOf(TaskType.class);
tasks.add(TaskType.VALIDATE);
// tasks.add(TaskType.EXTRACT_FEATURES);
// tasks.add(TaskType.FIX_METADATA);
@@ -105,7 +103,6 @@ public class PDFValidator extends Validator {
fixerConfig, tasks
);
// Creating processor and output stream.
final ByteArrayOutputStream reportStream = new ByteArrayOutputStream();
final InputStream inputStream = new ByteArrayInputStream(fileContents);
try (ItemProcessor processor = ProcessorFactory.createProcessor(processorConfig)) {
// Generating list of files for processing
@@ -258,37 +255,32 @@ public class PDFValidator extends Validator {
zfXML = zi.getUTF8();
// step 3 find signatures
try {
final byte[] symtraxSignature = "Symtrax".getBytes("UTF-8");
final byte[] mustangSignature = "via mustangproject".getBytes("UTF-8");
final byte[] facturxpythonSignature = "by Alexis de Lattre".getBytes("UTF-8");
final byte[] intarsysSignature = "intarsys ".getBytes("UTF-8");
final byte[] konikSignature = "Konik".getBytes("UTF-8");
final byte[] pdfMachineSignature = "pdfMachine from Broadgun Software".getBytes("UTF-8");
final byte[] ghostscriptSignature = "%%Invocation:".getBytes("UTF-8");
final byte[] symtraxSignature = "Symtrax".getBytes(StandardCharsets.UTF_8);
final byte[] mustangSignature = "via mustangproject".getBytes(StandardCharsets.UTF_8);
final byte[] facturxpythonSignature = "by Alexis de Lattre".getBytes(StandardCharsets.UTF_8);
final byte[] intarsysSignature = "intarsys ".getBytes(StandardCharsets.UTF_8);
final byte[] konikSignature = "Konik".getBytes(StandardCharsets.UTF_8);
final byte[] pdfMachineSignature = "pdfMachine from Broadgun Software".getBytes(StandardCharsets.UTF_8);
final byte[] ghostscriptSignature = "%%Invocation:".getBytes(StandardCharsets.UTF_8);
if (ByteArraySearcher.contains(fileContents, symtraxSignature)) {
Signature = "Symtrax";
} else if (ByteArraySearcher.contains(fileContents, mustangSignature)) {
Signature = "Mustang";
} else if (ByteArraySearcher.contains(fileContents, facturxpythonSignature)) {
Signature = "Factur/X Python";
} else if (ByteArraySearcher.contains(fileContents, intarsysSignature)) {
Signature = "Intarsys";
} else if (ByteArraySearcher.contains(fileContents, konikSignature)) {
Signature = "Konik";
} else if (ByteArraySearcher.contains(fileContents, pdfMachineSignature)) {
Signature = "pdfMachine";
} else if (ByteArraySearcher.contains(fileContents, ghostscriptSignature)) {
Signature = "Ghostscript";
}
context.setSignature(Signature);
} catch (final UnsupportedEncodingException e) {
LOGGER.error(e.getMessage(), e);
if (ByteArraySearcher.contains(fileContents, symtraxSignature)) {
Signature = "Symtrax";
} else if (ByteArraySearcher.contains(fileContents, mustangSignature)) {
Signature = "Mustang";
} else if (ByteArraySearcher.contains(fileContents, facturxpythonSignature)) {
Signature = "Factur/X Python";
} else if (ByteArraySearcher.contains(fileContents, intarsysSignature)) {
Signature = "Intarsys";
} else if (ByteArraySearcher.contains(fileContents, konikSignature)) {
Signature = "Konik";
} else if (ByteArraySearcher.contains(fileContents, pdfMachineSignature)) {
Signature = "pdfMachine";
} else if (ByteArraySearcher.contains(fileContents, ghostscriptSignature)) {
Signature = "Ghostscript";
}
context.setSignature(Signature);
// step 4:validate additional data
final HashMap<String, byte[]> additionalData = zi.getAdditionalData();
for (final String filename : additionalData.keySet()) {
@@ -329,9 +321,14 @@ public class PDFValidator extends Validator {
}
}
public void setFileContents(byte[] fileContents) {
this.fileContents = fileContents;
}
public void setFileContents(byte[] fileContents) {
this.fileContents = fileContents;
}
public void setFilenameAndContents(String filename, byte[] fileContents) {
this.pdfFilename = filename;
this.fileContents = fileContents;
}
public String getRawXML() {
return zfXML;

View File

@@ -1,85 +0,0 @@
package org.mustangproject.validator;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
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.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
public class SchematronPipeline {
static final ClassLoader cl = SchematronPipeline.class.getClassLoader();
private static final TransformerFactory factory = getTransformerFactory();
private static final String xslExt = ".xsl";
private static final String resourcePath = "iso-schematron-xslt2/";
private static final String isoDsdlXsl = resourcePath + "iso_dsdl_include" + xslExt;
private static final String isoExpXsl = resourcePath + "iso_abstract_expand" + xslExt;
private static final String isoSvrlXsl = resourcePath + "iso_svrl_for_xslt2" + xslExt;
private static final Templates cachedIsoDsdXsl = createCachedTransform(isoDsdlXsl);
private static final Templates cachedExpXsl = createCachedTransform(isoExpXsl);
private static final Templates cachedIsoSvrlXsl = createCachedTransform(isoSvrlXsl);
private static TransformerFactory getTransformerFactory() {
TransformerFactory fact = TransformerFactory.newInstance();
fact.setURIResolver(new ClasspathResourceURIResolver());
return fact;
}
static Templates createCachedTransform(final String transName) {
try {
return factory.newTemplates(new StreamSource(cl.getResourceAsStream(transName)));
} catch (TransformerConfigurationException excep) {
throw new IllegalStateException("Policy Schematron transformer XSL " + transName + " not found.", excep);
}
}
public static void processSchematron(InputStream schematronSource, OutputStream xslDest)
throws TransformerException, IOException {
File isoDsdResult = createTempFileResult(cachedIsoDsdXsl.newTransformer(), new StreamSource(schematronSource),
"IsoDsd");
File isoExpResult = createTempFileResult(cachedExpXsl.newTransformer(), new StreamSource(isoDsdResult),
"ExpXsl");
cachedIsoSvrlXsl.newTransformer().transform(new StreamSource(isoExpResult), new StreamResult(xslDest));
isoDsdResult.delete();
isoExpResult.delete();
}
private static File createTempFileResult(final Transformer transformer, final StreamSource toTransform,
final String suffix) throws TransformerException, IOException {
File result = File.createTempFile("ZUV_", suffix);
result.deleteOnExit();
try (FileOutputStream fos = new FileOutputStream(result)) {
transformer.transform(toTransform, new StreamResult(fos));
}
return result;
}
private static class ClasspathResourceURIResolver implements URIResolver {
ClasspathResourceURIResolver() {
// Do nothing, just prevents synthetic access warning.
}
@Override
public Source resolve(String href, String base) throws TransformerException {
return new StreamSource(cl.getResourceAsStream(resourcePath +"xslt/"+ href));
// return new StreamSource(cl.getResourceAsStream(resourcePath + href));
}
}
public static void applySchematronXsl(final InputStream xmlFile,
final OutputStream policyReport) throws TransformerException {
Transformer transformer = factory.newTransformer(new StreamSource(cl.getResourceAsStream(resourcePath+"ZUGFeRDSchematronStylesheetXSLT1.xsl")));
transformer.transform(new StreamSource(xmlFile), new StreamResult(policyReport));
}
}

View File

@@ -1,7 +1,23 @@
package org.mustangproject.validator;
import com.helger.schematron.ISchematronResource;
import com.helger.schematron.svrl.SVRLMarshaller;
import com.helger.schematron.svrl.jaxb.SchematronOutputType;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Calendar;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.mustangproject.XMLTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -9,22 +25,12 @@ import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.helger.schematron.xslt.SchematronResourceXSLT;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xpath.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Calendar;
import com.helger.schematron.ISchematronResource;
import com.helger.schematron.svrl.SVRLMarshaller;
import com.helger.schematron.svrl.jaxb.SchematronOutputType;
import com.helger.schematron.xslt.SchematronResourceXSLT;
public class XMLValidator extends Validator {
@@ -62,11 +68,16 @@ public class XMLValidator extends Validator {
final ValidationResultItem vri = new ValidationResultItem(ESeverity.exception, e.getMessage()).setSection(9)
.setPart(EPart.fx);
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
vri.setStacktrace(sw.toString());
context.addResultItem(vri);
try (final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw))
{
e.printStackTrace(pw);
vri.setStacktrace(sw.toString());
context.addResultItem(vri);
}
catch (IOException ex) {
throw new UncheckedIOException (ex);
}
}
}
@@ -427,6 +438,7 @@ public class XMLValidator extends Validator {
} catch (final Exception e) {
throw new IrrecoverableValidationError(e.getMessage());
}
// SVRLHelper.getAllFailedAssertions (sout);
Document SVRLReport = new SVRLMarshaller().getAsDocument(sout);
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "//*[local-name() = 'failed-assert']";

View File

@@ -1,5 +1,6 @@
package org.mustangproject.validator;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -7,10 +8,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
@@ -26,14 +26,15 @@ import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.mustangproject.XMLTools;
import org.riversun.bigdoc.bin.BigFileSearcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import jakarta.xml.bind.annotation.adapters.HexBinaryAdapter;
import com.helger.commons.io.stream.StreamHelper;
import jakarta.xml.bind.DatatypeConverter;
//abstract class
public class ZUGFeRDValidator {
@@ -74,6 +75,133 @@ public class ZUGFeRDValidator {
return wasCompletelyValid;
}
private String internalValidate (String contextFilename, InputStream inputStream, long inputLength) {
context.clear();
StringBuilder finalStringResult = new StringBuilder();
SimpleDateFormat isoDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
startTime = Calendar.getInstance().getTimeInMillis();
context.setFilename(contextFilename);// fallback to provided name
finalStringResult.append("<validation filename='").append (contextFilename).append ("' datetime='").append (isoDF.format(date)).append ("'>");
boolean isPDF = false;
byte[] content = null;
try {
if (contextFilename == null || contextFilename.isEmpty ()) {
optionsRecognized = false;
context.addResultItem(new ValidationResultItem(ESeverity.fatal, "Filename not specified").setSection(10)
.setPart(EPart.pdf));
}
PDFValidator pdfv = new PDFValidator(context);
if (inputStream == null) {
context.addResultItem(
new ValidationResultItem(ESeverity.fatal, "File not found").setSection(1).setPart(EPart.pdf));
} else if (inputLength < 32) {
// with less than 32 bytes it can not even be a proper XML file
// Except it is "<?xml version='1.0'?><xml/>" LOL
context.addResultItem(
new ValidationResultItem(ESeverity.fatal, "File too small").setSection(5).setPart(EPart.pdf));
} else if (inputLength >= Integer.MAX_VALUE) {
// Byte arrays are limited to 2GB in Java
context.addResultItem(
new ValidationResultItem(ESeverity.fatal, "File too big").setSection(5).setPart(EPart.pdf));
} else {
content = IOUtils.toByteArray(inputStream);
XMLValidator xv = new XMLValidator(context);
if (disableNotices) {
xv.disableNotices();
}
isPDF = ByteArraySearcher.startsWith(content, new byte[] {'%', 'P', 'D', 'F'});
if (isPDF) {
// Avoid reading again from file
pdfv.setFilenameAndContents(contextFilename, content);
optionsRecognized = true;
finalStringResult.append("<pdf>");
try {
pdfv.validate();
sha1Checksum = calcSHA1(content);
// Validate PDF
getPdfValidationResults(finalStringResult, pdfv, xv);
} catch (IrrecoverableValidationError irx) {
LOGGER.info(irx.getMessage());
}
finalStringResult.append("</pdf>\n");
context.clearCustomXML();
} else {
boolean isXML = false;
String xmlAsString = null;
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
content = XMLTools.removeBOM(content);
xmlAsString = new String(content, StandardCharsets.UTF_8);
InputSource is = new InputSource(new StringReader(xmlAsString));
Document doc = db.parse(is);
Element root = doc.getDocumentElement();
isXML = true;//no exception so far
} catch (Exception ex) {
// probably no xml file, sth like SAXParseException content not allowed in prolog
// ignore isXML is already false
// in the tests, this may error-out anyway
LOGGER.info("No XML part provided");
}
if (isXML) {
pdfValidity = true;
optionsRecognized = true;
xv.setStringContent (xmlAsString);
xv.disableAutoload();
xv.setFilename(contextFilename);
sha1Checksum = calcSHA1(content);
displayXMLValidationOutput = true;
} else {
optionsRecognized = false;
context.addResultItem(new ValidationResultItem(ESeverity.exception,
"File does not look like PDF nor XML (contains neither %PDF nor <?xml)").setSection(8));
}
}
if ((optionsRecognized) && (displayXMLValidationOutput)) {
finalStringResult.append("<xml>");
try {
xv.validate();
} catch (IrrecoverableValidationError irx) {
LOGGER.info("The hell");
}
finalStringResult.append(xv.getXMLResult());
finalStringResult.append("</xml>");
context.clearCustomXML();
}
if ((isPDF) && (!pdfValidity)) {
context.setInvalid();
}
}
} catch (IrrecoverableValidationError | IOException irx) {
LOGGER.info(irx.getMessage());
context.setInvalid ();
} finally {
finalStringResult.append(context.getXMLResult());
finalStringResult.append("</validation>");
}
return formatOutput(finalStringResult, isPDF);
}
/***
* performs a validation on the file filename
@@ -82,266 +210,63 @@ public class ZUGFeRDValidator {
* @return a xml string with the validation result
*/
public String validate(String filename) {
boolean xmlValidity;
context.clear();
StringBuffer finalStringResult = new StringBuffer();
SimpleDateFormat isoDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
startTime = Calendar.getInstance().getTimeInMillis();
try {
Path path = Paths.get(filename);
context.setFilename(path.getFileName().toString());// set filename without path
} catch (NullPointerException ex) {
// ignore
}
finalStringResult
.append("<validation filename='" + context.getFilename() + "' datetime='" + isoDF.format(date) + "'>");
boolean isPDF = false;
byte[] content = null;
try {
if (filename == null) {
optionsRecognized = false;
context.addResultItem(new ValidationResultItem(ESeverity.fatal, "Filename not specified").setSection(10)
.setPart(EPart.pdf));
}
PDFValidator pdfv = new PDFValidator(context);
File file = new File(filename);
if (!file.exists()) {
context.addResultItem(
new ValidationResultItem(ESeverity.fatal, "File not found").setSection(1).setPart(EPart.pdf));
} else if (file.length() < 32) {
// with less than 32 bytes it can not even be a proper XML file
context.addResultItem(
new ValidationResultItem(ESeverity.fatal, "File too small").setSection(5).setPart(EPart.pdf));
} else {
BigFileSearcher searcher = new BigFileSearcher();
content = Files.readAllBytes(file.toPath());
XMLValidator xv = new XMLValidator(context);
if (disableNotices) {
xv.disableNotices();
}
byte[] pdfSignature = {'%', 'P', 'D', 'F'};
isPDF = searcher.indexOf(file, pdfSignature) == 0;
if (isPDF) {
pdfv.setFilename(filename);
pdfv.setFileContents(content);
optionsRecognized = true;
try {
if (!file.exists()) {
context.addResultItem(
new ValidationResultItem(ESeverity.exception, "File " + filename + " not found")
.setSection(1));
}
} catch (IrrecoverableValidationError irx) {
// @todo log
}
finalStringResult.append("<pdf>");
optionsRecognized = true;
try {
pdfv.validate();
sha1Checksum = calcSHA1(new FileInputStream(file));
// Validate PDF
getPdfValidationResults(finalStringResult, pdfv, xv);
} catch (IrrecoverableValidationError | FileNotFoundException irx) {
// @todo log
}
finalStringResult.append("</pdf>\n");
context.clearCustomXML();
} else {
boolean isXML = false;
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
content = XMLTools.removeBOM(content);
String s = new String(content, StandardCharsets.UTF_8);
InputSource is = new InputSource(new StringReader(s));
Document doc = db.parse(is);
Element root = doc.getDocumentElement();
isXML = true;//no exception so far
} catch (Exception ex) {
// probably no xml file, sth like SAXParseException content not allowed in prolog
// ignore isXML is already false
// in the tests, this may error-out anyway
//ex.printStackTrace();
}
if (isXML) {
pdfValidity = true;
optionsRecognized = true;
xv.setFilename(filename);
if (file.exists()) {
sha1Checksum = calcSHA1(Files.newInputStream(file.toPath()));
}
displayXMLValidationOutput = true;
} else {
optionsRecognized = false;
context.addResultItem(new ValidationResultItem(ESeverity.exception,
"File does not look like PDF nor XML (contains neither %PDF nor <?xml)").setSection(8));
}
}
if ((optionsRecognized) && (displayXMLValidationOutput)) {
finalStringResult.append("<xml>");
try {
xv.validate();
} catch (IrrecoverableValidationError irx) {
// @todo log
}
finalStringResult.append(xv.getXMLResult());
finalStringResult.append("</xml>");
context.clearCustomXML();
}
if ((isPDF) && (!pdfValidity)) {
context.setInvalid();
}
}
} catch (IrrecoverableValidationError | IOException irx) {
// @todo log
} finally {
finalStringResult.append(context.getXMLResult());
finalStringResult.append("</validation>");
}
return formatOutput(finalStringResult, isPDF);
String contextFilename;
InputStream inputStream;
long inputLength;
if (filename == null) {
// No filename provided
contextFilename = "";
inputStream = null;
inputLength = 0;
} else {
File file = new File(filename);
// set filename without path
contextFilename = file.getName ();
if (file.isFile ()) {
try {
inputStream = new FileInputStream (file);
inputLength = Files.size (file.toPath ());
} catch (IOException ex) {
throw new UncheckedIOException (ex);
}
} else {
// Non-existing or Directory
inputStream = null;
inputLength = 0;
}
}
try {
return internalValidate (contextFilename, inputStream, inputLength);
} finally {
StreamHelper.close (inputStream);
}
}
public String validate(InputStream inputStream, String fileNameOfInputStream) {
boolean xmlValidity;
context.clear();
StringBuffer finalStringResult = new StringBuffer();
SimpleDateFormat isoDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
startTime = Calendar.getInstance().getTimeInMillis();
context.setFilename(fileNameOfInputStream);// set filename without path
finalStringResult.append("<validation filename='").append(context.getFilename()).append("' datetime='").append(isoDF.format(date)).append("'>");
public String validate(InputStream inputStream, String fileNameOfInputStream) {
long inputLength;
try {
inputLength = inputStream == null ? 0 : inputStream.available ();
}
catch (IOException ex) {
throw new UncheckedIOException (ex);
}
try {
return internalValidate (fileNameOfInputStream, inputStream, inputLength);
} finally {
StreamHelper.close (inputStream);
}
}
boolean isPDF = false;
byte[] content = new byte[0];
try {
public String validate(byte[] bytes, String fileNameOfInputStream) {
try(ByteArrayInputStream bais = new ByteArrayInputStream (bytes)) {
return internalValidate (fileNameOfInputStream, bais, bytes.length);
}
catch (IOException ex) {
throw new UncheckedIOException (ex);
}
}
if (fileNameOfInputStream == null) {
optionsRecognized = false;
context.addResultItem(new ValidationResultItem(ESeverity.fatal, "Filename not specified").setSection(10)
.setPart(EPart.pdf));
}
PDFValidator pdfv = new PDFValidator(context);
if (inputStream == null) {
context.addResultItem(
new ValidationResultItem(ESeverity.fatal, "File not found").setSection(1).setPart(EPart.pdf));
} else if (inputStream.available() < 32) {
// with less then 32 bytes it can not even be a proper XML file
context.addResultItem(
new ValidationResultItem(ESeverity.fatal, "File too small").setSection(5).setPart(EPart.pdf));
} else {
content = IOUtils.toByteArray(inputStream);
isPDF = ByteArraySearcher.contains(content, new byte[]{'%', 'P', 'D', 'F'});
XMLValidator xv = new XMLValidator(context);
if (isPDF) {
pdfv.setAutoload(false);
pdfv.setFilename(fileNameOfInputStream);
pdfv.setFileContents(content);
optionsRecognized = true;
finalStringResult.append("<pdf>");
try {
pdfv.validate();
sha1Checksum = calcSHA1(inputStream);
// Validate PDF
getPdfValidationResults(finalStringResult, pdfv, xv);
} catch (IrrecoverableValidationError irx) {
LOGGER.info(irx.getMessage());
}
finalStringResult.append("</pdf>\n");
context.clearCustomXML();
} else {
boolean isXML = false;
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
content = XMLTools.removeBOM(content);
String s = new String(content, StandardCharsets.UTF_8);
InputSource is = new InputSource(new StringReader(s));
Document doc = db.parse(is);
Element root = doc.getDocumentElement();
isXML = true;//no exception so far
} catch (Exception ex) {
LOGGER.info("No XML part provided");
}
if (isXML) {
pdfValidity = true;
optionsRecognized = true;
xv.setAutoload(false);
xv.setFilename(fileNameOfInputStream);
sha1Checksum = calcSHA1(inputStream);
displayXMLValidationOutput = true;
} else {
optionsRecognized = false;
context.addResultItem(new ValidationResultItem(
ESeverity.exception,
"File does not look like PDF nor XML (contains neither %PDF nor <?xml)"
).setSection(8));
}
}
if ((optionsRecognized) && (displayXMLValidationOutput)) {
finalStringResult.append("<xml>");
try {
xv.validate();
} catch (IrrecoverableValidationError irx) {
LOGGER.info("The hell");
}
finalStringResult.append(xv.getXMLResult());
finalStringResult.append("</xml>");
context.clearCustomXML();
}
if ((isPDF) && (!pdfValidity)) {
context.setInvalid();
}
}
} catch (IrrecoverableValidationError | IOException irx) {
LOGGER.info(irx.getMessage());
context.setInvalid ();
} finally {
finalStringResult.append(context.getXMLResult());
finalStringResult.append("</validation>");
}
return formatOutput(finalStringResult, isPDF);
}
private void getPdfValidationResults(StringBuffer finalStringResult, PDFValidator pdfv, XMLValidator xv) throws IrrecoverableValidationError {
private void getPdfValidationResults(StringBuilder finalStringResult, PDFValidator pdfv, XMLValidator xv) throws IrrecoverableValidationError {
finalStringResult.append(pdfv.getXMLResult());
pdfValidity = context.isValid();
@@ -357,7 +282,7 @@ public class ZUGFeRDValidator {
}
}
private String formatOutput(StringBuffer finalStringResult, boolean isPDF) {
private String formatOutput(StringBuilder finalStringResult, boolean isPDF) {
boolean xmlValidity;
OutputFormat format = OutputFormat.createPrettyPrint();
StringWriter sw = new StringWriter();
@@ -409,7 +334,7 @@ public class ZUGFeRDValidator {
/**
* Read the file and calculate the SHA-1 checksum
*
* @param inputStream the InputStream to read
* @param data the InputStream to read
* @return the hex representation of the SHA-1 using uppercase chars
* @throws FileNotFoundException if the file does not exist, is a directory
* rather than a regular file, or for some
@@ -417,26 +342,19 @@ public class ZUGFeRDValidator {
* @throws IOException if an I/O error occurs
* @throws NoSuchAlgorithmException should never happen
*/
private static String calcSHA1(InputStream inputStream) {
private static String calcSHA1(byte[] data) {
MessageDigest sha1 = null;
try {
sha1 = MessageDigest.getInstance("SHA-1");
byte[] buffer = new byte[8192];
int len = inputStream.read(buffer);
while (len != -1) {
sha1.update(buffer, 0, len);
len = inputStream.read(buffer);
}
inputStream.close();
} catch (IOException | NoSuchAlgorithmException e) {
sha1.update(data, 0, data.length);
} catch (NoSuchAlgorithmException e) {
LOGGER.error(e.getMessage(), e);
}
if (sha1 == null) {
return "";
} else {
return new HexBinaryAdapter().marshal(sha1.digest());
return DatatypeConverter.printHexBinary(sha1.digest());
}
}

View File

@@ -0,0 +1,42 @@
package org.mustangproject.validator;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.nio.charset.StandardCharsets;
import org.junit.Test;
public class ByteArraySearcherTest
{
@Test
public void testIndexOf () {
byte [] haystack = "Hello World".getBytes (StandardCharsets.ISO_8859_1);
assertEquals (0, ByteArraySearcher.indexOf (haystack, new byte [] { 'H' }));
assertEquals (1, ByteArraySearcher.indexOf (haystack, new byte [] { 'e' }));
assertEquals (0, ByteArraySearcher.indexOf (haystack, new byte [] { 'H', 'e' }));
assertEquals (0, ByteArraySearcher.indexOf (haystack, new byte [] { 'H', 'e' }));
assertEquals (0, ByteArraySearcher.indexOf (haystack, new byte [] { 'H', 'e', 'l', 'l' }));
assertEquals (0, ByteArraySearcher.indexOf (haystack, haystack));
assertEquals (-1, ByteArraySearcher.indexOf (haystack, new byte [0]));
assertEquals (-1, ByteArraySearcher.indexOf (haystack, new byte [] { 'a' }));
assertEquals (-1, ByteArraySearcher.indexOf (haystack, new byte [] { 'h' }));
assertEquals (-1, ByteArraySearcher.indexOf (haystack, new byte [] { 'r', 'o' }));
}
@Test
public void testStartsWith () {
byte [] haystack = "Hello World".getBytes (StandardCharsets.ISO_8859_1);
assertTrue (ByteArraySearcher.startsWith (haystack, new byte [] { 'H' }));
assertFalse (ByteArraySearcher.startsWith (haystack, new byte [] { 'e' }));
assertTrue (ByteArraySearcher.startsWith (haystack, new byte [] { 'H', 'e' }));
assertTrue (ByteArraySearcher.startsWith (haystack, new byte [] { 'H', 'e' }));
assertTrue (ByteArraySearcher.startsWith (haystack, new byte [] { 'H', 'e', 'l', 'l' }));
assertTrue (ByteArraySearcher.startsWith (haystack, haystack));
assertFalse (ByteArraySearcher.startsWith (haystack, new byte [0]));
assertFalse (ByteArraySearcher.startsWith (haystack, new byte [] { 'a' }));
assertFalse (ByteArraySearcher.startsWith (haystack, new byte [] { 'h' }));
assertFalse (ByteArraySearcher.startsWith (haystack, new byte [] { 'r', 'o' }));
}
}

View File

@@ -1,10 +1,5 @@
package org.mustangproject.validator;
import org.xmlunit.builder.Input;
import org.xmlunit.xpath.JAXPXPathEngine;
import org.xmlunit.xpath.XPathEngine;
import javax.xml.transform.Source;
import java.io.File;
import static org.xmlunit.assertj.XmlAssert.assertThat;

View File

@@ -13,15 +13,15 @@ public class MiscValidatorTest extends ResourceCase {
ZUGFeRDValidator zfv=new ZUGFeRDValidator();
String res=zfv.validate(null);
assertTrue(res.matches("<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>\n" +
"\n" +
"<validation filename=\"\" datetime=\".*?\">\n" +
" <messages>\n" +
" <error type=\"10\">Filename not specified</error> \n" +
" </messages>\n" +
" <summary status=\"invalid\"/>\n" +
"</validation>\n" +
""));
assertTrue(res.matches("<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>\n" +
"\n" +
"<validation filename=\"\" datetime=\".*?\">\n" +
" <messages>\n" +
" <error type=\"10\">Filename not specified</error> \n" +
" </messages>\n" +
" <summary status=\"invalid\"/>\n" +
"</validation>\n" +
""));
res=zfv.validate("/dhfkbv/sfjkh");
assertTrue(res.matches("<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>\n" +

View File

@@ -57,15 +57,13 @@ public class PDFValidatorTest extends ResourceCase {
byte [] contents = getResourceAsByteArray("XMLinvalidV2PDF.pdf");// need a more invalid file here
pv.setFilename("XMLinvalidV2PDF.pdf");
pv.setFileContents(contents);
pv.setFilenameAndContents("XMLinvalidV2PDF.pdf", contents);
pv.validate();
// assertEquals("", pv.getXMLResult());
//
contents = getResourceAsByteArray("Facture_F20180027.pdf");
pv.setFilename("Facture_F20180027.pdf");
pv.setFileContents(contents);
pv.setFilenameAndContents("Facture_F20180027.pdf", contents);
pv.validate();
String actual = pv.getXMLResult();
assertEquals(true, actual.contains("summary status=\"valid"));
@@ -91,8 +89,7 @@ public class PDFValidatorTest extends ResourceCase {
// valid one
contents = getResourceAsByteArray("validV2PDF.pdf");
pv.setFilename("validV2PDF.pdf");
pv.setFileContents(contents);
pv.setFilenameAndContents("validV2PDF.pdf", contents);
vc.clear();
pv.validate();
actual = pv.getXMLResult();
@@ -115,8 +112,7 @@ public class PDFValidatorTest extends ResourceCase {
// invalid file here
byte [] contents = getResourceAsByteArray("attributeBasedXMP_zugferd_2p0_EN16931_Einfach.pdf");
pv.setFilename("attributeBasedXMP_zugferd_2p0_EN16931_Einfach.pdf");
pv.setFileContents(contents);
pv.setFilenameAndContents("attributeBasedXMP_zugferd_2p0_EN16931_Einfach.pdf", contents);
pv.validate();
String pdfvres = pv.getXMLResult();
@@ -132,8 +128,7 @@ public class PDFValidatorTest extends ResourceCase {
vc.clear();
contents = getResourceAsByteArray("validV1WithAdditionalData.pdf");// need a more invalid file here
pv.setFilename("validV1WithAdditionalData.pdf");
pv.setFileContents(contents);
pv.setFilenameAndContents("validV1WithAdditionalData.pdf", contents);
pv.validate();
pdfvres = pv.getXMLResult();
@@ -157,8 +152,7 @@ public class PDFValidatorTest extends ResourceCase {
try {
byte [] contents = getResourceAsByteArray("invalidXMP.pdf");
pv.setFilename("invalidXMP.pdf");
pv.setFileContents(contents);
pv.setFilenameAndContents("invalidXMP.pdf", contents);
vc.clear();
pv.validate();
String actual = pv.getXMLResult();
@@ -168,8 +162,7 @@ public class PDFValidatorTest extends ResourceCase {
contents = getResourceAsByteArray("attributeBasedXMP_zugferd_2p0_EN16931_Einfach.pdf");
pv.setFilename("attributeBasedXMP_zugferd_2p0_EN16931_Einfach.pdf");
pv.setFileContents(contents);
pv.setFilenameAndContents("attributeBasedXMP_zugferd_2p0_EN16931_Einfach.pdf", contents);
vc.clear();
pv.validate();
actual = pv.getXMLResult();

View File

@@ -1,7 +1,5 @@
package org.mustangproject.validator;
import static org.xmlunit.assertj.XmlAssert.assertThat;
import java.io.File;
import javax.xml.transform.Source;

View File

@@ -1,11 +1,7 @@
package org.mustangproject.validator;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.xmlunit.builder.Input;
import org.xmlunit.xpath.JAXPXPathEngine;
import org.xmlunit.xpath.XPathEngine;
import static org.xmlunit.assertj.XmlAssert.assertThat;
@@ -83,6 +79,59 @@ public class ZUGFeRDValidatorTest extends ResourceCase {
}
public void testPDFValidationInputStream() {
byte[] fileBytes = getResourceAsByteArray("invalidPDF.pdf");
/**used to be Rule Status
Specification: ISO 19005-3:2012, Clause: 6.2.11.4, Test number: 4
If the FontDescriptor dictionary of an embedded CID font contains a CIDSet stream, then it shall identify all CIDs which are present in the font program, regardless of whether a CID in the font is referenced or used by the PDF or not. Failed
2 occurrences Hide
PDCIDFont
fontFile_size == 0 || fontName.search(/[A-Z]{6}\+/) != 0 || CIDSet_size == 0 || cidSetListsAllGlyphs == true
root/document[0]/pages[1](9 0 obj PDPage)/contentStream[0](18 0 obj PDContentStream)/operators[166]/font[0](WIUIIO+CIDFont+F2)/DescendantFonts[0](WIUIIO+CIDFont+F2)
root/document[0]/pages[1](9 0 obj PDPage)/contentStream[0](18 0 obj PDContentStream)/operators[192]/font[0](VEXQUA+CIDFont+F1)/DescendantFonts[0](VEXQUA+CIDFont+F1)
but new sample since that has been downgraded to warning
*/
ZUGFeRDValidator zfv = new ZUGFeRDValidator();
String res = zfv.validate(new ByteArrayInputStream (fileBytes), "invalidPDF.pdf");
assertThat(res).valueByXPath("/validation/pdf/summary/@status")
.isEqualTo("invalid");
assertThat(res).valueByXPath("/validation/xml/summary/@status")
.isEqualTo("valid");
assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("invalid");
fileBytes = getResourceAsByteArray("validAvoir_FR_type380_BASICWL.pdf");
zfv = new ZUGFeRDValidator();
res = zfv.validate(new ByteArrayInputStream (fileBytes), "validAvoir_FR_type380_BASICWL.pdf");
assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("valid");
fileBytes = getResourceAsByteArray("validXRechnung.pdf");
zfv = new ZUGFeRDValidator();
res = zfv.validate(new ByteArrayInputStream (fileBytes), "validXRechnung.pdf");
assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("valid");
fileBytes = getResourceAsByteArray("invalidXRechnung.pdf");
zfv = new ZUGFeRDValidator();
res = zfv.validate(new ByteArrayInputStream (fileBytes), "invalidXRechnung.pdf");
assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("invalid");
zfv = new ZUGFeRDValidator();
res = zfv.validate(new ByteArrayInputStream (new byte[0]), "/does/not/exist");
assertThat(res).valueByXPath("/validation/summary/@status")
.isEqualTo("invalid");
}
/***
* the XMLValidatorTests only cover the <xml></xml> part, this one includes the root element and
* the global <summary></summary> part as well