org.jrimum.bopepo.pdf.PdfDocMix Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bpp-cobranca Show documentation
Show all versions of bpp-cobranca Show documentation
This is a fork and merge from JRimum ( http://www.jrimum.org ),
- Bopepo: https://github.com/jrimum/bopepo
- Texgit: https://github.com/jrimum/texgit
- Valia: https://github.com/jrimum/vallia
- Utilix: https://github.com/jrimum/utilix
- Domkee: https://github.com/jrimum/domkee
For Brazillian Boleto Payment Method. So much thanks for original authors:
Gilmar P. S. L, Misael Barreto and Rômulo Augusto.
The newest version!
/*
* Copyright 2011 JRimum Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
* applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*
* Created at: 14/04/2011 - 14:49:07
*
* ================================================================================
*
* Direitos autorais 2011 JRimum Project
*
* Licenciado sob a Licença Apache, Versão 2.0 ("LICENÇA"); você não pode usar
* esse arquivo exceto em conformidade com a esta LICENÇA. Você pode obter uma
* cópia desta LICENÇA em http://www.apache.org/licenses/LICENSE-2.0 A menos que
* haja exigência legal ou acordo por escrito, a distribuição de software sob
* esta LICENÇA se dará “COMO ESTÁ”, SEM GARANTIAS OU CONDIÇÕES DE QUALQUER
* TIPO, sejam expressas ou tácitas. Veja a LICENÇA para a redação específica a
* reger permissões e limitações sob esta LICENÇA.
*
* Criado em: 14/04/2011 - 14:49:07
*
*/
package org.jrimum.bopepo.pdf;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfBoolean;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.jrimum.utilix.Collections.hasElement;
import static org.jrimum.utilix.Objects.checkNotNull;
import static org.jrimum.utilix.Objects.isNotNull;
import static org.jrimum.utilix.Objects.isNull;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.net.URL;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.WeakHashMap;
import org.apache.log4j.Logger;
import org.jrimum.utilix.Collections;
import org.jrimum.utilix.Exceptions;
import org.jrimum.utilix.Objects;
import org.jrimum.utilix.Strings;
/**
* Classe geradora de documentos PDF utilizando templates com fields.
*
* @author Gilmar P.S.L.
* @author Rômulo Augusto
*
* @version 0.2.3
*
* @since 0.2
*/
public class PdfDocMix {
private static final Logger LOG = Logger.getLogger(PdfDocMix.class);
private PdfReader reader;
private PdfStamper stamper;
private AcroFields form;
private ByteArrayOutputStream outputStream;
private Map imagesInUseMap = new WeakHashMap();
/**
* Template em byte array.
*/
private byte[] template;
/**
* Informações sobre o documento.
*/
private PdfDocInfo docInfo = PdfDocInfo.create();
/**
* Map dos campos de texto do documento com nome e valor.
*/
private Map txtMap;
/**
* Map dos campos de imagem do documento com nome e valor.
*/
private Map imgMap;
/**
* Modo full compression do PDF, default = true.
*
* @since 0.2
*/
private boolean fullCompression = true;
/**
* Remove todos os campos do PDF, default = true.
*
* @since 0.2
*/
private boolean removeFields = true;
/**
* Indicação de que o título do documento deve ser mostrado barra superior.
*
* @since 0.2
*/
private Boolean displayDocTitle;
/**
* Cria uma instância sem o template que será utilizado para construir o
* documento.
*
* @since 0.2
*/
private PdfDocMix() {
}
/**
* Cria uma instância com o template que será utilizado para construir o
* documento.
*
* @param template
*
* @since 0.2
*
* @throws IllegalArgumentException Caso o {@code template} seja nulo
*/
public PdfDocMix(byte[] template) {
checkTemplateFile(template);
setTemplate(template);
}
/**
* Cria uma instância com o template que será utilizado para construir o
* documento.
*
* @param templateUrl
*
* @since 0.2
*
* @throws IllegalArgumentException Caso o {@code template} seja nulo
*/
public PdfDocMix(URL templateUrl) {
checkTemplateFile(templateUrl);
setTemplate(templateUrl);
}
/**
* Cria uma instância com o template que será utilizado para construir o
* documento.
*
* @param templateInput
*
* @since 0.2
*
* @throws IllegalArgumentException Caso o {@code template} seja nulo
*/
public PdfDocMix(InputStream templateInput) {
checkTemplateFile(templateInput);
setTemplate(templateInput);
}
/**
* Cria uma instância com o template que será utilizado para construir o
* documento.
*
* @param templatePath
*
* @since 0.2
*
* @throws IllegalArgumentException Caso o {@code template} seja nulo
*/
public PdfDocMix(String templatePath) {
checkTemplatePath(templatePath);
setTemplate(templatePath);
}
/**
* Cria uma instância com o template que será utilizado para construir o
* documento.
*
* @param templateFile
*
* @since 0.2
*
* @throws IllegalArgumentException Caso o {@code template} seja nulo
*/
public PdfDocMix(File templateFile) {
checkTemplateFile(templateFile);
setTemplate(templateFile);
}
/**
* Cria uma instância sem o template que será utilizado para construir o
* documento.
*
* @since 0.2
*
* @return Esta instância após a operação
*/
public static PdfDocMix create() {
return new PdfDocMix();
}
/**
* Cria uma instância com o template que será utilizado para construir o
* documento.
*
* @param template
*
* @since 0.2
*
* @return Esta instância após a operação
*
* @throws IllegalArgumentException Caso o {@code template} seja nulo
*/
public static PdfDocMix createWithTemplate(byte[] template) {
checkTemplateFile(template);
return new PdfDocMix(template);
}
/**
* Cria uma instância com o template que será utilizado para construir o
* documento.
*
* @param templateUrl
*
* @since 0.2
*
* @return Esta instância após a operação
*
* @throws IllegalArgumentException Caso o {@code template} seja nulo
*/
public static PdfDocMix createWithTemplate(URL templateUrl) {
checkTemplateFile(templateUrl);
return new PdfDocMix(templateUrl);
}
/**
* Cria uma instância com o template que será utilizado para construir o
* documento.
*
* @param templateInput
*
* @since 0.2
*
* @return Esta instância após a operação
*
* @throws IllegalArgumentException Caso o {@code template} seja nulo
*/
public static PdfDocMix createWithTemplate(InputStream templateInput) {
checkTemplateFile(templateInput);
return new PdfDocMix(templateInput);
}
/**
* Cria uma instância com o template que será utilizado para construir o
* documento.
*
* @param templatePath
*
* @since 0.2
*
* @return Esta instância após a operação
*
* @throws IllegalArgumentException Caso o {@code template} seja nulo
*/
public static PdfDocMix createWithTemplate(String templatePath) {
checkTemplatePath(templatePath);
return new PdfDocMix(templatePath);
}
/**
* Cria uma instância com o template que será utilizado para construir o
* documento.
*
* @param templateFile
*
* @since 0.2
*
* @return Esta instância após a operação
*
* @throws IllegalArgumentException Caso o {@code template} seja nulo
*/
public static PdfDocMix createWithTemplate(File templateFile) {
checkTemplateFile(templateFile);
return new PdfDocMix(templateFile);
}
/**
* Define o template que será utilizado para construir o documento.
*
* @param template
*
* @since 0.2
*
* @return Esta instância após a operação
*
* @throws IllegalArgumentException Caso o {@code template} seja nulo
*/
public PdfDocMix withTemplate(byte[] template) {
checkTemplateFile(template);
return setTemplate(template);
}
/**
* Define o template que será utilizado para construir o documento.
*
* @param templateUrl
*
* @since 0.2
*
* @return Esta instância após a operação
*
* @throws IllegalArgumentException Caso o {@code template} seja nulo
*/
public PdfDocMix withTemplate(URL templateUrl) {
checkTemplateFile(templateUrl);
return setTemplate(templateUrl);
}
/**
* Define o template que será utilizado para construir o documento.
*
* @param templateInput
*
* @since 0.2
*
* @return Esta instância após a operação
*
* @throws IllegalArgumentException Caso o {@code template} seja nulo
*/
public PdfDocMix withTemplate(InputStream templateInput) {
checkTemplateFile(templateInput);
return setTemplate(templateInput);
}
/**
* Define o template que será utilizado para construir o documento.
*
* @param templatePath
*
* @since 0.2
*
* @return Esta instância após a operação
*
* @throws IllegalArgumentException Caso o {@code template} seja nulo
*/
public PdfDocMix withTemplate(String templatePath) {
checkTemplatePath(templatePath);
return setTemplate(templatePath);
}
/**
* Define o template que será utilizado para construir o documento.
*
* @param templateFile
*
* @since 0.2
*
* @return Esta instância após a operação
*
* @throws IllegalArgumentException Caso o {@code template} seja nulo
*/
public PdfDocMix withTemplate(File templateFile) {
checkTemplateFile(templateFile);
return setTemplate(templateFile);
}
/**
* Retorna um {@code Map} com os campos e seus respectivos textos
* adicionados nessa instância.
*
* @return Map de campo,texto
*
* @since 0.2
*/
public Map getTextFields() {
return this.txtMap;
}
/**
* Coloca todos chave-valor na instância, caso uma chave existe o valor será
* substituído. Caso a instância não contenha valores ainda, atribui o
* {@code Map} informado para uso no preenchimento de campos de Texto na
* instância.
*
* @param txtMap Map com os campos(key) e textos(value)
* @return Esta instância após a operação
*
* @since 0.2
*/
public PdfDocMix putAllTexts(Map txtMap) {
Collections.checkNotEmpty(txtMap, "Campos ausentes!");
if (isNull(this.txtMap)) {
this.txtMap = txtMap;
} else {
this.txtMap.putAll(txtMap);
}
return this;
}
/**
* Coloca um par {@code key,value} para uso no preenchimento de campos de
* Texto na instância.
*
* @param name Nome do campo
* @param value Valor em texto do campo
*
* @return Esta instância após a operação
*
* @since 0.2
*/
public PdfDocMix put(String name, String value) {
Strings.checkNotBlank(name, "Nome do campo ausente!");
if (isNull(txtMap)) {
this.txtMap = new WeakHashMap();
}
this.txtMap.put(name, value);
return this;
}
/**
* Retorna um {@code Map} com os campos e suas respectivas imagens
* adicionadas nessa instância.
*
* @return Map de campo,imagem
*
* @since 0.2
*/
public Map getImageFields() {
return this.imgMap;
}
/**
* Coloca todos chave-valor na instância, caso uma chave existe o valor será
* substituído. Caso a instância não contenha valores ainda, atribui o
* {@code Map} informado para uso no preenchimento de campos de Imagem na
* instância.
*
* @param imgMap Map com os campos(key) e imagens(value)
* @return Esta instância após a operação
*
* @since 0.2
*/
public PdfDocMix putAllImages(Map imgMap) {
Collections.checkNotEmpty(imgMap, "Campos ausentes!");
if (isNull(this.imgMap)) {
this.imgMap = imgMap;
} else {
this.imgMap.putAll(imgMap);
}
return this;
}
/**
* Coloca um par {@code key,value} para uso no preenchimento de campos de
* Imagem na instância.
*
* @param name Nome do campo
* @param value Valor em {@link java.awt.Image} do campo
*
* @return Esta instância após a operação
*
* @since 0.2
*/
public PdfDocMix put(String name, java.awt.Image value) {
Strings.checkNotBlank(name, "Nome do campo ausente!");
if (isNull(imgMap)) {
this.imgMap = new WeakHashMap();
}
this.imgMap.put(name, value);
return this;
}
/**
* Habilita/Desabilita o modo full compression do PDF veja
* {@link com.lowagie.text.pdf.PdfStamper#setFullCompression()}.
*
*
* Itext doc: Sets the document's compression to the new 1.5 mode with
* object streams and xref streams.
*
*
* @param option Escolha de compressão
*
* @return Esta instância após a operação
*
* @since 0.2
*
*/
public PdfDocMix withFullCompression(boolean option) {
this.fullCompression = option;
return this;
}
/**
* Habilita/Desabilita a remoção dos campos do PDF.
*
*
* Por padrão os campos são removidos, ou seja, default = true.
*
*
* @param option Escolha por remoção
*
* @return Esta instância após a operação
*
* @since 0.2
*
*/
public PdfDocMix removeFields(boolean option) {
this.removeFields = option;
return this;
}
/**
* Define o Título do documento.
*
* @param title
*
* @return Esta instância após a operação
*/
public PdfDocMix withTitle(String title) {
docInfo.title(title);
return this;
}
/**
* Define o Autor do documento.
*
* @param author
*
* @return Esta instância após a operação
*/
public PdfDocMix withAuthor(String author) {
docInfo.author(author);
return this;
}
/**
* Define o Assunto do documento.
*
* @param subject
*
* @return Esta instância após a operação
*/
public PdfDocMix withSubject(String subject) {
docInfo.subject(subject);
return this;
}
/**
* Define as Palavras-chave do documento.
*
* @param keywords
*
* @return Esta instância após a operação
*/
public PdfDocMix withKeywords(String keywords) {
docInfo.keywords(keywords);
return this;
}
/**
* Define o Software/Ferramenta de criação do documento.
*
* @param creator
*
* @return Esta instância após a operação
*/
public PdfDocMix withCreator(String creator) {
docInfo.creator(creator);
return this;
}
/**
* Define a data de criação do documento.
*
* @param date Data de criação
*
* @return Esta instância após a operação
*/
public PdfDocMix withCreation(Calendar date) {
docInfo.creation(date);
return this;
}
/**
* Redefine as meta-informações do documento, ex: título, autor, data de
* criação, etc.
*
*
* Todas as informações anteriormente atribuídas por:
* {@linkplain #withTitle(String)}, {@linkplain #withSubject(String)}, etc.
* serão substituídas pelo conteúdo do {@code docInfo} nessa operação.
*
*
* @param docInfo Informações sobre o documento
*
* @return Esta instância após a operação
*
* @see org.jrimum.bopepo.pdf.PdfDocInfo
*/
public PdfDocMix withDocInfo(PdfDocInfo docInfo) {
checkNotNull(docInfo, "Valor null para docInfo não permitido!");
this.docInfo = docInfo;
return this;
}
/**
* Define se o título do documento será exibido na barra superior do PDF.
*
*
* Caso não seja informada uma opção, prevalece a definição do template PDF.
*
*
* @param option
*
* @return Esta instância após a operação
*/
public PdfDocMix withDisplayDocTilteOption(boolean option) {
this.displayDocTitle = option;
return this;
}
/**
* Retorna o documento em forma de arquivo PDF.
*
* @param destPath Caminho completo do arquivo o qual o documento será
* gerado
* @return Documento em forma de arquivo PDF
*
* @since 0.2
*
*/
public File toFile(String destPath) {
checkDestPath(destPath);
return toFile(new File(destPath));
}
/**
* Retorna o documento em forma de arquivo PDF.
*
* @param destURL URL do arquivo o qual o documento será gerado
* @return Documento em forma de arquivo PDF
*
* @since 0.2
*
*/
public File toFile(URL destURL) {
checkDestURL(destURL);
try {
return toFile(new File(destURL.toURI()));
} catch (Exception e) {
LOG.error(
"Erro durante a criação do arquivo! "
+ e.getLocalizedMessage(), e);
return Exceptions.throwIllegalStateException(
"Erro ao tentar criar arquivo! " + "Causado por "
+ e.getLocalizedMessage(), e);
}
}
/**
* Retorna o documento em forma de arquivo PDF.
*
* @param destFile Arquivo o qual o boleto será gerado
* @return Documento em forma de arquivo PDF
* @throws IllegalStateException Caso ocorral algum problema imprevisto
*
* @since 0.2
*
*/
public File toFile(File destFile) {
checkDestFile(destFile);
try {
process();
return Files.bytesToFile(destFile, outputStream.toByteArray());
} catch (Exception e) {
LOG.error(
"Erro durante a criação do arquivo! "
+ e.getLocalizedMessage(), e);
return Exceptions.throwIllegalStateException(
"Erro ao tentar criar arquivo! " + "Causado por "
+ e.getLocalizedMessage(), e);
}
}
/**
* Retorna o arquivo PDF em um stream de array de bytes.
*
* @return O PDF em stream
*
* @since 0.2
*
*/
public ByteArrayOutputStream toStream() {
try {
process();
return Files.bytesToStream(outputStream.toByteArray());
} catch (Exception e) {
LOG.error(
"Erro durante a criação do stream! "
+ e.getLocalizedMessage(), e);
return Exceptions.throwIllegalStateException(
"Erro durante a criação do stream! " + "Causado por "
+ e.getLocalizedMessage(), e);
}
}
/**
* Retorna o arquivo PDF em array de bytes.
*
* @return O PDF em array de bytes
*
* @since 0.2
*
*/
public byte[] toBytes() {
try {
process();
return outputStream.toByteArray();
} catch (Exception e) {
LOG.error(
"Erro durante a criação do array de bytes! "
+ e.getLocalizedMessage(), e);
return Exceptions.throwIllegalStateException(
"Erro durante a criação do array de bytes! "
+ "Causado por " + e.getLocalizedMessage(), e);
}
}
/**
* Retorna o uma cópia do template atual do viewer em array de bytes.
*
* @return Template em bytes
*
* @since 0.2
*
*/
public byte[] getTemplate() {
return template.clone();
}
/**
* Define o template que será utilizado para construir o documento.
*
* @param template
*
* @return Esta instância após a operação
*
* @since 0.2
*
*/
private PdfDocMix setTemplate(byte[] template) {
this.template = template;
return this;
}
/**
* Define o template que será utilizado para construir o documento.
*
* @param templateUrl
*
* @return Esta instância após a operação
*
* @since 0.2
*
*/
private PdfDocMix setTemplate(URL templateUrl) {
try {
setTemplate(templateUrl.openStream());
return this;
} catch (Exception e) {
return Exceptions.throwIllegalStateException(e);
}
}
/**
* Define o template que será utilizado para construir o documento.
*
* @param templateInput
*
* @return Esta instância após a operação
*
* @since 0.2
*
*/
private PdfDocMix setTemplate(InputStream templateInput) {
try {
setTemplate(Files.toByteArray(templateInput));
return this;
} catch (Exception e) {
return Exceptions.throwIllegalStateException(e);
}
}
/**
* Define o template que será utilizado para construir o documento.
*
* @param templatePath
*
* @return Esta instância após a operação
*
* @since 0.2
*
*/
private PdfDocMix setTemplate(String templatePath) {
setTemplate(new File(templatePath));
return this;
}
/**
* Define o template que será utilizado para construir o documento.
*
* @param templateFile
*
* @return Esta instância após a operação
*
* @since 0.2
*
*/
private PdfDocMix setTemplate(File templateFile) {
try {
setTemplate(Files.fileToBytes(templateFile));
return this;
} catch (Exception e) {
return Exceptions.throwIllegalStateException(e);
}
}
/**
* Indica se o viewer foi habilitado a comprimir o pdf do documento gerado.
*
* @see #withFullCompression(boolean)
*
* @return indicativo de compressão
*
* @since 0.2
*
*/
private boolean isFullCompression() {
return this.fullCompression;
}
/**
* Indica se o viewer foi habilitado para remover todos os campos do pdf
* gerado.
*
* @see #removeFields
*
* @return indicativo de compressão
*
* @since 0.2
*/
private boolean isRemoveFields() {
return removeFields;
}
/**
* Executa os seguintes métodos na sequência:
*
* - {@linkplain #init()}
* - {@linkplain #fillFields()}
* - {@linkplain #end()}
*
*
* @since 0.2
*/
private void process() {
init();
fillFields();
end();
}
/**
* Inicializa os principais objetos para a escrita dos dados do documento no
* template PDF: {@code stamper}, {@code reader} e {@code outputStream}.
*
* @since 0.2
*/
private void init() {
try {
reader = new PdfReader(getTemplate());
outputStream = new ByteArrayOutputStream();
stamper = new PdfStamper(reader, outputStream);
final String JRIMUM = "jrimum.org/bopepo";
String creator = docInfo.creator();
if (isBlank(creator)) {
withCreator(JRIMUM);
} else {
withCreator(creator + " by (" + JRIMUM + ")");
}
if (isNull(docInfo.creation())) {
docInfo.creation(Calendar.getInstance());
}
stamper.setMoreInfo((Map) (HashMap, ?>) docInfo.toMap());
if (isNotNull(displayDocTitle)) {
stamper.addViewerPreference(PdfName.DISPLAYDOCTITLE, displayDocTitle ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE);
}
stamper.addViewerPreference(PdfName.NEEDAPPEARANCES, PdfBoolean.PDFTRUE);
form = stamper.getAcroFields();
form.setGenerateAppearances(true);
} catch (Exception e) {
Exceptions.throwIllegalStateException(e);
}
}
/**
* Preenche todos os campos do formulário PDF com os dados do documento
* contido na instância.
*
* @since 0.2
*/
private void fillFields() {
setTextFields();
setImageFields();
}
/**
* Adiciona, caso existam, os textos definidos em
* {@linkplain #put(String, String)} ou {@linkplain #putAllTexts(Map)}.
*
* @since 0.2
*/
private void setTextFields() {
if (hasElement(txtMap)) {
for (Entry e : txtMap.entrySet()) {
try {
form.setField(e.getKey(), e.getValue());
//System.out.println("form.setField(\"" + e.getKey() + "\", \"" + e.getValue() + "\");");
} catch (Exception ex) {
Exceptions.throwIllegalStateException(ex);
}
}
}
}
/**
* Coloca as imagens dos campos no pdf de acordo com o nome dos campos do
* documento atribuídos no map e templante.
*
* @since 0.2
*/
private void setImageFields() {
if (hasElement(imgMap)) {
for (Entry e : imgMap.entrySet()) {
setImage(e.getKey(), e.getValue());
}
}
}
/**
* Coloca uma imagem no pdf de acordo com o nome do field no templante.
*
* @param fieldName
* @param image
*
* @since 0.2
*/
private void setImage(String fieldName, java.awt.Image image) {
if (isNotBlank(fieldName)) {
List posImgField = form.getFieldPositions(fieldName);
if (isNotNull(posImgField)) {
try {
for (AcroFields.FieldPosition pos : posImgField) {
PDFs.changeFieldToImage(stamper, new PdfRectangle(pos.position), getPdfImage(image));
}
} catch (Exception e) {
e.printStackTrace();
Exceptions.throwIllegalStateException(e);
}
} else {
LOG.warn("Posicionamento do campo de imagem nao encontrado! CAMPO: " + fieldName);
}
}
}
public Image getPdfImage(java.awt.Image image) {
Image pdfImage = imagesInUseMap.get(image);
if (isNull(pdfImage)) {
try {
pdfImage = Image.getInstance(image, null);
imagesInUseMap.put(image, pdfImage);
} catch (Exception ex) {
Exceptions.throwIllegalStateException(ex);
}
}
return pdfImage;
}
/**
* Finaliza a escrita de dados no template através do fechamento do
* {@code stamper}, {@code reader} e {@code outputStream}.
*
* @since 0.2
*/
private void end() {
/*
if (isFullCompression()) {
try {
stamper.setFullCompression();
} catch (DocumentException ex) {
throw new RuntimeException(ex);
}
}*/
if (isRemoveFields()) {
stamper.setFreeTextFlattening(true);
stamper.setFormFlattening(true);
reader.removeFields();
} else {
stamper.setFreeTextFlattening(false);
stamper.setFormFlattening(false);
}
reader.consolidateNamedDestinations();
reader.eliminateSharedStreams();
try {
// Send immediately
//outputStream.flush();
// close All in this order
https://stackoverflow.com/questions/23469286/merging-of-pdf-with-digital-signature-with-itext-5-4-0-or-greatest-gives-error
//stamper.flush();
stamper.close();
//reader.close();
//outputStream.close();
//new FileOutputStream("/tmp/test.pdf").write(outputStream.toByteArray());
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
private static void checkDestPath(String path) {
checkString(path,
"Caminho destinado a geração do(s) arquivo(s) não contém informação!");
}
private static void checkTemplatePath(String path) {
checkString(path, "Caminho do template não contém informação!");
}
private static void checkTemplateFile(Object template) {
Objects.checkNotNull(template, "Arquivo de template nulo!");
}
private static void checkString(String str, String msg) {
Objects.checkNotNull(str);
Strings.checkNotBlank(str, msg);
}
private static void checkDestURL(URL url) {
Objects.checkNotNull(url,
"URL destinada a geração do(s) documentos(s) nula!");
}
private static void checkDestFile(File file) {
Objects.checkNotNull(file,
"Arquivo destinado a geração do(s) documentos(s) nulo!");
}
}