prepare document as late as possible
This commit is contained in:
30
History.md
30
History.md
@@ -1,22 +1,26 @@
|
||||
1.5.0
|
||||
=====
|
||||
<date>
|
||||
Now using factory. Export is now also possible on OutputStream.
|
||||
Further dev improvements: no more need to call PDFattachZugferdFile(null) or exporter close();
|
||||
toecount now has options to combine documents and upgrade xml file from ZF1 to ZF2
|
||||
More unit tests, e.g. for custom xml export, PDF/A Schema extensions.
|
||||
Toecount is now integrated and the main class so "java -jar mustang-1.5.0.jar" should suffice
|
||||
2017-11-30
|
||||
|
||||
Support for ZUGFeRD 2.0 "public review" part 1.
|
||||
Now using factories to create/configure ZUGFeRDExporter.
|
||||
Export is now also possible on OutputStream.
|
||||
Removed need to call PDFattachZugferdFile(null) or exporter close();
|
||||
More unit tests, e.g. for custom xml export, PDF/A Schema extensions.
|
||||
The command line utility "toecount" is now integrated and the main class so "java -jar mustang-1.5.0.jar" should suffice.
|
||||
It now also features options to combine PDF with XML and upgrade XML files from ZF1 to ZF2.
|
||||
|
||||
First attempts be able to start with a PDF/A-3 in the first place and better error messages for non-PDF/A-conformance.
|
||||
|
||||
Further changes:
|
||||
|
||||
be able to specify profile #50
|
||||
close pdf files automatically after export #49
|
||||
ZUGFeRDimporter does not close #48
|
||||
command line option -e does not work on all-in-one jar #47
|
||||
invoices have wrong namespaces #45
|
||||
invalid a3 #44
|
||||
warn on export #39
|
||||
* be able to specify profile #50
|
||||
* close pdf files automatically after export #49
|
||||
* ZUGFeRDimporter does not close #48
|
||||
* command line option -e does not work on all-in-one jar #47
|
||||
* invoices have wrong namespaces #45
|
||||
* invalid a3 #44
|
||||
* warn on export #39
|
||||
|
||||
|
||||
1.4.0
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -3,7 +3,6 @@ package org.mustangproject.ZUGFeRD;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.xmpbox.XMPMetadata;
|
||||
|
||||
public interface IExporterFactory {
|
||||
@@ -25,8 +24,6 @@ public interface IExporterFactory {
|
||||
* @throws IOException
|
||||
*/
|
||||
public ZUGFeRDExporter load(InputStream pdfSource) throws IOException;
|
||||
public void prepareDocument(PDDocument doc) throws IOException;
|
||||
public void addXMP(XMPMetadata metadata);
|
||||
|
||||
public IExporterFactory setCreator(String creator);
|
||||
public IExporterFactory setConformanceLevel(PDFAConformanceLevel newLevel);
|
||||
@@ -34,6 +31,5 @@ public interface IExporterFactory {
|
||||
public IExporterFactory setZUGFeRDVersion(int version);
|
||||
public IExporterFactory ignorePDFAErrors();
|
||||
public IExporterFactory setZUGFeRDConformanceLevel(ZUGFeRDConformanceLevel zugferdConformanceLevel);
|
||||
public IExporterFactory setAttachZUGFeRDHeaders(final boolean attachZugferdHeaders);
|
||||
|
||||
}
|
||||
|
||||
@@ -16,18 +16,29 @@ import org.apache.pdfbox.cos.COSDictionary;
|
||||
import org.apache.pdfbox.cos.COSName;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
|
||||
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
|
||||
import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary;
|
||||
import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode;
|
||||
import org.apache.pdfbox.pdmodel.common.PDMetadata;
|
||||
import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification;
|
||||
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
|
||||
import org.apache.xmpbox.XMPMetadata;
|
||||
import org.apache.xmpbox.schema.AdobePDFSchema;
|
||||
import org.apache.xmpbox.schema.DublinCoreSchema;
|
||||
import org.apache.xmpbox.schema.PDFAIdentificationSchema;
|
||||
import org.apache.xmpbox.schema.XMPBasicSchema;
|
||||
import org.apache.xmpbox.type.BadFieldValueException;
|
||||
import org.apache.xmpbox.xml.XmpSerializer;
|
||||
|
||||
import javax.xml.transform.TransformerException;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -59,7 +70,7 @@ public class ZUGFeRDExporter implements Closeable {
|
||||
|
||||
// BASIC, COMFORT etc - may be set from outside.
|
||||
@Deprecated
|
||||
private ZUGFeRDConformanceLevel zUGFeRDConformanceLevel = ZUGFeRDConformanceLevel.EXTENDED;
|
||||
private ZUGFeRDConformanceLevel profile = ZUGFeRDConformanceLevel.EXTENDED;
|
||||
|
||||
/**
|
||||
* Data (XML invoice) to be added to the ZUGFeRD PDF. It may be externally set,
|
||||
@@ -68,14 +79,22 @@ public class ZUGFeRDExporter implements Closeable {
|
||||
* IZUGFeRDExportableTransaction for the XML to be populated.
|
||||
*/
|
||||
IXMLProvider xmlProvider;
|
||||
protected PDMetadata metadata = null;
|
||||
protected PDFAIdentificationSchema pdfaid = null;
|
||||
protected XMPMetadata xmp = null;
|
||||
protected String producer = "mustangproject";
|
||||
protected String creator = "mustangproject";
|
||||
|
||||
@Deprecated
|
||||
private boolean ignoreA1Errors;
|
||||
protected boolean ensurePDFisUpgraded = true;
|
||||
private PDDocument doc;
|
||||
int ZFVersion;
|
||||
|
||||
private boolean disableAutoClose;
|
||||
|
||||
private boolean fileAttached=false;
|
||||
private boolean fileAttached = false;
|
||||
protected boolean attachZUGFeRDHeaders = true;
|
||||
|
||||
public ZUGFeRDExporter() {
|
||||
init();
|
||||
@@ -116,7 +135,7 @@ public class ZUGFeRDExporter implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Deprecated
|
||||
public void setZUGFeRDVersion(int ver) {
|
||||
if (ver == 1) {
|
||||
ZUGFeRD1PullProvider z1p = new ZUGFeRD1PullProvider();
|
||||
@@ -129,7 +148,7 @@ public class ZUGFeRDExporter implements Closeable {
|
||||
}
|
||||
ZFVersion = ver;
|
||||
}
|
||||
|
||||
|
||||
public IXMLProvider getProvider() {
|
||||
return xmlProvider;
|
||||
}
|
||||
@@ -233,8 +252,7 @@ public class ZUGFeRDExporter implements Closeable {
|
||||
public PDDocumentCatalog PDFmakeA3compliant(String filename, String producer, String creator,
|
||||
boolean attachZugferdHeaders) throws IOException, TransformerException {
|
||||
|
||||
doc = createPDFA1Factory().setProducer(producer).setCreator(creator)
|
||||
.setAttachZUGFeRDHeaders(attachZugferdHeaders).load(filename).doc;
|
||||
doc = createPDFA1Factory().setProducer(producer).setCreator(creator).load(filename).doc;
|
||||
|
||||
return doc.getDocumentCatalog();
|
||||
}
|
||||
@@ -246,8 +264,7 @@ public class ZUGFeRDExporter implements Closeable {
|
||||
public PDDocumentCatalog PDFmakeA3compliant(InputStream file, String producer, String creator,
|
||||
boolean attachZugferdHeaders) throws IOException, TransformerException {
|
||||
|
||||
doc = createPDFA1Factory().setProducer(producer).setCreator(creator)
|
||||
.setAttachZUGFeRDHeaders(attachZugferdHeaders).load(file).doc;
|
||||
doc = createPDFA1Factory().setProducer(producer).setCreator(creator).load(file).doc;
|
||||
|
||||
return doc.getDocumentCatalog();
|
||||
}
|
||||
@@ -257,7 +274,7 @@ public class ZUGFeRDExporter implements Closeable {
|
||||
if (ignoreA1Errors) {
|
||||
factory.ignorePDFAErrors();
|
||||
}
|
||||
return factory.setZUGFeRDConformanceLevel(zUGFeRDConformanceLevel).setConformanceLevel(conformanceLevel);
|
||||
return factory.setZUGFeRDConformanceLevel(profile).setConformanceLevel(conformanceLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -277,6 +294,8 @@ public class ZUGFeRDExporter implements Closeable {
|
||||
* <code>setZUGFeRDXMLData(byte[] zugferdData)</code>
|
||||
*/
|
||||
public void PDFattachZugferdFile(IZUGFeRDExportableTransaction trans) throws IOException {
|
||||
prepareDocument(doc);
|
||||
|
||||
xmlProvider.generateXML(trans);
|
||||
String filename = getFilenameForVersion(ZFVersion);
|
||||
PDFAttachGenericFile(doc, filename, "Alternative",
|
||||
@@ -286,7 +305,8 @@ public class ZUGFeRDExporter implements Closeable {
|
||||
|
||||
public void export(String ZUGFeRDfilename) throws IOException {
|
||||
if (!fileAttached) {
|
||||
throw new IOException("File must be attached (usually with PDFattachZugferdFile) before perfoming this operation");
|
||||
throw new IOException(
|
||||
"File must be attached (usually with PDFattachZugferdFile) before perfoming this operation");
|
||||
}
|
||||
doc.save(ZUGFeRDfilename);
|
||||
if (!disableAutoClose) {
|
||||
@@ -296,15 +316,15 @@ public class ZUGFeRDExporter implements Closeable {
|
||||
|
||||
public void export(OutputStream output) throws IOException {
|
||||
if (!fileAttached) {
|
||||
throw new IOException("File must be attached (usually with PDFattachZugferdFile) before perfoming this operation");
|
||||
throw new IOException(
|
||||
"File must be attached (usually with PDFattachZugferdFile) before perfoming this operation");
|
||||
}
|
||||
doc.save(output);
|
||||
if (!disableAutoClose) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Embeds an external file (generic - any type allowed) in the PDF.
|
||||
*
|
||||
@@ -324,7 +344,7 @@ public class ZUGFeRDExporter implements Closeable {
|
||||
*/
|
||||
public void PDFAttachGenericFile(PDDocument doc, String filename, String relationship, String description,
|
||||
String subType, byte[] data) throws IOException {
|
||||
fileAttached=true;
|
||||
fileAttached = true;
|
||||
|
||||
PDComplexFileSpecification fs = new PDComplexFileSpecification();
|
||||
fs.setFile(filename);
|
||||
@@ -412,7 +432,7 @@ public class ZUGFeRDExporter implements Closeable {
|
||||
if (zUGFeRDConformanceLevel == null) {
|
||||
throw new NullPointerException("ZUGFeRD conformance level");
|
||||
}
|
||||
this.zUGFeRDConformanceLevel = zUGFeRDConformanceLevel;
|
||||
this.profile = zUGFeRDConformanceLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -425,7 +445,7 @@ public class ZUGFeRDExporter implements Closeable {
|
||||
*/
|
||||
@Deprecated
|
||||
public void setZUGFeRDConformanceLevel(String zUGFeRDConformanceLevel) {
|
||||
this.zUGFeRDConformanceLevel = ZUGFeRDConformanceLevel.valueOf(zUGFeRDConformanceLevel);
|
||||
this.profile = ZUGFeRDConformanceLevel.valueOf(zUGFeRDConformanceLevel);
|
||||
}
|
||||
|
||||
/****
|
||||
@@ -437,6 +457,107 @@ public class ZUGFeRDExporter implements Closeable {
|
||||
return doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* This will add both the RDF-indication which embedded file is Zugferd and the
|
||||
* neccessary PDF/A schema extension description to be able to add this
|
||||
* information to RDF
|
||||
*
|
||||
* @param metadata
|
||||
*/
|
||||
protected void addXMP(XMPMetadata metadata) {
|
||||
|
||||
if (attachZUGFeRDHeaders) {
|
||||
XMPSchemaZugferd zf = new XMPSchemaZugferd(metadata, profile,
|
||||
ZUGFeRDExporter.getNamespaceForVersion(ZFVersion), ZUGFeRDExporter.getPrefixForVersion(ZFVersion),
|
||||
ZUGFeRDExporter.getFilenameForVersion(ZFVersion));
|
||||
|
||||
metadata.addSchema(zf);
|
||||
}
|
||||
|
||||
XMPSchemaPDFAExtensions pdfaex = new XMPSchemaPDFAExtensions(metadata, ZFVersion, attachZUGFeRDHeaders);
|
||||
pdfaex.setZUGFeRDVersion(ZFVersion);
|
||||
metadata.addSchema(pdfaex);
|
||||
|
||||
}
|
||||
|
||||
protected byte[] serializeXmpMetadata(XMPMetadata xmpMetadata) throws TransformerException {
|
||||
XmpSerializer serializer = new XmpSerializer();
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
|
||||
String prefix = "<?xpacket begin=\"\uFEFF\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>";
|
||||
String suffix = "<?xpacket end=\"w\"?>";
|
||||
|
||||
try {
|
||||
buffer.write(prefix.getBytes("UTF-8")); // see https://github.com/ZUGFeRD/mustangproject/issues/44
|
||||
serializer.serialize(xmpMetadata, buffer, false);
|
||||
buffer.write(suffix.getBytes("UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return buffer.toByteArray();
|
||||
}
|
||||
|
||||
protected void prepareDocument(PDDocument doc) throws IOException {
|
||||
String fullProducer = producer + " (via mustangproject.org " + org.mustangproject.ZUGFeRD.Version.VERSION + ")";
|
||||
|
||||
PDDocumentCatalog cat = doc.getDocumentCatalog();
|
||||
metadata = new PDMetadata(doc);
|
||||
cat.setMetadata(metadata);
|
||||
|
||||
xmp = XMPMetadata.createXMPMetadata();
|
||||
|
||||
pdfaid = new PDFAIdentificationSchema(xmp);
|
||||
|
||||
xmp.addSchema(pdfaid);
|
||||
|
||||
DublinCoreSchema dc = xmp.createAndAddDublinCoreSchema();
|
||||
|
||||
dc.addCreator(creator);
|
||||
|
||||
XMPBasicSchema xsb = xmp.createAndAddXMPBasicSchema();
|
||||
|
||||
xsb.setCreatorTool(creator);
|
||||
xsb.setCreateDate(GregorianCalendar.getInstance());
|
||||
// PDDocumentInformation pdi=doc.getDocumentInformation();
|
||||
PDDocumentInformation pdi = new PDDocumentInformation();
|
||||
pdi.setProducer(fullProducer);
|
||||
pdi.setAuthor(creator);
|
||||
doc.setDocumentInformation(pdi);
|
||||
|
||||
AdobePDFSchema pdf = xmp.createAndAddAdobePDFSchema();
|
||||
pdf.setProducer(fullProducer);
|
||||
if (ensurePDFisUpgraded) {
|
||||
try {
|
||||
pdfaid.setConformance(conformanceLevel.getLetter());// $NON-NLS-1$ //$NON-NLS-1$
|
||||
} catch (BadFieldValueException ex) {
|
||||
// This should be impossible, because it would occur only if an illegal
|
||||
// conformance level is supplied,
|
||||
// however the enum enforces that the conformance level is valid.
|
||||
throw new Error(ex);
|
||||
}
|
||||
|
||||
pdfaid.setPart(3);
|
||||
}
|
||||
if (attachZUGFeRDHeaders) {
|
||||
addXMP(xmp); /*
|
||||
* this is the only line where we do something Zugferd-specific, i.e. add PDF
|
||||
* metadata specifically for Zugferd, not generically for a embedded file
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
metadata.importXMPMetadata(serializeXmpMetadata(xmp));
|
||||
|
||||
} catch (TransformerException e) {
|
||||
throw new ZUGFeRDExportException("Could not export XmpMetadata", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAutoCloseDisabled() {
|
||||
return disableAutoClose;
|
||||
}
|
||||
@@ -445,4 +566,22 @@ public class ZUGFeRDExporter implements Closeable {
|
||||
this.disableAutoClose = disableAutoClose;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setCreator(String creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setProducer(String producer) {
|
||||
this.producer = producer;
|
||||
}
|
||||
|
||||
public void setPDFA3(boolean ensurePDFisUpgraded) {
|
||||
this.ensurePDFisUpgraded = ensurePDFisUpgraded;
|
||||
}
|
||||
|
||||
public void setAttachZUGFeRDHeaders(boolean attachZUGFeRDHeaders) {
|
||||
this.attachZUGFeRDHeaders=attachZUGFeRDHeaders;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,55 +1,10 @@
|
||||
package org.mustangproject.ZUGFeRD;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.xml.transform.TransformerException;
|
||||
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.xmpbox.type.BadFieldValueException;
|
||||
|
||||
public class ZUGFeRDExporterFromA1Factory extends ZUGFeRDExporterFromA3Factory implements IExporterFactory {
|
||||
|
||||
/**
|
||||
* Make a PDF A/3 from the PDF A/1
|
||||
*/
|
||||
public void prepareDocument(PDDocument doc) throws IOException {
|
||||
super.prepareDocument(doc);
|
||||
/*
|
||||
* // Mandatory: PDF/A3-a is tagged PDF which has to be expressed using a //
|
||||
* MarkInfo dictionary (PDF A/3 Standard sec. 6.7.2.2) PDMarkInfo markinfo = new
|
||||
* PDMarkInfo(); markinfo.setMarked(true);
|
||||
* doc.getDocumentCatalog().setMarkInfo(markinfo);
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* To be on the safe side, we use level B without Markinfo because we can not
|
||||
* guarantee that the user correctly tagged the templates for the PDF.
|
||||
*/
|
||||
try {
|
||||
pdfaid.setConformance(conformanceLevel.getLetter());// $NON-NLS-1$ //$NON-NLS-1$
|
||||
} catch (BadFieldValueException ex) {
|
||||
// This should be impossible, because it would occur only if an illegal
|
||||
// conformance level is supplied,
|
||||
// however the enum enforces that the conformance level is valid.
|
||||
throw new Error(ex);
|
||||
}
|
||||
|
||||
pdfaid.setPart(3);
|
||||
|
||||
if (attachZugferdHeaders) {
|
||||
addXMP(xmp); /*
|
||||
* this is the only line where we do something Zugferd-specific, i.e. add PDF
|
||||
* metadata specifically for Zugferd, not generically for a embedded file
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
metadata.importXMPMetadata(serializeXmpMetadata(xmp));
|
||||
public ZUGFeRDExporterFromA1Factory() {
|
||||
ensurePDFisUpgraded=true;
|
||||
|
||||
} catch (TransformerException e) {
|
||||
throw new ZUGFeRDExportException("Could not export XmpMetadata", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,31 +2,19 @@ package org.mustangproject.ZUGFeRD;
|
||||
|
||||
import org.apache.pdfbox.io.IOUtils;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
|
||||
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
|
||||
import org.apache.pdfbox.pdmodel.common.PDMetadata;
|
||||
import org.apache.pdfbox.preflight.PreflightDocument;
|
||||
import org.apache.pdfbox.preflight.exception.ValidationException;
|
||||
import org.apache.pdfbox.preflight.parser.PreflightParser;
|
||||
import org.apache.pdfbox.preflight.utils.ByteArrayDataSource;
|
||||
import org.apache.xmpbox.XMPMetadata;
|
||||
import org.apache.xmpbox.schema.AdobePDFSchema;
|
||||
import org.apache.xmpbox.schema.DublinCoreSchema;
|
||||
import org.apache.xmpbox.schema.PDFAIdentificationSchema;
|
||||
import org.apache.xmpbox.schema.XMPBasicSchema;
|
||||
import org.apache.xmpbox.xml.XmpSerializer;
|
||||
|
||||
|
||||
import javax.activation.DataSource;
|
||||
import javax.activation.FileDataSource;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class ZUGFeRDExporterFromA3Factory implements IExporterFactory {
|
||||
protected boolean ignorePDFAErrors = false;
|
||||
@@ -34,13 +22,10 @@ public class ZUGFeRDExporterFromA3Factory implements IExporterFactory {
|
||||
protected PDFAConformanceLevel conformanceLevel = PDFAConformanceLevel.UNICODE;
|
||||
protected String producer = "mustangproject";
|
||||
protected String creator = "mustangproject";
|
||||
protected boolean attachZugferdHeaders = true;
|
||||
|
||||
|
||||
protected PDMetadata metadata = null;
|
||||
protected PDFAIdentificationSchema pdfaid = null;
|
||||
protected XMPMetadata xmp = null;
|
||||
protected int ZFVersion=ZUGFeRDExporter.DefaultZUGFeRDVersion;
|
||||
protected boolean ensurePDFisUpgraded=false;
|
||||
private boolean attachZUGFeRDHeaders=true;
|
||||
/**
|
||||
* Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the
|
||||
* metadata level, this will not e.g. convert graphics to JPG-2000)
|
||||
@@ -53,46 +38,18 @@ public class ZUGFeRDExporterFromA3Factory implements IExporterFactory {
|
||||
ensurePDFIsValidPDFA(new FileDataSource(pdfFilename));
|
||||
ZUGFeRDExporter zugFeRDExporter;
|
||||
PDDocument doc = PDDocument.load(new File(pdfFilename));
|
||||
prepareDocument(doc);
|
||||
zugFeRDExporter = new ZUGFeRDExporter(doc);
|
||||
zugFeRDExporter.setZUGFeRDVersion(ZFVersion);
|
||||
zugFeRDExporter.setZUGFeRDConformanceLevel(zugferdConformanceLevel);
|
||||
zugFeRDExporter.setCreator(creator);
|
||||
zugFeRDExporter.setProducer(producer);
|
||||
zugFeRDExporter.setAttachZUGFeRDHeaders(attachZUGFeRDHeaders);
|
||||
zugFeRDExporter.setPDFA3(ensurePDFisUpgraded);
|
||||
|
||||
return zugFeRDExporter;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void prepareDocument(PDDocument doc) throws IOException {
|
||||
String fullProducer = producer + " (via mustangproject.org " + org.mustangproject.ZUGFeRD.Version.VERSION + ")";
|
||||
|
||||
PDDocumentCatalog cat = doc.getDocumentCatalog();
|
||||
metadata = new PDMetadata(doc);
|
||||
cat.setMetadata(metadata);
|
||||
|
||||
xmp = XMPMetadata.createXMPMetadata();
|
||||
|
||||
pdfaid = new PDFAIdentificationSchema(xmp);
|
||||
|
||||
xmp.addSchema(pdfaid);
|
||||
|
||||
DublinCoreSchema dc = xmp.createAndAddDublinCoreSchema();
|
||||
|
||||
dc.addCreator(creator);
|
||||
|
||||
XMPBasicSchema xsb = xmp.createAndAddXMPBasicSchema();
|
||||
|
||||
xsb.setCreatorTool(creator);
|
||||
xsb.setCreateDate(GregorianCalendar.getInstance());
|
||||
// PDDocumentInformation pdi=doc.getDocumentInformation();
|
||||
PDDocumentInformation pdi = new PDDocumentInformation();
|
||||
pdi.setProducer(fullProducer);
|
||||
pdi.setAuthor(creator);
|
||||
doc.setDocumentInformation(pdi);
|
||||
|
||||
AdobePDFSchema pdf = xmp.createAndAddAdobePDFSchema();
|
||||
pdf.setProducer(fullProducer);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -106,12 +63,21 @@ public class ZUGFeRDExporterFromA3Factory implements IExporterFactory {
|
||||
ensurePDFIsValidPDFA(new ByteArrayDataSource(new ByteArrayInputStream(pdfBinary)));
|
||||
ZUGFeRDExporter zugFeRDExporter;
|
||||
PDDocument doc = PDDocument.load(pdfBinary);
|
||||
prepareDocument(doc);
|
||||
zugFeRDExporter = new ZUGFeRDExporter(doc);
|
||||
zugFeRDExporter.setZUGFeRDVersion(ZFVersion);
|
||||
zugFeRDExporter.setZUGFeRDConformanceLevel(zugferdConformanceLevel);
|
||||
zugFeRDExporter.setCreator(creator);
|
||||
zugFeRDExporter.setProducer(producer);
|
||||
zugFeRDExporter.setAttachZUGFeRDHeaders(attachZUGFeRDHeaders);
|
||||
zugFeRDExporter.setPDFA3(ensurePDFisUpgraded);
|
||||
|
||||
return zugFeRDExporter;
|
||||
}
|
||||
|
||||
public ZUGFeRDExporterFromA3Factory () {
|
||||
|
||||
ensurePDFisUpgraded=false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes A PDF/A3a-compliant document from a PDF-A1 compliant document (on the
|
||||
@@ -135,53 +101,10 @@ public class ZUGFeRDExporterFromA3Factory implements IExporterFactory {
|
||||
IOUtils.copy(in, buffer);
|
||||
return buffer.toByteArray();
|
||||
}
|
||||
|
||||
public byte[] serializeXmpMetadata(XMPMetadata xmpMetadata) throws TransformerException {
|
||||
XmpSerializer serializer = new XmpSerializer();
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
|
||||
String prefix="<?xpacket begin=\"\uFEFF\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>";
|
||||
String suffix="<?xpacket end=\"w\"?>";
|
||||
|
||||
try {
|
||||
buffer.write(prefix.getBytes("UTF-8")); // see https://github.com/ZUGFeRD/mustangproject/issues/44
|
||||
serializer.serialize(xmpMetadata, buffer, false);
|
||||
buffer.write(suffix.getBytes("UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return buffer.toByteArray();
|
||||
}
|
||||
|
||||
private static boolean isValidA1(DataSource dataSource) throws IOException {
|
||||
private static boolean isValidA1(DataSource dataSource) throws IOException {
|
||||
return getPDFAParserValidationResult(new PreflightParser(dataSource));
|
||||
}
|
||||
|
||||
/**
|
||||
* This will add both the RDF-indication which embedded file is Zugferd and the
|
||||
* neccessary PDF/A schema extension description to be able to add this
|
||||
* information to RDF
|
||||
*
|
||||
* @param metadata
|
||||
*/
|
||||
public void addXMP(XMPMetadata metadata) {
|
||||
|
||||
if (attachZugferdHeaders) {
|
||||
XMPSchemaZugferd zf = new XMPSchemaZugferd(metadata, zugferdConformanceLevel, ZUGFeRDExporter.getNamespaceForVersion(ZFVersion), ZUGFeRDExporter.getPrefixForVersion(ZFVersion), ZUGFeRDExporter.getFilenameForVersion(ZFVersion) );
|
||||
|
||||
metadata.addSchema(zf);
|
||||
}
|
||||
|
||||
XMPSchemaPDFAExtensions pdfaex = new XMPSchemaPDFAExtensions(metadata, ZFVersion, attachZugferdHeaders);
|
||||
pdfaex.setZUGFeRDVersion(ZFVersion);
|
||||
metadata.addSchema(pdfaex);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ZUGFeRD conformance level (override).
|
||||
*
|
||||
@@ -246,10 +169,6 @@ public class ZUGFeRDExporterFromA3Factory implements IExporterFactory {
|
||||
return this;
|
||||
}
|
||||
|
||||
public IExporterFactory setAttachZUGFeRDHeaders(final boolean attachZugferdHeaders) {
|
||||
this.attachZugferdHeaders = attachZugferdHeaders;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IExporterFactory setCreator(String creator) {
|
||||
this.creator = creator;
|
||||
@@ -260,6 +179,10 @@ public class ZUGFeRDExporterFromA3Factory implements IExporterFactory {
|
||||
this.producer = producer;
|
||||
return this;
|
||||
}
|
||||
public IExporterFactory setAttachZUGFeRDHeaders(boolean attachHeaders) {
|
||||
this.attachZUGFeRDHeaders = attachHeaders;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user