From 535a04fa05f739ec16dd81666e3b0f82dfbd442d Mon Sep 17 00:00:00 2001 From: tknall Date: Wed, 9 Jan 2013 15:41:29 +0000 Subject: pdf-as-lib maven project files moved to pdf-as-lib git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/pdf-as/trunk@926 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .../java/at/knowcenter/wag/egov/egiz/PdfAS.java | 1575 ++++++++++++++++++++ 1 file changed, 1575 insertions(+) create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java (limited to 'pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java') diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java new file mode 100644 index 0000000..c222259 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java @@ -0,0 +1,1575 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a + * joint initiative of the Federal Chancellery Austria and Graz University of + * Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + * + * $Id: PdfAS.java,v 1.5 2006/10/31 08:04:50 wprinz Exp $ + */ +package at.knowcenter.wag.egov.egiz; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.Properties; +import java.util.Vector; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.pdfas.api.analyze.NonTextObjectInfo; +import at.gv.egiz.pdfas.api.commons.DynamicSignatureProfileImpl; +import at.gv.egiz.pdfas.api.commons.SignatureInformation; +import at.gv.egiz.pdfas.api.timestamp.TimeStamper; +import at.gv.egiz.pdfas.api.verify.VerifyParameters; +import at.gv.egiz.pdfas.api.xmldsig.ExtendedSignatureInformation; +import at.gv.egiz.pdfas.api.xmldsig.XMLDsigData; +import at.gv.egiz.pdfas.commandline.CommandlineConnectorChooser; +import at.gv.egiz.pdfas.exceptions.ErrorCode; +import at.gv.egiz.pdfas.exceptions.framework.CorrectorException; +import at.gv.egiz.pdfas.framework.ConnectorParameters; +import at.gv.egiz.pdfas.framework.input.PdfDataSource; +import at.gv.egiz.pdfas.framework.input.correction.Corrector; +import at.gv.egiz.pdfas.framework.input.correction.CorrectorFactory; +import at.gv.egiz.pdfas.framework.output.DataSink; +import at.gv.egiz.pdfas.framework.signator.SignatorInformation; +import at.gv.egiz.pdfas.impl.api.commons.PdfDataSourceAdapter; +import at.gv.egiz.pdfas.impl.input.ByteArrayPdfDataSourceImpl; +import at.gv.egiz.pdfas.impl.input.helper.DataSourceHelper; +import at.gv.egiz.pdfas.utils.PDFASUtils; +import at.knowcenter.wag.egov.egiz.cfg.OverridePropertyHolder; +import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; +import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; +import at.knowcenter.wag.egov.egiz.exceptions.ConnectorFactoryException; +import at.knowcenter.wag.egov.egiz.exceptions.NormalizeException; +import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException; +import at.knowcenter.wag.egov.egiz.exceptions.PresentableException; +import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; +import at.knowcenter.wag.egov.egiz.exceptions.SignatureException; +import at.knowcenter.wag.egov.egiz.exceptions.SignatureTypesException; +import at.knowcenter.wag.egov.egiz.framework.FoundBlock; +import at.knowcenter.wag.egov.egiz.framework.FoundKey; +import at.knowcenter.wag.egov.egiz.pdf.AbsoluteTextSignature; +import at.knowcenter.wag.egov.egiz.pdf.BinarySignatureHolder; +import at.knowcenter.wag.egov.egiz.pdf.ObjectExtractor; +import at.knowcenter.wag.egov.egiz.pdf.PDFSignatureCreation; +import at.knowcenter.wag.egov.egiz.pdf.PDFSignatureObject; +import at.knowcenter.wag.egov.egiz.pdf.PDFUtilities; +import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; +import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder; +import at.knowcenter.wag.egov.egiz.pdf.TablePos; +import at.knowcenter.wag.egov.egiz.pdf.TextualSignature; +import at.knowcenter.wag.egov.egiz.pdf.TextualSignatureHolder; +import at.knowcenter.wag.egov.egiz.sig.SignatureData; +import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl; +import at.knowcenter.wag.egov.egiz.sig.SignatureObject; +import at.knowcenter.wag.egov.egiz.sig.SignatureResponse; +import at.knowcenter.wag.egov.egiz.sig.SignatureTypeDefinition; +import at.knowcenter.wag.egov.egiz.sig.SignatureTypes; +import at.knowcenter.wag.egov.egiz.sig.connectors.Connector; +import at.knowcenter.wag.egov.egiz.sig.connectors.ConnectorChooser; +import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject; +import at.knowcenter.wag.egov.egiz.sig.signatureobject.SignatureObjectHelper; +import at.knowcenter.wag.egov.egiz.tools.Normalizer; +import at.knowcenter.wag.exactparser.ParseDocument; +import at.knowcenter.wag.exactparser.parsing.PDFUtils; +import at.knowcenter.wag.exactparser.parsing.results.HeaderParseResult; + +import com.lowagie.text.Rectangle; +import com.lowagie.text.pdf.PdfPTable; +import com.lowagie.text.pdf.PdfReader; + +/** + * This class contains the major methods used by both, the commandline and the + * webapp, to perform signation and verification. + * + * @author wprinz + * @author mruhmer + */ +public abstract class PdfAS +{ +//23.11.2010 changed by exthex - added method: verifyExtendedSignatureHolders(List extended_signature_info, String connectorType, boolean returnHashInputData, Date verificationTime) + + /** + * The current version of the pdf-as library. This version string is logged on every invocation + * of the api or the web application. + */ + public static final String PDFAS_VERSION = "3.2"; + + /** + * The key of the strict mode setting. + */ + public static final String STRICT_MODE_KEY = "strict_mode"; + + /** + * The left/right border. + */ + public static final float SIGNATURE_BORDER = 100f; + + /** + * The top/bottom border. + */ + public static final float SIGNATURE_MARGIN = 20f; + + /** + * The Mime Type of a PDF document. + */ + public static final String PDF_MIME_TYPE = "application/pdf"; + + public static final String CORRECT_DOCUMENT_IF_NECESSARY_KEY = "correct_document_if_necessary"; + + /** + * The logger definition. + */ + private static final Log log = LogFactory.getLog(PdfAS.class); + + /** + * Tells, if strict PDF checking the PDF version is enabled. + * + * @return Returns true, if incoming PDFs should be checked strictly. + */ + public static boolean isStrictPdfChecking() + { + try + { + SettingsReader settings = SettingsReader.getInstance(); + String strict_mode = settings.getSetting(STRICT_MODE_KEY, "false"); + if (strict_mode.equals("true")) + { + return true; + } + } + catch (SettingsException e) + { + log.error(e.getMessage(), e); + } + return false; + } + + /** + * Checks the version of the given PDF to be 1.4 or lower. + * + *

+ * This scans the first 1000 bytes of the PDF for the pdf Header. + *

+ * + * @param pdfDataSource + * The PDF. + * @return Returns true, if the given PDF is strict 1.4, false otherwise. + * @throws PDFDocumentException + * Forwarded exception. + */ + public static boolean isPdf14(PdfDataSource pdfDataSource) throws PDFDocumentException + { + try + { + byte[] firstBytes = new byte[1000]; + InputStream is = pdfDataSource.createInputStream(); + is.read(firstBytes); + is.close(); + + HeaderParseResult hpr = PDFUtils.parseHeader(firstBytes, 0); + + if (hpr.major <= 1 && hpr.minor <= 4) + { + return true; + } + return false; + } + catch (Exception e) + { + throw new PDFDocumentException(201, e); + } + } + + /** + * Applies strict version mode on the PDF and throws an exception, if the pdf + * is not 1.4. + * + *

+ * Furthermore (independently of strict mode) the PDF is checked for + * parsability. + *

+ * + * @param pdfDataSource + * The pdf to be checked against strict mode. + * @throws PDFDocumentException + * @throws SettingsException + * @throws CorrectorException + */ + public static PdfDataSource applyStrictMode(PdfDataSource pdfDataSource) throws PDFDocumentException, SettingsException, CorrectorException + { + if (isStrictPdfChecking()) + { + if (!isPdf14(pdfDataSource)) + { + throw new PDFDocumentException(201, "StrictMode: The pdf version is not 1.4 or lower."); + } + } + try + { + byte[] pdf = DataSourceHelper.convertDataSourceToByteArray(pdfDataSource); + ParseDocument.parseDocument(pdf); + } + catch (Exception e) + { + log.debug("Error while parsing Document.", e); + + boolean tryToCorrect = SettingsReader.getInstance().getSetting(CORRECT_DOCUMENT_IF_NECESSARY_KEY, "false").equals("true"); + if (!tryToCorrect) + { + throw new PDFDocumentException(201, e); + } + log.info("Correcting document..."); + Corrector cor = CorrectorFactory.createCorrector(); + PdfDataSource correctedDS = cor.correctDocument(pdfDataSource); + log.info("Correction finished."); + + return correctedDS; + } + + return pdfDataSource; + } + + public static at.gv.egiz.pdfas.api.io.DataSource applyStrictMode (at.gv.egiz.pdfas.api.io.DataSource dataSource) throws PDFDocumentException, SettingsException, CorrectorException + { + if (dataSource.getMimeType().equals("application/pdf")) + { + PdfDataSource pdfDS = new PdfDataSourceAdapter(dataSource); + PdfDataSource correctedDS = applyStrictMode(pdfDS); + if (correctedDS != pdfDS) + { + return new at.gv.egiz.pdfas.impl.api.commons.DataSourceApiAdapter(correctedDS); + } + } + return dataSource; + } + + // TODO: unused method - remove + // /** + // * Verifies the given PDF document. + // * + // * @param pdf + // * The PDF document. + // * @param connector + // * The connector. + // * @return Returns the List of results. + // * @throws PresentableException + // * Forwarded exception. + // */ + // public static List verifyPdf(final byte[] pdf, final String connector) + // throws PresentableException + // { + // VerificationFilter vf = new VerificationFilter(); + // List signature_holders = vf.extractSignaturesFromPdf(pdf); + // if (signature_holders.isEmpty()) + // { + // throw new PDFDocumentException(206); + // } + // + // List results = verifySignatureHolders(signature_holders, connector); + // + // return results; + // } + + // TODO: unused method - remove + // /** + // * Verifies the given text that is supposed to be extracted from a PDF + // * document using text extraction mechanisms. + // * + // * @param text + // * The text to be verified. + // * @param connector + // * The connecor. + // * @return Returns the List of results. + // * @throws PresentableException + // * Forwarded exception. + // */ + // public static List verifyText(final String text, final String connector) + // throws PresentableException + // { + // VerificationFilter vf = new VerificationFilter(); + // List signature_holders = vf.extractSignaturesFromPlainText(text); + // if (signature_holders.isEmpty()) + // { + // throw new PDFDocumentException(206); + // } + // + // List results = verifySignatureHolders(signature_holders, connector); + // + // return results; + // } + + /** + * Extracts all signature blocks from the given raw text using textual mode. + * + * @param raw_text + * The raw text. + * @return Returns a List of all SignatureHolders extracted from the text. + * @throws PDFDocumentException + * F.e. + * @throws SignatureException + * F.e. + * @throws SignatureTypesException + * @throws NormalizeException + */ + public static List extractSignatureHoldersTextual(String raw_text, boolean old_style) throws PDFDocumentException, SignatureException, SignatureTypesException, NormalizeException + { + List signature_holders = new ArrayList(); + + String text = raw_text; + for (;;) + { + TextualSignatureHolder holder = extractSignatureHolderTextual(text, old_style); + if (holder == null) + { + break; + } + { + log.debug("Found holder: " + holder.getSignatureObject().getSignationType()); + } + signature_holders.add(0, holder); + + text = holder.getSignedText(); + } + + return signature_holders; + } + + /** + * Extracts the last signature holder from the given text. + * + * @param raw_text + * @param old_style + * @return Returns the found singature holder, or null, if none could be + * found. + * @throws SignatureException + * @throws SignatureTypesException + * @throws NormalizeException + */ + public static TextualSignatureHolder extractSignatureHolderTextual(String raw_text, boolean old_style) throws SignatureException, SignatureTypesException, NormalizeException + { + List signatureTypes_ = AbsoluteTextSignature.getSignatureTypesForTextAnalysis(); + + List found_blocks = new ArrayList(); + for (int cur_type = 0; cur_type < signatureTypes_.size(); cur_type++) + { + SignatureTypeDefinition cur_std = (SignatureTypeDefinition) signatureTypes_.get(cur_type); + + List found_keys = findBlockInText(raw_text, cur_std, old_style); + if (found_keys != null) + { + FoundBlock found_block = new FoundBlock(); + found_block.found_keys = found_keys; + found_block.end_index = raw_text.length(); + found_block.std = cur_std; + found_blocks.add(found_block); + } + } + + List last_most_blocks = sortOutEarlyBlocks(found_blocks); + + List minimum_blocks = sortOutLargeBlocks(last_most_blocks); + + if (minimum_blocks.size() > 1) + { + log.debug("There are still " + minimum_blocks.size() + " candidates:"); + + for (int i = 0; i < minimum_blocks.size(); i++) + { + FoundBlock fb = (FoundBlock) minimum_blocks.get(i); + log.debug(" fb: " + fb.std.getType()); + } + + log.debug("... checking for Semantic Equality."); + } + + boolean semantic_equality = checkForSemanticEquality(minimum_blocks); + + if (minimum_blocks.size() > 1) + { + log.debug("... Semantic Equality = " + semantic_equality); + } + + if (!semantic_equality) + { + throw new SignatureException(ErrorCode.NOT_SEMANTICALLY_EQUAL, "The found blocks are not semantically equal."); + } + + if (!minimum_blocks.isEmpty()) + { + FoundBlock actual_block = (FoundBlock) minimum_blocks.get(0); + + String signed_text = raw_text.substring(0, actual_block.getFirstKey().start_index); + + SignatureObject signatureObject_ = new SignatureObject(); + signatureObject_.setSigType(actual_block.std.getType()); + signatureObject_.initByType(); + + int end_index = actual_block.end_index; + for (int i = 0; i < actual_block.found_keys.size(); i++) + { + FoundKey cur_key = (FoundKey) actual_block.found_keys.get(i); + int start_index = cur_key.getStartIndex() + cur_key.caption.length(); + + String value = raw_text.substring(start_index, end_index); + + signatureObject_.setSigValueCaption(cur_key.getKey(), value, cur_key.caption); + + end_index = cur_key.getStartIndex(); + } + + // this normalization is required to get rid of possible trailing + // newlines. + String normalized_text = normalizeText(signed_text); + TextualSignatureHolder holder = new TextualSignatureHolder(normalized_text, signatureObject_); + return holder; + } + + return null; + } + + /** + * Tries to find a block of the given type in the text. + * + * @param text + * The text. + * @param sig_type_def + * The type of the block. + * @param old_style + * Tells, if the block is old style (SIG_KZ will be ignored), or if + * it is a new block. + * @return Returns a List of the found keys of the block, or null, if the + * block could not be found. + */ + public static List findBlockInText(String text, SignatureTypeDefinition sig_type_def, boolean old_style) + { + Vector keys = sig_type_def.getRevertSortedKeys(); + Vector captions = sig_type_def.getRevertSortedCaptions(); + + int last_index = text.length(); + List found_keys = new ArrayList(); + for (int key_idx = 0; key_idx < keys.size(); key_idx++) + { + String key = (String) keys.get(key_idx); + // logger_.debug("Key="+key); + if (old_style && key.equals(SignatureTypes.SIG_KZ)) + { + // If separating the old style way - skip The "Kennzeichnung" + // key, because it wasn't present in old profiles. + continue; + } + + String caption = (String) captions.get(key_idx); + + // int found_index = text.lastIndexOf(caption); + // we're searching for captions that start at the beginning of the line. + int found_index = text.lastIndexOf("\n" + caption) + 1;// text.lastIndexOf("\n" + // + caption) + 1; + // // the +1 + // text.lastIndexOf(caption) + // + 1; // + // compensates the + // \n + if (found_index == 0) + { + // try without /n + found_index = text.lastIndexOf(caption); + + // fix #331 here ?? + } + log.debug("found key:" + caption + " at index:" + found_index); + if (key.equals(SignatureTypes.SIG_ID)) + { + if (found_index < 0 || found_index >= last_index) + { + // not found, SIG_ID is not required + continue; + } + FoundKey fk = new FoundKey(key, caption, found_index); + found_keys.add(fk); + } + else + { + if (found_index < 0 || found_index >= last_index) + { + // one key is not found - the profile doesn't match. + return null; + } + + FoundKey fk = new FoundKey(key, caption, found_index); + found_keys.add(fk); + last_index = found_index; + } + } + + sortFoundKeysDescendingly(found_keys); + + boolean matched = checkThatOrderIsCorrectAndCorrectFoundKeys(found_keys, keys, old_style); + // boolean found_required = checkFoundRequiredKeys(found_keys, old_style); + // logger_.debug("KKKKKKKKKKmatched="+matched); + if (matched) + { + return found_keys; + } + return null; + } + + /** + * Sorts the FoundKeys List descendingly according to the start indices of the + * found keys (the first found key in the list will have the highest start + * index, the second one the second highest and so forth). + * + * @param found_keys + * The List of FoundKey objects to be sorted. + */ + public static void sortFoundKeysDescendingly(List found_keys) + { + // sort the found_keys according to their start pos reversely. + + Collections.sort(found_keys, new Comparator() { + public int compare(Object arg0, Object arg1) + { + FoundKey fk0 = (FoundKey) arg0; + FoundKey fk1 = (FoundKey) arg1; + // sort reversely! + return fk1.start_index - fk0.start_index; + } + }); + } + + /** + * Sorts the FoundKeys List ascendingly according to the start indices of the + * found keys (the first found key in the list will have the lowest start + * index, the second one the second lowest and so forth). + * + * @param found_keys + * The List of FoundKey objects to be sorted. + */ + public static void sortFoundKeysAscendingly(List found_keys) + { + // sort the found_keys according to their start pos. + + Collections.sort(found_keys, new Comparator() { + public int compare(Object arg0, Object arg1) + { + FoundKey fk0 = (FoundKey) arg0; + FoundKey fk1 = (FoundKey) arg1; + return fk0.start_index - fk1.start_index; + } + }); + } + + /** + * Checks that the found keys are in correct order regarding SIG_ID as + * optional key. + * + *

+ * If the SIG_ID key is misplaced, it will be removed from the found keys + * list. + *

+ * + * @param found_keys + * The found keys ordered descendingly to their start position + * @param profile_keys + * The profile keys. + * @param old_style + * Tells, if SIG_KZ should be ignored, or not. + * @return Returns true, if the keys are correct. + */ + public static boolean checkThatOrderIsCorrectAndCorrectFoundKeys(List found_keys, List profile_keys, boolean old_style) + { + + int found_index = 0; + for (int profile_index = 0; profile_index < profile_keys.size(); profile_index++) + { + String key = (String) profile_keys.get(profile_index); + + if (old_style && key.equals(SignatureTypes.SIG_KZ)) + { + continue; + } + + FoundKey found_key = (FoundKey) found_keys.get(found_index); + + boolean match = key.equals(found_key.getKey()); + if (match) + { + found_index++; + continue; + } + + if (key.equals(SignatureTypes.SIG_ID)) + { + continue; + } + + // doesn't match + return false; + } + + // remove all fields above the found_index - they are not correctly matched + // indices (should be only the ID + int size = found_keys.size(); + for (int i = found_index; i < size; i++) + { + // this removes all (size - found_index) objects above found_index + found_keys.remove(found_index); + } + + return true; + } + + /** + * Sorts out early blocks and leaves only those at the bottom of the text. + * + * @param found_blocks + * The found blocks. + * @return Returns a list of the last blocks. + */ + public static List sortOutEarlyBlocks(List found_blocks) + { + int last_most_index = Integer.MIN_VALUE; + + List last_most_blocks = new ArrayList(); + for (int block_index = 0; block_index < found_blocks.size(); block_index++) + { + FoundBlock block = (FoundBlock) found_blocks.get(block_index); + + int this_last_index = block.getLastKey().start_index; + if (this_last_index < last_most_index) + { + // this block cannot be the last most block. + continue; + } + if (this_last_index == last_most_index) + { + last_most_blocks.add(block); + continue; + } + if (this_last_index > last_most_index) + { + last_most_blocks = new ArrayList(); + last_most_blocks.add(block); + last_most_index = this_last_index; + } + } + + return last_most_blocks; + } + + /** + * Sorts out large blocks. + * + * @param found_blocks + * The found blocks. + * @return Returns a list of the smallest blocks. + */ + public static List sortOutLargeBlocks(List found_blocks) + { + int last_min_size = Integer.MAX_VALUE; + + List min_size_blocks = new ArrayList(); + for (int block_index = 0; block_index < found_blocks.size(); block_index++) + { + FoundBlock block = (FoundBlock) found_blocks.get(block_index); + + int size = block.getSize(); + + if (size > last_min_size) + { + // this block is larger + continue; + } + if (size == last_min_size) + { + min_size_blocks.add(block); + continue; + } + if (size < last_min_size) + { + min_size_blocks = new ArrayList(); + min_size_blocks.add(block); + last_min_size = size; + } + } + + return min_size_blocks; + } + + /** + * Checks the list of blocks for semantic equality. + * + * @param found_blocks + * The list of found blocks. + * @return Returns true if all blocks are semantically equal. + */ + public static boolean checkForSemanticEquality(List found_blocks) + { + if (found_blocks.size() <= 1) + { + return true; + } + + for (int block_index = 0; block_index < found_blocks.size() - 1; block_index++) + { + FoundBlock first_block = (FoundBlock) found_blocks.get(block_index); + FoundBlock second_block = (FoundBlock) found_blocks.get(block_index + 1); + + if (!first_block.isSemanticallyEqual(second_block)) + { + return false; + } + } + + return true; + } + + public static int getIndexOfFoundKey(List found_keys, String key) + { + for (int i = 0; i < found_keys.size(); i++) + { + FoundKey fk = (FoundKey) found_keys.get(i); + if (fk.getKey().equals(key)) + { + return i; + } + } + return -1; + } + + public static boolean containsFoundKey(List found_keys, String key) + { + return getIndexOfFoundKey(found_keys, key) >= 0; + } + + /** + * Checks the found keys for the required keys regarding the old style. + * + * @param found_keys + * The found keys. + * @param old_style + * Flag that tells, if KZ is not required. + * @return Returns true, if all required keys were found. + */ + public static boolean checkFoundRequiredKeys(List found_keys, boolean old_style) + { + if (!containsFoundKey(found_keys, SignatureTypes.SIG_DATE)) + { + return false; + } + if (!containsFoundKey(found_keys, SignatureTypes.SIG_ISSUER)) + { + return false; + } + if (!containsFoundKey(found_keys, SignatureTypes.SIG_NUMBER)) + { + return false; + } + if (!containsFoundKey(found_keys, SignatureTypes.SIG_VALUE)) + { + return false; + } + if (!old_style && !containsFoundKey(found_keys, SignatureTypes.SIG_KZ)) + { + return false; + } + return true; + } + + public static List verifySignatureHolders(List signature_holders, String connectorType, boolean returnHashInputData, Date verificationTime) throws PDFDocumentException, NormalizeException, SignatureException, ConnectorException, ConnectorFactoryException + { + List results = new ArrayList(); + for (int i = 0; i < signature_holders.size(); i++) + { + SignatureHolder holder = (SignatureHolder) signature_holders.get(i); + + // logger_.debug(); + // logger_.debug(); + // logger_.debug("Verifying Holder " + i + "..."); + // logger_.debug("holder[" + i + "].signed_text = " + + // holder.signed_text); + // logger_.debug("holder[" + i + "].sig_obj = "); + // logger_.debug("holder[" + i + "].type = " + + // (holder.signature_object.isTextual() ? "textual" : "binary")); + // logger_.debug(holder.signature_object.toString()); + + SignatureResponse result = verify(holder, connectorType, returnHashInputData, verificationTime, null); + results.add(result); + + // logger_.debug(); + // logger_.debug("check[" + i + "].cert = " + + // result.getCertificateCheckInfo()); + // logger_.debug("check[" + i + "].sig = " + + // result.getSignatureCheckInfo().trim()); + // logger_.debug("check[" + i + "].manifest = " + + // result.getSignatureManifestCheckInfo()); + // logger_.debug(); + } + return results; + } + + /** + * Verify a list of signatures + * + * @param extended_signature_info a list of {@link ExtendedSignatureInformation} to be verified + * @param connectorType the connector to use for verification + * @param returnHashInputData + * @param verificationTime + * @param verifySignatureAtIndex only verify the signature at the given index in the extended_signature_info list. A value < 0 means to verify all signatures in the list. + * @return a list of {@link SignatureResponse}s + * @throws PDFDocumentException + * @throws NormalizeException + * @throws SignatureException + * @throws ConnectorException + * @throws ConnectorFactoryException + */ + public static List verifyExtendedSignatureHolders(List extended_signature_info, String connectorType, boolean returnHashInputData, Date verificationTime, int verifySignatureAtIndex) throws PDFDocumentException, NormalizeException, SignatureException, ConnectorException, ConnectorFactoryException + { + List results = new ArrayList(); + for (int i = 0; i < extended_signature_info.size(); i++) + { + if (verifySignatureAtIndex < 0 || verifySignatureAtIndex == i) + { + ExtendedSignatureInformation sigInfo = (ExtendedSignatureInformation) extended_signature_info.get(i); + SignatureInformation si = sigInfo.getSignatureInformation(); + SignatureHolder holder = (SignatureHolder) si.getInternalSignatureInformation(); + + SignatureResponse result = verify(holder, connectorType, returnHashInputData, verificationTime, sigInfo.getXmlDsigData()); + results.add(result); + } + } + return results; + } + + /** + * Verifies a SignatureHolder using the given connector. + * + * @param signature_holder + * The SignatureHolder to be verified. + * @param connector + * The connector. + * @return Returns the SignatureResponse object. + * @throws NormalizeException + * F.e. + * @throws PDFDocumentException + * F.e. + * @throws SignatureException + * F.e. + * @throws ConnectorException + * @throws ConnectorFactoryException + */ + public static SignatureResponse verify(SignatureHolder signature_holder, String connectorType, boolean returnHashInputData, Date verificationTime, XMLDsigData dsig) throws NormalizeException, PDFDocumentException, SignatureException, ConnectorException, ConnectorFactoryException + { + // String text_to_be_verified = signature_holder.getSignedText(); + // logger_.debug("verify text_to_be_verified"+text_to_be_verified); + SignatureObject so_to_be_verified = signature_holder.getSignatureObject(); + + // if (text_to_be_verified == null) + // { + // throw new SignatureException(311, "Document can not be verified because + // the text to be verified is either null."); + // } + // if (text_to_be_verified.length() <= 0) + // { + // throw new SignatureException(311, "Document can not be verified because + // the length of the text to be verified is 0. (length = " + + // text_to_be_verified.length() + ")"); + // } + + if (so_to_be_verified == null) + { + throw new SignatureException(312, "Document can not be verified because no signature object are set."); + } + + // fixed by tknall + if (so_to_be_verified.getX509Cert() == null) + { + throw new SignatureException(ErrorCode.CERTIFICATE_NOT_FOUND, "Document certificate is not defined."); + } + + SignSignatureObject so = SignatureObjectHelper.convertSignatureObjectToSignSignatureObject(so_to_be_verified); + SignatureData sd = convertSignatureHolderToSignatureData(signature_holder); + + String profile = so_to_be_verified.getSignatureTypeDefinition().getType(); +// Connector c = ConnectorChooser.chooseCommandlineConnectorForVerify(connector, so_to_be_verified.getKZ(), so.id, profile); + String connectorId = CommandlineConnectorChooser.chooseCommandlineConnectorForVerify(connectorType, so_to_be_verified.getKZ(), so.id, profile); + + ConnectorParameters cp = new ConnectorParameters(); + cp.setProfileId(profile); + cp.setReturnHashInputData(returnHashInputData); + cp.setVerificationTime(verificationTime); + Connector c = at.gv.egiz.pdfas.framework.ConnectorFactory.createConnector(connectorId, cp); + + return executeVerify(dsig, so, sd, c); + } + + private static SignatureResponse executeVerify(XMLDsigData dsig, SignSignatureObject so, + SignatureData sd, Connector c) throws ConnectorException { + SignatureResponse res = null; + try { + return c.doVerify(sd, so, dsig); + } catch (ConnectorException e) { + if (VerifyParameters.isSuppressVerifyExceptions()) { + res = new SignatureResponse(); + res.setVerificationImpossibleEx(e); + } else { + throw e; + } + } + return res; + } + + public static SignatureResponse verifyWeb(SignatureHolder signature_holder, String connector, String loc_ref) throws NormalizeException, PDFDocumentException, SignatureException, ConnectorException + { + // String text_to_be_verified = signature_holder.getSignedText(); + // logger_.debug("verify text_to_be_verified"+text_to_be_verified); + SignatureObject so_to_be_verified = signature_holder.getSignatureObject(); + + // if (text_to_be_verified == null) + // { + // throw new SignatureException(311, "Document can not be verified because + // the text to be verified is either null."); + // } + // if (text_to_be_verified.length() <= 0) + // { + // throw new SignatureException(311, "Document can not be verified because + // the length of the text to be verified is 0. (length = " + + // text_to_be_verified.length() + ")"); + // } + + if (so_to_be_verified == null) + { + throw new SignatureException(312, "Document can not be verified because no signature object are set."); + } + + // added by tknall + if (so_to_be_verified.getX509Cert() == null) + { + throw new SignatureException(ErrorCode.CERTIFICATE_NOT_FOUND, "Document certificate is not defined."); + } + + + SignSignatureObject so = SignatureObjectHelper.convertSignatureObjectToSignSignatureObject(so_to_be_verified); + SignatureData sd = convertSignatureHolderToSignatureData(signature_holder); + + String profile = so_to_be_verified.getSignatureTypeDefinition().getType(); + Connector c = ConnectorChooser.chooseWebConnectorForVerify(connector, so_to_be_verified.getKZ(), so.id, profile, loc_ref); + + return executeVerify(null, so, sd, c); + + } + + public static SignatureData convertSignatureHolderToSignatureData(SignatureHolder signature_holder) + { + SignatureData sd = null; + if (signature_holder instanceof BinarySignatureHolder) + { + BinarySignatureHolder bsh = (BinarySignatureHolder) signature_holder; + sd = new SignatureDataImpl(bsh.getDataSource(), "application/pdf"); + } + else + { + TextualSignatureHolder tsh = (TextualSignatureHolder)signature_holder; + sd = new SignatureDataImpl(tsh.getDataSource(), "text/plain", "UTF-8"); + } + return sd; + } + + /** + * Signs the given text with the provided connector using the given signature + * type. + * + * @param data_to_sign + * The data to be signed. + * @param signature_type + * The type of the signature. + * @param connector + * The connector. + * @return Returns the corresponding SignatureObject. + * @throws SignatureException + * F.e. + * @throws PDFDocumentException + * F.e. + * @throws ConnectorException + */ + public static SignSignatureObject sign(final SignatureData data_to_sign, final Connector connector, final TimeStamper timeStamper) throws SignatureException, PDFDocumentException, ConnectorException + { +// if (data_to_sign == null || data_to_sign.getData() == null) +// { +// throw new SignatureException(301, "Signature can not be produced. Data is null."); //$NON-NLS-1$ +// } + // if (data_to_sign.getData().length <= 0) + // { + // throw new SignatureException(301, "Signature can not be produced. Data is + // empty. (length = " + data_to_sign.getData().length + ")"); //$NON-NLS-1$ + // //$NON-NLS-2$ + // } + + SignSignatureObject signed_signature_object = connector.doSign(data_to_sign); + + // call timestamper if available + if (timeStamper != null) { + log.debug("execute timestamping with stamper: " + timeStamper.getClass()); + signed_signature_object.sigTimeStamp = timeStamper.applyTimeStamp(signed_signature_object.getSignatureValue()); + } + + return signed_signature_object; + } + + /** + * Helper method that creates a SignatureObject and initializes it with the + * given type. + * + * @param signature_type + * The type. + * @return Returns the created SignatureObject. + * @throws SignatureException + * f.e. + * @throws SignatureTypesException + * f.e. + */ + public static SignatureObject createSignatureObjectFromType(final String signature_type) throws SignatureException, SignatureTypesException + { + SignatureObject sig_obj = new SignatureObject(); + sig_obj.setSigType(signature_type); + sig_obj.initByType(); + + return sig_obj; + } + +// /** +// * @deprecated moved to Main.processSign use signCommandline instead +// * @param pdfDataSource +// * @param dataSink +// * @param signatorId +// * @param connectorType +// * @param profile +// * @param pos +// * @throws PresentableException +// */ +// public static void sign(PdfDataSource pdfDataSource, DataSink dataSink, PdfASID signatorId, final String connectorType, final String profile, TablePos pos) throws PresentableException +// { +//// //Signator signator = SignatorFactory.createSignator(algorithm); +//// at.gv.egiz.pdfas.framework.signator.Signator signator = at.gv.egiz.pdfas.framework.SignatorFactory.createSignator(algorithm); +//// +//// //IncrementalUpdateInformation iui = signator.prepareSign(pdfDataSource, signature_type, pos, ConnectorFactory.needsSIG_ID(connector)); +//// SignatorInformation si = signator.prepareSign(pdfDataSource, signature_type, pos, ConnectorFactory.needsSIG_ID(connector)); +// +// // Connector c = ConnectorChooser.chooseCommandlineConnectorForSign(connector, signature_type); +// +//// SignSignatureObject sso = sign(si.getSignatureData(), c); +//// +//// si.setSignSignatureObject(sso); +//// +//// signator.finishSign(si, dataSink); +// +// String connectorId = CommandlineConnectorChooser.chooseCommandlineConnectorForSign(connectorType); +// +// signCommandline(pdfDataSource, dataSink, signatorId, connectorId, profile, pos); +// } + + public static SignatorInformation signCommandline(PdfDataSource pdfDataSource, DataSink dataSink, PdfASID signatorId, String connectorId, final String profile, final String signatureKeyIdentifier, TablePos pos, TimeStamper timeStamper, Properties overrideProps) throws PresentableException + { + try { + at.gv.egiz.pdfas.framework.signator.Signator signator = at.gv.egiz.pdfas.framework.SignatorFactory.createSignator(signatorId); + if (overrideProps != null) { + OverridePropertyHolder.setOverrideProps(overrideProps); + } + + ConnectorParameters cp = new ConnectorParameters(); + cp.setProfileId(profile); + cp.setSignatureKeyIdentifier(signatureKeyIdentifier); + Connector c = at.gv.egiz.pdfas.framework.ConnectorFactory.createConnector(connectorId, cp); + + // SignatorInformation si = signator.prepareSign(pdfDataSource, profile, pos, ConnectorFactory.needsSIG_ID(connector)); + SignatorInformation si = signator.prepareSign(pdfDataSource, profile, pos, timeStamper); + + SignSignatureObject sso = sign(si.getSignatureData(), c, timeStamper); + + si.setSignSignatureObject(sso); + + signator.finishSign(si, dataSink); + + return si; + } finally { + OverridePropertyHolder.removeProperties(); + DynamicSignatureProfileImpl.disposeLocalProfile(); + } + } + + public static SignatorInformation signCommandline(PdfDataSource pdfDataSource, DataSink dataSink, PdfASID signatorId, String connectorId, final String profile, TablePos pos) throws PresentableException { + return signCommandline(pdfDataSource, dataSink, signatorId, connectorId, profile, null, pos, null, null); + } + + /** + * Extracts and normalizes the text from the pdf. + * + * @param pdf + * The PDF document. + * @return Returns the text String. + * @throws PresentableException + * F.e. + */ +// public static String extractNormalizedTextTextual(final byte[] pdf) throws PresentableException +// { +// // ByteArrayInputStream bais = new ByteArrayInputStream(pdf); +// // String raw_document_text = TextualSignature.extractTextTextual(bais); +// // +// // String document_text = normalizeText(raw_document_text); +// +// return extractNormalizedTextTextual(pdf, pdf.length); +// } + + + /** + * + * @param pdfDs + * @return List of {@link NonTextObjectInfo} + */ + public static List extractNonTextualObjects(PdfDataSource pdfDs) { + return ObjectExtractor.extractNonTextInfo(pdfDs); + } + + + /** + * @deprecated + * Use version with explicit encoding {@link PdfAS#extractNormalizedTextTextual(PdfDataSource, String)}. + * This one uses cp1252. + * + * @param pdfDataSource + * @return + * @throws PresentableException + */ + public static String extractNormalizedTextTextual(PdfDataSource pdfDataSource) throws PresentableException { + return extractNormalizedTextTextual(pdfDataSource, "cp1252"); + + } + + public static String extractNormalizedTextTextual(PdfDataSource pdfDataSource, String encoding) throws PresentableException + { + String raw_document_text = TextualSignature.extractTextTextual(pdfDataSource, encoding); + String document_text = normalizeText(raw_document_text); + return document_text; + } + /** + @deprecated + */ + public static String extractNormalizedTextTextual(byte [] pdf, int length) throws PresentableException + { + ByteArrayPdfDataSourceImpl pdfDataSource = new ByteArrayPdfDataSourceImpl(pdf, length); + String raw_document_text = TextualSignature.extractTextTextual(pdfDataSource, "cp1252"); + String document_text = normalizeText(raw_document_text); + return document_text; + } + +// public static String extractNormalizedTextTextual(InputStream pdfInputStream, int length) throws PresentableException +// { +// DelimitedInputStream dis = new DelimitedInputStream(pdfInputStream, length); +// String raw_document_text = TextualSignature.extractTextTextual(dis); +// String document_text = normalizeText(raw_document_text); +// return document_text; +// } +// /** +// * Extracts and normalizes the text from the pdf. +// * +// * @param pdf +// * The PDF document. +// * @param length +// * The length of the PDF document. The decument is considered to be +// * that long even if the byte array is longer. +// * @return Returns the text String. +// * @throws PresentableException +// * F.e. +// */ +// public static String extractNormalizedTextTextual(final byte[] pdf, final int length) throws PresentableException +// { +// ByteArrayInputStream bais = new ByteArrayInputStream(pdf, 0, length); +// String raw_document_text = TextualSignature.extractTextTextual(bais); +// // logger_.info("extractNormalizedTextTextual +// // raw_document_text="+raw_document_text); +// String document_text = normalizeText(raw_document_text); +// // logger_.info("extractNormalizedTextTextual document_text +// // ="+document_text); +// return document_text; +// } + + /** + * Normalizes the given text. + * + * @param text + * The text to be normalized. + * @return Returns the normalized text. + * @throws NormalizeException + * F.e. + */ + public static String normalizeText(final String text) throws NormalizeException + { + Normalizer normalizer = new Normalizer(); + String normalized_text = normalizer.normalize(text, false); + // fix #331 ?? + //normalized_text = normalized_text.replaceAll("\n", ""); + return normalized_text; + } + + /** + * Creates the iText PDFPTable from a given SignatureObject. + * + * @param signature_object + * The SignatureObject. + * @return Returns the created PDFPTable. + * @throws PDFDocumentException + * F.e. + * @throws SignatureException + * F.e. + */ + public static PdfPTable createPdfPTableFromSignatureObject(final SignatureObject signature_object) throws PDFDocumentException, SignatureException + { + PDFSignatureCreation creation = new PDFSignatureCreation(signature_object); + PDFSignatureObject pdf_sig_obj = creation.getPDFSignatureObject(); + PdfPTable pdf_table = (PdfPTable) pdf_sig_obj.getSignatureObject(); + + return pdf_table; + } + + /** + * Evalutates absolute positioning and prepares the PositioningInstruction for + * placing the table. + * + * @param pos + * The absolute positioning parameter. If null it is sought in the + * profile definition. + * @param signature_type + * The profile definition of the table to be written. + * @param pdf + * The pdf. + * @param pdf_table + * The pdf table to be written. + * @return Returns the PositioningInformation. + * @throws PDFDocumentException + * F.e. + * @throws SettingsException + * F.e. + */ + public static PositioningInstruction determineTablePositioning(TablePos pos, String signature_type, PdfDataSource pdfDataSource, PdfPTable pdf_table) throws PDFDocumentException, SettingsException + { + if (pos == null) + { + String pos_string = SettingsReader.getInstance().getSetting(SignatureTypes.SIG_OBJ + signature_type + ".pos", null); + if (pos_string != null) + { + pos = PdfAS.parsePositionFromPosString(pos_string); + } + } + if (pos == null) + { + // The default algorithm. x,y,w =auto ,p=lastpage, f:ignored because + // y:auto + pos = new TablePos(); + } + // System.out.println("Tablepos="+pos); + return PdfAS.adjustSignatureTableandCalculatePosition(pdfDataSource, pdf_table, pos); + } + + /** + * Sets the width of the table according to the layout of the document and + * calculates the y position where the PDFPTable should be placed. + * + * @param pdf + * The PDF document. + * @param pdf_table + * The PDFPTable to be placed. + * @return Returns the position where the PDFPTable should be placed. + * @throws PDFDocumentException + * F.e. + */ + public static PositioningInstruction adjustSignatureTableandCalculatePosition(final PdfDataSource pdfDataSource, PdfPTable pdf_table, TablePos pos) throws PDFDocumentException + { + // first check pageinstruction in TablePos-object + // new,auto,absolut + PdfReader reader = readInPdfDocument(pdfDataSource); + PDFASUtils.checkReaderPermissions(reader); + // get pages of currentdocument + int doc_pages = reader.getNumberOfPages(); + int page = doc_pages; + boolean make_new_page = pos.isNewPage(); + if (!(pos.isNewPage() || pos.isPauto())) + { + // we should posit signaturtable on this page + + page = pos.getPage(); + // System.out.println("XXXXPAGE="+page+" doc_pages="+doc_pages); + if (page > doc_pages) + { + make_new_page = true; + page = doc_pages; + // throw new PDFDocumentException(227, "Page number is to big(=" + page+ + // ") cannot be parsed."); + } + } + + // getPagedimensions + Rectangle psize = reader.getPageSizeWithRotation(page); + int page_rotation = reader.getPageRotation(page); + +// [tknall] for iText 1.x.x: +// float page_width = psize.width(); +// float page_height = psize.height(); + +// [tknall] for iText 2.x.x: +// float page_width = psize.getWidth(); +// float page_height = psize.getHeight(); + + float page_width = psize.getWidth(); + float page_height = psize.getHeight(); + + // now we can calculate x-position + float pre_pos_x = SIGNATURE_BORDER / 2; + if (!pos.isXauto()) + { + // we do have absolute x + pre_pos_x = pos.getPosX(); + } + // calculate width + // center + float pre_width = page_width - pre_pos_x - pre_pos_x; + if (!pos.isWauto()) + { + // we do have absolute width + pre_width = pos.getWidth(); + if (pos.isXauto()) + { // center x + pre_pos_x = (page_width - pre_width) / 2; + } + } + final float pos_x = pre_pos_x; + final float width = pre_width; + // Signatur table dimensions are complete + pdf_table.setTotalWidth(width); + pdf_table.setLockedWidth(true); + final float table_height = pdf_table.getTotalHeight(); + // now check pos_y + float pos_y = pos.getPosY(); + if (!pos.isYauto()) + { + // we do have y-position too --> all parameters but page ok + if (make_new_page) + { + page++; + } + return new PositioningInstruction(make_new_page, page, pos_x, pos_y); + } + // pos_y is auto + if (make_new_page) + { + // ignore footer in new page + page++; + pos_y = page_height - SIGNATURE_BORDER / 2; + return new PositioningInstruction(make_new_page, page, pos_x, pos_y); + } + // up to here no checks have to be made if Tablesize and Pagesize are fit + // Now we have to getfreespace in page and reguard footerline + float footer_line = pos.getFooterLine(); + float pre_page_length = PDFUtilities.calculatePageLength(pdfDataSource, page - 1, page_height - footer_line, page_rotation); + if (pre_page_length == Float.NEGATIVE_INFINITY) + { + // we do have an empty page or nothing in area above footerline + pre_page_length = page_height; + // no text --> SIGNATURE_BORDER + pos_y = page_height - SIGNATURE_BORDER / 2; + if (pos_y - footer_line <= table_height) + { + make_new_page = true; + if (!pos.isPauto()) + { + // we have to correct pagenumber + page = reader.getNumberOfPages(); + } + page++; + // no text --> SIGNATURE_BORDER + pos_y = page_height - SIGNATURE_BORDER / 2; + } + return new PositioningInstruction(make_new_page, page, pos_x, pos_y); + } + final float page_length = pre_page_length; + // we do have text take SIGNATURE_MARGIN + pos_y = page_height - page_length - SIGNATURE_MARGIN; + if (pos_y - footer_line <= table_height) + { + make_new_page = true; + if (!pos.isPauto()) + { + // we have to correct pagenumber in case of absolute page and not enough + // space + page = reader.getNumberOfPages(); + } + page++; + // no text --> SIGNATURE_BORDER + pos_y = page_height - SIGNATURE_BORDER / 2; + } + return new PositioningInstruction(make_new_page, page, pos_x, pos_y); + } + +// /** +// * Sets the width of the table according to the layout of the document and +// * calculates the y position where the PDFPTable should be placed. +// * +// * @deprecated +// * @param pdf +// * The PDF document. +// * @param pdf_table +// * The PDFPTable to be placed. +// * @return Returns the position where the PDFPTable should be placed. +// * @throws PDFDocumentException +// * F.e. +// */ +// public static PositioningInstruction adjustTableAndCalculatePosition(final byte[] pdf, PdfPTable pdf_table) throws PDFDocumentException +// { +// boolean make_new_page = false; +// +// PdfReader reader = readInPdfDocument(pdf); +// +// int page = reader.getNumberOfPages(); +// Rectangle psize = reader.getPageSizeWithRotation(page); +// float page_width = psize.width(); +// float page_height = psize.height(); +// +// final float width = page_width - SIGNATURE_BORDER; +// pdf_table.setTotalWidth(width); +// pdf_table.setLockedWidth(true); +// +// final float pos_x = SIGNATURE_BORDER / 2; +// +// final float table_height = pdf_table.getTotalHeight(); +// final float page_length = PDFUtilities.calculateLastPageLength(pdf, page_height); +// float pos_y = page_height - page_length - SIGNATURE_MARGIN; +// +// if (pos_y <= table_height) +// { +// make_new_page = true; +// page++; +// +// pos_y = page_height - SIGNATURE_BORDER / 2; +// } +// +// return new PositioningInstruction(make_new_page, page, pos_x, pos_y); +// } + +// /** +// * Sets the width of the table according to the layout of the document and +// * calculates the y position where the PDFPTable should be placed. +// * +// *

+// * This algorithm tries to position the table between the end of the text and +// * the footer line. +// *

+// * +// * @deprecated +// * @param pdf +// * The PDF document. +// * @param pdf_table +// * The PDFPTable to be placed. +// * @return Returns the position where the PDFPTable should be placed. +// * @throws PDFDocumentException +// * F.e. +// */ +// public static PositioningInstruction adjustTableAndCalculatePositionRegardingFooter(final byte[] pdf, PdfPTable pdf_table, float footer_line) throws PDFDocumentException +// { +// boolean make_new_page = false; +// +// PdfReader reader = readInPdfDocument(pdf); +// +// int page = reader.getNumberOfPages(); +// Rectangle psize = reader.getPageSizeWithRotation(page); +// float page_width = psize.width(); +// float page_height = psize.height(); +// +// final float width = page_width - SIGNATURE_BORDER; +// pdf_table.setTotalWidth(width); +// pdf_table.setLockedWidth(true); +// +// final float pos_x = SIGNATURE_BORDER / 2; +// +// final float table_height = pdf_table.getTotalHeight(); +// +// final float page_length = PDFUtilities.calculateLastPageLength(pdf, page_height - footer_line); +// float pos_y = page_height - page_length - SIGNATURE_MARGIN; +// +// if (pos_y - footer_line <= table_height) +// { +// make_new_page = true; +// page++; +// +// pos_y = page_height - SIGNATURE_BORDER / 2; +// } +// +// return new PositioningInstruction(make_new_page, page, pos_x, pos_y); +// } + + /** + * Creates an iText Reader that parses the document. + *

+ * This is a convenience function for wrapping the Reader's exceptions into + * PDFDocumentException. + *

+ * + * @param pdf + * The PDF document. + * @return Returns the created PdfReader. + * @throws PDFDocumentException + * F.e. + */ + public static PdfReader readInPdfDocument(final PdfDataSource pdfDataSource) throws PDFDocumentException + { + try + { + //InputStream is = pdfDataSource.createInputStream(); + // PERF: byte array instead of stream + byte [] pdf_data = pdfDataSource.getAsByteArray(); + PdfReader reader = new PdfReader(pdf_data); + //is.close(); + return reader; + } + catch (IOException e) + { + throw new PDFDocumentException(201, e); + } + } + + /** + * Parses the TablePos object from a given String with the appropriate format. + * + * @param pos_string + * The pos string. e.g. x:40.0;y:auto;w:auto;p:1;f:300.0 + * @return Returns the parsed TablePos object. + * @throws PDFDocumentException + * Thrown, if the String doesn't have the proper format. + */ + public static TablePos parsePositionFromPosString(String pos_string) throws PDFDocumentException + { + TablePos pos = new TablePos(pos_string); + return pos; + } + +} -- cgit v1.2.3