This commit is contained in:
jstaerk
2021-10-04 11:35:19 +02:00
parent 9e67bf5a94
commit df83c303a8
4 changed files with 88 additions and 36 deletions

View File

@@ -1,4 +1,11 @@
- support XR 2.1 (UN/CEFACT) 2.3.0
=======
2021-10-04
- support validating XR 2.1 (UN/CEFACT)
- invalid output PDF for input with incomplete CIDsets #249
To prevent regressions it is recommended to re-validate your PDF output after upgrading to 2.3.0
- Upgrade to PDFBox 2.0.24
2.2.1 2.2.1
======= =======

View File

@@ -67,7 +67,7 @@
<dependency> <dependency>
<groupId>org.apache.pdfbox</groupId> <groupId>org.apache.pdfbox</groupId>
<artifactId>preflight</artifactId> <artifactId>preflight</artifactId>
<version>2.0.23</version> <version>2.0.24</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.pdfbox</groupId> <groupId>org.apache.pdfbox</groupId>

View File

@@ -28,6 +28,10 @@ import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecifica
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile; import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDMarkInfo; import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDMarkInfo;
import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureTreeRoot; import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureTreeRoot;
import org.apache.pdfbox.pdmodel.font.PDCIDFontType2;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDFontDescriptor;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent; import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent;
import org.apache.pdfbox.preflight.utils.ByteArrayDataSource; import org.apache.pdfbox.preflight.utils.ByteArrayDataSource;
import org.apache.xmpbox.XMPMetadata; import org.apache.xmpbox.XMPMetadata;
@@ -46,11 +50,7 @@ import javax.activation.DataSource;
import javax.activation.FileDataSource; import javax.activation.FileDataSource;
import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerException;
import java.io.*; import java.io.*;
import java.util.ArrayList; import java.util.*;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporter, IExporter, Closeable { public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporter, IExporter, Closeable {
private boolean isFacturX = true; private boolean isFacturX = true;
@@ -92,13 +92,19 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
*/ */
protected String creatorTool = "mustangproject"; protected String creatorTool = "mustangproject";
/** @deprecated author is never set yet */ /**
* @deprecated author is never set yet
*/
@Deprecated @Deprecated
protected String author; protected String author;
/** @deprecated title is never set yet */ /**
* @deprecated title is never set yet
*/
@Deprecated @Deprecated
protected String title; protected String title;
/** @deprecated subject is never set yet */ /**
* @deprecated subject is never set yet
*/
@Deprecated @Deprecated
protected String subject; protected String subject;
@@ -129,17 +135,17 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
} }
public ZUGFeRDExporterFromA3 setProfile(Profile p) { public ZUGFeRDExporterFromA3 setProfile(Profile p) {
this.profile=p; this.profile = p;
if (xmlProvider!=null) { if (xmlProvider != null) {
xmlProvider.setProfile(p); xmlProvider.setProfile(p);
} }
return this; return this;
} }
public ZUGFeRDExporterFromA3 setProfile(String profilename) { public ZUGFeRDExporterFromA3 setProfile(String profilename) {
this.profile=Profiles.getByName(profilename); this.profile = Profiles.getByName(profilename);
if (xmlProvider!=null) { if (xmlProvider != null) {
xmlProvider.setProfile(this.profile); xmlProvider.setProfile(this.profile);
} }
return this; return this;
@@ -208,8 +214,8 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
* Factur-X is now set by default since ZF 2.1, you have to disable it if you dont wont it * Factur-X is now set by default since ZF 2.1, you have to disable it if you dont wont it
* Generate ZF2.1 files with filename factur-x.xml * Generate ZF2.1 files with filename factur-x.xml
* *
* @deprecated
* @return this (fluent setter) * @return this (fluent setter)
* @deprecated
*/ */
public ZUGFeRDExporterFromA3 setFacturX() { public ZUGFeRDExporterFromA3 setFacturX() {
isFacturX = true; isFacturX = true;
@@ -244,8 +250,9 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
public void attachFile(FileAttachment file) { public void attachFile(FileAttachment file) {
fileAttachments.add(file); fileAttachments.add(file);
} }
public void attachFile(String filename, byte[] data, String mimetype, String relation) { public void attachFile(String filename, byte[] data, String mimetype, String relation) {
FileAttachment fa=new FileAttachment(filename, mimetype, relation, data); FileAttachment fa = new FileAttachment(filename, mimetype, relation, data);
fileAttachments.add(fa); fileAttachments.add(fa);
} }
@@ -474,12 +481,48 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
metadata.addSchema(pdfaex); metadata.addSchema(pdfaex);
} }
private void removeCidSet(PDDocumentCatalog catalog, PDDocument doc) {
// https://github.com/ZUGFeRD/mustangproject/issues/249
COSName cidSet = COSName.getPDFName("CIDSet");
// iterate over all pdf pages
for (Object object : doc.getPages()) {
if (object instanceof PDPage) {
PDPage page = (PDPage) object;
PDResources res = page.getResources();
for (COSName fontName : res.getFontNames()) {
try {
PDFont pdFont = res.getFont(fontName);
if (pdFont instanceof PDType0Font) {
PDType0Font typedFont = (PDType0Font) pdFont;
if (typedFont.getDescendantFont() instanceof PDCIDFontType2) {
PDCIDFontType2 f = (PDCIDFontType2) typedFont.getDescendantFont();
PDFontDescriptor fontDescriptor = pdFont.getFontDescriptor();
fontDescriptor.getCOSObject().removeItem(cidSet);
}
}
} catch (IOException e) {
e.printStackTrace();
}
// do stuff with the font
}
}
}
}
protected void prepareDocument() throws IOException { protected void prepareDocument() throws IOException {
PDDocumentCatalog cat = doc.getDocumentCatalog(); PDDocumentCatalog cat = doc.getDocumentCatalog();
metadata = new PDMetadata(doc); metadata = new PDMetadata(doc);
cat.setMetadata(metadata); cat.setMetadata(metadata);
removeCidSet(cat, doc);
xmp = getXmpMetadata(); xmp = getXmpMetadata();
writeAdobePDFSchema(xmp); writeAdobePDFSchema(xmp);
writePDFAIdentificationSchema(xmp); writePDFAIdentificationSchema(xmp);
@@ -521,7 +564,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
return prepare(); return prepare();
} }
public IExporter prepare() throws IOException{ public IExporter prepare() throws IOException {
prepareDocument(); prepareDocument();
xmlProvider.generateXML(trans); xmlProvider.generateXML(trans);
String filename = getFilenameForVersion(ZFVersion, xmlProvider.getProfile()); String filename = getFilenameForVersion(ZFVersion, xmlProvider.getProfile());
@@ -529,7 +572,7 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
"Invoice metadata conforming to ZUGFeRD standard (http://www.ferd-net.de/front_content.php?idcat=231&lang=4)", "Invoice metadata conforming to ZUGFeRD standard (http://www.ferd-net.de/front_content.php?idcat=231&lang=4)",
"text/xml", xmlProvider.getXML()); "text/xml", xmlProvider.getXML());
for (FileAttachment attachment: fileAttachments) { for (FileAttachment attachment : fileAttachments) {
PDFAttachGenericFile(doc, attachment.getFilename(), attachment.getRelation(), attachment.getDescription(), attachment.getMimetype(), attachment.getData()); PDFAttachGenericFile(doc, attachment.getFilename(), attachment.getRelation(), attachment.getDescription(), attachment.getMimetype(), attachment.getData());
} }
@@ -739,10 +782,11 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
protected void setXMLProvider(IXMLProvider p) { protected void setXMLProvider(IXMLProvider p) {
this.xmlProvider = p; this.xmlProvider = p;
if (profile!=null) { if (profile != null) {
xmlProvider.setProfile(profile); xmlProvider.setProfile(profile);
} }
} }
@Override @Override
public ZUGFeRDExporterFromA3 setZUGFeRDVersion(int version) { public ZUGFeRDExporterFromA3 setZUGFeRDVersion(int version) {
this.ZFVersion = version; this.ZFVersion = version;

View File

@@ -272,7 +272,8 @@ public class ZUGFeRDImporter {
return extractString("//ApplicableHeaderTradeSettlement//InvoiceCurrencyCode"); return extractString("//ApplicableHeaderTradeSettlement//InvoiceCurrencyCode");
} }
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
return ""; return "";
} }
} }
@@ -306,7 +307,7 @@ public class ZUGFeRDImporter {
return extractString("//BuyerOrderReferencedDocument//IssuerAssignedID"); return extractString("//BuyerOrderReferencedDocument//IssuerAssignedID");
} }
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
return ""; return "";
} }
} }
@@ -329,7 +330,7 @@ public class ZUGFeRDImporter {
return extractString("//ExchangedDocument//IssueDateTime//DateTimeString"); return extractString("//ExchangedDocument//IssueDateTime//DateTimeString");
} }
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
return ""; return "";
} }
} }
@@ -345,7 +346,7 @@ public class ZUGFeRDImporter {
return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//TaxBasisTotalAmount"); return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//TaxBasisTotalAmount");
} }
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
return ""; return "";
} }
} }
@@ -361,7 +362,7 @@ public class ZUGFeRDImporter {
return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//TaxTotalAmount"); return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//TaxTotalAmount");
} }
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
return ""; return "";
} }
} }
@@ -377,7 +378,7 @@ public class ZUGFeRDImporter {
return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//RoundingAmount"); return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//RoundingAmount");
} }
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
return ""; return "";
} }
} }
@@ -393,7 +394,7 @@ public class ZUGFeRDImporter {
return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//TotalPrepaidAmount"); return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//TotalPrepaidAmount");
} }
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
return ""; return "";
} }
} }
@@ -431,7 +432,7 @@ public class ZUGFeRDImporter {
return extractString("//ExchangedDocument//IncludedNote"); return extractString("//ExchangedDocument//IncludedNote");
} }
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
return ""; return "";
} }
} }
@@ -456,7 +457,7 @@ public class ZUGFeRDImporter {
return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//LineTotalAmount"); return extractString("//SpecifiedTradeSettlementHeaderMonetarySummation//LineTotalAmount");
} }
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
return ""; return "";
} }
} }
@@ -479,7 +480,7 @@ public class ZUGFeRDImporter {
return extractString("//ActualDeliverySupplyChainEvent//OccurrenceDateTime//DateTimeString"); return extractString("//ActualDeliverySupplyChainEvent//OccurrenceDateTime//DateTimeString");
} }
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
return ""; return "";
} }
} }
@@ -495,7 +496,7 @@ public class ZUGFeRDImporter {
return extractString("//ExchangedDocument//ID"); return extractString("//ExchangedDocument//ID");
} }
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
return ""; return "";
} }
} }
@@ -513,7 +514,7 @@ public class ZUGFeRDImporter {
return extractString("//ExchangedDocument/TypeCode"); return extractString("//ExchangedDocument/TypeCode");
} }
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
return ""; return "";
} }
} }
@@ -530,7 +531,7 @@ public class ZUGFeRDImporter {
return extractString("//ApplicableHeaderTradeAgreement/BuyerReference"); return extractString("//ApplicableHeaderTradeAgreement/BuyerReference");
} }
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
return ""; return "";
} }
} }
@@ -718,7 +719,7 @@ public class ZUGFeRDImporter {
nl = getNodeListByPath("//CrossIndustryInvoice//SupplyChainTradeTransaction//ApplicableHeaderTradeAgreement//BuyerTradeParty//PostalTradeAddress"); nl = getNodeListByPath("//CrossIndustryInvoice//SupplyChainTradeTransaction//ApplicableHeaderTradeAgreement//BuyerTradeParty//PostalTradeAddress");
} }
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
return null; return null;
} }
@@ -741,7 +742,7 @@ public class ZUGFeRDImporter {
nl = getNodeListByPath("//CrossIndustryInvoice//SupplyChainTradeTransaction//ApplicableHeaderTradeAgreement//SellerTradeParty//PostalTradeAddress"); nl = getNodeListByPath("//CrossIndustryInvoice//SupplyChainTradeTransaction//ApplicableHeaderTradeAgreement//SellerTradeParty//PostalTradeAddress");
} }
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
return null; return null;
} }
@@ -940,7 +941,7 @@ public class ZUGFeRDImporter {
nl = getNodeListByPath("//CrossIndustryInvoice//SupplyChainTradeTransaction//IncludedSupplyChainTradeLineItem"); nl = getNodeListByPath("//CrossIndustryInvoice//SupplyChainTradeTransaction//IncludedSupplyChainTradeLineItem");
} }
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
} }
for (int i = 0; i < nl.getLength(); i++) { for (int i = 0; i < nl.getLength(); i++) {
@@ -985,7 +986,7 @@ public class ZUGFeRDImporter {
final XPathExpression xpr = xPath.compile(s); final XPathExpression xpr = xPath.compile(s);
return (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET); return (NodeList) xpr.evaluate(getDocument(), XPathConstants.NODESET);
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
return null; return null;
} }
} }