diff options
Diffstat (limited to 'pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib')
35 files changed, 327 insertions, 5255 deletions
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/backend/PDFASBackend.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/backend/PDFASBackend.java new file mode 100644 index 00000000..d601532e --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/backend/PDFASBackend.java @@ -0,0 +1,13 @@ +package at.gv.egiz.pdfas.lib.backend; + +import at.gv.egiz.pdfas.lib.impl.placeholder.PlaceholderExtractor; +import at.gv.egiz.pdfas.lib.impl.signing.IPdfSigner; +import at.gv.egiz.pdfas.lib.impl.verify.VerifyBackend; + +public interface PDFASBackend { + public String getName(); + public boolean usedAsDefault(); + public IPdfSigner getPdfSigner(); + public PlaceholderExtractor getPlaceholderExtractor(); + public VerifyBackend getVerifier(); +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java index 85a11d0d..3d9725a7 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java @@ -25,9 +25,7 @@ package at.gv.egiz.pdfas.lib.impl; import iaik.x509.X509Certificate; -import java.awt.Graphics2D; import java.awt.Image; -import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -38,13 +36,6 @@ import java.util.Iterator; import java.util.List; import org.apache.commons.io.IOUtils; -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.cos.COSString; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDPage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,10 +45,8 @@ import at.gv.egiz.pdfas.common.exceptions.PdfAsException; import at.gv.egiz.pdfas.common.exceptions.PdfAsSettingsException; import at.gv.egiz.pdfas.common.settings.ISettings; import at.gv.egiz.pdfas.common.settings.Settings; -import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings; import at.gv.egiz.pdfas.common.utils.PDFUtils; import at.gv.egiz.pdfas.common.utils.StreamUtils; -import at.gv.egiz.pdfas.lib.api.ByteArrayDataSource; import at.gv.egiz.pdfas.lib.api.Configuration; import at.gv.egiz.pdfas.lib.api.IConfigurationConstants; import at.gv.egiz.pdfas.lib.api.PdfAs; @@ -67,30 +56,18 @@ import at.gv.egiz.pdfas.lib.api.sign.SignParameter; import at.gv.egiz.pdfas.lib.api.sign.SignResult; import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter; import at.gv.egiz.pdfas.lib.api.verify.VerifyResult; +import at.gv.egiz.pdfas.lib.backend.PDFASBackend; +import at.gv.egiz.pdfas.lib.impl.backend.BackendLoader; import at.gv.egiz.pdfas.lib.impl.configuration.ConfigurationImpl; -import at.gv.egiz.pdfas.lib.impl.configuration.SignatureProfileConfiguration; -import at.gv.egiz.pdfas.lib.impl.positioning.Positioning; import at.gv.egiz.pdfas.lib.impl.preprocessor.PreProcessorLoader; import at.gv.egiz.pdfas.lib.impl.signing.IPdfSigner; -import at.gv.egiz.pdfas.lib.impl.signing.PdfSignerFactory; -import at.gv.egiz.pdfas.lib.impl.signing.pdfbox.PdfboxSignerWrapper; -import at.gv.egiz.pdfas.lib.impl.signing.sig_interface.SignatureDataExtractor; -import at.gv.egiz.pdfas.lib.impl.stamping.IPDFStamper; -import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject; -import at.gv.egiz.pdfas.lib.impl.stamping.StamperFactory; -import at.gv.egiz.pdfas.lib.impl.stamping.TableFactory; -import at.gv.egiz.pdfas.lib.impl.stamping.pdfbox.PDFAsVisualSignatureProperties; -import at.gv.egiz.pdfas.lib.impl.stamping.pdfbox.PdfBoxVisualObject; +import at.gv.egiz.pdfas.lib.impl.signing.PDFASSignatureExtractor; import at.gv.egiz.pdfas.lib.impl.status.OperationStatus; -import at.gv.egiz.pdfas.lib.impl.status.PDFObject; import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature; import at.gv.egiz.pdfas.lib.impl.verify.IVerifier; import at.gv.egiz.pdfas.lib.impl.verify.IVerifyFilter; import at.gv.egiz.pdfas.lib.impl.verify.VerifierDispatcher; import at.gv.egiz.pdfas.lib.util.SignatureUtils; -import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; -import at.knowcenter.wag.egov.egiz.pdf.TablePos; -import at.knowcenter.wag.egov.egiz.table.Table; public class PdfAsImpl implements PdfAs, IConfigurationConstants, ErrorConstants { @@ -160,16 +137,27 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants, // execute pre Processors signPreProcessing(parameter); - + + // allocated Backend + PDFASBackend backend = BackendLoader.getPDFASBackend(); + + if (backend == null) { + throw new PDFASError(ERROR_NO_BACKEND); + } + ISettings settings = (ISettings) parameter.getConfiguration(); - status = new OperationStatus(settings, parameter); + status = new OperationStatus(settings, parameter, backend); + + IPdfSigner signer = backend.getPdfSigner(); + + status.setPdfObject(signer.buildPDFObject(status)); // set Original PDF Document Data status.getPdfObject() .setOriginalDocument(parameter.getDataSource()); - PDDocument doc = status.getPdfObject().getDocument(); - PDFUtils.checkPDFPermissions(doc); + // Check PDF Permissions + signer.checkPDFPermissions(status.getPdfObject()); // PlaceholderConfiguration placeholderConfiguration = status // .getPlaceholderConfiguration(); @@ -196,9 +184,9 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants, // this.stampPdf(status); // Create signature - IPdfSigner signer = PdfSignerFactory.createPdfSigner(); - signer.signPDF(status.getPdfObject(), requestedSignature, - new PdfboxSignerWrapper(status.getSignParamter() + + signer.signPDF(status.getPdfObject(), requestedSignature, signer + .buildSignaturInterface(status.getSignParamter() .getPlainSigner(), parameter, requestedSignature)); // ================================================================ @@ -225,140 +213,18 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants, // execute pre Processors verifyPreProcessing(parameter); - - int signatureToVerify = parameter.getWhichSignature(); - int currentSignature = 0; - PDDocument doc = null; - try { - List<VerifyResult> result = new ArrayList<VerifyResult>(); - ISettings settings = (ISettings) parameter.getConfiguration(); - VerifierDispatcher verifier = new VerifierDispatcher(settings); - doc = PDDocument.load(parameter.getDataSource().getInputStream()); - COSDictionary trailer = doc.getDocument().getTrailer(); - if (trailer == null) { - // No signatures ... - return result; - } - COSDictionary root = (COSDictionary) trailer - .getDictionaryObject(COSName.ROOT); - if (root == null) { - // No signatures ... - return result; - } - COSDictionary acroForm = (COSDictionary) root - .getDictionaryObject(COSName.ACRO_FORM); - if (acroForm == null) { - // No signatures ... - return result; - } - COSArray fields = (COSArray) acroForm - .getDictionaryObject(COSName.FIELDS); - if (fields == null) { - // No signatures ... - return result; - } + // allocated Backend + PDFASBackend backend = BackendLoader.getPDFASBackend(); - int lastSig = -1; - for (int i = 0; i < fields.size(); i++) { - COSDictionary field = (COSDictionary) fields.getObject(i); - String type = field.getNameAsString("FT"); - if ("Sig".equals(type)) { - lastSig = i; - } - } + if (backend == null) { + throw new PDFASError(ERROR_NO_BACKEND); + } - byte[] inputData = IOUtils.toByteArray(parameter.getDataSource() - .getInputStream()); - - for (int i = 0; i < fields.size(); i++) { - COSDictionary field = (COSDictionary) fields.getObject(i); - String type = field.getNameAsString("FT"); - if ("Sig".equals(type)) { - boolean verifyThis = true; - - if (signatureToVerify >= 0) { - // verify only specific siganture! - verifyThis = signatureToVerify == currentSignature; - } - - if (signatureToVerify == -2) { - verifyThis = i == lastSig; - } - - if (verifyThis) { - logger.trace("Found Signature: "); - COSBase base = field.getDictionaryObject("V"); - COSDictionary dict = (COSDictionary) base; - - logger.debug("Signer: " + dict.getNameAsString("Name")); - logger.debug("SubFilter: " - + dict.getNameAsString("SubFilter")); - logger.debug("Filter: " - + dict.getNameAsString("Filter")); - logger.debug("Modified: " + dict.getNameAsString("M")); - COSArray byteRange = (COSArray) dict - .getDictionaryObject("ByteRange"); - - StringBuilder sb = new StringBuilder(); - int[] bytes = new int[byteRange.size()]; - for (int j = 0; j < byteRange.size(); j++) { - bytes[j] = byteRange.getInt(j); - sb.append(" " + bytes[j]); - } - - logger.debug("ByteRange" + sb.toString()); - - COSString content = (COSString) dict - .getDictionaryObject("Contents"); - - ByteArrayOutputStream contentData = new ByteArrayOutputStream(); - for (int j = 0; j < bytes.length; j = j + 2) { - int offset = bytes[j]; - int length = bytes[j + 1]; - - contentData.write(inputData, offset, length); - } - contentData.close(); - - IVerifyFilter verifyFilter = verifier.getVerifier( - dict.getNameAsString("Filter"), - dict.getNameAsString("SubFilter")); - - IVerifier lvlVerifier = verifier - .getVerifierByLevel(parameter - .getSignatureVerificationLevel()); - lvlVerifier.setConfiguration(parameter - .getConfiguration()); - if (verifyFilter != null) { - List<VerifyResult> results = verifyFilter.verify( - contentData.toByteArray(), - content.getBytes(), - parameter.getVerificationTime(), bytes, - lvlVerifier); - if (results != null && !results.isEmpty()) { - result.addAll(results); - } - } - } - currentSignature++; - } - } - return result; - } catch (IOException e) { - logger.error("Failed to verify document", e); - throw ErrorExtractor.searchPdfAsError(e); - } catch (PdfAsException e) { - logger.error("Failed to verify document", e); + try { + return backend.getVerifier().verify(parameter); + } catch (Throwable e) { throw ErrorExtractor.searchPdfAsError(e); - } finally { - if (doc != null) { - try { - doc.close(); - } catch (IOException e) { - logger.info("Failed to close doc"); - } - } } } @@ -380,9 +246,21 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants, // execute pre Processors signPreProcessing(parameter); - + + // allocated Backend + PDFASBackend backend = BackendLoader.getPDFASBackend(); + + if (backend == null) { + throw new PDFASError(ERROR_NO_BACKEND); + } + ISettings settings = (ISettings) parameter.getConfiguration(); - OperationStatus status = new OperationStatus(settings, parameter); + OperationStatus status = new OperationStatus(settings, parameter, + backend); + + IPdfSigner signer = backend.getPdfSigner(); + + status.setPdfObject(signer.buildPDFObject(status)); RequestedSignature requestedSignature = new RequestedSignature( status); @@ -428,11 +306,14 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants, .getPDFFilter(); String pdfSubFilter = status.getSignParamter().getPlainSigner() .getPDFSubFilter(); - SignatureDataExtractor signatureDataExtractor = new SignatureDataExtractor( - request.getCertificate(), pdfFilter, pdfSubFilter, - status.getSigningDate()); - IPdfSigner signer = PdfSignerFactory.createPdfSigner(); + IPdfSigner signer = status.getBackend().getPdfSigner(); + + PDFASSignatureExtractor signatureDataExtractor = signer + .buildBlindSignaturInterface(request.getCertificate(), + pdfFilter, pdfSubFilter, + status.getSigningDate()); + signer.signPDF(status.getPdfObject(), status.getRequestedSignature(), signatureDataExtractor); @@ -462,9 +343,8 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants, // Inject signature byte[] into signedDocument int offset = request.getSignatureDataByteRange()[1] + 1; - String signature = new COSString(request.getSignature()) - .getHexString(); - byte[] pdfSignature = signature.getBytes(); + byte[] pdfSignature = status.getBackend().getPdfSigner() + .rewritePlainSignature(request.getSignature()); // byte[] input = // PDFUtils.blackOutSignature(status.getPdfObject().getSignedDocument(), // request.getSignatureDataByteRange()); @@ -517,53 +397,61 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants, private void listPreProcessors(List<PreProcessor> preProcessors) { logger.debug("--------------"); logger.debug("Listing PreProcessors:"); - + Iterator<PreProcessor> preProcessorsIterator = preProcessors.iterator(); int idx = 0; - while(preProcessorsIterator.hasNext()) { + while (preProcessorsIterator.hasNext()) { PreProcessor preProcessor = preProcessorsIterator.next(); - logger.debug("{}: {} [{}]", idx, preProcessor.getName(), preProcessor.getClass().getName()); + logger.debug("{}: {} [{}]", idx, preProcessor.getName(), + preProcessor.getClass().getName()); idx++; } logger.debug("--------------"); } - - private void verifyPreProcessing(VerifyParameter parameter) throws PDFASError { - List<PreProcessor> preProcessors = PreProcessorLoader.getPreProcessors(parameter.getConfiguration()); - + + private void verifyPreProcessing(VerifyParameter parameter) + throws PDFASError { + List<PreProcessor> preProcessors = PreProcessorLoader + .getPreProcessors(parameter.getConfiguration()); + listPreProcessors(preProcessors); - + logger.debug("executing PreProcessors for verifing:"); Iterator<PreProcessor> preProcessorsIterator = preProcessors.iterator(); - - while(preProcessorsIterator.hasNext()) { + + while (preProcessorsIterator.hasNext()) { PreProcessor preProcessor = preProcessorsIterator.next(); - logger.debug("executing: {} [{}]", preProcessor.getName(), preProcessor.getClass().getName()); + logger.debug("executing: {} [{}]", preProcessor.getName(), + preProcessor.getClass().getName()); preProcessor.verify(parameter); - logger.debug("done executing: {} [{}]", preProcessor.getName(), preProcessor.getClass().getName()); + logger.debug("done executing: {} [{}]", preProcessor.getName(), + preProcessor.getClass().getName()); } - + logger.debug("executing PreProcessors for verifing done"); } - + private void signPreProcessing(SignParameter parameter) throws PDFASError { - List<PreProcessor> preProcessors = PreProcessorLoader.getPreProcessors(parameter.getConfiguration()); - + List<PreProcessor> preProcessors = PreProcessorLoader + .getPreProcessors(parameter.getConfiguration()); + listPreProcessors(preProcessors); - + logger.debug("executing PreProcessors for signing:"); Iterator<PreProcessor> preProcessorsIterator = preProcessors.iterator(); - - while(preProcessorsIterator.hasNext()) { + + while (preProcessorsIterator.hasNext()) { PreProcessor preProcessor = preProcessorsIterator.next(); - logger.debug("executing: {} [{}]", preProcessor.getName(), preProcessor.getClass().getName()); + logger.debug("executing: {} [{}]", preProcessor.getName(), + preProcessor.getClass().getName()); preProcessor.sign(parameter); - logger.debug("done executing: {} [{}]", preProcessor.getName(), preProcessor.getClass().getName()); + logger.debug("done executing: {} [{}]", preProcessor.getName(), + preProcessor.getClass().getName()); } - + logger.debug("executing PreProcessors for signing done"); } - + private SignResult createSignResult(OperationStatus status) throws IOException { // ================================================================ @@ -580,7 +468,8 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants, } public Image generateVisibleSignaturePreview(SignParameter parameter, - java.security.cert.X509Certificate cert, int resolution) throws PDFASError { + java.security.cert.X509Certificate cert, int resolution) + throws PDFASError { OperationStatus status = null; try { @@ -589,14 +478,20 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants, throw new PDFASError(ERROR_SET_INVALID_SETTINGS_OBJ); } X509Certificate iaikCert; - if(!(cert instanceof X509Certificate)) { + if (!(cert instanceof X509Certificate)) { iaikCert = new X509Certificate(cert.getEncoded()); } else { - iaikCert = (X509Certificate)cert; + iaikCert = (X509Certificate) cert; } - + // allocated Backend + PDFASBackend backend = BackendLoader.getPDFASBackend(); + ISettings settings = (ISettings) parameter.getConfiguration(); - status = new OperationStatus(settings, parameter); + status = new OperationStatus(settings, parameter, backend); + + IPdfSigner signer = backend.getPdfSigner(); + + status.setPdfObject(signer.buildPDFObject(status)); RequestedSignature requestedSignature = new RequestedSignature( status); @@ -607,93 +502,8 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants, return null; } - PDFObject pdfObject = status.getPdfObject(); - - PDDocument origDoc = new PDDocument(); - origDoc.addPage(new PDPage(PDPage.PAGE_SIZE_A4)); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - origDoc.save(baos); - baos.close(); - - pdfObject.setOriginalDocument(new ByteArrayDataSource(baos - .toByteArray())); - - SignatureProfileSettings signatureProfileSettings = TableFactory - .createProfile(requestedSignature.getSignatureProfileID(), - pdfObject.getStatus().getSettings()); - - // create Table describtion - Table main = TableFactory.createSigTable(signatureProfileSettings, - MAIN, pdfObject.getStatus(), requestedSignature); - - IPDFStamper stamper = StamperFactory.createDefaultStamper(pdfObject - .getStatus().getSettings()); - - IPDFVisualObject visualObject = stamper.createVisualPDFObject( - pdfObject, main); - - SignatureProfileConfiguration signatureProfileConfiguration = pdfObject - .getStatus().getSignatureProfileConfiguration( - requestedSignature.getSignatureProfileID()); - - String signaturePosString = signatureProfileConfiguration - .getDefaultPositioning(); - PositioningInstruction positioningInstruction = null; - if (signaturePosString != null) { - positioningInstruction = Positioning.determineTablePositioning( - new TablePos(signaturePosString), "", origDoc, - visualObject, false); - } else { - positioningInstruction = Positioning.determineTablePositioning( - new TablePos(), "", origDoc, visualObject, false); - } - - origDoc.close(); - - SignaturePositionImpl position = new SignaturePositionImpl(); - position.setX(positioningInstruction.getX()); - position.setY(positioningInstruction.getY()); - position.setPage(positioningInstruction.getPage()); - position.setHeight(visualObject.getHeight()); - position.setWidth(visualObject.getWidth()); - - requestedSignature.setSignaturePosition(position); - - PDFAsVisualSignatureProperties properties = new PDFAsVisualSignatureProperties( - pdfObject.getStatus().getSettings(), pdfObject, - (PdfBoxVisualObject) visualObject, positioningInstruction); - - properties.buildSignature(); - PDDocument visualDoc = PDDocument.load(properties - .getVisibleSignature()); - // PDPageable pageable = new PDPageable(visualDoc); - List<PDPage> pages = new ArrayList<PDPage>(); - visualDoc.getDocumentCatalog().getPages().getAllKids(pages); - - PDPage firstPage = pages.get(0); - - float stdRes = 72; - float targetRes = resolution; - float factor = targetRes / stdRes; - - BufferedImage outputImage = firstPage.convertToImage( - BufferedImage.TYPE_4BYTE_ABGR, (int) targetRes); - - BufferedImage cutOut = new BufferedImage( - (int) (position.getWidth() * factor), - (int) (position.getHeight() * factor), - BufferedImage.TYPE_4BYTE_ABGR); - - Graphics2D graphics = (Graphics2D) cutOut.getGraphics(); - - graphics.drawImage(outputImage, 0, 0, cutOut.getWidth(), cutOut - .getHeight(), (int) (1 * factor), (int) (outputImage - .getHeight() - ((position.getHeight() + 1) * factor)), - (int) ((1 + position.getWidth()) * factor), - (int) (outputImage.getHeight() - - ((position.getHeight() + 1) * factor) + (position - .getHeight() * factor)), null); - return cutOut; + return signer.generateVisibleSignaturePreview(parameter, iaikCert, + resolution, status, requestedSignature); } catch (PdfAsException e) { logger.error("PDF-AS Exception", e); throw ErrorExtractor.searchPdfAsError(e); diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/backend/BackendLoader.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/backend/BackendLoader.java new file mode 100644 index 00000000..4e00209a --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/backend/BackendLoader.java @@ -0,0 +1,107 @@ +package at.gv.egiz.pdfas.lib.impl.backend; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.ServiceLoader; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.pdfas.common.exceptions.ErrorConstants; +import at.gv.egiz.pdfas.common.exceptions.PDFASError; +import at.gv.egiz.pdfas.lib.api.Configuration; +import at.gv.egiz.pdfas.lib.backend.PDFASBackend; + +/** + * The Class BackendLoader. + */ +public class BackendLoader implements ErrorConstants { + + /** The Constant logger. */ + private static final Logger logger = LoggerFactory + .getLogger(BackendLoader.class); + + /** The pdf as backend loader. */ + private static ServiceLoader<PDFASBackend> pdfAsBackendLoader = ServiceLoader.load(PDFASBackend.class); + + /** The available backends. */ + private static Map<String, PDFASBackend> availableBackends = new HashMap<String, PDFASBackend>(); + + /** The Constant BACKEND_CONFIG. */ + public static final String BACKEND_CONFIG = "runtime.backend"; + + /** The default backend. */ + private static PDFASBackend defaultBackend = null; + + static { + logger.debug("building PDF-AS Backends"); + + Iterator<PDFASBackend> backendIterator = pdfAsBackendLoader.iterator(); + + while(backendIterator.hasNext()) { + PDFASBackend backend = backendIterator.next(); + logger.debug("Loading " + backend.getName() + " [" + backend.getClass().getName() + "]"); + availableBackends.put(backend.getName(), backend); + logger.debug("PDF-Backend added " + backend.getName()); + if(backend.usedAsDefault()) { + defaultBackend = backend; + logger.debug("PDF-Backend added as default " + backend.getName()); + } + } + + logger.debug("PDF-AS Backends constructed"); + + if(defaultBackend != null) { + logger.debug("Default backend is " + defaultBackend.getName()); + } + } + + /** + * Gets the PDFAS backend. + * + * @param configuration the configuration + * @return the PDFAS backend + * @throws PDFASError the PDFAS error + */ + public static PDFASBackend getPDFASBackend(Configuration configuration) throws PDFASError { + String backendName = configuration.getValue(BACKEND_CONFIG); + return getPDFASBackend(backendName); + } + + /** + * Gets the PDFAS backend. + * + * @param name the name + * @return the PDFAS backend + * @throws PDFASError the PDFAS error + */ + public static PDFASBackend getPDFASBackend(String name) throws PDFASError { + if(name != null) { + if(availableBackends.containsKey(name)) { + return availableBackends.get(name); + } + throw new PDFASError(ERROR_NO_BACKEND); + } + + if(defaultBackend != null) { + return defaultBackend; + } + + throw new PDFASError(ERROR_NO_BACKEND); + } + + /** + * Gets the PDFAS backend. + * + * @return the PDFAS backend + * @throws PDFASError the PDFAS error + */ + public static PDFASBackend getPDFASBackend() throws PDFASError { + if(defaultBackend != null) { + return defaultBackend; + } + + throw new PDFASError(ERROR_NO_BACKEND); + } +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderExtractor.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderExtractor.java new file mode 100644 index 00000000..62a26a16 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderExtractor.java @@ -0,0 +1,9 @@ +package at.gv.egiz.pdfas.lib.impl.placeholder; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.lib.impl.status.PDFObject; + +public interface PlaceholderExtractor { + public SignaturePlaceholderData extract(PDFObject doc, + String placeholderId, int matchMode) throws PdfAsException; +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderFilter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderFilter.java index 1bb57cb8..1417f634 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderFilter.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderFilter.java @@ -31,59 +31,18 @@ import at.gv.egiz.pdfas.lib.api.IConfigurationConstants; import at.gv.egiz.pdfas.lib.impl.status.OperationStatus; public class PlaceholderFilter implements IConfigurationConstants { - + public static SignaturePlaceholderData checkPlaceholderSignature( - OperationStatus status, ISettings settings) - throws PdfAsException, IOException { - + OperationStatus status, ISettings settings) throws PdfAsException, + IOException { + if (status.getPlaceholderConfiguration().isGlobalPlaceholderEnabled()) { - SignaturePlaceholderData signaturePlaceholderData = SignaturePlaceholderExtractor - .extract(status.getPdfObject().getDocument(), null, 1); + PlaceholderExtractor extractor = status.getBackend() + .getPlaceholderExtractor(); + SignaturePlaceholderData signaturePlaceholderData = extractor + .extract(status.getPdfObject(), null, 1); return signaturePlaceholderData; - /* - if (signaturePlaceholderData != null) { - RequestedSignature requestedSignature = status - .getRequestedSignature(); - - if (signaturePlaceholderData.getProfile() != null) { - requestedSignature - .setSignatureProfileID(signaturePlaceholderData - .getProfile()); - } - - //String signatureProfileID = requestedSignature - // .getSignatureProfileID(); - - TablePos tablePos = signaturePlaceholderData.getTablePos(); - - return tablePos; - - */ - /* - SignatureProfileSettings signatureProfileSettings = TableFactory - .createProfile(signatureProfileID, settings); - - Table main = TableFactory.createSigTable( - signatureProfileSettings, MAIN, settings, - requestedSignature); - - IPDFStamper stamper = StamperFactory - .createDefaultStamper(settings); - - IPDFVisualObject visualObject = stamper.createVisualPDFObject( - status.getPdfObject(), main); - - PDDocument originalDocument = PDDocument - .load(new ByteArrayInputStream(status.getPdfObject() - .getOriginalDocument())); - - PositioningInstruction positioningInstruction = Positioning - .determineTablePositioning(tablePos, "", - originalDocument, visualObject, false); - - return positioningInstruction;*/ - //} } return null; } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderData.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderData.java index 333e581b..cf0ad149 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderData.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderData.java @@ -100,7 +100,7 @@ public class SignaturePlaceholderData { return tablePos; } - void setTablePos(TablePos tablePos) { + public void setTablePos(TablePos tablePos) { this.tablePos = tablePos; } @@ -113,7 +113,7 @@ public class SignaturePlaceholderData { return profile; } - void setProfile(String profile) { + public void setProfile(String profile) { this.profile = profile; } @@ -125,7 +125,7 @@ public class SignaturePlaceholderData { return type; } - void setType(String type) { + public void setType(String type) { this.type = type; } @@ -138,7 +138,7 @@ public class SignaturePlaceholderData { return key; } - void setKey(String key) { + public void setKey(String key) { this.key = key; } @@ -146,7 +146,7 @@ public class SignaturePlaceholderData { return getClass().toString() + ": profile=" + profile + "; type=" + type + "; sigKey=" + key + "; table pos=" + tablePos; } - void setPlaceholderName(String name) { + public void setPlaceholderName(String name) { this.placeholderName = name; } @@ -168,7 +168,7 @@ public class SignaturePlaceholderData { return id; } - void setId(String id) { + public void setId(String id) { this.id = id; } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderExtractor.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderExtractor.java deleted file mode 100644 index 93162bd3..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderExtractor.java +++ /dev/null @@ -1,371 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -/** - * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright> - * 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. - */ -package at.gv.egiz.pdfas.lib.impl.placeholder; - -import java.awt.geom.AffineTransform; -import java.awt.geom.NoninvertibleTransformException; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.InputStream; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Vector; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.pdfbox.cos.COSBase; -import org.apache.pdfbox.cos.COSName; -import org.apache.pdfbox.exceptions.WrappedIOException; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDPage; -import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObject; -import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage; -import org.apache.pdfbox.util.Matrix; -import org.apache.pdfbox.util.PDFOperator; -import org.apache.pdfbox.util.PDFStreamEngine; -import org.apache.pdfbox.util.ResourceLoader; - -import at.gv.egiz.pdfas.common.exceptions.PDFIOException; -import at.gv.egiz.pdfas.common.exceptions.PdfAsException; -import at.gv.egiz.pdfas.common.exceptions.PlaceholderExtractionException; -import at.knowcenter.wag.egov.egiz.pdf.TablePos; - -import com.google.zxing.BarcodeFormat; -import com.google.zxing.BinaryBitmap; -import com.google.zxing.DecodeHintType; -import com.google.zxing.LuminanceSource; -import com.google.zxing.MultiFormatReader; -import com.google.zxing.NotFoundException; -import com.google.zxing.ReaderException; -import com.google.zxing.Result; -import com.google.zxing.client.j2se.BufferedImageLuminanceSource; -import com.google.zxing.common.HybridBinarizer; - -////// - -/** - * Extract all relevant information from a placeholder image. - * - * @author exthex - * - */ -public class SignaturePlaceholderExtractor extends PDFStreamEngine { - /** - * The log. - */ - private static Log log = LogFactory - .getLog(SignaturePlaceholderExtractor.class); - - public static final String QR_PLACEHOLDER_IDENTIFIER = "PDF-AS-POS"; - public static final int PLACEHOLDER_MATCH_MODE_STRICT = 0; - public static final int PLACEHOLDER_MATCH_MODE_MODERATE = 1; - public static final int PLACEHOLDER_MATCH_MODE_LENIENT = 2; - - private List<SignaturePlaceholderData> placeholders = new Vector<SignaturePlaceholderData>(); - private int currentPage = 0; - - private SignaturePlaceholderExtractor(String placeholderId, - int placeholderMatchMode) throws IOException { - super(ResourceLoader.loadProperties( - "placeholder/pdfbox-reader.properties", true)); - } - - /** - * Search the document for placeholder images and possibly included - * additional info.<br/> - * Searches only for the first placeholder page after page from top. - * - * @param inputStream - * @return all available info from the first found placeholder. - * @throws PDFDocumentException - * if the document could not be read. - * @throws PlaceholderExtractionException - * if STRICT matching mode was requested and no suitable - * placeholder could be found. - */ - public static SignaturePlaceholderData extract(PDDocument doc, - String placeholderId, int matchMode) throws PdfAsException { - SignaturePlaceholderContext.setSignaturePlaceholderData(null); - - SignaturePlaceholderExtractor extractor; - try { - extractor = new SignaturePlaceholderExtractor(placeholderId, - matchMode); - } catch (IOException e2) { - throw new PDFIOException("error.pdf.io.04", e2); - } - List<?> pages = doc.getDocumentCatalog().getAllPages(); - Iterator<?> iter = pages.iterator(); - int pageNr = 0; - while (iter.hasNext()) { - pageNr++; - PDPage page = (PDPage) iter.next(); - try { - extractor.setCurrentPage(pageNr); - extractor.processStream(page, page.findResources(), page - .getContents().getStream()); - SignaturePlaceholderData ret = matchPlaceholderPage( - extractor.placeholders, placeholderId, matchMode); - if (ret != null) { - SignaturePlaceholderContext - .setSignaturePlaceholderData(ret); - return ret; - } - } catch (IOException e1) { - throw new PDFIOException("error.pdf.io.04", e1); - } - - } - if (extractor.placeholders.size() > 0) { - SignaturePlaceholderData ret = matchPlaceholderDocument( - extractor.placeholders, placeholderId, matchMode); - SignaturePlaceholderContext.setSignaturePlaceholderData(ret); - return ret; - } - // no placeholders found, apply strict mode if set - if (matchMode == PLACEHOLDER_MATCH_MODE_STRICT) { - throw new PlaceholderExtractionException("error.pdf.stamp.09"); - } - - return null; - } - - private static SignaturePlaceholderData matchPlaceholderDocument( - List<SignaturePlaceholderData> placeholders, String placeholderId, - int matchMode) throws PlaceholderExtractionException { - - if (matchMode == PLACEHOLDER_MATCH_MODE_STRICT) - throw new PlaceholderExtractionException("error.pdf.stamp.09"); - - if (placeholders.size() == 0) - return null; - - for (int i = 0; i < placeholders.size(); i++) { - SignaturePlaceholderData spd = placeholders.get(i); - if (spd.getId() == null) - return spd; - } - - if (matchMode == PLACEHOLDER_MATCH_MODE_LENIENT) - return placeholders.get(0); - - return null; - } - - private static SignaturePlaceholderData matchPlaceholderPage( - List<SignaturePlaceholderData> placeholders, String placeholderId, - int matchMode) { - if (placeholders.size() == 0) - return null; - for (int i = 0; i < placeholders.size(); i++) { - SignaturePlaceholderData data = placeholders.get(i); - if (placeholderId != null && placeholderId.equals(data.getId())) - return data; - if (placeholderId == null && data.getId() == null) - return data; - } - return null; - } - - private void setCurrentPage(int pageNr) { - this.currentPage = pageNr; - } - - @Override - protected void processOperator(PDFOperator operator, List<COSBase> arguments) - throws IOException { - String operation = operator.getOperation(); - if (operation.equals("Do")) { - COSName objectName = (COSName) arguments.get(0); - Map<?, ?> xobjects = getResources().getXObjects(); - PDXObject xobject = (PDXObject) xobjects.get(objectName.getName()); - if (xobject instanceof PDXObjectImage) { - try { - PDXObjectImage image = (PDXObjectImage) xobject; - SignaturePlaceholderData data = checkImage(image); - if (data != null) { - PDPage page = getCurrentPage(); - Matrix ctm = getGraphicsState() - .getCurrentTransformationMatrix(); - double rotationInRadians = (page.findRotation() * Math.PI) / 180; - - AffineTransform rotation = new AffineTransform(); - rotation.setToRotation(rotationInRadians); - AffineTransform rotationInverse = rotation - .createInverse(); - Matrix rotationInverseMatrix = new Matrix(); - rotationInverseMatrix - .setFromAffineTransform(rotationInverse); - Matrix rotationMatrix = new Matrix(); - rotationMatrix.setFromAffineTransform(rotation); - - Matrix unrotatedCTM = ctm - .multiply(rotationInverseMatrix); - - float x = unrotatedCTM.getXPosition(); - float y = unrotatedCTM.getYPosition() - + unrotatedCTM.getYScale(); - float w = unrotatedCTM.getXScale(); - - String posString = "p:" + currentPage + ";x:" + x - + ";y:" + y + ";w:" + w; - try { - data.setTablePos(new TablePos(posString)); - data.setPlaceholderName(objectName.getName()); - placeholders.add(data); - } catch (PdfAsException e) { - throw new WrappedIOException(e); - } - } - } catch (NoninvertibleTransformException e) { - throw new WrappedIOException(e); - } - } - } else { - super.processOperator(operator, arguments); - } - } - - /** - * Checks an image if it is a placeholder for a signature. - * - * @param image - * @return - * @throws IOException - */ - private SignaturePlaceholderData checkImage(PDXObjectImage image) - throws IOException { - BufferedImage bimg = image.getRGBImage(); - if (bimg == null) { - String type = image.getSuffix(); - if (type != null) { - type = type.toUpperCase() + " images"; - } else { - type = "Image type"; - } - log.info("Unable to extract image for QRCode analysis. " - + type - + " not supported. Add additional JAI Image filters to your classpath. Refer to https://jai.dev.java.net. Skipping image."); - return null; - } - if (bimg.getHeight() < 10 || bimg.getWidth() < 10) { - log.debug("Image too small for QRCode. Skipping image."); - return null; - } - - LuminanceSource source = new BufferedImageLuminanceSource(bimg); - BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); - Result result; - long before = System.currentTimeMillis(); - try { - Hashtable<DecodeHintType, Vector<BarcodeFormat>> hints = new Hashtable<DecodeHintType, Vector<BarcodeFormat>>(); - Vector<BarcodeFormat> formats = new Vector<BarcodeFormat>(); - formats.add(BarcodeFormat.QR_CODE); - hints.put(DecodeHintType.POSSIBLE_FORMATS, formats); - result = new MultiFormatReader().decode(bitmap, hints); - - String text = result.getText(); - String profile = null; - String type = null; - String sigKey = null; - String id = null; - if (text != null) { - if (text.startsWith(QR_PLACEHOLDER_IDENTIFIER)) { - String[] data = text.split(";"); - if (data.length > 1) { - for (int i = 1; i < data.length; i++) { - String kvPair = data[i]; - String[] kv = kvPair.split("="); - if (kv.length != 2) { - log.debug("Invalid parameter in placeholder data: " - + kvPair); - } else { - if (kv[0] - .equalsIgnoreCase(SignaturePlaceholderData.ID_KEY)) { - id = kv[1]; - } else if (kv[0] - .equalsIgnoreCase(SignaturePlaceholderData.PROFILE_KEY)) { - profile = kv[1]; - } else if (kv[0] - .equalsIgnoreCase(SignaturePlaceholderData.SIG_KEY_KEY)) { - sigKey = kv[1]; - } else if (kv[0] - .equalsIgnoreCase(SignaturePlaceholderData.TYPE_KEY)) { - type = kv[1]; - } - } - } - } - return new SignaturePlaceholderData(profile, type, sigKey, - id); - } else { - log.warn("QR-Code found but does not start with \"" - + QR_PLACEHOLDER_IDENTIFIER - + "\". Ignoring QR placeholder."); - } - } - } catch (ReaderException re) { - if (log.isDebugEnabled()) { - log.debug("Could not decode - not a placeholder. needed: " - + (System.currentTimeMillis() - before)); - } - if (!(re instanceof NotFoundException)) { - if (log.isInfoEnabled()) { - log.info("Failed to decode image", re); - } - } - } catch (ArrayIndexOutOfBoundsException e) { - if (log.isInfoEnabled()) { - log.info("Failed to decode image. Probably a zxing bug", e); - } - } - return null; - } - -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/Positioning.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/Positioning.java deleted file mode 100644 index 7c8cb2e4..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/Positioning.java +++ /dev/null @@ -1,244 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -package at.gv.egiz.pdfas.lib.impl.positioning; - -import java.util.ArrayList; -import java.util.List; - -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.PDPage; -import org.apache.pdfbox.pdmodel.PDPageNode; -import org.apache.pdfbox.pdmodel.common.PDRectangle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.gv.egiz.pdfas.common.exceptions.PdfAsException; -import at.gv.egiz.pdfas.common.utils.PDFUtils; -import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject; -import at.knowcenter.wag.egov.egiz.pdf.PDFUtilities; -import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; -import at.knowcenter.wag.egov.egiz.pdf.TablePos; - -/** - * Created with IntelliJ IDEA. User: afitzek Date: 8/29/13 Time: 4:30 PM To - * change this template use File | Settings | File Templates. - */ -public class Positioning { - - private static final Logger logger = LoggerFactory - .getLogger(Positioning.class); - - /** - * The left/right margin. - */ - public static final float SIGNATURE_MARGIN_HORIZONTAL = 50f; - - /** - * The top/bottom margin. - */ - public static final float SIGNATURE_MARGIN_VERTICAL = 20f; - - /** - * 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 pdfDataSource - * The pdf. - * @param pdf_table - * The pdf table to be written. - * @return Returns the PositioningInformation. - * @throws PdfAsException - * F.e. - */ - public static PositioningInstruction determineTablePositioning( - TablePos pos, String signature_type, PDDocument pdfDataSource, - IPDFVisualObject pdf_table, boolean legacy32) throws PdfAsException { - return adjustSignatureTableandCalculatePosition(pdfDataSource, - pdf_table, pos, legacy32); - } - - /** - * 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 pdfDataSource - * The PDF document. - * @param pdf_table - * The PDFPTable to be placed. - * @return Returns the position where the PDFPTable should be placed. - * @throws PdfAsException - * F.e. - */ - public static PositioningInstruction adjustSignatureTableandCalculatePosition( - final PDDocument pdfDataSource, IPDFVisualObject pdf_table, - TablePos pos, boolean legacy32) throws PdfAsException { - - PDFUtils.checkPDFPermissions(pdfDataSource); - // get pages of currentdocument - - int doc_pages = pdfDataSource.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."); - } - } - - PDPage pdPage = (PDPage) pdfDataSource.getDocumentCatalog() - .getAllPages().get(page - 1); - PDRectangle cropBox = pdPage.getCropBox(); - - // fallback to MediaBox if Cropbox not available! - - if (cropBox == null) { - cropBox = pdPage.findCropBox(); - } - - if (cropBox == null) { - cropBox = pdPage.findMediaBox(); - } - - // getPagedimensions - // Rectangle psize = reader.getPageSizeWithRotation(page); - // int page_rotation = reader.getPageRotation(page); - - // Integer rotation = pdPage.getRotation(); - // int page_rotation = rotation.intValue(); - - float page_width = cropBox.getWidth(); - float page_height = cropBox.getHeight(); - - // now we can calculate x-position - float pre_pos_x = SIGNATURE_MARGIN_HORIZONTAL; - if (!pos.isXauto()) { - // we do have absolute x - pre_pos_x = pos.getPosX(); - } - // calculate width - // center - float pre_width = page_width - 2 * 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.setWidth(width); - pdf_table.fixWidth(); - // pdf_table.setTotalWidth(width); - // pdf_table.setLockedWidth(true); - - final float table_height = pdf_table.getHeight(); - // now check pos_y - float pos_y = pos.getPosY(); - - // in case an absolute y position is already given OR - // if the table is related to an invisible signature - // there is no need for further calculations - // (fixed adding new page in case of invisible signatures) - if (!pos.isYauto() || table_height == 0) { - // 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.rotation); - } - // pos_y is auto - if (make_new_page) { - // ignore footer in new page - page++; - pos_y = page_height - SIGNATURE_MARGIN_VERTICAL; - return new PositioningInstruction(make_new_page, page, pos_x, - pos_y, pos.rotation); - } - // 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, */ - legacy32); - - 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_MARGIN_VERTICAL; - if (pos_y - footer_line <= table_height) { - make_new_page = true; - if (!pos.isPauto()) { - // we have to correct pagenumber - page = pdfDataSource.getNumberOfPages(); - } - page++; - // no text --> SIGNATURE_BORDER - pos_y = page_height - SIGNATURE_MARGIN_VERTICAL; - } - return new PositioningInstruction(make_new_page, page, pos_x, - pos_y, pos.rotation); - } - final float page_length = pre_page_length; - // we do have text take SIGNATURE_MARGIN - pos_y = page_height - page_length - SIGNATURE_MARGIN_VERTICAL; - 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 = pdfDataSource.getNumberOfPages(); - } - page++; - // no text --> SIGNATURE_BORDER - pos_y = page_height - SIGNATURE_MARGIN_VERTICAL; - } - return new PositioningInstruction(make_new_page, page, pos_x, pos_y, - pos.rotation); - - } - -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/IPdfSigner.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/IPdfSigner.java index 98ade583..6a249041 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/IPdfSigner.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/IPdfSigner.java @@ -23,13 +23,38 @@ ******************************************************************************/ package at.gv.egiz.pdfas.lib.impl.signing; +import iaik.x509.X509Certificate; + +import java.awt.Image; +import java.util.Calendar; + +import at.gv.egiz.pdfas.common.exceptions.PDFASError; import at.gv.egiz.pdfas.common.exceptions.PdfAsException; -import at.gv.egiz.pdfas.lib.impl.signing.sig_interface.PDFASSignatureInterface; +import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner; +import at.gv.egiz.pdfas.lib.api.sign.SignParameter; +import at.gv.egiz.pdfas.lib.impl.status.OperationStatus; import at.gv.egiz.pdfas.lib.impl.status.PDFObject; import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature; public interface IPdfSigner { - void signPDF(PDFObject pdfObject, - RequestedSignature requestedSignature, PDFASSignatureInterface signer) throws PdfAsException; + PDFASSignatureInterface buildSignaturInterface(IPlainSigner signer, + SignParameter parameters, RequestedSignature requestedSignature); + + PDFASSignatureExtractor buildBlindSignaturInterface( + X509Certificate certificate, String filter, String subfilter, + Calendar date); + + PDFObject buildPDFObject(OperationStatus operationStatus); + + void checkPDFPermissions(PDFObject object) throws PdfAsException; + + void signPDF(PDFObject pdfObject, RequestedSignature requestedSignature, + PDFASSignatureInterface signer) throws PdfAsException; + + byte[] rewritePlainSignature(byte[] plainSignature); + + public Image generateVisibleSignaturePreview(SignParameter parameter, + java.security.cert.X509Certificate cert, int resolution, OperationStatus status, + RequestedSignature requestedSignature) throws PDFASError; } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/PDFASSignatureExtractor.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/PDFASSignatureExtractor.java new file mode 100644 index 00000000..c8f94046 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/PDFASSignatureExtractor.java @@ -0,0 +1,5 @@ +package at.gv.egiz.pdfas.lib.impl.signing; + +public interface PDFASSignatureExtractor extends PDFASSignatureInterface { + public byte[] getSignatureData(); +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/PdfSignerFactory.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/PDFASSignatureInterface.java index 947574ba..db695614 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/PdfSignerFactory.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/PDFASSignatureInterface.java @@ -23,10 +23,10 @@ ******************************************************************************/ package at.gv.egiz.pdfas.lib.impl.signing; -import at.gv.egiz.pdfas.lib.impl.signing.pdfbox.PADESPDFBOXSigner; +import java.util.Calendar; -public class PdfSignerFactory { - public static IPdfSigner createPdfSigner() { - return new PADESPDFBOXSigner(); - } +public interface PDFASSignatureInterface { + public String getPDFSubFilter(); + public String getPDFFilter(); + public Calendar getSigningDate(); } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java deleted file mode 100644 index a129f18a..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java +++ /dev/null @@ -1,471 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -package at.gv.egiz.pdfas.lib.impl.signing.pdfbox; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.List; - -import org.apache.commons.io.IOUtils; -import org.apache.pdfbox.cos.COSBase; -import org.apache.pdfbox.cos.COSDictionary; -import org.apache.pdfbox.cos.COSName; -import org.apache.pdfbox.exceptions.COSVisitorException; -import org.apache.pdfbox.exceptions.SignatureException; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDDocumentCatalog; -import org.apache.pdfbox.pdmodel.PDPage; -import org.apache.pdfbox.pdmodel.PDPageNode; -import org.apache.pdfbox.pdmodel.PDResources; -import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent; -import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg; -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureOptions; -import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; -import org.apache.pdfbox.pdmodel.interactive.form.PDField; -import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.gv.egiz.pdfas.common.exceptions.PdfAsException; -import at.gv.egiz.pdfas.common.messages.MessageResolver; -import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings; -import at.gv.egiz.pdfas.common.utils.StreamUtils; -import at.gv.egiz.pdfas.common.utils.TempFileHelper; -import at.gv.egiz.pdfas.lib.api.IConfigurationConstants; -import at.gv.egiz.pdfas.lib.impl.SignaturePositionImpl; -import at.gv.egiz.pdfas.lib.impl.configuration.SignatureProfileConfiguration; -import at.gv.egiz.pdfas.lib.impl.placeholder.PlaceholderFilter; -import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderData; -import at.gv.egiz.pdfas.lib.impl.positioning.Positioning; -import at.gv.egiz.pdfas.lib.impl.signing.IPdfSigner; -import at.gv.egiz.pdfas.lib.impl.signing.sig_interface.PDFASSignatureInterface; -import at.gv.egiz.pdfas.lib.impl.stamping.IPDFStamper; -import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject; -import at.gv.egiz.pdfas.lib.impl.stamping.StamperFactory; -import at.gv.egiz.pdfas.lib.impl.stamping.TableFactory; -import at.gv.egiz.pdfas.lib.impl.stamping.ValueResolver; -import at.gv.egiz.pdfas.lib.impl.stamping.pdfbox.PDFAsVisualSignatureProperties; -import at.gv.egiz.pdfas.lib.impl.stamping.pdfbox.PdfBoxVisualObject; -import at.gv.egiz.pdfas.lib.impl.status.PDFObject; -import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature; -import at.gv.egiz.pdfas.lib.util.SignatureUtils; -import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; -import at.knowcenter.wag.egov.egiz.pdf.TablePos; -import at.knowcenter.wag.egov.egiz.table.Table; - -public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { - - private static final Logger logger = LoggerFactory - .getLogger(PADESPDFBOXSigner.class); - - public void signPDF(PDFObject pdfObject, - RequestedSignature requestedSignature, - PDFASSignatureInterface signer) throws PdfAsException { - String fisTmpFile = null; - - TempFileHelper helper = pdfObject.getStatus().getTempFileHelper(); - PDDocument doc = null; - try { - fisTmpFile = helper.getStaticFilename(); - - // write to temporary file - FileOutputStream fos = new FileOutputStream(new File(fisTmpFile)); - IOUtils.copy(pdfObject.getOriginalDocument().getInputStream(), fos); - - FileInputStream fis = new FileInputStream(new File(fisTmpFile)); - - doc = pdfObject.getDocument(); - - PDSignature signature = new PDSignature(); - signature.setFilter(COSName.getPDFName(signer.getPDFFilter())); // default - // filter - signature - .setSubFilter(COSName.getPDFName(signer.getPDFSubFilter())); - - SignatureProfileSettings signatureProfileSettings = TableFactory - .createProfile(requestedSignature.getSignatureProfileID(), - pdfObject.getStatus().getSettings()); - - ValueResolver resolver = new ValueResolver(requestedSignature, - pdfObject.getStatus()); - String signerName = resolver.resolve("SIG_SUBJECT", - signatureProfileSettings.getValue("SIG_SUBJECT"), - signatureProfileSettings); - - signature.setName(signerName); - signature.setSignDate(Calendar.getInstance()); - String signerReason = signatureProfileSettings.getSigningReason(); - - if (signerReason == null) { - signerReason = "PAdES Signature"; - } - - signature.setReason(signerReason); - logger.debug("Signing reason: " + signerReason); - - logger.debug("Signing @ " - + signer.getSigningDate().getTime().toString()); - // the signing date, needed for valid signature - // signature.setSignDate(signer.getSigningDate()); - - signer.setPDSignature(signature); - SignatureOptions options = new SignatureOptions(); - - // Is visible Signature - if (requestedSignature.isVisual()) { - logger.info("Creating visual siganture block"); - - SignatureProfileConfiguration signatureProfileConfiguration = pdfObject - .getStatus().getSignatureProfileConfiguration( - requestedSignature.getSignatureProfileID()); - - SignaturePlaceholderData signaturePlaceholderData = PlaceholderFilter - .checkPlaceholderSignature(pdfObject.getStatus(), - pdfObject.getStatus().getSettings()); - - TablePos tablePos = null; - - if (signaturePlaceholderData != null) { - // Placeholder found! - - if (signaturePlaceholderData.getProfile() != null) { - requestedSignature - .setSignatureProfileID(signaturePlaceholderData - .getProfile()); - } - - tablePos = signaturePlaceholderData.getTablePos(); - } - - if (tablePos == null) { - // ================================================================ - // PositioningStage (visual) -> find position or use fixed - // position - - String posString = pdfObject.getStatus().getSignParamter() - .getSignaturePosition(); - - TablePos signaturePos = null; - - String signaturePosString = signatureProfileConfiguration - .getDefaultPositioning(); - - if (signaturePosString != null) { - logger.debug("using signature Positioning: " - + signaturePos); - signaturePos = new TablePos(signaturePosString); - } - - logger.debug("using Positioning: " + posString); - - if (posString != null) { - // Merge Signature Position - tablePos = new TablePos(posString, signaturePos); - } else { - // Fallback to signature Position! - tablePos = signaturePos; - } - - if (tablePos == null) { - // Last Fallback default position - tablePos = new TablePos(); - } - } - boolean legacy32Position = signatureProfileConfiguration - .getLegacy32Positioning(); - - // create Table describtion - Table main = TableFactory.createSigTable( - signatureProfileSettings, MAIN, pdfObject.getStatus(), - requestedSignature); - - IPDFStamper stamper = StamperFactory - .createDefaultStamper(pdfObject.getStatus() - .getSettings()); - - IPDFVisualObject visualObject = stamper.createVisualPDFObject( - pdfObject, main); - - /* - * PDDocument originalDocument = PDDocument .load(new - * ByteArrayInputStream(pdfObject.getStatus() - * .getPdfObject().getOriginalDocument())); - */ - - PositioningInstruction positioningInstruction = Positioning - .determineTablePositioning(tablePos, "", doc, - visualObject, legacy32Position); - - SignaturePositionImpl position = new SignaturePositionImpl(); - position.setX(positioningInstruction.getX()); - position.setY(positioningInstruction.getY()); - position.setPage(positioningInstruction.getPage()); - position.setHeight(visualObject.getHeight()); - position.setWidth(visualObject.getWidth()); - - requestedSignature.setSignaturePosition(position); - - PDFAsVisualSignatureProperties properties = new PDFAsVisualSignatureProperties( - pdfObject.getStatus().getSettings(), pdfObject, - (PdfBoxVisualObject) visualObject, - positioningInstruction); - - properties.buildSignature(); - - /* - * ByteArrayOutputStream sigbos = new ByteArrayOutputStream(); - * sigbos.write(StreamUtils.inputStreamToByteArray(properties - * .getVisibleSignature())); sigbos.close(); - */ - - if (signaturePlaceholderData != null) { - // Placeholder found! - // replace placeholder - InputStream is = PADESPDFBOXSigner.class - .getResourceAsStream("/placeholder/empty.jpg"); - PDJpeg img = new PDJpeg(doc, is); - img.getCOSObject().setNeedToBeUpdate(true); - - PDDocumentCatalog root = doc.getDocumentCatalog(); - PDPageNode rootPages = root.getPages(); - List<PDPage> kids = new ArrayList<PDPage>(); - rootPages.getAllKids(kids); - int pageNumber = positioningInstruction.getPage(); - rootPages.getAllKids(kids); - PDPage page = kids.get(pageNumber); - - logger.info("Placeholder name: " - + signaturePlaceholderData.getPlaceholderName()); - COSDictionary xobjectsDictionary = (COSDictionary) page - .findResources().getCOSDictionary() - .getDictionaryObject(COSName.XOBJECT); - xobjectsDictionary.setItem( - signaturePlaceholderData.getPlaceholderName(), img); - xobjectsDictionary.setNeedToBeUpdate(true); - page.findResources().getCOSObject().setNeedToBeUpdate(true); - logger.info("Placeholder name: " - + signaturePlaceholderData.getPlaceholderName()); - } - - if (positioningInstruction.isMakeNewPage()) { - int last = doc.getNumberOfPages() - 1; - PDDocumentCatalog root = doc.getDocumentCatalog(); - PDPageNode rootPages = root.getPages(); - List<PDPage> kids = new ArrayList<PDPage>(); - rootPages.getAllKids(kids); - PDPage lastPage = kids.get(last); - rootPages.getCOSObject().setNeedToBeUpdate(true); - PDPage p = new PDPage(lastPage.findMediaBox()); - p.setResources(new PDResources()); - - doc.addPage(p); - } - - if (signatureProfileSettings.isPDFA()) { - PDDocumentCatalog root = doc.getDocumentCatalog(); - COSBase base = root.getCOSDictionary().getItem( - COSName.OUTPUT_INTENTS); - if (base == null) { - InputStream colorProfile = PDDocumentCatalog.class - .getResourceAsStream("/icm/sRGB Color Space Profile.icm"); - try { - PDOutputIntent oi = new PDOutputIntent(doc, - colorProfile); - oi.setInfo("sRGB IEC61966-2.1"); - oi.setOutputCondition("sRGB IEC61966-2.1"); - oi.setOutputConditionIdentifier("sRGB IEC61966-2.1"); - oi.setRegistryName("http://www.color.org"); - - root.addOutputIntent(oi); - root.getCOSObject().setNeedToBeUpdate(true); - logger.info("added Output Intent"); - } catch (Throwable e) { - e.printStackTrace(); - throw new PdfAsException( - "Failed to add Output Intent", e); - } - } - } - -// if (signatureProfileSettings.isPDFA()) { // Check for PDF-UA -// PDDocumentCatalog root = doc.getDocumentCatalog(); -// PDStructureTreeRoot treeRoot = root.getStructureTreeRoot(); -// if (treeRoot != null) { // Handle as PDF-UA -// logger.info("Tree Root: {}", treeRoot.toString()); -// PDStructureElement docElement = PDFBoxTaggingUtils -// .getDocumentElement(treeRoot); -// PDStructureElement sigBlock = new PDStructureElement( -// "Table", docElement); -// root.getCOSObject().setNeedToBeUpdate(true); -// docElement.getCOSObject().setNeedToBeUpdate(true); -// treeRoot.getCOSObject().setNeedToBeUpdate(true); -// sigBlock.setTitle("Signature Table"); -// } -// } - - options.setPreferedSignatureSize(0x1000); - options.setPage(positioningInstruction.getPage()); - options.setVisualSignature(properties.getVisibleSignature()); - } - - doc.addSignature(signature, signer, options); - - String sigFieldName = signatureProfileSettings.getSignFieldValue(); - - if (sigFieldName == null) { - sigFieldName = "PDF-AS Signatur"; - } - - int count = SignatureUtils.countSignatures(doc, sigFieldName); - - sigFieldName = sigFieldName + count; - - PDAcroForm acroFormm = doc.getDocumentCatalog().getAcroForm(); - if (acroFormm != null) { - @SuppressWarnings("unchecked") - List<PDField> fields = acroFormm.getFields(); - PDSignatureField signatureField = null; - - if (fields != null) { - for (PDField pdField : fields) { - if (pdField instanceof PDSignatureField) { - if (((PDSignatureField) pdField).getSignature() - .getDictionary() - .equals(signature.getDictionary())) { - signatureField = (PDSignatureField) pdField; - } - } - } - } else { - logger.warn("Failed to name Signature Field! [Cannot find Field list in acroForm!]"); - } - - if (signatureField != null) { - signatureField.setPartialName(sigFieldName); - } - } else { - logger.warn("Failed to name Signature Field! [Cannot find acroForm!]"); - } - - if (requestedSignature.isVisual()) { - - // if(requestedSignature.getSignaturePosition().) - /* - PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm(); - if (acroForm != null) { - - @SuppressWarnings("unchecked") - List<PDField> fields = acroForm.getFields(); - PDSignatureField signatureField = null; - - if (fields != null) { - for (PDField pdField : fields) { - if (pdField instanceof PDSignatureField) { - if (((PDSignatureField) pdField).getSignature() - .getDictionary() - .equals(signature.getDictionary())) { - signatureField = (PDSignatureField) pdField; - } - } - } - } else { - logger.warn("Failed to apply rotation! [Cannot find Field list in acroForm!]"); - } - - if (signatureField != null) { - if (signatureField.getWidget() != null) { - if (signatureField.getWidget() - .getAppearanceCharacteristics() == null) { - PDAppearanceCharacteristicsDictionary dict = new PDAppearanceCharacteristicsDictionary( - new COSDictionary()); - signatureField.getWidget() - .setAppearanceCharacteristics(dict); - } - - if (signatureField.getWidget() - .getAppearanceCharacteristics() != null) { - signatureField.getWidget() - .getAppearanceCharacteristics() - .setRotation(90); - } - } - } else { - logger.warn("Failed to apply rotation! [Cannot find signature Field!]"); - } - } else { - logger.warn("Failed to apply rotation! [Cannot find acroForm!]"); - }*/ - } - - // pdfbox patched (FIS -> IS) - doc.saveIncremental(fis, fos); - fis.close(); - fos.flush(); - fos.close(); - fos = null; - - fis = new FileInputStream(new File(fisTmpFile)); - - // write to resulting output stream - // ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // bos.write(); - // bos.close(); - - pdfObject - .setSignedDocument(StreamUtils.inputStreamToByteArray(fis)); - fis.close(); - fis = null; - System.gc(); - - helper.deleteFile(fisTmpFile); - - } catch (IOException e) { - logger.error(MessageResolver.resolveMessage("error.pdf.sig.01"), e); - throw new PdfAsException("error.pdf.sig.01", e); - } catch (SignatureException e) { - logger.error(MessageResolver.resolveMessage("error.pdf.sig.01"), e); - throw new PdfAsException("error.pdf.sig.01", e); - } catch (COSVisitorException e) { - logger.error(MessageResolver.resolveMessage("error.pdf.sig.01"), e); - throw new PdfAsException("error.pdf.sig.01", e); - } finally { - if (doc != null) { - try { - doc.close(); - } catch (IOException e) { - logger.debug("Failed to close COS Doc!", e); - // Ignore - } - } - logger.debug("Signature done!"); - - } - } -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java deleted file mode 100644 index 7c715911..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -package at.gv.egiz.pdfas.lib.impl.signing.pdfbox; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Calendar; - -import org.apache.pdfbox.exceptions.SignatureException; -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.gv.egiz.pdfas.common.exceptions.PdfAsException; -import at.gv.egiz.pdfas.common.exceptions.PdfAsWrappedIOException; -import at.gv.egiz.pdfas.common.utils.PDFUtils; -import at.gv.egiz.pdfas.common.utils.StreamUtils; -import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner; -import at.gv.egiz.pdfas.lib.api.sign.SignParameter; -import at.gv.egiz.pdfas.lib.impl.signing.sig_interface.PDFASSignatureInterface; -import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature; - -public class PdfboxSignerWrapper implements PDFASSignatureInterface { - - private static final Logger logger = LoggerFactory - .getLogger(PdfboxSignerWrapper.class); - - private IPlainSigner signer; - private PDSignature signature; - private int[] byteRange; - private Calendar date; - private SignParameter parameters; - private RequestedSignature requestedSignature; - - public PdfboxSignerWrapper(IPlainSigner signer, SignParameter parameters, RequestedSignature requestedSignature) { - this.signer = signer; - this.date = Calendar.getInstance(); - this.parameters = parameters; - this.requestedSignature = requestedSignature; - } - - public byte[] sign(InputStream inputStream) throws SignatureException, - IOException { - byte[] data = StreamUtils.inputStreamToByteArray(inputStream); - byteRange = PDFUtils.extractSignatureByteRange(data); - int[] byteRange2 = signature.getByteRange(); - logger.debug("Byte Range 2: " + byteRange2); - try { - logger.debug("Signing with Pdfbox Wrapper"); - byte[] signature = signer.sign(data, byteRange, this.parameters, this.requestedSignature); - return signature; - } catch (PdfAsException e) { - throw new PdfAsWrappedIOException(e); - } - } - - public int[] getByteRange() { - return byteRange; - } - - public String getPDFSubFilter() { - return this.signer.getPDFSubFilter(); - } - - public String getPDFFilter() { - return this.signer.getPDFFilter(); - } - - public void setPDSignature(PDSignature signature) { - this.signature = signature; - } - - public Calendar getSigningDate() { - return this.date; - } -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/PDFASSignatureInterface.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/PDFASSignatureInterface.java deleted file mode 100644 index c4ace1d7..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/PDFASSignatureInterface.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -package at.gv.egiz.pdfas.lib.impl.signing.sig_interface; - -import java.util.Calendar; - -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureInterface; - -public interface PDFASSignatureInterface extends SignatureInterface { - public String getPDFSubFilter(); - public String getPDFFilter(); - public void setPDSignature(PDSignature signature); - public Calendar getSigningDate(); -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/SignatureDataExtractor.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/SignatureDataExtractor.java deleted file mode 100644 index 32cfb410..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/SignatureDataExtractor.java +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -package at.gv.egiz.pdfas.lib.impl.signing.sig_interface; - -import iaik.x509.X509Certificate; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Calendar; - -import org.apache.pdfbox.exceptions.SignatureException; -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; - -import at.gv.egiz.pdfas.common.utils.StreamUtils; - -public class SignatureDataExtractor implements PDFASSignatureInterface { - - protected X509Certificate certificate; - protected byte[] signatureData; - - protected String pdfSubFilter; - protected String pdfFilter; - protected PDSignature signature; - protected int[] byteRange; - protected Calendar date; - - public SignatureDataExtractor(X509Certificate certificate, - String filter, String subfilter, Calendar date) { - this.certificate = certificate; - this.pdfFilter = filter; - this.pdfSubFilter = subfilter; - this.date = date; - } - - public X509Certificate getCertificate() { - return certificate; - } - - public String getPDFSubFilter() { - return this.pdfSubFilter; - } - - public String getPDFFilter() { - return this.pdfFilter; - } - - public byte[] getSignatureData() { - return this.signatureData; - } - - public byte[] sign(InputStream content) throws SignatureException, - IOException { - signatureData = StreamUtils.inputStreamToByteArray(content); - byteRange = this.signature.getByteRange(); - return new byte[] { 0 }; - } - - public void setPDSignature(PDSignature signature) { - this.signature = signature; - } - - public int[] getByteRange() { - return byteRange; - } - - public Calendar getSigningDate() { - return this.date; - } - - - -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/SignatureDataInjector.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/SignatureDataInjector.java deleted file mode 100644 index e667f0ea..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/sig_interface/SignatureDataInjector.java +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -package at.gv.egiz.pdfas.lib.impl.signing.sig_interface; - -import iaik.x509.X509Certificate; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Calendar; - -import org.apache.pdfbox.exceptions.SignatureException; - -import at.gv.egiz.pdfas.common.utils.StreamUtils; - -public class SignatureDataInjector extends SignatureDataExtractor { - - protected byte[] signature; - protected byte[] oldSignatureData; - - public SignatureDataInjector(X509Certificate certificate, String filter, - String subfilter, Calendar date, byte[] signature, byte[] signatureData) { - super(certificate, filter, subfilter, date); - this.signature = signature; - this.oldSignatureData = signatureData; - } - - @Override - public byte[] sign(InputStream content) throws SignatureException, - IOException { - byte[] signatureData = StreamUtils.inputStreamToByteArray(content); - - if(signatureData.length != this.oldSignatureData.length) { - throw new SignatureException("Signature Data missmatch!"); - } - - for(int i = 0; i < signatureData.length; i++) { - if(signatureData[i] != this.oldSignatureData[i]) { - throw new SignatureException("Signature Data missmatch! " + i + " " + signatureData[i] + " vs " + this.oldSignatureData[i]); - } - } - - return signature; - } - -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/CertificateResolver.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/CertificateResolver.java index 5a26974c..7012a93a 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/CertificateResolver.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/CertificateResolver.java @@ -38,7 +38,6 @@ import org.slf4j.LoggerFactory; import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings; import at.gv.egiz.pdfas.common.utils.DNUtils; import at.gv.egiz.pdfas.common.utils.OgnlUtils; -import at.gv.egiz.pdfas.lib.impl.status.ICertificateProvider; import at.gv.egiz.pdfas.lib.impl.status.OperationStatus; public class CertificateResolver implements IResolver { @@ -47,7 +46,6 @@ public class CertificateResolver implements IResolver { private OgnlContext ctx; private X509Certificate certificate; - private OperationStatus operationStatus; public CertificateResolver(X509Certificate certificate, OperationStatus operationStatus) { this.certificate = certificate; @@ -71,7 +69,7 @@ public class CertificateResolver implements IResolver { Map<String, String> iuiMap = new HashMap<String, String>(); try { - iuiMap.put("pdfVersion", String.valueOf(operationStatus.getPdfObject().getDocument().getDocument().getVersion())); + iuiMap.put("pdfVersion", operationStatus.getPdfObject().getPDFVersion()); } catch(Throwable e) { logger.warn("Cannot determine pdfVersion: " + e.getMessage()); } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IResolver.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IResolver.java index 92f80045..107aed2c 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IResolver.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IResolver.java @@ -24,7 +24,6 @@ package at.gv.egiz.pdfas.lib.impl.stamping; import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings; -import at.gv.egiz.pdfas.lib.impl.status.ICertificateProvider; /** * Created with IntelliJ IDEA. diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/ImageObject.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/ImageObject.java deleted file mode 100644 index f8ec2073..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/ImageObject.java +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; - -import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage; - -public class ImageObject { - private PDXObjectImage image; - private float width; - private float height; - - public ImageObject(PDXObjectImage image, float width, float height) { - this.image = image; - this.width = width; - this.height = height; - } - - public PDXObjectImage getImage() { - return image; - } - - public void setImage(PDXObjectImage image) { - this.image = image; - } - - public float getWidth() { - return width; - } - - public void setWidth(float width) { - this.width = width; - } - - public float getHeight() { - return height; - } - - public void setHeight(float height) { - this.height = height; - } - -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsTemplateCreator.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsTemplateCreator.java deleted file mode 100644 index feacc52d..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsTemplateCreator.java +++ /dev/null @@ -1,170 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.pdfbox.exceptions.COSVisitorException; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDPage; -import org.apache.pdfbox.pdmodel.PDResources; -import org.apache.pdfbox.pdmodel.common.PDRectangle; -import org.apache.pdfbox.pdmodel.common.PDStream; -import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectForm; -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDFTemplateCreator; -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDFTemplateStructure; -import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; -import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.gv.egiz.pdfas.common.exceptions.PdfAsException; - -public class PDFAsTemplateCreator extends PDFTemplateCreator { - - PDFAsVisualSignatureBuilder pdfBuilder; - private static final Logger logger = LoggerFactory.getLogger(PDFAsTemplateCreator.class); - - public PDFAsTemplateCreator(PDFAsVisualSignatureBuilder bookBuilder) { - super(bookBuilder); - this.pdfBuilder = bookBuilder; - } - - - public InputStream buildPDF(PDFAsVisualSignatureDesigner properties) - throws IOException, PdfAsException { - logger.debug("pdf building has been started"); - PDFTemplateStructure pdfStructure = pdfBuilder.getStructure(); - - // we create array of [Text, ImageB, ImageC, ImageI] - this.pdfBuilder.createProcSetArray(); - - //create page - this.pdfBuilder.createPage(properties); - PDPage page = pdfStructure.getPage(); - - //create template - this.pdfBuilder.createTemplate(page); - PDDocument template = pdfStructure.getTemplate(); - - //create /AcroForm - this.pdfBuilder.createAcroForm(template); - PDAcroForm acroForm = pdfStructure.getAcroForm(); - - // AcroForm contains singature fields - this.pdfBuilder.createSignatureField(acroForm); - PDSignatureField pdSignatureField = pdfStructure.getSignatureField(); - - // create signature - this.pdfBuilder.createSignature(pdSignatureField, page, properties.getSignatureFieldName()); - - // that is /AcroForm/DR entry - this.pdfBuilder.createAcroFormDictionary(acroForm, pdSignatureField); - - // create AffineTransform - this.pdfBuilder.createAffineTransform(properties.getAffineTransformParams()); - //AffineTransform transform = pdfStructure.getAffineTransform(); - - // rectangle, formatter, image. /AcroForm/DR/XObject contains that form - this.pdfBuilder.createSignatureRectangle(pdSignatureField, properties, properties.getRotation()); - this.pdfBuilder.createFormaterRectangle(properties.getFormaterRectangleParams()); - PDRectangle formater = pdfStructure.getFormaterRectangle(); - - //this.pdfBuilder.createSignatureImage(template, properties.getImageStream()); - - // create form stream, form and resource. - this.pdfBuilder.createHolderFormStream(template); - PDStream holderFormStream = pdfStructure.getHolderFormStream(); - this.pdfBuilder.createHolderFormResources(); - PDResources holderFormResources = pdfStructure.getHolderFormResources(); - this.pdfBuilder.createHolderForm(holderFormResources, holderFormStream, formater); - - // that is /AP entry the appearance dictionary. - this.pdfBuilder.createAppearanceDictionary(pdfStructure.getHolderForm(), pdSignatureField, - properties.getRotation()); - - // inner formstream, form and resource (hlder form containts inner form) - this.pdfBuilder.createInnerFormStreamPdfAs(template); - this.pdfBuilder.createInnerFormResource(); - PDResources innerFormResource = pdfStructure.getInnerFormResources(); - this.pdfBuilder.createInnerForm(innerFormResource, pdfStructure.getInnterFormStream(), formater); - PDXObjectForm innerForm = pdfStructure.getInnerForm(); - - // inner form must be in the holder form as we wrote - this.pdfBuilder.insertInnerFormToHolerResources(innerForm, holderFormResources); - - // Image form is in this structure: /AcroForm/DR/FRM0/Resources/XObject/n0 - //this.pdfBuilder.createImageFormStream(template); - //PDStream imageFormStream = pdfStructure.getImageFormStream(); - //this.pdfBuilder.createImageFormResources(); - //PDResources imageFormResources = pdfStructure.getImageFormResources(); - //this.pdfBuilder.createImageForm(imageFormResources, innerFormResource, imageFormStream, formater, transform, - // pdfStructure.getJpedImage()); - - // now inject procSetArray - /*this.pdfBuilder.injectProcSetArray(innerForm, page, innerFormResource, imageFormResources, holderFormResources, - pdfStructure.getProcSet());*/ - this.pdfBuilder.injectProcSetArray(innerForm, page, innerFormResource, null, holderFormResources, - pdfStructure.getProcSet()); - - - /*String imgFormName = pdfStructure.getImageFormName(); - String imgName = pdfStructure.getImageName();*/ - String innerFormName = pdfStructure.getInnerFormName(); - - // now create Streams of AP - /*this.pdfBuilder.injectAppearanceStreams(holderFormStream, imageFormStream, imageFormStream, imgFormName, - imgName, innerFormName, properties);*/ - this.pdfBuilder.injectAppearanceStreams(holderFormStream, null, null, null, - null, innerFormName, properties); - this.pdfBuilder.createVisualSignature(template); - this.pdfBuilder.createWidgetDictionary(pdSignatureField, holderFormResources); - - ByteArrayInputStream in = null; - try - { - //COSDocument doc = pdfStructure.getVisualSignature(); - //doc. - //in = pdfStructure.getTemplateAppearanceStream(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - template.save(baos); - baos.close(); - in = new ByteArrayInputStream(baos.toByteArray()); - } - catch (COSVisitorException e) - { - logger.error("COSVisitorException: can't get apereance stream ", e); - } - logger.debug("stream returning started, size= " + in.available()); - - // we must close the document - template.close(); - - // return result of the stream - return in; - } -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java deleted file mode 100644 index e3ee19f6..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java +++ /dev/null @@ -1,994 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; - -import java.awt.Color; -import java.awt.geom.AffineTransform; -import java.awt.geom.Point2D; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.imageio.ImageIO; - -import org.apache.pdfbox.cos.COSArray; -import org.apache.pdfbox.cos.COSDictionary; -import org.apache.pdfbox.cos.COSName; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDPage; -import org.apache.pdfbox.pdmodel.PDResources; -import org.apache.pdfbox.pdmodel.common.PDRectangle; -import org.apache.pdfbox.pdmodel.common.PDStream; -import org.apache.pdfbox.pdmodel.edit.PDPageContentStream; -import org.apache.pdfbox.pdmodel.font.PDFont; -import org.apache.pdfbox.pdmodel.font.PDType1Font; -import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg; -import org.apache.pdfbox.pdmodel.graphics.xobject.PDPixelMap; -import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectForm; -import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage; -import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary; -import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream; -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSigBuilder; -import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; -import org.apache.pdfbox.pdmodel.interactive.form.PDField; -import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.gv.egiz.pdfas.common.exceptions.PdfAsException; -import at.gv.egiz.pdfas.common.settings.ISettings; -import at.gv.egiz.pdfas.common.utils.ImageUtils; -import at.knowcenter.wag.egov.egiz.table.Entry; -import at.knowcenter.wag.egov.egiz.table.Style; - -public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder { - - private static final Logger logger = LoggerFactory - .getLogger(PDFAsVisualSignatureBuilder.class); - - private void drawDebugLine(PDPageContentStream contentStream, float x, - float y, float width, float height) { - try { - contentStream.setStrokingColor(Color.RED); - contentStream.drawLine(x, y, x + width, y); - contentStream.setStrokingColor(Color.BLUE); - contentStream.drawLine(x, y, x, y - height); - contentStream.setStrokingColor(Color.GREEN); - contentStream.drawLine(x + width, y, x + width, y - height); - contentStream.setStrokingColor(Color.ORANGE); - contentStream.drawLine(x, y - height, x + width, y - height); - - contentStream.setStrokingColor(Color.BLACK); - } catch (Throwable e) { - e.printStackTrace(); - } - } - - private void drawDebugPadding(PDPageContentStream contentStream, float x, - float y, float padding, float width, float height) { - try { - contentStream.setStrokingColor(Color.RED); - contentStream.drawLine(x, y, x + padding, y - padding); - contentStream.drawLine(x + width, y, x + width - padding, y - - padding); - contentStream.drawLine(x + width, y - height, x + width - padding, - y - height + padding); - contentStream.drawLine(x, y - height, x + padding, y - height - + padding); - contentStream.setStrokingColor(Color.BLACK); - } catch (Throwable e) { - e.printStackTrace(); - } - } - - private void drawTable(PDPage page, PDPageContentStream contentStream, - float x, float y, float width, float height, - PDFBoxTable abstractTable, PDDocument doc, boolean subtable) - throws IOException, PdfAsException { - - final int rows = abstractTable.getRowCount(); - final int cols = abstractTable.getColCount(); - float[] colsSizes = abstractTable.getColsRelativeWith(); - int max_cols = abstractTable.getColCount(); - float padding = abstractTable.getPadding(); - float fontSize = PDFBoxFont.defaultFontSize; - PDFont textFont = PDFBoxFont.defaultFont; - if (colsSizes == null) { - colsSizes = new float[max_cols]; - // set the column ratio for all columns to 1 - for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) { - colsSizes[cols_idx] = 1; - } - } - - logger.debug("Drawing Table:"); - abstractTable.dumpTable(); - - if (abstractTable.getBGColor() != null) { - contentStream.setNonStrokingColor(abstractTable.getBGColor()); - contentStream.fillRect(x, y, abstractTable.getWidth(), - abstractTable.getHeight()); - contentStream.setNonStrokingColor(Color.BLACK); - } - float total = 0; - - for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) { - total += colsSizes[cols_idx]; - } - - for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) { - colsSizes[cols_idx] = (colsSizes[cols_idx] / total) - * abstractTable.getWidth(); - } - - for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) { - logger.debug("Col: " + cols_idx + " : " + colsSizes[cols_idx]); - } - - float border = abstractTable.style.getBorder(); - contentStream.setLineWidth(border); - - float tableHeight = abstractTable.getHeight(); - float tableWidth = abstractTable.getWidth(); - final float colWidth = tableWidth / (float) cols; - - // draw if boarder > 0 - if (border != 0) { - - float nexty = y + tableHeight; - float lasty = nexty; - for (int i = 0; i < rows; i++) { - ArrayList<Entry> row = abstractTable.getRow(i); - // Draw row border! - logger.debug("ROW LINE: {} {} {} {}", x, nexty, x + width, - nexty); - contentStream.drawLine(x, nexty, x + width, nexty); - lasty = nexty; - if (i < abstractTable.getRowHeights().length) { - // nexty -= abstractTable.getRowHeights()[i] + padding * 2; - nexty -= abstractTable.getRowHeights()[i]; - } - - // if (subtable && i + 1 == - // abstractTable.getRowHeights().length) { - // nexty -= padding; - // } - - float nextx = x; - float ypos = y; - float yheight = y + abstractTable.getHeight(); - if (subtable) { - // ypos -= padding; - yheight = y + abstractTable.getHeight(); - } - - for (int j = 0; j < row.size(); j++) { - Entry cell = (Entry) row.get(j); - - if (subtable && j == cols) { - continue; - } - logger.debug("COL LINE: {} {} {} {}", nextx, ypos, nextx, - yheight); - contentStream.drawLine(nextx, lasty, nextx, nexty); - for (int k = 0; k < cell.getColSpan(); k++) { - if (k + j < colsSizes.length) { - nextx += (colsSizes != null) ? colsSizes[k + j] - : colWidth; - } - } - } - if (!subtable) { - contentStream.drawLine(nextx, lasty, nextx, nexty); - } - } - - contentStream.drawLine(x, nexty, x + tableWidth, nexty); - - } - - float textx = x; - float texty = y + tableHeight; - for (int i = 0; i < abstractTable.getRowCount(); i++) { - ArrayList<Entry> row = abstractTable.getRow(i); - for (int j = 0; j < row.size(); j++) { - Entry cell = (Entry) row.get(j); - - Style inherit_style = Style.doInherit(cell.getStyle(), - abstractTable.style); - cell.setStyle(inherit_style); - - // if(subtable) { - drawDebugPadding(contentStream, textx, texty, padding, - ((colsSizes != null) ? colsSizes[j] : colWidth), - abstractTable.getRowHeights()[i]); - // } - // if(true) { - // textx += (colsSizes != null) ? colsSizes[j] : colWidth; - // continue; - // } - - if (cell.getType() == Entry.TYPE_CAPTION - || cell.getType() == Entry.TYPE_VALUE) { - - if (cell.getType() == Entry.TYPE_CAPTION) { - textFont = abstractTable.getFont().getFont(doc); - fontSize = abstractTable.getFont().getFontSize(); - } else if (cell.getType() == Entry.TYPE_VALUE) { - textFont = abstractTable.getValueFont().getFont(doc); - fontSize = abstractTable.getValueFont().getFontSize(); - } - - String text = (String) cell.getValue(); - - // COSName name = COSName.getPDFName("ANDI_TAG!"); - // contentStream.beginMarkedContentSequence(COSName.ALT, - // name); - String fontName = textFont.equals(PDType1Font.COURIER) ? "COURIER" - : "HELVETICA"; - - float fheight = textFont.getFontDescriptor().getCapHeight() - / 1000 * fontSize; - - String[] tlines = text.split("\n"); - float textHeight = fontSize * tlines.length; - - Style cellStyle = cell.getStyle(); - String valign = null; - String halign = null; - - if (cell.getType() == Entry.TYPE_CAPTION - && cellStyle != null) { - valign = cellStyle.getVAlign(); - halign = cellStyle.getHAlign(); - } else if (cell.getType() == Entry.TYPE_VALUE - && cellStyle != null) { - valign = cellStyle.getValueVAlign(); - halign = cellStyle.getValueHAlign(); - } - float ty = texty - padding; - float tx = textx + padding; - if (Style.BOTTOM.equals(valign)) { - float bottom_offset = abstractTable.getRowHeights()[i] - - textHeight; - ty -= bottom_offset; - } else if (Style.MIDDLE.equals(valign)) { - float bottom_offset = abstractTable.getRowHeights()[i] - - textHeight; - bottom_offset = bottom_offset / 2.0f; - ty -= bottom_offset; - } - - float columnWidth = (colsSizes != null) ? colsSizes[j] - : colWidth; - float maxWidth = 0; - for (int k = 0; k < tlines.length; k++) { - float lineWidth; - if (textFont instanceof PDType1Font) { - lineWidth = textFont.getStringWidth(tlines[k]) - / 1000.0f * fontSize; - } else { - float fwidth = textFont - .getStringWidth("abcdefghijklmnopqrstuvwxyz ") - / 1000.0f * fontSize; - fwidth = fwidth - / (float) "abcdefghijklmnopqrstuvwxyz" - .length(); - lineWidth = tlines[k].length() * fwidth; - } - - if (maxWidth < lineWidth) { - maxWidth = lineWidth; - } - } - - if (Style.CENTER.equals(halign)) { - float offset = columnWidth - maxWidth - 2 * padding; - if (offset > 0) { - offset = offset / 2.0f; - tx += offset; - } - } else if (Style.RIGHT.equals(halign)) { - float offset = columnWidth - maxWidth - 2 * padding; - if (offset > 0) { - tx += offset; - } - } - - drawDebugLine(contentStream, tx, ty, maxWidth, textHeight); - - contentStream.beginText(); - - if (innerFormResources.getFonts().containsValue(textFont)) { - String fontID = getFontID(textFont); - logger.debug("Using Font: " + fontID); - contentStream.appendRawCommands("/" + fontID + " " - + fontSize + " Tf\n"); - } else { - contentStream.setFont(textFont, fontSize); - } - - logger.debug("Writing: " + tx + " : " + (ty - fheight) - + " = " + text + " as " + cell.getType() + " w " - + fontName); - contentStream.moveTextPositionByAmount(tx, (ty - fheight)); - - if (text.contains("\n")) { - String[] lines = text.split("\n"); - contentStream.appendRawCommands(fontSize + " TL\n"); - for (int k = 0; k < lines.length; k++) { - contentStream.drawString(lines[k]); - if (k < lines.length - 1) { - contentStream.appendRawCommands("T*\n"); - } - } - } else { - contentStream.drawString(text); - } - contentStream.endText(); - // contentStream.endMarkedContentSequence(); - } else if (cell.getType() == Entry.TYPE_IMAGE) { - String img_ref = (String) cell.getValue(); - if (!images.containsKey(img_ref)) { - logger.error("Image not prepared! : " + img_ref); - throw new PdfAsException("Image not prepared! : " - + img_ref); - } - ImageObject image = images.get(img_ref); - PDXObjectImage pdImage = image.getImage(); - - float imgx = textx + padding; - float hoffset = ((colsSizes != null) ? colsSizes[j] - : colWidth) - image.getWidth(); - if (cell.getStyle().getImageVAlign() != null - && cell.getStyle().getImageVAlign() - .equals(Style.CENTER)) { - hoffset = hoffset / 2.0f; - imgx += hoffset; - } else if (cell.getStyle().getImageHAlign() != null - && cell.getStyle().getImageHAlign() - .equals(Style.RIGHT)) { - imgx += hoffset; - } - - float imgy = texty - padding; - float voffset = abstractTable.getRowHeights()[i] - - image.getHeight(); - if (cell.getStyle().getImageVAlign() != null - && cell.getStyle().getImageVAlign() - .equals(Style.MIDDLE)) { - voffset = voffset / 2.0f; - imgy -= voffset; - } else if (cell.getStyle().getImageVAlign() != null - && cell.getStyle().getImageVAlign() - .equals(Style.BOTTOM)) { - imgy -= voffset; - } - - drawDebugLine(contentStream, imgx, imgy, image.getWidth(), - image.getHeight()); - - logger.debug("Image: " + imgx + " : " - + (imgy - image.getHeight())); - contentStream.drawXObject(pdImage, imgx, - imgy - image.getHeight(), image.getWidth(), - image.getHeight()); - // contentStream.endMarkedContentSequence(); - - } else if (cell.getType() == Entry.TYPE_TABLE) { - - float tableY = texty - abstractTable.getRowHeights()[i]; - float tableX = textx; - // texty = texty - padding; - PDFBoxTable tbl_value = (PDFBoxTable) cell.getValue(); - - Style inherit_styletab = Style.doInherit( - abstractTable.style, cell.getStyle()); - tbl_value.table.setStyle(inherit_styletab); - - logger.debug("Table: " + tableX + " : " + tableY); - // logger.debug("Table height: " + ); - TableDrawUtils.drawTable(page, contentStream, tableX, - tableY, (colsSizes != null) ? colsSizes[j] - : colWidth, - abstractTable.getRowHeights()[i], tbl_value, doc, - true, innerFormResources, images, settings); - } - textx += (colsSizes != null) ? colsSizes[j] : colWidth; - } - // if (i + 1 < abstractTable.getRowHeights().length) { - logger.debug("Row {} from {} - {} - {} = {}", i, texty, - abstractTable.getRowHeights()[i], padding * 2, texty - - (abstractTable.getRowHeights()[i])); - texty -= abstractTable.getRowHeights()[i]; - // texty = texty - abstractTable.getRowHeights()[i + 1] - padding - // * 2; - // texty = texty - abstractTable.getRowHeights()[i] - padding - // * 2; - // } - textx = x; - } - } - - private void drawTable2(PDPage page, PDPageContentStream contentStream, - float x, float y, float width, float height, - PDFBoxTable abstractTable, PDDocument doc, boolean subtable) { - - } - - private PDFAsVisualSignatureProperties properties; - private PDFAsVisualSignatureDesigner designer; - private ISettings settings; - private PDResources innerFormResources; - private Map<String, ImageObject> images = new HashMap<String, ImageObject>(); - - private String getFontID(PDFont font) { - Iterator<java.util.Map.Entry<String, PDFont>> it = innerFormResources - .getFonts().entrySet().iterator(); - while (it.hasNext()) { - java.util.Map.Entry<String, PDFont> entry = it.next(); - if (entry.getValue().equals(font)) { - return entry.getKey(); - } - } - return ""; - } - - public PDFAsVisualSignatureBuilder( - PDFAsVisualSignatureProperties properties, ISettings settings, - PDFAsVisualSignatureDesigner designer) { - this.properties = properties; - this.settings = settings; - this.designer = designer; - } - - @Override - public void createProcSetArray() { - COSArray procSetArr = new COSArray(); - procSetArr.add(COSName.getPDFName("PDF")); - procSetArr.add(COSName.getPDFName("Text")); - procSetArr.add(COSName.getPDFName("ImageC")); - procSetArr.add(COSName.getPDFName("ImageB")); - procSetArr.add(COSName.getPDFName("ImageI")); - getStructure().setProcSet(procSetArr); - logger.debug("ProcSet array has been created"); - } - - public void createMyPage(PDFAsVisualSignatureDesigner properties) { - PDPage page = properties.getSignaturePage(); - if (page == null) { - page = new PDPage(); - page.setMediaBox(new PDRectangle(properties.getPageWidth(), - properties.getPageHeight())); - - } - getStructure().setPage(page); - logger.info("PDF page has been created"); - } - - @Override - public void createTemplate(PDPage page) throws IOException { - PDDocument template = new PDDocument(); - - template.addPage(page); - getStructure().setTemplate(template); - } - - private void readTableResources(PDFBoxTable table, PDDocument template) - throws PdfAsException, IOException { - - float[] colsSizes = table.getColsRelativeWith(); - int max_cols = table.getColCount(); - float padding = table.getPadding(); - if (colsSizes == null) { - colsSizes = new float[max_cols]; - // set the column ratio for all columns to 1 - for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) { - colsSizes[cols_idx] = 1; - } - } - - logger.debug("TOTAL Width: " + table.getWidth()); - - float total = 0; - - for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) { - total += colsSizes[cols_idx]; - } - - for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) { - colsSizes[cols_idx] = (colsSizes[cols_idx] / total) - * table.getWidth(); - } - - for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) { - logger.debug("Col: " + cols_idx + " : " + colsSizes[cols_idx]); - } - - /* - * if(!addedFonts.contains(table.getFont().getFont(null))) { PDFont font - * = table.getFont().getFont(template); addedFonts.add(font); - * innerFormResources.addFont(font); } - * - * if(!addedFonts.contains(table.getValueFont().getFont(null))) { PDFont - * font = table.getValueFont().getFont(template); addedFonts.add(font); - * innerFormResources.addFont(font); } - */ - - for (int i = 0; i < table.getRowCount(); i++) { - ArrayList<Entry> row = table.getRow(i); - for (int j = 0; j < row.size(); j++) { - Entry cell = (Entry) row.get(j); - if (cell.getType() == Entry.TYPE_IMAGE) { - String img_ref = (String) cell.getValue(); - if (!images.containsKey(img_ref)) { - File img_file = new File(img_ref); - if (!img_file.isAbsolute()) { - logger.debug("Image file declaration is relative. Prepending path of resources directory."); - logger.debug("Image Location: " - + settings.getWorkingDirectory() - + File.separator + img_ref); - img_file = new File(settings.getWorkingDirectory() - + File.separator + img_ref); - } else { - logger.debug("Image file declaration is absolute. Skipping file relocation."); - } - - if (!img_file.exists()) { - logger.debug("Image file \"" - + img_file.getCanonicalPath() - + "\" doesn't exist."); - throw new PdfAsException("error.pdf.stamp.04"); - } - - BufferedImage img = null; - try { - img = ImageIO.read(img_file); - } catch (IOException e) { - throw new PdfAsException("error.pdf.stamp.04", e); - } - - float width = colsSizes[j]; - float height = table.getRowHeights()[i] + padding * 2; - - float iwidth = (int) Math.floor((double) width); - iwidth -= 2 * padding; - - float iheight = (int) Math.floor((double) height); - iheight -= 2 * padding; - - float origWidth = (float) img.getWidth(); - float origHeight = (float) img.getHeight(); - - if (table.style != null) { - if (table.style.getImageScaleToFit() != null) { - iwidth = table.style.getImageScaleToFit() - .getWidth(); - iheight = table.style.getImageScaleToFit() - .getHeight(); - } - } - - float wfactor = iwidth / origWidth; - float hfactor = iheight / origHeight; - float scaleFactor = wfactor; - if (hfactor < wfactor) { - scaleFactor = hfactor; - } - - iwidth = (float) Math - .floor((double) (scaleFactor * origWidth)); - iheight = (float) Math - .floor((double) (scaleFactor * origHeight)); - - logger.debug("Scaling image to: " + iwidth + " x " - + iheight); - - if (img.getAlphaRaster() == null - && img.getColorModel().hasAlpha()) { - img = ImageUtils.removeAlphaChannel(img); - } - - PDXObjectImage pdImage = new PDPixelMap(template, img); - - ImageObject image = new ImageObject(pdImage, iwidth, - iheight); - images.put(img_ref, image); - innerFormResources.addXObject(pdImage, "Im"); - } - } else if (cell.getType() == Entry.TYPE_TABLE) { - PDFBoxTable tbl_value = (PDFBoxTable) cell.getValue(); - readTableResources(tbl_value, template); - } - } - } - } - - public void createInnerFormStreamPdfAs(PDDocument template) throws PdfAsException { - try { - - // Hint we have to create all PDXObjectImages before creating the - // PDPageContentStream - // only PDFbox developers know why ... - //if (getStructure().getPage().getResources() != null) { - // innerFormResources = getStructure().getPage().getResources(); - //} else { - innerFormResources = new PDResources(); - getStructure().getPage().setResources(innerFormResources); - //} - readTableResources(properties.getMainTable(), template); - - PDPageContentStream stream = new PDPageContentStream(template, - getStructure().getPage()); - // stream.setFont(PDType1Font.COURIER, 5); - TableDrawUtils.drawTable(getStructure().getPage(), stream, 1, 1, - designer.getWidth(), designer.getHeight(), - properties.getMainTable(), template, false, - innerFormResources, images, settings); - stream.close(); - PDStream innterFormStream = getStructure().getPage().getContents(); - getStructure().setInnterFormStream(innterFormStream); - logger.debug("Strean of another form (inner form - it would be inside holder form) has been created"); - - } catch (Throwable e) { - logger.error("Failed to create visual signature block", e); - throw new PdfAsException("Failed to create visual signature block", e); - } - } - - @Override - public void injectProcSetArray(PDXObjectForm innerForm, PDPage page, - PDResources innerFormResources, PDResources imageFormResources, - PDResources holderFormResources, COSArray procSet) { - innerForm.getResources().getCOSDictionary() - .setItem(COSName.PROC_SET, procSet); // - page.getCOSDictionary().setItem(COSName.PROC_SET, procSet); - innerFormResources.getCOSDictionary() - .setItem(COSName.PROC_SET, procSet); - /* - * imageFormResources.getCOSDictionary() .setItem(COSName.PROC_SET, - * procSet); - */ - holderFormResources.getCOSDictionary().setItem(COSName.PROC_SET, - procSet); - logger.debug("inserted ProcSet to PDF"); - } - - public void injectAppearanceStreams(PDStream holderFormStream, - PDStream innterFormStream, PDStream imageFormStream, - String imageObjectName, String imageName, String innerFormName, - PDFAsVisualSignatureDesigner properties) throws IOException { - - // 100 means that document width is 100% via the rectangle. if rectangle - // is 500px, images 100% is 500px. - // String imgFormComment = "q "+imageWidthSize+ " 0 0 50 0 0 cm /" + - // imageName + " Do Q\n" + builder.toString(); - /* - * String imgFormComment = "q " + 100 + " 0 0 50 0 0 cm /" + imageName + - * " Do Q\n"; - */ - double m00 = getStructure().getAffineTransform().getScaleX(); - double m10 = getStructure().getAffineTransform().getShearY(); - double m01 = getStructure().getAffineTransform().getShearX(); - double m11 = getStructure().getAffineTransform().getScaleY(); - double m02 = getStructure().getAffineTransform().getTranslateX(); - double m12 = getStructure().getAffineTransform().getTranslateY(); - - String holderFormComment = "q " + m00 + " " + m10 + " " + m01 + " " - + m11 + " " + m02 + " " + m12 + " cm /" + innerFormName - + " Do Q \n"; - - logger.debug("Holder Form Stream: " + holderFormComment); - - // String innerFormComment = "q 1 0 0 1 0 0 cm /" + imageObjectName + - // " Do Q\n"; - String innerFormComment = getStructure().getInnterFormStream() - .getInputStreamAsString(); - - //logger.debug("Inner Form Stream: " + innerFormComment); - - // appendRawCommands(getStructure().getInnterFormStream().createOutputStream(), - // getStructure().getInnterFormStream().getInputStreamAsString()); - - appendRawCommands(getStructure().getHolderFormStream() - .createOutputStream(), holderFormComment); - appendRawCommands(getStructure().getInnterFormStream() - .createOutputStream(), innerFormComment); - // appendRawCommands(getStructure().getImageFormStream().createOutputStream(), - // imgFormComment); - logger.debug("Injected apereance stream to pdf"); - - } - - public void createPage(PDFAsVisualSignatureDesigner properties) { - PDPage page = new PDPage(); - page.setMediaBox(new PDRectangle(properties.getPageWidth(), properties - .getPageHeight())); - getStructure().setPage(page); - logger.debug("PDF page has been created"); - } - - public void createAcroForm(PDDocument template) { - PDAcroForm theAcroForm = new PDAcroForm(template); - template.getDocumentCatalog().setAcroForm(theAcroForm); - getStructure().setAcroForm(theAcroForm); - logger.debug("Acro form page has been created"); - - } - - public void createSignatureField(PDAcroForm acroForm) throws IOException { - PDSignatureField sf = new PDSignatureField(acroForm); - getStructure().setSignatureField(sf); - logger.debug("Signature field has been created"); - } - - public void createSignature(PDSignatureField pdSignatureField, PDPage page, - String signatureName) throws IOException { - PDSignature pdSignature = new PDSignature(); - pdSignatureField.setSignature(pdSignature); - pdSignatureField.getWidget().setPage(page); - page.getAnnotations().add(pdSignatureField.getWidget()); - pdSignature.setName(signatureName); - pdSignature.setByteRange(new int[] { 0, 0, 0, 0 }); - pdSignature.setContents(new byte[4096]); - getStructure().setPdSignature(pdSignature); - logger.debug("PDSignatur has been created"); - } - - public void createAcroFormDictionary(PDAcroForm acroForm, - PDSignatureField signatureField) throws IOException { - @SuppressWarnings("unchecked") - List<PDField> acroFormFields = acroForm.getFields(); - COSDictionary acroFormDict = acroForm.getDictionary(); - acroFormDict.setDirect(true); - acroFormDict.setInt(COSName.SIG_FLAGS, 3); - acroFormFields.add(signatureField); - acroFormDict.setString(COSName.DA, "/sylfaen 0 Tf 0 g"); - getStructure().setAcroFormFields(acroFormFields); - getStructure().setAcroFormDictionary(acroFormDict); - logger.debug("AcroForm dictionary has been created"); - } - - public void createSignatureRectangle(PDSignatureField signatureField, - PDFAsVisualSignatureDesigner properties, float degrees) - throws IOException { - - PDRectangle rect = new PDRectangle(); - - Point2D upSrc = new Point2D.Float(); - upSrc.setLocation(properties.getxAxis() + properties.getWidth(), - properties.getPageHeight() - properties.getyAxis()); - - Point2D llSrc = new Point2D.Float(); - llSrc.setLocation(properties.getxAxis(), properties.getPageHeight() - - properties.getyAxis() - properties.getHeight()); - AffineTransform transform = new AffineTransform(); - transform.setToIdentity(); - if (degrees % 360 != 0) { - transform.setToRotation(Math.toRadians(degrees), llSrc.getX(), - llSrc.getY()); - } - Point2D upDst = new Point2D.Float(); - transform.transform(upSrc, upDst); - - Point2D llDst = new Point2D.Float(); - transform.transform(llSrc, llDst); - - rect.setUpperRightX((float) upDst.getX()); - rect.setUpperRightY((float) upDst.getY()); - rect.setLowerLeftY((float) llDst.getY()); - rect.setLowerLeftX((float) llDst.getX()); - logger.debug("rectangle of signature has been created: {}", - rect.toString()); - signatureField.getWidget().setRectangle(rect); - getStructure().setSignatureRectangle(rect); - logger.debug("rectangle of signature has been created"); - } - - public void createAffineTransform(float[] params) { - AffineTransform transform = new AffineTransform(params[0], params[1], - params[2], params[3], params[4], params[5]); - // transform.rotate(90); - getStructure().setAffineTransform(transform); - logger.debug("Matrix has been added"); - } - - public void createSignatureImage(PDDocument template, - InputStream inputStream) throws IOException { - PDJpeg img = new PDJpeg(template, inputStream); - getStructure().setJpedImage(img); - logger.debug("Visible Signature Image has been created"); - // pdfStructure.setTemplate(template); - inputStream.close(); - - } - - public void createFormaterRectangle(float[] params) { - - PDRectangle formrect = new PDRectangle(); - float[] translated = new float[4]; - getStructure().getAffineTransform().transform(params, 0, translated, 0, - 2); - - formrect.setUpperRightX(translated[0]); - formrect.setUpperRightY(translated[1]); - formrect.setLowerLeftX(translated[2]); - formrect.setLowerLeftY(translated[3]); - - getStructure().setFormaterRectangle(formrect); - logger.debug("Formater rectangle has been created"); - - } - - public void createHolderFormStream(PDDocument template) { - PDStream holderForm = new PDStream(template); - getStructure().setHolderFormStream(holderForm); - logger.debug("Holder form Stream has been created"); - } - - public void createHolderFormResources() { - PDResources holderFormResources = new PDResources(); - getStructure().setHolderFormResources(holderFormResources); - logger.debug("Holder form resources have been created"); - - } - - public void createHolderForm(PDResources holderFormResources, - PDStream holderFormStream, PDRectangle formrect) { - - PDXObjectForm holderForm = new PDXObjectForm(holderFormStream); - holderForm.setResources(holderFormResources); - holderForm.setBBox(formrect); - holderForm.setFormType(1); - getStructure().setHolderForm(holderForm); - logger.debug("Holder form has been created"); - - } - - public void createAppearanceDictionary(PDXObjectForm holderForml, - PDSignatureField signatureField, float degrees) throws IOException { - - PDAppearanceDictionary appearance = new PDAppearanceDictionary(); - appearance.getCOSObject().setDirect(true); - - PDAppearanceStream appearanceStream = new PDAppearanceStream( - holderForml.getCOSStream()); - AffineTransform transform = new AffineTransform(); - transform.setToIdentity(); - transform.rotate(Math.toRadians(degrees)); - appearanceStream.setMatrix(transform); - appearance.setNormalAppearance(appearanceStream); - signatureField.getWidget().setAppearance(appearance); - - getStructure().setAppearanceDictionary(appearance); - logger.debug("PDF appereance Dictionary has been created"); - - } - - public void createInnerFormResource() { - getStructure().setInnerFormResources(innerFormResources); - logger.debug("Resources of another form (inner form - it would be inside holder form) have been created"); - } - - public void createInnerForm(PDResources innerFormResources, - PDStream innerFormStream, PDRectangle formrect) { - PDXObjectForm innerForm = new PDXObjectForm(innerFormStream); - innerForm.setResources(innerFormResources); - innerForm.setBBox(formrect); - innerForm.setFormType(1); - getStructure().setInnerForm(innerForm); - logger.debug("Another form (inner form - it would be inside holder form) have been created"); - - } - - public void insertInnerFormToHolerResources(PDXObjectForm innerForm, - PDResources holderFormResources) { - String name = holderFormResources.addXObject(innerForm, "FRM"); - getStructure().setInnerFormName(name); - logger.debug("Alerady inserted inner form inside holder form"); - } - - public void createImageFormStream(PDDocument template) { - PDStream imageFormStream = new PDStream(template); - getStructure().setImageFormStream(imageFormStream); - logger.debug("Created image form Stream"); - } - - public void createImageFormResources() { - PDResources imageFormResources = new PDResources(); - getStructure().setImageFormResources(imageFormResources); - logger.debug("Created image form Resources"); - } - - public void createImageForm(PDResources imageFormResources, - PDResources innerFormResource, PDStream imageFormStream, - PDRectangle formrect, AffineTransform affineTransform, PDJpeg img) - throws IOException { - - /* - * if you need text on the visible signature - * - * PDFont font = PDTrueTypeFont.loadTTF(this.pdfStructure.getTemplate(), - * new File("D:\\arial.ttf")); font.setFontEncoding(new - * WinAnsiEncoding()); - * - * Map<String, PDFont> fonts = new HashMap<String, PDFont>(); - * fonts.put("arial", font); - */ - PDXObjectForm imageForm = new PDXObjectForm(imageFormStream); - imageForm.setBBox(formrect); - imageForm.setMatrix(affineTransform); - imageForm.setResources(imageFormResources); - imageForm.setFormType(1); - /* - * imageForm.getResources().addFont(font); - * imageForm.getResources().setFonts(fonts); - */ - - imageFormResources.getCOSObject().setDirect(true); - String imageFormName = innerFormResource.addXObject(imageForm, "n"); - String imageName = imageFormResources.addXObject(img, "img"); - this.getStructure().setImageForm(imageForm); - this.getStructure().setImageFormName(imageFormName); - this.getStructure().setImageName(imageName); - logger.debug("Created image form"); - } - - public void appendRawCommands(OutputStream os, String commands) - throws IOException { - os.write(commands.getBytes("UTF-8")); - os.close(); - } - - public void createVisualSignature(PDDocument template) { - this.getStructure().setVisualSignature(template.getDocument()); - logger.debug("Visible signature has been created"); - - } - - public void createWidgetDictionary(PDSignatureField signatureField, - PDResources holderFormResources) throws IOException { - - COSDictionary widgetDict = signatureField.getWidget().getDictionary(); - widgetDict.setNeedToBeUpdate(true); - widgetDict.setItem(COSName.DR, holderFormResources.getCOSObject()); - - getStructure().setWidgetDictionary(widgetDict); - logger.debug("WidgetDictionary has been crated"); - } - - public void closeTemplate(PDDocument template) throws IOException { - template.close(); - this.getStructure().getTemplate().close(); - } - -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureDesigner.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureDesigner.java deleted file mode 100644 index 17b02d9d..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureDesigner.java +++ /dev/null @@ -1,450 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; - -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -import javax.imageio.ImageIO; - -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDPage; -import org.apache.pdfbox.pdmodel.common.PDRectangle; - -public class PDFAsVisualSignatureDesigner { - -// private static final Logger logger = LoggerFactory.getLogger(PDFAsVisualSignatureDesigner.class); - - private Float sigImgWidth; - private Float sigImgHeight; - private float xAxis; - private float yAxis; - private float pageHeight; - private float pageWidth; - private InputStream imgageStream; - private String signatureFieldName = "sig"; // default - private float[] formaterRectangleParams = { 0, 0, 100, 50 }; // default - //private float[] AffineTransformParams = { 0, 1, -1, 0, 0, 0 }; // default - private float[] AffineTransformParams = { 1, 0, 0, 1, 0, 0 }; // default - private float imageSizeInPercents; - private PDDocument document = null; - private int page = 0; - private boolean newpage = false; - PDFAsVisualSignatureProperties properties; - - /** - * - * @param doc - * - Already created PDDocument of your PDF document - * @param imageStream - * @param page - * @throws IOException - * - If we can't read, flush, or can't close stream - */ - public PDFAsVisualSignatureDesigner(PDDocument doc, int page, - PDFAsVisualSignatureProperties properties, boolean newpage) throws IOException { - this.properties = properties; - calculatePageSize(doc, page, newpage); - document = doc; - this.page = page; - this.newpage = newpage; - } - - /** - * Each page of document can be different sizes. - * - * @param document - * @param page - */ - private void calculatePageSize(PDDocument document, int page, boolean newpage) { - - if (page < 1) { - throw new IllegalArgumentException("First page of pdf is 1, not " - + page); - } - - List<?> pages = document.getDocumentCatalog().getAllPages(); - if(newpage) { - PDPage lastPage = (PDPage) pages.get(pages.size()-1); - PDRectangle mediaBox = lastPage.findMediaBox(); - this.pageHeight(mediaBox.getHeight()); - this.pageWidth = mediaBox.getWidth(); - } else { - PDPage firstPage = (PDPage) pages.get(page - 1); - PDRectangle mediaBox = firstPage.findMediaBox(); - this.pageHeight(mediaBox.getHeight()); - this.pageWidth = mediaBox.getWidth(); - } - float x = this.pageWidth; - float y = 0; - this.pageWidth = this.pageWidth + y; - float tPercent = (100 * y / (x + y)); - this.imageSizeInPercents = 100 - tPercent; - } - - /** - * - * @param path - * of image location - * @return image Stream - * @throws IOException - */ - public PDFAsVisualSignatureDesigner signatureImage(String path) - throws IOException { - InputStream fin = new FileInputStream(path); - return signatureImageStream(fin); - } - - /** - * zoom signature image with some percent. - * - * @param percent - * - x % increase image with x percent. - * @return Visible Signature Configuration Object - */ - public PDFAsVisualSignatureDesigner zoom(float percent) { - sigImgHeight = sigImgHeight + (sigImgHeight * percent) / 100; - sigImgWidth = sigImgWidth + (sigImgWidth * percent) / 100; - return this; - } - - /** - * - * @param xAxis - * - x coordinate - * @param yAxis - * - y coordinate - * @return Visible Signature Configuration Object - */ - public PDFAsVisualSignatureDesigner coordinates(float x, float y) { - xAxis(x); - yAxis(y); - return this; - } - - /** - * - * @return xAxis - gets x coordinates - */ - public float getxAxis() { - return xAxis; - } - - /** - * - * @param xAxis - * - x coordinate - * @return Visible Signature Configuration Object - */ - public PDFAsVisualSignatureDesigner xAxis(float xAxis) { - this.xAxis = xAxis; - return this; - } - - /** - * - * @return yAxis - */ - public float getyAxis() { - return yAxis; - } - - /** - * - * @param yAxis - * @return Visible Signature Configuration Object - */ - public PDFAsVisualSignatureDesigner yAxis(float yAxis) { - this.yAxis = yAxis; - return this; - } - - /** - * - * @return signature image width - */ - public float getWidth() { - return this.properties.getMainTable().getWidth(); - } - - /** - * - * @param sets - * signature image width - * @return Visible Signature Configuration Object - */ - public PDFAsVisualSignatureDesigner width(float signatureImgWidth) { - this.sigImgWidth = signatureImgWidth; - return this; - } - - /** - * - * @return signature image height - */ - public float getHeight() { - return this.properties.getMainTable().getHeight(); - } - - /** - * - * @param set - * signature image Height - * @return Visible Signature Configuration Object - */ - public PDFAsVisualSignatureDesigner height(float signatureImgHeight) { - this.sigImgHeight = signatureImgHeight; - return this; - } - - /** - * - * @return template height - */ - protected float getTemplateHeight() { - return getPageHeight(); - } - - /** - * - * @param templateHeight - * @return Visible Signature Configuration Object - */ - private PDFAsVisualSignatureDesigner pageHeight(float templateHeight) { - this.pageHeight = templateHeight; - return this; - } - - /** - * - * @return signature field name - */ - public String getSignatureFieldName() { - return signatureFieldName; - } - - /** - * - * @param signatureFieldName - * @return Visible Signature Configuration Object - */ - public PDFAsVisualSignatureDesigner signatureFieldName( - String signatureFieldName) { - this.signatureFieldName = signatureFieldName; - return this; - } - - /** - * - * @return image Stream - */ - public InputStream getImageStream() { - return imgageStream; - } - - /** - * - * @param imgageStream - * - stream of your visible signature image - * @return Visible Signature Configuration Object - * @throws IOException - * - If we can't read, flush, or close stream of image - */ - private PDFAsVisualSignatureDesigner signatureImageStream( - InputStream imageStream) throws IOException { - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - int len; - while ((len = imageStream.read(buffer)) > -1) { - baos.write(buffer, 0, len); - } - baos.flush(); - baos.close(); - - byte[] byteArray = baos.toByteArray(); - byte[] byteArraySecond = byteArray.clone(); - - InputStream inputForBufferedImage = new ByteArrayInputStream(byteArray); - InputStream revertInputStream = new ByteArrayInputStream( - byteArraySecond); - - if (sigImgHeight == null || sigImgWidth == null) { - calcualteImageSize(inputForBufferedImage); - } - - this.imgageStream = revertInputStream; - - return this; - } - - /** - * calculates image width and height. sported formats: all - * - * @param fis - * - input stream of image - * @throws IOException - * - if can't read input stream - */ - private void calcualteImageSize(InputStream fis) throws IOException { - - BufferedImage bimg = ImageIO.read(fis); - int width = bimg.getWidth(); - int height = bimg.getHeight(); - - sigImgHeight = (float) height; - sigImgWidth = (float) width; - - } - - /** - * - * @return Affine Transform parameters of for PDF Matrix - */ - public float[] getAffineTransformParams() { - return AffineTransformParams; - } - - /** - * - * @param affineTransformParams - * @return Visible Signature Configuration Object - */ - public PDFAsVisualSignatureDesigner affineTransformParams( - float[] affineTransformParams) { - AffineTransformParams = affineTransformParams; - return this; - } - - /** - * - * @return formatter PDRectanle parameters - */ - public float[] getFormaterRectangleParams() { - return formaterRectangleParams; - } - - /** - * sets formatter PDRectangle; - * - * @param formaterRectangleParams - * @return Visible Signature Configuration Object - */ - public PDFAsVisualSignatureDesigner formaterRectangleParams( - float[] formaterRectangleParams) { - this.formaterRectangleParams = formaterRectangleParams; - return this; - } - - /** - * - * @return page width - */ - public float getPageWidth() { - return pageWidth; - } - - public PDPage getSignaturePage() { - if (page < 1) { - throw new IllegalArgumentException("First page of pdf is 1, not " - + page); - } - PDPage pdPage = null; - List<?> pages = document.getDocumentCatalog().getAllPages(); - if(newpage) { - pdPage = new PDPage(); - } else { - pdPage = (PDPage) pages.get(page - 1); - } - - return pdPage; - } - - /** - * - * @param sets - * pageWidth - * @return Visible Signature Configuration Object - */ - public PDFAsVisualSignatureDesigner pageWidth(float pageWidth) { - this.pageWidth = pageWidth; - return this; - } - - /** - * - * @return page height - */ - public float getPageHeight() { - return pageHeight; - } - - /** - * get image size in percents - * - * @return - */ - public float getImageSizeInPercents() { - return imageSizeInPercents; - } - - /** - * - * @param imageSizeInPercents - */ - public void imageSizeInPercents(float imageSizeInPercents) { - this.imageSizeInPercents = imageSizeInPercents; - } - - /** - * returns visible signature text - * - * @return - */ - public String getSignatureText() { - throw new UnsupportedOperationException( - "That method is not yet implemented"); - } - - /** - * - * @param signatureText - * - adds the text on visible signature - * @return - */ - public PDFAsVisualSignatureDesigner signatureText(String signatureText) { - throw new UnsupportedOperationException( - "That method is not yet implemented"); - } - - public float getRotation() { - return this.properties.getRotation(); - } - -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java deleted file mode 100644 index b7dbdfeb..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java +++ /dev/null @@ -1,102 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; - -import java.io.IOException; - -import org.apache.pdfbox.cos.COSDictionary; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDPage; -import org.apache.pdfbox.pdmodel.common.PDRectangle; -import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSigProperties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.gv.egiz.pdfas.common.exceptions.PdfAsException; -import at.gv.egiz.pdfas.common.exceptions.PdfAsWrappedIOException; -import at.gv.egiz.pdfas.common.settings.ISettings; -import at.gv.egiz.pdfas.lib.impl.status.PDFObject; -import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; - -public class PDFAsVisualSignatureProperties extends PDVisibleSigProperties { - - private static final Logger logger = LoggerFactory.getLogger(PDFAsVisualSignatureProperties.class); - - private ISettings settings; - - private PDFBoxTable main; - - private PDFAsVisualSignatureDesigner designer; - - private float rotationAngle = 0; - - public PDFAsVisualSignatureProperties(ISettings settings, PDFObject object, - PdfBoxVisualObject visObj, PositioningInstruction pos) { - this.settings = settings; - try { - main = visObj.getTable(); - } catch (Throwable e) { - e.printStackTrace(); - } - this.rotationAngle = pos.getRotation(); - try { - PDDocument origDoc = object.getDocument(); - - designer = new PDFAsVisualSignatureDesigner(origDoc, pos.getPage(), this, pos.isMakeNewPage()); - float posy = designer.getPageHeight() - pos.getY(); - designer.coordinates(pos.getX(), posy); - float[] form_rect = new float[] {0,0, main.getWidth() + 2, main.getHeight() + 2}; - logger.debug("AP Rect: {} {} {} {}", form_rect[0], form_rect[1], form_rect[2], form_rect[3]); - designer.formaterRectangleParams(form_rect); - //this.setPdVisibleSignature(designer); - } catch (Throwable e) { - e.printStackTrace(); - } - } - - @Override - public void buildSignature() throws IOException { - PDFAsVisualSignatureBuilder builder = new PDFAsVisualSignatureBuilder(this, this.settings, designer); - PDFAsTemplateCreator creator = new PDFAsTemplateCreator(builder); - try { - setVisibleSignature(creator.buildPDF(designer)); - } catch (PdfAsException e) { - throw new PdfAsWrappedIOException(e); - } - } - - public PDFBoxTable getMainTable() { - return main; - } - - - public float getRotation() { - return this.rotationAngle; - } - - public PDFAsVisualSignatureDesigner getDesigner() { - return designer; - } - -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxFont.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxFont.java deleted file mode 100644 index 8fcca9b7..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxFont.java +++ /dev/null @@ -1,169 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; - -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.font.PDFont; -import org.apache.pdfbox.pdmodel.font.PDTrueTypeFont; -import org.apache.pdfbox.pdmodel.font.PDType1Font; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.gv.egiz.pdfas.common.settings.ISettings; - -public class PDFBoxFont { - - private static final Logger logger = LoggerFactory - .getLogger(PDFBoxFont.class); - - private static final String HELVETICA = "HELVETICA"; - private static final String COURIER = "COURIER"; - private static final String TIMES_ROMAN = "TIMES_ROMAN"; - private static final String BOLD = "BOLD"; - private static final String NORMAL = "NORMAL"; - private static final String ITALIC = "ITALIC"; - private static final String SEP = ":"; - - public static PDFont defaultFont = PDType1Font.HELVETICA; - public static float defaultFontSize = 8; - - private static Map<String, PDFont> fontStyleMap = new HashMap<String, PDFont>(); - - static { - fontStyleMap.put(HELVETICA+SEP+NORMAL, PDType1Font.HELVETICA); - fontStyleMap.put(HELVETICA+SEP+BOLD, PDType1Font.HELVETICA_BOLD); - - fontStyleMap.put(COURIER+SEP+NORMAL, PDType1Font.COURIER); - fontStyleMap.put(COURIER+SEP+BOLD, PDType1Font.COURIER_BOLD); - - fontStyleMap.put(TIMES_ROMAN+SEP+NORMAL, PDType1Font.TIMES_ROMAN); - fontStyleMap.put(TIMES_ROMAN+SEP+BOLD, PDType1Font.TIMES_BOLD); - fontStyleMap.put(TIMES_ROMAN+SEP+ITALIC, PDType1Font.TIMES_ITALIC); - } - - public static void showBuildinFonts() { - Iterator<String> it = fontStyleMap.keySet().iterator(); - logger.info("Available Fonts:"); - while(it.hasNext()) { - logger.info(it.next()); - } - } - - PDFont font; - PDFont cachedfont = null; - float fontSize; - String fontDesc; - String ttfFontDesc; - PDDocument doc; - ISettings settings; - - private PDFont generateTTF(String fonttype, PDDocument doc) throws IOException { - boolean cacheNow = false; - if(doc == null) { - if(this.doc == null) { - this.doc = new PDDocument(); - } - doc = this.doc; - } else { - cacheNow = true; - } - ttfFontDesc = fonttype; - String fontName = fonttype.replaceFirst("TTF:", ""); - - logger.debug("Instantiating font."); - String fontPath = this.settings.getWorkingDirectory() + File.separator + "fonts" + File.separator + fontName; - logger.debug("Instantiating \"" + fontPath + "\"."); - - if(cacheNow) { - cachedfont = PDTrueTypeFont.loadTTF(doc, fontPath); - return cachedfont; - } else { - return PDTrueTypeFont.loadTTF(doc, fontPath); - } - } - - private PDFont generateFont(String fonttype, String fontder) throws IOException { - if(fonttype.startsWith("TTF:")) { - // Load TTF Font - return generateTTF(fonttype, null); - } else { - if(fontder == null) { - fontder = NORMAL; - } - - String fontDesc = fonttype + SEP + fontder; - PDFont font = fontStyleMap.get(fontDesc); - if(font == null) { - showBuildinFonts(); - throw new IOException("Invalid font descriptor"); - } - return font; - } - } - - private void setFont(String desc) throws IOException { - String[] fontArr = desc.split(","); - - if(fontArr.length == 3) { - font = generateFont(fontArr[0], fontArr[2]); - fontSize = Float.parseFloat(fontArr[1]); - } else if(fontArr.length == 2 && fontArr[0].startsWith("TTF:")) { - font = generateFont(fontArr[0], null); - fontSize = Float.parseFloat(fontArr[1]); - } else { - logger.warn("Using default font because: {} is not a valid font descriptor.", desc); - this.font = defaultFont; - this.fontSize = defaultFontSize; - } - - } - - public PDFBoxFont(String fontDesc, ISettings settings) throws IOException { - this.settings = settings; - this.fontDesc = fontDesc; - logger.debug("Creating Font: " + fontDesc); - this.setFont(fontDesc); - } - - public PDFont getFont(PDDocument doc) throws IOException { - if(cachedfont != null) { - return cachedfont; - } - if(font instanceof PDTrueTypeFont && doc != null) { - return generateTTF(ttfFontDesc, doc); - } else { - return font; - } - } - - public float getFontSize() { - return fontSize; - } -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxTable.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxTable.java deleted file mode 100644 index e84bd498..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxTable.java +++ /dev/null @@ -1,691 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; - -import java.awt.Color; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.List; - -import org.apache.fontbox.ttf.TrueTypeFont; -import org.apache.pdfbox.pdmodel.font.PDFont; -import org.apache.pdfbox.pdmodel.font.PDTrueTypeFont; -import org.apache.pdfbox.pdmodel.font.PDType1Font; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.gv.egiz.pdfas.common.exceptions.PdfAsException; -import at.gv.egiz.pdfas.common.exceptions.PdfAsWrappedIOException; -import at.gv.egiz.pdfas.common.settings.ISettings; -import at.gv.egiz.pdfas.common.utils.StringUtils; -import at.knowcenter.wag.egov.egiz.table.Entry; -import at.knowcenter.wag.egov.egiz.table.Style; -import at.knowcenter.wag.egov.egiz.table.Table; - -public class PDFBoxTable { - - private static final Logger logger = LoggerFactory - .getLogger(PDFBoxTable.class); - - Table table; - Style style; - PDFBoxFont font; - PDFBoxFont valueFont; - ISettings settings; - - float padding; - int positionX = 0; - int positionY = 0; - float tableWidth; - float tableHeight; - Color bgColor; - - boolean[] addPadding; - float[] rowHeights; - float[] colWidths; - - private void normalizeContent(Table abstractTable) throws PdfAsException { - try { - int rows = abstractTable.getRows().size(); - for (int i = 0; i < rows; i++) { - ArrayList<Entry> row = this.table.getRows().get(i); - for (int j = 0; j < row.size(); j++) { - Entry cell = (Entry) row.get(j); - - switch (cell.getType()) { - case Entry.TYPE_CAPTION: - case Entry.TYPE_VALUE: - String value = (String) cell.getValue(); - cell.setValue(StringUtils - .convertStringToPDFFormat(value)); - break; - } - } - } - } catch (UnsupportedEncodingException e) { - throw new PdfAsException("Unsupported Encoding", e); - } - } - - private void initializeStyle(Table abstractTable, PDFBoxTable parent) - throws IOException { - this.table = abstractTable; - try { - normalizeContent(abstractTable); - } catch (PdfAsException e) { - throw new PdfAsWrappedIOException(e); - } - - if (parent != null) { - style = Style.doInherit(abstractTable.getStyle(), parent.style); - } else { - style = abstractTable.getStyle(); - } - - if (style == null) { - throw new IOException("Failed to determine Table style, for table " - + abstractTable.getName()); - } - - String fontString = style.getFont(); - - String vfontString = style.getValueFont(); - - if (parent != null && style == parent.style) { - font = parent.getFont(); - - valueFont = parent.getValueFont(); - } else { - if (fontString == null && parent != null && parent.style != null) { - fontString = parent.style.getFont(); - } else if (fontString == null) { - throw new IOException( - "Failed to determine Table font style, for table " - + abstractTable.getName()); - } - - font = new PDFBoxFont(fontString, settings); - - if (vfontString == null && parent != null && parent.style != null) { - vfontString = parent.style.getValueFont(); - } else if (fontString == null) { - throw new IOException( - "Failed to determine value Table font style, for table " - + abstractTable.getName()); - } - - valueFont = new PDFBoxFont(vfontString, settings); - } - padding = style.getPadding(); - - bgColor = style.getBgColor(); - } - - public PDFBoxTable(Table abstractTable, PDFBoxTable parent, float fixSize, - ISettings settings) throws IOException { - this.settings = settings; - initializeStyle(abstractTable, parent); - float[] relativSizes = abstractTable.getColsRelativeWith(); - if (relativSizes != null) { - colWidths = new float[relativSizes.length]; - float totalrel = 0; - - for (int i = 0; i < relativSizes.length; i++) { - totalrel += relativSizes[i]; - } - - float unit = (fixSize / totalrel); - - for (int i = 0; i < relativSizes.length; i++) { - - colWidths[i] = unit * relativSizes[i]; - } - } else { - colWidths = new float[abstractTable.getMaxCols()]; - float totalrel = abstractTable.getMaxCols(); - float unit = (fixSize / totalrel); - for (int i = 0; i < colWidths.length; i++) { - - colWidths[i] = unit; - } - } - calculateHeightsBasedOnWidths(); - - logger.debug("Generating Table with fixed With {} got width {}", fixSize, getWidth()); - } - - public PDFBoxTable(Table abstractTable, PDFBoxTable parent, - ISettings settings) throws IOException { - this.settings = settings; - initializeStyle(abstractTable, parent); - this.calculateWidthHeight(); - } - - private void calculateHeightsBasedOnWidths() throws IOException { - int rows = this.table.getRows().size(); - rowHeights = new float[rows]; - addPadding = new boolean[rows]; - - for (int i = 0; i < rows; i++) { - rowHeights[i] = 0; - } - - for (int i = 0; i < rows; i++) { - ArrayList<Entry> row = this.table.getRows().get(i); - for (int j = 0; j < row.size(); j++) { - Entry cell = (Entry) row.get(j); - - float colWidth = 0;//colWidths[j]; - - int colsleft = cell.getColSpan(); - - if (j + colsleft > colWidths.length) { - throw new IOException( - "Configuration is wrong. Cannot determine column width!"); - } - - for (int k = 0; k < colsleft; k++) { - colWidth = colWidth + colWidths[j + k]; - } - - float cellheight = getCellHeight(cell, colWidth); - - if (rowHeights[i] < cellheight) { - rowHeights[i] = cellheight; - } - - logger.debug("ROW: {} COL: {} Width: {} Height: {}", i, j, - colWidth, cellheight); - - int span = cell.getColSpan() - 1; - j += span; - } - } - - calcTotals(); - } - - private void calculateWidthHeight() throws IOException { - int cols = this.table.getMaxCols(); - colWidths = new float[cols]; - - for (int i = 0; i < cols; i++) { - colWidths[i] = 0; - } - - int rows = this.table.getRows().size(); - rowHeights = new float[rows]; - - for (int i = 0; i < rows; i++) { - rowHeights[i] = 0; - } - - for (int i = 0; i < rows; i++) { - ArrayList<Entry> row = this.table.getRows().get(i); - for (int j = 0; j < row.size(); j++) { - Entry cell = (Entry) row.get(j); - float cellWidth = getCellWidth(cell); - - if (colWidths[j] < cellWidth) { - colWidths[j] = cellWidth; - } - - float cellheight = getCellHeight(cell); - - if (rowHeights[i] < cellheight) { - rowHeights[i] = cellheight; - } - - logger.debug("ROW: {} COL: {} Width: {} Height: {}", i, j, - cellWidth, cellheight); - - int span = cell.getColSpan() - 1; - j += span; - } - } - - calcTotals(); - } - - private void calcTotals() { - - this.tableHeight = 0; - - for (int i = 0; i < rowHeights.length; i++) { - this.tableHeight += rowHeights[i]; - } - - // Post Process heights for inner Tables ... - for (int i = 0; i < rowHeights.length; i++) { - ArrayList<Entry> row = this.table.getRows().get(i); - for (int j = 0; j < row.size(); j++) { - Entry cell = (Entry) row.get(j); - if(cell.getType() == Entry.TYPE_TABLE) { - PDFBoxTable tbl = (PDFBoxTable)cell.getValue(); - if(rowHeights[i] != tbl.getHeight()) - { - tbl.setHeight(rowHeights[i]); - } - } - } - } - - this.tableWidth = 0; - - for (int i = 0; i < colWidths.length; i++) { - this.tableWidth += colWidths[i]; - } - } - - private float getCellWidth(Entry cell) throws IOException { - boolean isValue = true; - switch (cell.getType()) { - case Entry.TYPE_CAPTION: - isValue = false; - case Entry.TYPE_VALUE: - PDFont c = null; - float fontSize; - String string = (String) cell.getValue(); - if (isValue) { - c = valueFont.getFont(null); - fontSize = valueFont.getFontSize(); - } else { - c = font.getFont(null); - fontSize = font.getFontSize(); - } - if (string == null) { - string = ""; - cell.setValue(string); - } - if (string.contains("\n")) { - float maxWidth = 0; - String[] lines = string.split("\n"); - for (int i = 0; i < lines.length; i++) { - float w = c.getStringWidth(lines[i]) / 1000 * fontSize; - if (maxWidth < w) { - maxWidth = w; - } - } - return maxWidth; - } else { - return c.getStringWidth(string) / 1000 * fontSize; - } - case Entry.TYPE_IMAGE: - if (style != null && style.getImageScaleToFit() != null) { - return style.getImageScaleToFit().getWidth(); - } - return 80.f; - case Entry.TYPE_TABLE: - PDFBoxTable pdfBoxTable = null; - if (cell.getValue() instanceof Table) { - pdfBoxTable = new PDFBoxTable((Table) cell.getValue(), this, - this.settings); - cell.setValue(pdfBoxTable); - } else if (cell.getValue() instanceof PDFBoxTable) { - pdfBoxTable = (PDFBoxTable) cell.getValue(); - } else { - throw new IOException("Failed to build PDFBox Table"); - } - return pdfBoxTable.getWidth(); - default: - logger.warn("Invalid Cell Entry Type: " + cell.getType()); - } - return 0; - } - - private String concatLines(String[] lines) { - String v = ""; - for (int i = 0; i < lines.length; i++) { - v += lines[i]; - if (i + 1 < lines.length) { - v += "\n"; - } - } - return v; - } - - private String[] breakString(String value, float maxwidth, PDFont font, - float fontSize) throws IOException { - String[] words = value.split(" "); - List<String> lines = new ArrayList<String>(); - String cLineValue = ""; - for (int i = 0; i < words.length; i++) { - String word = words[i]; - String[] lineBreaks = word.split("\n"); - if (lineBreaks.length > 1) { - for (int j = 0; j < lineBreaks.length; j++) { - String subword = lineBreaks[j]; - // if (cLine + subword.length() > maxline) { - if (j == 0 && word.startsWith("\n")) { - lines.add(cLineValue.trim()); - cLineValue = ""; - } else if (j != 0) { - lines.add(cLineValue.trim()); - cLineValue = ""; - } - // } - String tmpLine = cLineValue + subword; - float size = font.getStringWidth(tmpLine) / 1000.0f - * fontSize; - if (size > maxwidth && cLineValue.length() != 0) { - lines.add(cLineValue.trim()); - cLineValue = ""; - } - cLineValue += subword + " "; - } - } else { - String tmpLine = cLineValue + word; - float size = font.getStringWidth(tmpLine) / 1000.0f * fontSize; - if (size > maxwidth && cLineValue.length() != 0) { - lines.add(cLineValue.trim()); - cLineValue = ""; - } - cLineValue += word + " "; - } - } - lines.add(cLineValue.trim()); - return lines.toArray(new String[0]); - } - - private String[] breakString(String value, int maxline) { - String[] words = value.split(" "); - List<String> lines = new ArrayList<String>(); - int cLine = 0; - String cLineValue = ""; - for (int i = 0; i < words.length; i++) { - String word = words[i]; - String[] lineBreaks = word.split("\n"); - if (lineBreaks.length > 1) { - for (int j = 0; j < lineBreaks.length; j++) { - String subword = lineBreaks[j]; - // if (cLine + subword.length() > maxline) { - lines.add(cLineValue.trim()); - cLineValue = ""; - cLine = 0; - // } - cLineValue += subword + " "; - cLine += subword.length(); - } - } else { - if (cLine + word.length() > maxline && cLineValue.length() != 0) { - lines.add(cLineValue.trim()); - cLineValue = ""; - cLine = 0; - } - cLineValue += word + " "; - cLine += word.length(); - } - } - lines.add(cLineValue.trim()); - return lines.toArray(new String[0]); - } - - // private String[] breakString(String value, PDFont f, float maxwidth) - // throws IOException { - // String[] words = value.split(" "); - // List<String> lines = new ArrayList<String>(); - // int cLine = 0; - // String cLineValue = ""; - // for (int i = 0; i < words.length; i++) { - // String word = words[i]; - // String[] lineBreaks = word.split("\n"); - // if (lineBreaks.length > 1) { - // for (int j = 0; j < lineBreaks.length; j++) { - // String subword = lineBreaks[j]; - // // if (cLine + subword.length() > maxline) { - // lines.add(cLineValue.trim()); - // cLineValue = ""; - // cLine = 0; - // // } - // cLineValue += subword + " "; - // cLine += subword.length(); - // } - // } else { - // if (f.getStringWidth(cLineValue + word) > maxwidth && cLineValue.length() - // != 0) { - // lines.add(cLineValue.trim()); - // cLineValue = ""; - // cLine = 0; - // } - // cLineValue += word + " "; - // cLine += word.length(); - // } - // } - // lines.add(cLineValue.trim()); - // return lines.toArray(new String[0]); - // } - - private float[] getStringHeights(String[] lines, PDFont c, float fontSize) { - float[] heights = new float[lines.length]; - for (int i = 0; i < lines.length; i++) { - float maxLineHeight = 0; - try { - byte[] linebytes = StringUtils.applyWinAnsiEncoding(lines[i]); - for(int j = 0; j < linebytes.length; j++) { - float he = c.getFontHeight(linebytes, j, 1) / 1000 * fontSize; - if(he > maxLineHeight) { - maxLineHeight = he; - } - } - } catch (UnsupportedEncodingException e) { - logger.warn("failed to determine String height", e); - maxLineHeight = c.getFontDescriptor().getCapHeight() / 1000 * fontSize; - } catch (IOException e) { - logger.warn("failed to determine String height", e); - maxLineHeight = c.getFontDescriptor().getCapHeight() / 1000 * fontSize; - } - - heights[i] = maxLineHeight; - } - - return heights; - } - - private float getCellHeight(Entry cell, float width) throws IOException { - boolean isValue = true; - switch (cell.getType()) { - case Entry.TYPE_CAPTION: - isValue = false; - case Entry.TYPE_VALUE: - PDFont c = null; - float fontSize; - String string = (String) cell.getValue(); - if (isValue) { - c = valueFont.getFont(null); - fontSize = valueFont.getFontSize(); - } else { - c = font.getFont(null); - fontSize = font.getFontSize(); - } - - String[] lines = breakString(string, (width - padding * 2.0f), c, - fontSize); - cell.setValue(concatLines(lines)); - float[] heights = getStringHeights(lines, c, fontSize); - return fontSize * heights.length + padding * 2; - case Entry.TYPE_IMAGE: - if (style != null && style.getImageScaleToFit() != null) { - //if (style.getImageScaleToFit().getHeight() < width) { - return style.getImageScaleToFit().getHeight(); - //} - } - return width; - case Entry.TYPE_TABLE: - PDFBoxTable pdfBoxTable = null; - if (cell.getValue() instanceof Table) { - pdfBoxTable = new PDFBoxTable((Table) cell.getValue(), this, - width, this.settings); - cell.setValue(pdfBoxTable); - } else if (cell.getValue() instanceof PDFBoxTable) { - // recreate here beacuse of fixed width! - pdfBoxTable = (PDFBoxTable) cell.getValue(); - pdfBoxTable = new PDFBoxTable(pdfBoxTable.table, this, width, - this.settings); - cell.setValue(pdfBoxTable); - } else { - throw new IOException("Failed to build PDFBox Table"); - } - return pdfBoxTable.getHeight(); - default: - logger.warn("Invalid Cell Entry Type: " + cell.getType()); - } - return 0; - } - - private float getCellHeight(Entry cell) throws IOException { - boolean isValue = true; - switch (cell.getType()) { - case Entry.TYPE_CAPTION: - isValue = false; - case Entry.TYPE_VALUE: - PDFont c = null; - float fontSize; - String string = (String) cell.getValue(); - if (isValue) { - c = valueFont.getFont(null); - fontSize = valueFont.getFontSize(); - } else { - c = font.getFont(null); - fontSize = font.getFontSize(); - } - - if (string.contains("\n")) { - String[] lines = string.split("\n"); - - return fontSize * lines.length + padding * 2; - } else { - return fontSize + padding * 2; - } - case Entry.TYPE_IMAGE: - if (style != null && style.getImageScaleToFit() != null) { - return style.getImageScaleToFit().getHeight(); - } - return 80.f; - case Entry.TYPE_TABLE: - PDFBoxTable pdfBoxTable = null; - if (cell.getValue() instanceof Table) { - pdfBoxTable = new PDFBoxTable((Table) cell.getValue(), this, - this.settings); - cell.setValue(pdfBoxTable); - } else if (cell.getValue() instanceof PDFBoxTable) { - pdfBoxTable = (PDFBoxTable) cell.getValue(); - } else { - throw new IOException("Failed to build PDFBox Table"); - } - return pdfBoxTable.getHeight(); - default: - logger.warn("Invalid Cell Entry Type: " + cell.getType()); - } - return 0; - } - - public int getX() { - return this.positionX; - } - - public int getY() { - return this.positionY; - } - - public float getWidth() { - return tableWidth; - } - - public float getHeight() { - return tableHeight; - } - - public void setHeight(float height) { - float diff = height - this.getHeight(); - if(diff > 0) { - this.rowHeights[rowHeights.length - 1] += diff; - calcTotals(); - } else { - logger.warn("Table cannot be this small!"); - } - } - - public float[] getRowHeights() { - return rowHeights; - } - - public int getRowCount() { - return this.table.getRows().size(); - } - - public int getColCount() { - return this.table.getMaxCols();// .getColsRelativeWith().length; - } - - public float[] getColsRelativeWith() { - return this.table.getColsRelativeWith(); - } - - public float getPadding() { - return this.padding; - } - - public void dumpTable() { - logger.debug("====================================================================="); - logger.debug("Information about: " + this.table.getName()); - logger.debug("\tDimensions: {} x {} (W x H)", this.tableWidth, - this.tableHeight); - logger.debug("\tPadding: {}", padding); - logger.debug("\t================================"); - logger.debug("\tRow Heights:"); - for (int i = 0; i < rowHeights.length; i++) { - logger.debug("\t[{}] : {}", i, this.rowHeights[i]); - } - logger.debug("\t================================"); - logger.debug("\tCol Widths:"); - for (int i = 0; i < colWidths.length; i++) { - logger.debug("\t[{}] : {}", i, this.colWidths[i]); - } - logger.debug("\t================================"); - logger.debug("\tTable:"); - logger.debug("\t" + this.table.toString()); - logger.debug("====================================================================="); - } - - public Table getOrigTable() { - return this.table; - } - - public ArrayList<Entry> getRow(int i) { - return this.table.getRows().get(i); - } - - public PDFBoxFont getFont() { - return font; - } - - public PDFBoxFont getValueFont() { - return valueFont; - } - - public Color getBGColor() { - return this.bgColor; - } -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxStamper.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxStamper.java deleted file mode 100644 index c60c4283..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxStamper.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; - -import java.io.IOException; - -import at.gv.egiz.pdfas.common.exceptions.PdfAsException; -import at.gv.egiz.pdfas.common.settings.ISettings; -import at.gv.egiz.pdfas.lib.impl.stamping.IPDFStamper; -import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject; -import at.gv.egiz.pdfas.lib.impl.status.PDFObject; -import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; -import at.knowcenter.wag.egov.egiz.table.Table; - -public class PdfBoxStamper implements IPDFStamper { - -// private static final Logger logger = LoggerFactory.getLogger(PdfBoxStamper.class); - -// private PDFTemplateBuilder pdfBuilder; - - public PdfBoxStamper() { -// this.pdfBuilder = new PDVisibleSigBuilder(); - } - - public IPDFVisualObject createVisualPDFObject(PDFObject pdf, Table table) throws IOException { - return new PdfBoxVisualObject(table, pdf.getStatus().getSettings()); - } - - public byte[] writeVisualObject(IPDFVisualObject visualObject, - PositioningInstruction positioningInstruction, byte[] pdfData, - String placeholderName) throws PdfAsException { - return null; - } - - public void setSettings(ISettings settings) { - // not needed currently - } - -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxVisualObject.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxVisualObject.java deleted file mode 100644 index c7623cf9..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxVisualObject.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; - -import java.io.IOException; - -import at.gv.egiz.pdfas.common.settings.ISettings; -import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject; -import at.knowcenter.wag.egov.egiz.table.Table; - -public class PdfBoxVisualObject implements IPDFVisualObject { - - private Table abstractTable; - private PDFBoxTable table; - private float width; - private float x; - private float y; - private int page; - private ISettings settings; - - public PdfBoxVisualObject(Table table, ISettings settings) - throws IOException { - this.abstractTable = table; - this.table = new PDFBoxTable(table, null, settings); - this.settings = settings; - } - - public void setWidth(float width) { - this.width = width; - } - - public void fixWidth() { - try { - table = new PDFBoxTable(abstractTable, null, this.width, settings); - } catch (IOException e) { - // should not occur - e.printStackTrace(); - } - } - - public float getHeight() { - return table.getHeight(); - } - - public float getWidth() { - return table.getWidth(); - } - - public void setXPos(float x) { - this.x = x; - } - - public void setYPos(float y) { - this.y = y; - } - - public float getX() { - return x; - } - - public float getY() { - return y; - } - - public int getPage() { - return page; - } - - public void setPage(int page) { - this.page = page; - } - - public PDFBoxTable getTable() { - return this.table; - } -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/TableDrawUtils.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/TableDrawUtils.java deleted file mode 100644 index 88eb798a..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/TableDrawUtils.java +++ /dev/null @@ -1,564 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; - -import java.awt.Color; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Map; - -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDPage; -import org.apache.pdfbox.pdmodel.PDResources; -import org.apache.pdfbox.pdmodel.edit.PDPageContentStream; -import org.apache.pdfbox.pdmodel.font.PDFont; -import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.gv.egiz.pdfas.common.exceptions.PdfAsException; -import at.gv.egiz.pdfas.common.settings.ISettings; -import at.knowcenter.wag.egov.egiz.table.Entry; -import at.knowcenter.wag.egov.egiz.table.Style; - -public class TableDrawUtils { - - private static final Logger logger = LoggerFactory - .getLogger(TableDrawUtils.class); - - public static final String TABLE_DEBUG = "debug.table"; - - public static void drawTable(PDPage page, - PDPageContentStream contentStream, float x, float y, float width, - float height, PDFBoxTable abstractTable, PDDocument doc, - boolean subtable, PDResources formResources, - Map<String, ImageObject> images, ISettings settings) - throws PdfAsException { - - logger.debug("Drawing Table: X {} Y {} WIDTH {} HEIGHT {} \n{}", x, y, - width, height, abstractTable.getOrigTable().toString()); - - abstractTable.getOrigTable().setWidth(width); - - drawTableBackground(page, contentStream, x, y, width, height, - abstractTable, settings); - - drawBorder(page, contentStream, x, y, width, height, abstractTable, - doc, subtable, settings); - - drawContent(page, contentStream, x, y, width, height, abstractTable, - doc, subtable, formResources, images, settings); - } - - public static void drawContent(PDPage page, - PDPageContentStream contentStream, float x, float y, float width, - float height, PDFBoxTable abstractTable, PDDocument doc, - boolean subtable, PDResources formResources, - Map<String, ImageObject> images, ISettings settings) - throws PdfAsException { - - float contentx = x; - float contenty = y + height; - float padding = abstractTable.getPadding(); - float[] colsSizes = getColSizes(abstractTable); - - for (int i = 0; i < abstractTable.getRowCount(); i++) { - ArrayList<Entry> row = abstractTable.getRow(i); - for (int j = 0; j < row.size(); j++) { - Entry cell = (Entry) row.get(j); - - // Cell only contains default values so table style is the primary style - Style inherit_style = Style.doInherit(abstractTable.style, cell.getStyle()); - cell.setStyle(inherit_style); - - float colWidth = 0;//colWidths[j]; - - int colsleft = cell.getColSpan(); - - if (j + colsleft > colsSizes.length) { - throw new PdfAsException( - "Configuration is wrong. Cannot determine column width!"); - } - - for (int k = 0; k < colsleft; k++) { - colWidth = colWidth + colsSizes[j + k]; - } - - drawDebugPadding(contentStream, contentx, contenty, padding, - colWidth, abstractTable.getRowHeights()[i], settings); - - switch (cell.getType()) { - case Entry.TYPE_CAPTION: - drawCaption(page, contentStream, contentx, contenty, - colWidth, abstractTable.getRowHeights()[i], - padding, abstractTable, doc, cell, formResources, settings); - break; - case Entry.TYPE_VALUE: - drawValue(page, contentStream, contentx, contenty, - colWidth, abstractTable.getRowHeights()[i], - padding, abstractTable, doc, cell, formResources, settings); - break; - case Entry.TYPE_IMAGE: - drawImage(page, contentStream, contentx, contenty, - colWidth, abstractTable.getRowHeights()[i], - padding, abstractTable, doc, cell, formResources, - images, settings); - break; - case Entry.TYPE_TABLE: - - PDFBoxTable tbl_value = (PDFBoxTable) cell.getValue(); - - Style inherit_styletab = Style.doInherit( - abstractTable.style, cell.getStyle()); - tbl_value.table.setStyle(inherit_styletab); - - drawTable(page, contentStream, contentx, contenty - - abstractTable.getRowHeights()[i], colWidth, - abstractTable.getRowHeights()[i], tbl_value, doc, - true, formResources, images, settings); - break; - default: - logger.warn("Unknown Cell entry type: " + cell.getType()); - break; - } - - // Move content pointer - contentx += colWidth; - - int span = cell.getColSpan() - 1; - j += span; - } - - // Move content pointer - contenty -= abstractTable.getRowHeights()[i]; - contentx = x; - } - } - - private static void drawString(PDPage page, - PDPageContentStream contentStream, float contentx, float contenty, - float width, float height, float padding, - PDFBoxTable abstractTable, PDDocument doc, Entry cell, - float fontSize, float textHeight, String valign, String halign, - String[] tlines, PDFont textFont, PDResources formResources, - ISettings settings) throws PdfAsException { - try { - float ty = contenty - padding; - float tx = contentx + padding; - float innerHeight = height - (2 * padding); - float innerWidth = width - (2 * padding); - if (Style.BOTTOM.equals(valign)) { - float bottom_offset = innerHeight - textHeight; - ty -= bottom_offset; - } else if (Style.MIDDLE.equals(valign)) { - float bottom_offset = innerHeight - textHeight; - bottom_offset = bottom_offset / 2.0f; - ty -= bottom_offset; - } - - // calculate the max with of the text content - float maxWidth = 0; - for (int k = 0; k < tlines.length; k++) { - float lineWidth; - // if (textFont instanceof PDType1Font) { - lineWidth = textFont.getStringWidth(tlines[k]) / 1000.0f - * fontSize; - /* - * } else { float fwidth = textFont - * .getStringWidth("abcdefghijklmnopqrstuvwxyz ") / 1000.0f * - * fontSize; fwidth = fwidth / (float) - * "abcdefghijklmnopqrstuvwxyz" .length(); lineWidth = - * tlines[k].length() * fwidth; } - */ - if (maxWidth < lineWidth) { - maxWidth = lineWidth; - } - } - - if (Style.CENTER.equals(halign)) { - float offset = innerWidth - maxWidth; - if (offset > 0) { - offset = offset / 2.0f; - tx += offset; - } - } else if (Style.RIGHT.equals(halign)) { - float offset = innerWidth - maxWidth; - if (offset > 0) { - tx += offset; - } - } - - logger.debug("Text tx {} ty {} maxWidth {} textHeight {}", tx, ty, - maxWidth, textHeight); - - drawDebugLine(contentStream, tx, ty, maxWidth, textHeight, settings); - - contentStream.beginText(); - - if (formResources.getFonts().containsValue(textFont)) { - String fontID = getFontID(textFont, formResources); - logger.debug("Using Font: " + fontID); - contentStream.appendRawCommands("/" + fontID + " " + fontSize - + " Tf\n"); - } else { - contentStream.setFont(textFont, fontSize); - } - - logger.debug("Writing: " + tx + " : " + (ty - fontSize) + " as " - + cell.getType()); - contentStream.moveTextPositionByAmount(tx, (ty - fontSize)); - - contentStream.appendRawCommands(fontSize + " TL\n"); - for (int k = 0; k < tlines.length; k++) { - contentStream.drawString(tlines[k]); - if (k < tlines.length - 1) { - contentStream.appendRawCommands("T*\n"); - } - } - - contentStream.endText(); - - } catch (IOException e) { - logger.error("IO Exception", e); - throw new PdfAsException("Error", e); - } - } - - public static void drawCaption(PDPage page, - PDPageContentStream contentStream, float contentx, float contenty, - float width, float height, float padding, - PDFBoxTable abstractTable, PDDocument doc, Entry cell, - PDResources formResources, ISettings settings) - throws PdfAsException { - - logger.debug("Drawing Caption @ X: {} Y: {}", contentx, contenty); - - try { - float fontSize = PDFBoxFont.defaultFontSize; - PDFont textFont = PDFBoxFont.defaultFont; - - textFont = abstractTable.getFont().getFont(doc); - fontSize = abstractTable.getFont().getFontSize(); - - // get the cell Text - String text = (String) cell.getValue(); - String[] tlines = text.split("\n"); - float textHeight = fontSize * tlines.length; - - Style cellStyle = cell.getStyle(); - String valign = cellStyle.getVAlign(); - String halign = cellStyle.getHAlign(); - - drawString(page, contentStream, contentx, contenty, width, height, - padding, abstractTable, doc, cell, fontSize, textHeight, - valign, halign, tlines, textFont, formResources, settings); - } catch (IOException e) { - logger.error("IO Exception", e); - throw new PdfAsException("Error", e); - } - } - - public static void drawValue(PDPage page, - PDPageContentStream contentStream, float contentx, float contenty, - float width, float height, float padding, - PDFBoxTable abstractTable, PDDocument doc, Entry cell, - PDResources formResources, ISettings settings) - throws PdfAsException { - - logger.debug("Drawing Value @ X: {} Y: {}", contentx, contenty); - - try { - float fontSize = PDFBoxFont.defaultFontSize; - PDFont textFont = PDFBoxFont.defaultFont; - - textFont = abstractTable.getValueFont().getFont(doc); - fontSize = abstractTable.getValueFont().getFontSize(); - - // get the cell Text - String text = (String) cell.getValue(); - String[] tlines = text.split("\n"); - float textHeight = fontSize * tlines.length; - - Style cellStyle = cell.getStyle(); - String valign = cellStyle.getValueVAlign(); - String halign = cellStyle.getValueHAlign(); - - drawString(page, contentStream, contentx, contenty, width, height, - padding, abstractTable, doc, cell, fontSize, textHeight, - valign, halign, tlines, textFont, formResources, settings); - } catch (IOException e) { - logger.error("IO Exception", e); - throw new PdfAsException("Error", e); - } - } - - public static void drawImage(PDPage page, - PDPageContentStream contentStream, float contentx, float contenty, - float width, float height, float padding, - PDFBoxTable abstractTable, PDDocument doc, Entry cell, - PDResources formResources, Map<String, ImageObject> images, - ISettings settings) throws PdfAsException { - try { - float innerHeight = height; - float innerWidth = width; - - String img_ref = (String) cell.getValue(); - if (!images.containsKey(img_ref)) { - logger.error("Image not prepared! : " + img_ref); - throw new PdfAsException("Image not prepared! : " + img_ref); - } - ImageObject image = images.get(img_ref); - PDXObjectImage pdImage = image.getImage(); - - float imgx = contentx; - float hoffset = innerWidth - image.getWidth(); - if (cell.getStyle().getImageHAlign() != null - && cell.getStyle().getImageHAlign().equals(Style.LEFT)) { - hoffset = hoffset / 2.0f; - imgx += hoffset; - } else if (cell.getStyle().getImageHAlign() != null - && cell.getStyle().getImageHAlign().equals(Style.RIGHT)) { - imgx += hoffset; - } else { - hoffset = hoffset / 2.0f; - imgx += hoffset; - } - - float imgy = contenty; - float voffset = innerHeight - image.getHeight(); - if (cell.getStyle().getImageVAlign() != null - && cell.getStyle().getImageVAlign().equals(Style.MIDDLE)) { - voffset = voffset / 2.0f; - imgy -= voffset; - } else if (cell.getStyle().getImageVAlign() != null - && cell.getStyle().getImageVAlign().equals(Style.BOTTOM)) { - imgy -= voffset; - } - - drawDebugLine(contentStream, imgx, imgy, image.getWidth(), - image.getHeight(), settings); - - // logger.debug("Image: " + imgx + " : " + (imgy - - // image.getHeight())); - contentStream.drawXObject(pdImage, imgx, imgy - image.getHeight(), - image.getWidth(), image.getHeight()); - } catch (IOException e) { - logger.error("IO Exception", e); - throw new PdfAsException("Error", e); - } - - } - - public static float[] getColSizes(PDFBoxTable abstractTable) { - float[] origcolsSizes = abstractTable.getColsRelativeWith(); - int max_cols = abstractTable.getColCount(); - float[] colsSizes = new float[max_cols]; - if (origcolsSizes == null) { - // set the column ratio for all columns to 1 - for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) { - colsSizes[cols_idx] = 1; - } - } else { - // set the column ratio for all columns to 1 - for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) { - colsSizes[cols_idx] = origcolsSizes[cols_idx]; - } - } - - // adapt - float total = 0; - - for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) { - total += colsSizes[cols_idx]; - } - - for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) { - colsSizes[cols_idx] = (colsSizes[cols_idx] / total) - * abstractTable.getWidth(); - } - - float sum = 0; - - for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) { - sum += colsSizes[cols_idx]; - } - - logger.debug("Table Col Sizes SUM {} Table Width {}", sum, - abstractTable.getWidth()); - logger.debug("Table Table Height {}", abstractTable.getHeight()); - - return colsSizes; - } - - public static void drawBorder(PDPage page, - PDPageContentStream contentStream, float x, float y, float width, - float height, PDFBoxTable abstractTable, PDDocument doc, - boolean subtable, ISettings settings) throws PdfAsException { - try { - - logger.debug("Drawing Table borders for " - + abstractTable.getOrigTable().getName()); - - final int rows = abstractTable.getRowCount(); - float border = abstractTable.style.getBorder(); - float[] colsSizes = getColSizes(abstractTable); - - if (border > 0) { - contentStream.setLineWidth(border); - - float x_from = x; - float x_to = x + width; - float y_from = y + height; - float y_to = y + height; - - // draw first line - logger.debug("ROW LINE: {} {} {} {}", x_from, y_from, x_to, - y_from); - contentStream.drawLine(x, y_from, x_to, y_from); - - // Draw all row borders - for (int i = 0; i < rows; i++) { - y_from -= abstractTable.getRowHeights()[i]; - - // Draw row border! - logger.debug("ROW LINE: {} {} {} {}", x_from, y_from, x_to, - y_from); - contentStream.drawLine(x, y_from, x_to, y_from); - - } - - // reset y for "line feed" - y_from = y + height; - y_to = y_from - abstractTable.getRowHeights()[0]; - - // Draw all column borders - for (int i = 0; i < rows; i++) { - ArrayList<Entry> row = abstractTable.getRow(i); - - // reset x for "line feed" - x_from = x; - - // draw first line - logger.debug("COL LINE: {} {} {} {}", x_from, y_from, - x_from, y_to); - - contentStream.drawLine(x_from, y_from, x_from, y_to); - - for (int j = 0; j < row.size(); j++) { - Entry cell = (Entry) row.get(j); - - for (int k = 0; k < cell.getColSpan(); k++) { - if (k + j < colsSizes.length) { - x_from += colsSizes[k + j]; - } - } - logger.debug("COL LINE: {} {} {} {}", x_from, y_from, - x_from, y_to); - contentStream.drawLine(x_from, y_from, x_from, y_to); - } - - if (i + 1 < rows) { - y_from = y_to; - y_to = y_from - abstractTable.getRowHeights()[i + 1]; - } - } - - } - } catch (Throwable e) { - logger.warn("drawing table borders", e); - throw new PdfAsException("drawing table borders", e); - } - } - - public static void drawTableBackground(PDPage page, - PDPageContentStream contentStream, float x, float y, float width, - float height, PDFBoxTable abstractTable, ISettings settings) - throws PdfAsException { - try { - if (abstractTable.getBGColor() != null) { - contentStream.setNonStrokingColor(abstractTable.getBGColor()); - contentStream.fillRect(x, y, abstractTable.getWidth(), - abstractTable.getHeight()); - contentStream.setNonStrokingColor(Color.BLACK); - } - } catch (Throwable e) { - logger.warn("drawing table borders", e); - throw new PdfAsException("drawing table borders", e); - } - } - - private static void drawDebugLine(PDPageContentStream contentStream, - float x, float y, float width, float height, ISettings settings) { - if ("true".equals(settings.getValue(TABLE_DEBUG))) { - try { - contentStream.setStrokingColor(Color.RED); - contentStream.drawLine(x, y, x + width, y); - contentStream.setStrokingColor(Color.BLUE); - contentStream.drawLine(x, y, x, y - height); - contentStream.setStrokingColor(Color.GREEN); - contentStream.drawLine(x + width, y, x + width, y - height); - contentStream.setStrokingColor(Color.ORANGE); - contentStream.drawLine(x, y - height, x + width, y - height); - - contentStream.setStrokingColor(Color.BLACK); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - private static void drawDebugPadding(PDPageContentStream contentStream, - float x, float y, float padding, float width, float height, - ISettings settings) { - if ("true".equals(settings.getValue(TABLE_DEBUG))) { - try { - contentStream.setStrokingColor(Color.RED); - contentStream.drawLine(x, y, x + padding, y - padding); - contentStream.drawLine(x + width, y, x + width - padding, y - - padding); - contentStream.drawLine(x + width, y - height, x + width - - padding, y - height + padding); - contentStream.drawLine(x, y - height, x + padding, y - height - + padding); - contentStream.setStrokingColor(Color.BLACK); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - private static String getFontID(PDFont font, PDResources resources) { - Iterator<java.util.Map.Entry<String, PDFont>> it = resources.getFonts() - .entrySet().iterator(); - while (it.hasNext()) { - java.util.Map.Entry<String, PDFont> entry = it.next(); - if (entry.getValue().equals(font)) { - return entry.getKey(); - } - } - return ""; - } - -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/tagging/PDFBoxTaggingUtils.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/tagging/PDFBoxTaggingUtils.java deleted file mode 100644 index 534788ed..00000000 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/tagging/PDFBoxTaggingUtils.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> - * 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. - ******************************************************************************/ -package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox.tagging; - -import java.util.Iterator; -import java.util.List; - -import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDMarkedContentReference; -import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureElement; -import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureNode; -import org.apache.pdfbox.pdmodel.documentinterchange.markedcontent.PDMarkedContent; - -public class PDFBoxTaggingUtils { - - public static String DOCUMENT = "Document"; - - public static void beginMarkedContent(PDMarkedContentReference reference) { - PDMarkedContentReference ref; - PDMarkedContent mc; - } - - public static PDStructureElement getDocumentElement(PDStructureNode structElem) { - List<Object> kids = structElem.getKids(); - Iterator<Object> kidsit = kids.iterator(); - while (kidsit.hasNext()) { - Object kid = kidsit.next(); - if (kid instanceof PDStructureElement) { - PDStructureElement elem = (PDStructureElement) kid; - if(elem.getStructureType().equals(DOCUMENT)) { - return elem; - } - } - } - return null; - } - -} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java index 4a8445b5..7b2ce69c 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java @@ -31,6 +31,7 @@ import java.util.Map; import at.gv.egiz.pdfas.common.settings.ISettings; import at.gv.egiz.pdfas.common.utils.TempFileHelper; import at.gv.egiz.pdfas.lib.api.sign.SignParameter; +import at.gv.egiz.pdfas.lib.backend.PDFASBackend; import at.gv.egiz.pdfas.lib.impl.configuration.GlobalConfiguration; import at.gv.egiz.pdfas.lib.impl.configuration.PlaceholderConfiguration; import at.gv.egiz.pdfas.lib.impl.configuration.SignatureProfileConfiguration; @@ -43,7 +44,7 @@ public class OperationStatus implements Serializable { private static final long serialVersionUID = -2985007198666388528L; private SignParameter signParamter; - private PDFObject pdfObject = new PDFObject(this); + private PDFObject pdfObject; private ISettings configuration; private PlaceholderConfiguration placeholderConfiguration = null; @@ -52,10 +53,12 @@ public class OperationStatus implements Serializable { private TempFileHelper helper; private RequestedSignature requestedSignature; private Calendar signingDate; + private PDFASBackend backend; - public OperationStatus(ISettings configuration, SignParameter signParameter) { + public OperationStatus(ISettings configuration, SignParameter signParameter, PDFASBackend backend) { this.configuration = configuration; this.signParamter = signParameter; + this.backend = backend; helper = new TempFileHelper(configuration); } @@ -71,7 +74,7 @@ public class OperationStatus implements Serializable { } // ======================================================================== - + public void clear() { if (this.helper != null) { try { @@ -84,6 +87,10 @@ public class OperationStatus implements Serializable { } } + public PDFASBackend getBackend() { + return backend; + } + public RequestedSignature getRequestedSignature() { return requestedSignature; } @@ -162,5 +169,4 @@ public class OperationStatus implements Serializable { } return null; } - } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/PDFObject.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/PDFObject.java index f69c20a4..de88f610 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/PDFObject.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/PDFObject.java @@ -24,19 +24,16 @@ package at.gv.egiz.pdfas.lib.impl.status; import java.io.IOException; -import java.io.OutputStream; import javax.activation.DataSource; -import org.apache.pdfbox.pdmodel.PDDocument; -public class PDFObject { +public abstract class PDFObject { - private OperationStatus status; + protected OperationStatus status; - private PDDocument doc; - private DataSource originalDocument; - private byte[] signedDocument; + protected DataSource originalDocument; + protected byte[] signedDocument; public PDFObject(OperationStatus operationStatus) { this.status = operationStatus; @@ -45,41 +42,15 @@ public class PDFObject { @Override protected void finalize() throws Throwable { super.finalize(); - if(doc != null) { - doc.close(); - } } - public void close() { - if(doc != null) { - try { - doc.close(); - //System.gc(); - } catch(Throwable e) { - // ignore! - } - doc = null; - } - } + public abstract void close(); public DataSource getOriginalDocument() { return originalDocument; } - public void setOriginalDocument(DataSource originalDocument) throws IOException { - this.originalDocument = originalDocument; - if(doc != null) { - doc.close(); - } - this.doc = PDDocument.load(this.originalDocument.getInputStream()); - if(this.doc != null) { - this.doc.getDocument().setWarnMissingClose(false); - } - } - - public PDDocument getDocument() { - return this.doc; - } + public abstract void setOriginalDocument(DataSource originalDocument) throws IOException; public byte[] getSignedDocument() { return signedDocument; @@ -96,4 +67,6 @@ public class PDFObject { public void setStatus(OperationStatus status) { this.status = status; } + + public abstract String getPDFVersion(); } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/FilterEntry.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/FilterEntry.java index 83ef17e6..2d7b456d 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/FilterEntry.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/FilterEntry.java @@ -23,29 +23,29 @@ ******************************************************************************/ package at.gv.egiz.pdfas.lib.impl.verify; -import org.apache.pdfbox.cos.COSName; - public class FilterEntry { - private COSName filter; - private COSName subFilter; - - public FilterEntry(COSName filter, COSName subfilter) { + private String filter; + private String subFilter; + + public FilterEntry(String filter, String subfilter) { this.filter = filter; this.subFilter = subfilter; } - - public COSName getFilter() { + + public String getFilter() { return filter; } - public void setFilter(COSName filter) { + + public void setFilter(String filter) { this.filter = filter; } - public COSName getSubFilter() { + + public String getSubFilter() { return subFilter; } - public void setSubFilter(COSName subFilter) { + + public void setSubFilter(String subFilter) { this.subFilter = subFilter; } - - + } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/VerifierDispatcher.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/VerifierDispatcher.java index ce7b4707..26065adf 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/VerifierDispatcher.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/VerifierDispatcher.java @@ -138,23 +138,23 @@ public class VerifierDispatcher { while (it.hasNext()) { FilterEntry entry = it.next(); HashMap<String, IVerifyFilter> filters = filterMap - .get(entry.getFilter().getName()); + .get(entry.getFilter()); if (filters == null) { filters = new HashMap<String, IVerifyFilter>(); - filterMap.put(entry.getFilter().getName(), filters); + filterMap.put(entry.getFilter(), filters); } IVerifyFilter oldFilter = filters.get(entry.getSubFilter() - .getName()); + ); if (oldFilter != null) { throw new PdfAsException("Filter allready registered"); } - filters.put(entry.getSubFilter().getName(), filter); + filters.put(entry.getSubFilter(), filter); logger.debug("Registered Filter: " + cls.getName() - + " for " + entry.getFilter().getName() + "/" - + entry.getSubFilter().getName()); + + " for " + entry.getFilter() + "/" + + entry.getSubFilter()); } } } catch (Throwable e) { diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/VerifyBackend.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/VerifyBackend.java new file mode 100644 index 00000000..e29ac49e --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/VerifyBackend.java @@ -0,0 +1,11 @@ +package at.gv.egiz.pdfas.lib.impl.verify; + +import java.util.List; + +import at.gv.egiz.pdfas.common.exceptions.PDFASError; +import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter; +import at.gv.egiz.pdfas.lib.api.verify.VerifyResult; + +public interface VerifyBackend { + public List<VerifyResult> verify(VerifyParameter parameter) throws PDFASError; +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/util/SignatureUtils.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/util/SignatureUtils.java index 3b992e46..cdc7f11e 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/util/SignatureUtils.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/util/SignatureUtils.java @@ -9,10 +9,6 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.SignatureException; -import org.apache.pdfbox.cos.COSArray; -import org.apache.pdfbox.cos.COSDictionary; -import org.apache.pdfbox.cos.COSName; -import org.apache.pdfbox.pdmodel.PDDocument; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,49 +21,6 @@ public class SignatureUtils implements ErrorConstants { private static final Logger logger = LoggerFactory .getLogger(SignatureUtils.class); - - public static int countSignatures(PDDocument doc, String sigName) { - int count = 0; - COSDictionary trailer = doc.getDocument().getTrailer(); - COSDictionary root = (COSDictionary) trailer - .getDictionaryObject(COSName.ROOT); - COSDictionary acroForm = (COSDictionary) root - .getDictionaryObject(COSName.ACRO_FORM); - COSArray fields = (COSArray) acroForm - .getDictionaryObject(COSName.FIELDS); - for (int i = 0; i < fields.size(); i++) { - COSDictionary field = (COSDictionary) fields.getObject(i); - String type = field.getNameAsString("FT"); - if ("Sig".equals(type)) { - String name = field.getString(COSName.T); - if (name != null) { - logger.debug("Found Sig: " + name); - try { - if (name.startsWith(sigName)) { - String numberString = name.replace(sigName, ""); - - logger.debug("Found Number: " + numberString); - - int SigIDX = Integer.parseInt(numberString); - if(SigIDX > count) { - count = SigIDX; - } - } - } catch (Throwable e) { - logger.info("Found a different Signature, we do not need to count this."); - } - } - } - - } - - count++; - - logger.debug("Returning sig number: " + count); - - return count; - } - public static VerifyResult verifySignature(byte[] signature, byte[] input) throws PDFASError { //List<VerifyResult> results = new ArrayList<VerifyResult>(); |