diff --git a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2Exporter.java b/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2Exporter.java
deleted file mode 100644
index 72c348f2..00000000
--- a/src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRD2Exporter.java
+++ /dev/null
@@ -1,698 +0,0 @@
-package org.mustangproject.ZUGFeRD;
-/**
- * Mustangproject's ZUGFeRD implementation
- * ZUGFeRD exporter
- * Licensed under the APLv2
- * @date 2014-07-12
- * @version 1.1
- * @author jstaerk
- * */
-
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.text.SimpleDateFormat;
-import java.util.Arrays;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.xml.transform.TransformerException;
-
-import org.apache.pdfbox.cos.COSArray;
-import org.apache.pdfbox.cos.COSBase;
-import org.apache.pdfbox.cos.COSDictionary;
-import org.apache.pdfbox.cos.COSName;
-import org.apache.pdfbox.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.COSObjectable;
-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;
-
-
-
-public class ZUGFeRD2Exporter {
- /***
- * You will need Apache PDFBox. To use the ZUGFeRD exporter,
- implement IZUGFeRDExportableTransaction in yourTransaction
- (which will require you to implement Product, Item and Contact)
- then call
- doc = PDDocument.load(PDFfilename);
- // automatically add Zugferd to all outgoing invoices
- ZUGFeRDExporter ze = new ZUGFeRDExporter();
- ze.PDFmakeA3compliant(doc, "Your application name",
- System.getProperty("user.name"), true);
- ze.PDFattachZugferdFile(doc, yourTransaction);
-
- doc.save(PDFfilename);
-
- * @author jstaerk
- *
- */
-
-
-
- private class LineCalc {
- private IZUGFeRDExportableItem currentItem=null;
- private BigDecimal totalGross;
- private BigDecimal itemTotalNetAmount;
- private BigDecimal itemTotalVATAmount;
-
- public LineCalc(IZUGFeRDExportableItem currentItem) {
- this.currentItem=currentItem;
- BigDecimal multiplicator=currentItem.getProduct().getVATPercent().divide(new BigDecimal(100)).add(new BigDecimal(1));
-// priceGross=currentItem.getPrice().multiply(multiplicator);
- totalGross=currentItem.getPrice().multiply(multiplicator).multiply(currentItem.getQuantity());
- itemTotalNetAmount=currentItem.getQuantity().multiply(currentItem.getPrice()).setScale(2,BigDecimal.ROUND_HALF_UP);
- itemTotalVATAmount=totalGross.subtract(itemTotalNetAmount);
- }
-
- public BigDecimal getItemTotalNetAmount() {
- return itemTotalNetAmount;
- }
-
- public BigDecimal getItemTotalVATAmount() {
- return itemTotalVATAmount;
- }
-
- }
-
-
-
- //// MAIN CLASS
-
- private String conformanceLevel = "U";
- private String versionStr = "1.2.0";
-
- // BASIC, COMFORT etc - may be set from outside.
- private String ZUGFeRDConformanceLevel = null;
-
-
- /**
- * Data (XML invoice) to be added to the ZUGFeRD PDF. It may be externally set, in which case passing a
- * IZUGFeRDExportableTransaction is not necessary. By default it is null meaning the caller needs to
- * pass a IZUGFeRDExportableTransaction for the XML to be populated.
- */
- byte[] zugferdData = null;
- private boolean isTest;
- IZUGFeRDExportableTransaction trans=null;
-
-
- private String nDigitFormat(BigDecimal value, int scale) {
- /*
- * I needed 123,45, locale independent.I tried
- * NumberFormat.getCurrencyInstance().format( 12345.6789 ); but that is
- * locale specific.I also tried DecimalFormat df = new DecimalFormat(
- * "0,00" ); df.setDecimalSeparatorAlwaysShown(true);
- * df.setGroupingUsed(false); DecimalFormatSymbols symbols = new
- * DecimalFormatSymbols(); symbols.setDecimalSeparator(',');
- * symbols.setGroupingSeparator(' ');
- * df.setDecimalFormatSymbols(symbols);
- *
- * but that would not switch off grouping. Although I liked very much
- * the (incomplete) "BNF diagram" in
- * http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html
- * in the end I decided to calculate myself and take eur+sparator+cents
- *
- * This function will cut off, i.e. floor() subcent values Tests:
- * System.err.println(utils.currencyFormat(new BigDecimal(0),
- * ".")+"\n"+utils.currencyFormat(new BigDecimal("-1.10"),
- * ",")+"\n"+utils.currencyFormat(new BigDecimal("-1.1"),
- * ",")+"\n"+utils.currencyFormat(new BigDecimal("-1.01"),
- * ",")+"\n"+utils.currencyFormat(new BigDecimal("20000123.3489"),
- * ",")+"\n"+utils.currencyFormat(new BigDecimal("20000123.3419"),
- * ",")+"\n"+utils.currencyFormat(new BigDecimal("12"), ","));
- *
- * results 0.00 -1,10 -1,10 -1,01 20000123,34 20000123,34 12,00
- */
- value=value.setScale( scale, BigDecimal.ROUND_HALF_UP ); // first, round so that e.g. 1.189999999999999946709294817992486059665679931640625 becomes 1.19
- char[] repeat = new char[scale];
- Arrays.fill(repeat, '0');
-
- DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols();
- otherSymbols.setDecimalSeparator('.');
- DecimalFormat dec = new DecimalFormat("0."+new String(repeat), otherSymbols);
- return dec.format(value);
-
- }
-
- private String vatFormat(BigDecimal value) {
- return nDigitFormat(value, 2);
- }
-
- private String currencyFormat(BigDecimal value) {
- return nDigitFormat(value, 2);
- }
-
- private String priceFormat(BigDecimal value) {
- return nDigitFormat(value, 4);
- }
- private String quantityFormat(BigDecimal value) {
- return nDigitFormat(value, 4);
- }
-
- /**
- All files are PDF/A-3, setConformance refers to the level conformance.
-
- PDF/A-3 has three coformance levels, called "A", "U" and "B".
-
- PDF/A-3-B where B means only visually
- preservable, U -standard for Mustang- means visually and unicode
- preservable and A means full compliance, i.e. visually,
- unicode and structurally preservable and tagged PDF, i.e. useful metainformation for blind people.
-
- Feel free to pass "A" as new level if you know what you are doing :-)
-
-
- */
- public void setConformanceLevel(String newLevel) {
- conformanceLevel=newLevel;
- }
-
- /**
- * enables the flag to indicate a test invoice in the XML structure
- * */
- public void setTest() {
- isTest=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)
- * */
- public PDDocumentCatalog PDFmakeA3compliant(PDDocument doc, String producer, String creator,
- boolean attachZugferdHeaders) throws IOException,
- TransformerException {
- String fullProducer=producer + " (via mustangproject.org " + versionStr + ")";
- PDDocumentCatalog cat = doc.getDocumentCatalog();
- PDMetadata metadata = new PDMetadata(doc);
- cat.setMetadata(metadata);
- // we're using the jempbox org.apache.jempbox.xmp.XMPMetadata version,
- // not the xmpbox one
- XMPMetadata xmp = new XMPMetadata();
-
- XMPSchemaPDFAId pdfaid = new XMPSchemaPDFAId(xmp);
- pdfaid.setAbout(""); //$NON-NLS-1$
- xmp.addSchema(pdfaid);
-
- XMPSchemaDublinCore dc = xmp.addDublinCoreSchema();
- dc.addCreator(creator);
- dc.setAbout(""); //$NON-NLS-1$
-
- XMPSchemaBasic xsb = xmp.addBasicSchema();
- xsb.setAbout(""); //$NON-NLS-1$
-
- xsb.setCreatorTool(creator);
- xsb.setCreateDate(GregorianCalendar.getInstance());
- // PDDocumentInformation pdi=doc.getDocumentInformation();
- PDDocumentInformation pdi = new PDDocumentInformation();
- pdi.setProducer(fullProducer);
- pdi.setAuthor(creator);
- doc.setDocumentInformation(pdi);
-
- XMPSchemaPDF pdf = xmp.addPDFSchema();
- pdf.setProducer(fullProducer);
- pdf.setAbout(""); //$NON-NLS-1$
-
- /*
- // 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.
-
- * */
- pdfaid.setConformance(conformanceLevel);//$NON-NLS-1$ //$NON-NLS-1$
-
- pdfaid.setPart(3);
-
- if (attachZugferdHeaders) {
- addZugferdXMP(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
- */
- }
-
- metadata.importXMPMetadata(xmp);
- return cat;
- }
-
- private String getZugferdXMLForTransaction(IZUGFeRDExportableTransaction trans) {
- this.trans=trans;
-
- SimpleDateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); //$NON-NLS-1$
- SimpleDateFormat zugferdDateFormat = new SimpleDateFormat("yyyyMMdd"); //$NON-NLS-1$
- String testBooleanStr="false";
- if (isTest) {
- testBooleanStr="true";
-
- }
- String senderReg="";
- if (trans.getOwnOrganisationFullPlaintextInfo()!=null) {
- senderReg=""
- + "\n"
- + " \n"
- + trans.getOwnOrganisationFullPlaintextInfo()
- + " \n"
- + "REG\n"
- + "\n";
-
- }
- String xml= "\n" //$NON-NLS-1$
-
- + "\n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " urn:ferd:CrossIndustryDocument:invoice:1p0:comfort\n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " "+trans.getNumber()+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " RECHNUNG\n" //$NON-NLS-1$
- + " 380\n" //$NON-NLS-1$
- + " "+zugferdDateFormat.format(trans.getIssueDate())+"\n" //date format was 20130605 //$NON-NLS-1$ //$NON-NLS-2$
- + senderReg
-// + " \n"
-// + " \n"
-// + "Rechnung gemäß Bestellung Nr. 2013-471331 vom 01.03.2013.\n"
-// + "\n"
-// + " \n"
-// + " \n"
-// + " \n"
-// + " \n"
-// + "Es bestehen Rabatt- und Bonusvereinbarungen.\n"
-// + " \n"
-// + " AAK\n"
-// + " \n"
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
-// + " AB-312\n"
- + " \n" //$NON-NLS-1$
-// + " 4000001123452\n"
- + " "+trans.getOwnOrganisationName()+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " \n"
- + " "+trans.getOwnZIP()+"\n"
- + " "+trans.getOwnStreet()+"\n"
- + " "+trans.getOwnLocation()+"\n"
- + " "+trans.getOwnCountry()+"\n"
- + " \n"
- + " \n" //$NON-NLS-1$
- + " "+trans.getOwnTaxID()+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " "+trans.getOwnVATID()+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
-// + " GE2020211\n"
-// + " 4000001987658\n"
- + " "+trans.getRecipient().getName()+"\n" //$NON-NLS-1$ //$NON-NLS-2$
-// + " \n"
-// + " xxx\n"
-// + " \n"
- + " \n" //$NON-NLS-1$
- + " "+trans.getRecipient().getZIP()+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " "+trans.getRecipient().getStreet()+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " "+trans.getRecipient().getLocation()+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " "+trans.getRecipient().getCountry()+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " "+trans.getRecipient().getVATID()+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
-// + " \n"
-// + " 20130301\n"
-// + " 2013-471331\n"
-// + " \n"
- + " \n" //$NON-NLS-1$
- + " \n"
- + " \n"
- + " "+zugferdDateFormat.format(trans.getDeliveryDate())+"\n"
- + " \n"
- /*
- + " \n"
- + " 20130603\n"
- + " 2013-51112\n"
- + " \n" */
- + " \n"
- + " \n" //$NON-NLS-1$
- + " "+trans.getNumber()+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " EUR\n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " 42\n" //$NON-NLS-1$
- + " Überweisung\n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " "+trans.getOwnIBAN()+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " "+trans.getOwnBIC()+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " "+trans.getOwnBankName()+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " \n" //$NON-NLS-1$
- + " \n"; //$NON-NLS-1$
-
-
-
- HashMap VATPercentAmountMap=getVATPercentAmountMap();
- for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) {
- VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
- if (amount != null) {
- xml += " \n" //$NON-NLS-1$
- + " "+currencyFormat(amount.getCalculated())+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " VAT\n" //$NON-NLS-1$
- + " "+currencyFormat(amount.getBasis())+"\n"
- + " S\n" //$NON-NLS-1$
- + " "+vatFormat(currentTaxPercent)+"\n" //$NON-NLS-1$
- + " \n"; //$NON-NLS-1$
-
-
-
- }
- }
-/* xml+= "
- + " \n"
- + " false\n"
- + " 10\n"
- + " 1.00\n"
- + " Sondernachlass\n"
- + " \n"
- + " VAT\n"
- + " S\n"
- + " 19\n"
- + " \n"
- + " \n"
- + " \n"
- + " false\n"
- + " 137.30\n"
- + " 13.73\n"
- + " Sondernachlass\n"
- + " \n"
- + " VAT\n"
- + " S\n"
- + " 7\n"
- + " \n"
- + " \n"
- + " \n"
- + " Versandkosten\n"
- + " 5.80\n"
- + " \n"
- + " VAT\n"
- + " S\n"
- + " 7\n"
- + " \n"
- + " \n"*/
-
- xml=xml+ " \n" //$NON-NLS-1$
- + " Zahlbar ohne Abzug bis "+germanDateFormat.format(trans.getDueDate())+"\n"
- + " "+zugferdDateFormat.format(trans.getDueDate())+"\n"//20130704 //$NON-NLS-1$ //$NON-NLS-2$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " "+currencyFormat(getTotal())+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " 0.00\n" //$NON-NLS-1$
- + " 0.00\n" //$NON-NLS-1$
-// + " 5.80\n"
-// + " 14.73\n"
- + " "+currencyFormat(getTotal())+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " "+currencyFormat(getTotalGross().subtract(getTotal()))+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " "+currencyFormat(getTotalGross())+"\n" //$NON-NLS-1$ //$NON-NLS-2$
-// + " 0.00\n"
- + " "+currencyFormat(getTotalGross())+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " \n" //$NON-NLS-1$
- + " \n"; //$NON-NLS-1$
-// + " \n"
-// + " \n"
-// + " \n"
-// + " Wir erlauben uns Ihnen folgende Positionen aus der Lieferung Nr. 2013-51112 in Rechnung zu stellen:\n"
-// + " \n"
-// + " \n"
-// + " \n";
-
-
- int lineID=0;
- for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
- lineID++;
-
- LineCalc lc=new LineCalc(currentItem);
- xml=xml+ " \n"+ //$NON-NLS-1$
- " \n" //$NON-NLS-1$
- + " "+lineID+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " \n" //$NON-NLS-1$
-
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " "+priceFormat(currentItem.getPrice())+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " 1.0000\n" //$NON-NLS-1$ //$NON-NLS-2$
-// + " \n"
-// + " false\n"
-// + " 0.6667\n"
-// + " Rabatt\n"
-// + " \n"
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " "+priceFormat(currentItem.getPrice())+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " 1.0000\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
-
- + " \n" //$NON-NLS-1$
- + " "+quantityFormat(currentItem.getQuantity())+"\n" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " VAT\n" //$NON-NLS-1$
- + " S\n" //$NON-NLS-1$
- + " "+vatFormat(currentItem.getProduct().getVATPercent())+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " "+currencyFormat(lc.getItemTotalNetAmount())+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
- + " \n" //$NON-NLS-1$
-// + " 4012345001235\n"
-// + " KR3M\n"
-// + " 55T01\n"
- + " "+currentItem.getProduct().getName()+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " "+currentItem.getProduct().getDescription()+"\n" //$NON-NLS-1$ //$NON-NLS-2$
- + " \n" //$NON-NLS-1$
- + " \n"; //$NON-NLS-1$
-
-
-
- }
-
-
- xml=xml + " \n" //$NON-NLS-1$
- + ""; //$NON-NLS-1$
- return xml;
- }
-
-
- private BigDecimal getTotalGross() {
-
- BigDecimal res=getTotal();
- HashMap VATPercentAmountMap=getVATPercentAmountMap();
- for (BigDecimal currentTaxPercent : VATPercentAmountMap.keySet()) {
- VATAmount amount = VATPercentAmountMap.get(currentTaxPercent);
- res=res.add(amount.getCalculated());
- }
-
-
- return res;
- }
-
- private BigDecimal getTotal() {
- BigDecimal res=new BigDecimal(0);
- for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
- LineCalc lc=new LineCalc(currentItem);
- res=res.add(lc.getItemTotalNetAmount());
- }
- return res;
- }
-
- /**
- * which taxes have been used with which amounts in this transaction,
- * empty for no taxes, or e.g. 19=>190 and 7=>14 if 1000 Eur were applicable
- * to 19% VAT (=>190 EUR VAT) and 200 EUR were applicable to 7% (=>14 EUR VAT)
- * 190 Eur
- * @return
- *
- */
- private HashMap getVATPercentAmountMap() {
- HashMap hm=new HashMap ();
-
- for (IZUGFeRDExportableItem currentItem : trans.getZFItems()) {
- BigDecimal percent=currentItem.getProduct().getVATPercent();
- LineCalc lc=new LineCalc(currentItem);
- VATAmount itemVATAmount=new VATAmount(lc.getItemTotalNetAmount(), lc.getItemTotalVATAmount() ) ;
- VATAmount current=hm.get(percent);
- if (current==null) {
- hm.put(percent, itemVATAmount);
- } else {
- hm.put(percent, current.add(itemVATAmount));
-
- }
- }
-
- return hm;
- }
-
- /**
- * Embeds the Zugferd XML structure in a file named ZUGFeRD-invoice.xml.
- *
- * @param doc PDDocument to attach an XML invoice to
- * @param trans a IZUGFeRDExportableTransaction that provides the data-model to populate the XML.
- * This parameter may be null, if so the XML data should hav ebeen set via setZUGFeRDXMLData(byte[] zugferdData)
- */
- public void PDFattachZugferdFile(PDDocument doc, IZUGFeRDExportableTransaction trans) throws IOException {
-
- if (zugferdData == null) // XML ZUGFeRD data not set externally, needs to be built
- {
- // create a dummy file stream, this would probably normally be a
- // FileInputStream
-
- byte[] zugferdRaw = getZugferdXMLForTransaction(trans).getBytes("UTF-8"); //$NON-NLS-1$
-
- 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];
- System.arraycopy(zugferdRaw,3,zugferdData,0,zugferdRaw.length-3);
- } else {
- zugferdData=zugferdRaw;
- }
- }
-
-
- PDFAttachGenericFile(doc, "ZUGFeRD-invoice.xml", "Alternative", "Invoice metadata conforming to ZUGFeRD standard (http://www.ferd-net.de/front_content.php?idcat=231&lang=4)", "text/xml", zugferdData);
- }
-
-
- /**
- * Embeds an external file (generic - any type allowed) in the PDF.
- *
- * @param doc PDDocument to attach the file to.
- * @param filename name of the file that will become attachment name in the PDF
- * @param relationship how the file relates to the content, e.g. "Alternative"
- * @param description Human-readable description of the file content
- * @param subType type of the data e.g. could be "text/xml" - mime like
- * @param data the binary data of the file/attachment
- */
- public void PDFAttachGenericFile(PDDocument doc, String filename, String relationship, String description, String subType, byte[] data)
- throws IOException
- {
- PDComplexFileSpecification fs = new PDComplexFileSpecification();
- fs.setFile(filename);
-
- COSDictionary dict = fs.getCOSDictionary();
- dict.setName("AFRelationship", relationship);
- dict.setString("UF", filename);
- dict.setString("Desc", description);
-
- ByteArrayInputStream fakeFile = new ByteArrayInputStream(data);
- PDEmbeddedFile ef = new PDEmbeddedFile(doc, fakeFile);
- ef.setSubtype(subType);
- ef.setSize(data.length);
- ef.setCreationDate(new GregorianCalendar());
-
- ef.setModDate(GregorianCalendar.getInstance());
-
- fs.setEmbeddedFile(ef);
-
- // In addition make sure the embedded file is set under /UF
- dict = fs.getCOSDictionary();
- COSDictionary efDict = (COSDictionary)dict.getDictionaryObject(COSName.EF);
- COSBase lowerLevelFile = efDict.getItem(COSName.F);
- efDict.setItem(COSName.UF, lowerLevelFile);
-
- // now add the entry to the embedded file tree and set in the document.
- PDDocumentNameDictionary names = new PDDocumentNameDictionary(doc.getDocumentCatalog());
- PDEmbeddedFilesNameTreeNode efTree = names.getEmbeddedFiles();
- if (efTree == null)
- {
- efTree = new PDEmbeddedFilesNameTreeNode();
- }
-
- Map namesMap = new HashMap();
- Map oldNamesMap = efTree.getNames();
- if (oldNamesMap != null)
- {
- for (String key : oldNamesMap.keySet())
- {
- namesMap.put(key, oldNamesMap.get(key));
- }
- }
- namesMap.put(filename, fs);
- efTree.setNames(namesMap);
-
- names.setEmbeddedFiles(efTree);
- doc.getDocumentCatalog().setNames(names);
-
- // AF entry (Array) in catalog with the FileSpec
- COSArray cosArray = (COSArray)doc.getDocumentCatalog().getCOSDictionary().getItem("AF");
- if (cosArray == null)
- {
- cosArray = new COSArray();
- }
- cosArray.add(fs);
- doc.getDocumentCatalog().getCOSDictionary().setItem("AF", cosArray);
- }
-
-
- /**
- * Sets the ZUGFeRD XML data to be attached as a single byte array. This is useful for
- * use-cases where the XML has already been produced by some external API or component.
- *
- * @param zugferdData XML data to be set as a byte array (XML file in raw form).
- */
- public void setZUGFeRDXMLData(byte[] zugferdData)
- {
- this.zugferdData = zugferdData;
- }
-
-
- /**
- * Sets the ZUGFeRD conformance level (override).
- *
- * @param ZUGFeRDConformanceLevel the new conformance level
- */
- public void setZUGFeRDConformanceLevel(String ZUGFeRDConformanceLevel)
- {
- this.ZUGFeRDConformanceLevel = ZUGFeRDConformanceLevel;
- }
-
-/***
- * 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
- */
- private void addZugferdXMP(XMPMetadata metadata) {
-
- XMPSchemaZugferd zf = new XMPSchemaZugferd(metadata, this.ZUGFeRDConformanceLevel);
- zf.setAbout(""); //$NON-NLS-1$
- metadata.addSchema(zf);
-
- XMPSchemaPDFAExtensions pdfaex = new XMPSchemaPDFAExtensions(metadata);
- pdfaex.setAbout(""); //$NON-NLS-1$
- metadata.addSchema(pdfaex);
-
- }
-
-}