io.konik.PdfHandler Maven / Gradle / Ivy
/* Copyright (C) 2014 konik.io
*
* This file is part of the Konik library.
*
* The Konik library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* The Konik library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with the Konik library. If not, see .
*/
package io.konik;
import com.google.common.collect.Lists;
import io.konik.csv.pdf.FileAppenderPriorityComparator;
import io.konik.harness.FileAppender;
import io.konik.harness.FileExtractor;
import io.konik.harness.appender.DefaultAppendParameter;
import io.konik.harness.exception.InvoiceAppendError;
import io.konik.zugferd.Invoice;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.io.*;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
import java.util.logging.Logger;
import static io.konik.csv.pdf.FileAppenderPriorityComparator.Order;
import static java.util.logging.Level.WARNING;
/**
* Transforms, appends or extracts invoices to PDFs.
*/
@Named
@Singleton
public class PdfHandler {
private static final Logger LOG = Logger.getLogger(PdfHandler.class.getName());
private final FileAppender fileAppender;
private final FileExtractor fileExtractor;
private final InvoiceTransformer transformer;
/**
* Instantiates a new PDF handler.
*
* @param fileAppender the file appender
* @param fileExtractor the file extractor
* @param transformer the invoice model transformer
*/
@Inject
public PdfHandler(FileAppender fileAppender, FileExtractor fileExtractor, InvoiceTransformer transformer) {
this.fileAppender = fileAppender;
this.fileExtractor = fileExtractor;
this.transformer = transformer;
}
/**
* Instantiates a default invoice transformer using the Service loader to inject an PDF carriage that should be on the classpath.
*
* If error is thrown check you have a Konik PDF Carriage on the classpath.
*/
public PdfHandler() {
Iterator iterator = ServiceLoader.load(FileAppender.class).iterator();
List appenders = Lists.newArrayList(iterator);
if (appenders.isEmpty()) {
throw new IllegalStateException("FileAppender implementation not found in the classpath!");
}
Collections.sort(appenders, new FileAppenderPriorityComparator(Order.DESC));
this.fileAppender = appenders.get(0);
this.fileExtractor = ServiceLoader.load(FileExtractor.class).iterator().next();
this.transformer = new InvoiceTransformer();
}
/**
* Append an invoice to a PDF.
*
* The resulting Pdf Output is based on the input PDF, but might be converted to PDF/A-3 when needed.
*
* @param invoice that should be attached to the pdf.
* @param inputPdf to witch we are going to append the invoice to, input will not be modified
* @param resultingPdf is the modified copy of the input PDF with the invoice.
*/
public void appendInvoice(final Invoice invoice, final InputStream inputPdf, final OutputStream resultingPdf) {
try {
append(invoice, inputPdf, resultingPdf);
} catch (IOException e) {
throw new InvoiceAppendError("Not able to append invoice to PDF", e);
}
}
private void append(final Invoice invoice, final InputStream inputPdf, final OutputStream resultingPdf) throws IOException {
PipedOutputStream pipedOutputStream = new PipedOutputStream();
PipedInputStream pipedInputStream = new PipedInputStream(pipedOutputStream, 65536);
try {
String version = invoice.getContext().getGuideline().getVersion().versionAlt();
String confomanceLevel = invoice.getContext().getGuideline().getConformanceLevel().name();
transformer.fromModelAsync(invoice, pipedOutputStream);
DefaultAppendParameter parameter = new DefaultAppendParameter(inputPdf, pipedInputStream, resultingPdf,
version, confomanceLevel);
fileAppender.append(parameter);
} finally {
pipedInputStream.close();
}
}
/**
* Extract invoice from given pdf file
*
* @param pdfFile the pdf file containing the ZUGFeRD XML File
* @return the transformed ZUGFeRD invoice
* @throws FileNotFoundException if the pdf is not found
*/
public Invoice extractInvoice(File pdfFile) throws FileNotFoundException {
byte[] xmlInvoice = fileExtractor.extract(new FileInputStream(pdfFile));
return transformer.toModel(new ByteArrayInputStream(xmlInvoice));
}
/**
* Extract invoice from given pdf stream
*
* @param pdfInputStream the pdf input stream
* @return the transformed ZUGFeRD invoice
*/
public Invoice extractInvoice(InputStream pdfInputStream) {
InputStream invoiceInputStream = fileExtractor.extractToStream(pdfInputStream);
Invoice invoiceModel = transformer.toModel(invoiceInputStream);
closeQuietly(invoiceInputStream);
return invoiceModel;
}
private static void closeQuietly(InputStream stream) {
try {
if (stream != null) {
stream.close();
}
}catch(IOException e) {
LOG.log(WARNING, "Could not close InputStream. This can be a memory leak as the PDF might still be open.", e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy