aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java16
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PlaceholderExtractionException.java11
-rw-r--r--pdf-as-lib/bin/placeholder/empty.jpgbin0 -> 631 bytes
-rw-r--r--pdf-as-lib/bin/placeholder/pdfbox-reader.properties23
-rw-r--r--pdf-as-lib/build.gradle2
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java4
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java87
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderContext.java72
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderData.java152
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderExtractor.java351
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/package-info.java8
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java2
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java4
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifyFilter.java2
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BKUSLConnector.java2
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java2
-rw-r--r--pdf-as-lib/src/main/resources/placeholder/empty.jpgbin0 -> 631 bytes
-rw-r--r--pdf-as-lib/src/main/resources/placeholder/pdfbox-reader.properties23
-rw-r--r--signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESVerifier.java7
-rw-r--r--signature-standards/sigs-pcks7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedVerifier.java6
-rw-r--r--stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextStamper.java14
-rw-r--r--stamper/stmp-itext/src/main/java/com/lowagie/text/pdf/ITextStamperAccess.java47
-rw-r--r--stamper/stmp-itext/src/main/java/com/lowagie/text/pdf/package-info.java8
23 files changed, 818 insertions, 25 deletions
diff --git a/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java
index 4072e496..ed029aac 100644
--- a/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java
+++ b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java
@@ -41,16 +41,16 @@ public class DeveloperMain {
byte[] data;
try {
IPlainSigner signer = new PKCS7DetachedSigner(keyStoreFile, keyAlias, keyStorePass, keyPass, keyStoreType);
- data = StreamUtils.inputStreamToByteArray(new FileInputStream("/home/afitzek/tmp/pdf-a problem/TestGhostscriptPdfA.pdf"));
+ data = StreamUtils.inputStreamToByteArray(new FileInputStream("/home/afitzek/qr_2.pdf"));
SignParameter parameter = PdfAsFactory.createSignParameter(config, new ByteArrayDataSource(data));
ByteArrayDataSink bads = new ByteArrayDataSink();
parameter.setSignatureProfileId("SIGNATURBLOCK_DE_PDFA");
parameter.setOutput(bads);
//parameter.setPlainSigner(new PAdESSigner(new BKUSLConnector(config)));
- //parameter.setPlainSigner(signer);
- parameter.setPlainSigner(new PAdESSigner(new MOAConnector(config)));
- /*
- StatusRequest request = pdfas.startSign(parameter);
+ parameter.setPlainSigner(signer);
+ //parameter.setPlainSigner(new PAdESSigner(new MOAConnector(config)));
+
+ /*StatusRequest request = pdfas.startSign(parameter);
if(request.needCertificate()) {
request.setCertificate(signer.getCertificate().getEncoded());
@@ -78,12 +78,12 @@ public class DeveloperMain {
}
*/
pdfas.sign(parameter);
- FileOutputStream fos = new FileOutputStream("/home/afitzek/devel/pdfas_neu/simple_out3.pdf");
+ FileOutputStream fos = new FileOutputStream("/home/afitzek/qr_2_neu.pdf");
fos.write(bads.getData());
fos.close();
- VerifyParameter verify = new VerifyParameterImpl(config, new ByteArrayDataSource(bads.getData()));
- pdfas.verify(verify);
+ //VerifyParameter verify = new VerifyParameterImpl(config, new ByteArrayDataSource(bads.getData()));
+ //pdfas.verify(verify);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PlaceholderExtractionException.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PlaceholderExtractionException.java
new file mode 100644
index 00000000..bef8d245
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PlaceholderExtractionException.java
@@ -0,0 +1,11 @@
+package at.gv.egiz.pdfas.common.exceptions;
+
+public class PlaceholderExtractionException extends PdfAsException {
+ public PlaceholderExtractionException(String msgId) {
+ super(msgId);
+ }
+
+ public PlaceholderExtractionException(String msgId, Throwable e) {
+ super(msgId, e);
+ }
+}
diff --git a/pdf-as-lib/bin/placeholder/empty.jpg b/pdf-as-lib/bin/placeholder/empty.jpg
new file mode 100644
index 00000000..7913177d
--- /dev/null
+++ b/pdf-as-lib/bin/placeholder/empty.jpg
Binary files differ
diff --git a/pdf-as-lib/bin/placeholder/pdfbox-reader.properties b/pdf-as-lib/bin/placeholder/pdfbox-reader.properties
new file mode 100644
index 00000000..a3decc96
--- /dev/null
+++ b/pdf-as-lib/bin/placeholder/pdfbox-reader.properties
@@ -0,0 +1,23 @@
+BT = org.apache.pdfbox.util.operator.BeginText
+cm = org.apache.pdfbox.util.operator.Concatenate
+Do = org.apache.pdfbox.util.operator.Invoke
+ET = org.apache.pdfbox.util.operator.EndText
+gs = org.apache.pdfbox.util.operator.SetGraphicsStateParameters
+q = org.apache.pdfbox.util.operator.GSave
+Q = org.apache.pdfbox.util.operator.GRestore
+T* = org.apache.pdfbox.util.operator.NextLine
+Tc = org.apache.pdfbox.util.operator.SetCharSpacing
+Td = org.apache.pdfbox.util.operator.MoveText
+TD = org.apache.pdfbox.util.operator.MoveTextSetLeading
+Tf = org.apache.pdfbox.util.operator.SetTextFont
+Tj = org.apache.pdfbox.util.operator.ShowText
+TJ = org.apache.pdfbox.util.operator.ShowTextGlyph
+TL = org.apache.pdfbox.util.operator.SetTextLeading
+Tm = org.apache.pdfbox.util.operator.SetMatrix
+Tr = org.apache.pdfbox.util.operator.SetTextRenderingMode
+Ts = org.apache.pdfbox.util.operator.SetTextRise
+Tw = org.apache.pdfbox.util.operator.SetWordSpacing
+Tz = org.apache.pdfbox.util.operator.SetHorizontalTextScaling
+w = org.apache.pdfbox.util.operator.SetLineWidth
+\' = org.apache.pdfbox.util.operator.MoveAndShow
+\" = org.apache.pdfbox.util.operator.SetMoveAndShow \ No newline at end of file
diff --git a/pdf-as-lib/build.gradle b/pdf-as-lib/build.gradle
index 68d65d99..683df99c 100644
--- a/pdf-as-lib/build.gradle
+++ b/pdf-as-lib/build.gradle
@@ -67,6 +67,8 @@ dependencies {
compile group: 'eu.europa.ec.joinup.egovlabs.pdf-as.iaik', name: 'iaik_ecc_eval_signed', version: '2.19'
compile group: 'log4j', name: 'log4j', version: '1.2.17'
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.5'
+ compile group: 'com.google.zxing', name: 'core', version: '2.2'
+ compile group: 'com.google.zxing', name: 'javase', version: '2.2'
//compile group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.5'
testCompile group: 'junit', name: 'junit', version: '4.+'
/*generateJavaFromWsdlDeps('org.apache.axis:axis:1.4')
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java
index 10391ecc..e26e3fdb 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java
@@ -14,8 +14,8 @@ import at.gv.egiz.pdfas.lib.impl.VerifyParameterImpl;
public class PdfAsFactory {
static {
- //PropertyConfigurator.configure(ClassLoader.getSystemResourceAsStream("resources/log4j.properties"));
- BasicConfigurator.configure();
+ PropertyConfigurator.configure(ClassLoader.getSystemResourceAsStream("resources/log4j.properties"));
+ //BasicConfigurator.configure();
}
public static PdfAs createPdfAs(File configuration) {
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 4a8e41c3..2f2d47c8 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
@@ -3,6 +3,7 @@ package at.gv.egiz.pdfas.lib.impl;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
@@ -35,6 +36,8 @@ import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;
import at.gv.egiz.pdfas.lib.impl.configuration.ConfigurationImpl;
import at.gv.egiz.pdfas.lib.impl.configuration.PlaceholderConfiguration;
import at.gv.egiz.pdfas.lib.impl.configuration.SignatureProfileConfiguration;
+import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderData;
+import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderExtractor;
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.PdfSignerFactory;
@@ -105,13 +108,12 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
status.getPdfObject().setOriginalDocument(
parameter.getDataSource().getByteData());
- // Placeholder search?
- if (placeholderConfiguration.isGlobalPlaceholderEnabled()) {
- // TODO: Do placeholder search
- }
-
this.stampPdf(status);
+ FileOutputStream fos = new FileOutputStream("/home/afitzek/qr_2_stamped.pdf");
+ fos.write(status.getPdfObject().getStampedDocument());
+ fos.close();
+
/*
* if (requestedSignature.isVisual()) {
* logger.info("Creating visual siganture block"); //
@@ -259,7 +261,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
if (verifyFilter != null) {
List<VerifyResult> results = verifyFilter.verify(
contentData.toByteArray(), content.getBytes());
- if(results != null && !results.isEmpty()) {
+ if (results != null && !results.isEmpty()) {
result.addAll(results);
}
}
@@ -421,6 +423,72 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
}
}
+ private boolean checkPlaceholderSignature(OperationStatus status)
+ throws PdfAsException, IOException {
+ if (status.getPlaceholderConfiguration().isGlobalPlaceholderEnabled()) {
+ SignaturePlaceholderData signaturePlaceholderData = SignaturePlaceholderExtractor
+ .extract(new ByteArrayInputStream(status.getPdfObject()
+ .getOriginalDocument()), null, 1);
+
+ if (signaturePlaceholderData != null) {
+ RequestedSignature requestedSignature = status
+ .getRequestedSignature();
+
+ if (signaturePlaceholderData.getProfile() != null) {
+ requestedSignature
+ .setSignatureProfileID(signaturePlaceholderData
+ .getProfile());
+ }
+
+ String signatureProfileID = requestedSignature
+ .getSignatureProfileID();
+
+ TablePos tablePos = signaturePlaceholderData.getTablePos();
+
+ 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);
+
+ // ================================================================
+ // StampingStage (visual) -> stamp logical signature block to
+ // location (itext)
+
+ byte[] incrementalUpdate = stamper.writeVisualObject(visualObject,
+ positioningInstruction, status.getPdfObject()
+ .getOriginalDocument(), signaturePlaceholderData.getPlaceholderName());
+
+ 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);
+
+ status.getPdfObject().setStampedDocument(incrementalUpdate);
+ return true;
+ }
+ }
+ return false;
+ }
+
private void stampPdf(OperationStatus status) throws PdfAsException,
IOException {
@@ -429,6 +497,11 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
SignatureProfileConfiguration signatureProfileConfiguration = status
.getSignatureProfileConfiguration(signatureProfileID);
+ if (checkPlaceholderSignature(status)) {
+ logger.info("Placeholder found for Signature");
+ return;
+ }
+
if (requestedSignature.isVisual()) {
logger.info("Creating visual siganture block");
// ================================================================
@@ -477,7 +550,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
byte[] incrementalUpdate = stamper.writeVisualObject(visualObject,
positioningInstruction, status.getPdfObject()
- .getOriginalDocument());
+ .getOriginalDocument(), null);
SignaturePositionImpl position = new SignaturePositionImpl();
position.setX(positioningInstruction.getX());
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderContext.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderContext.java
new file mode 100644
index 00000000..28a34f6a
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderContext.java
@@ -0,0 +1,72 @@
+/**
+ * <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;
+
+/**
+ * Store and retrieve {@link SignaturePlaceholderData} in/from a thread local context.
+ *
+ * @author exthex
+ *
+ */
+public class SignaturePlaceholderContext {
+
+ private ThreadLocal sigHolder = new ThreadLocal();
+
+ private static SignaturePlaceholderContext instance = new SignaturePlaceholderContext();
+
+ /**
+ * Constructor. Private because this is a singleton.
+ */
+ private SignaturePlaceholderContext() {
+
+ }
+
+ /**
+ * Get the {@link SignaturePlaceholderData} which is currently bound to this thread.
+ * Might be null.
+ *
+ * @return
+ */
+ public static SignaturePlaceholderData getSignaturePlaceholderData(){
+ return (SignaturePlaceholderData)instance.sigHolder.get();
+ }
+
+ /**
+ *
+ * @return true if there is currently a {@link SignaturePlaceholderData} bound to this thread, false otherwise.
+ */
+ public static boolean isSignaturePlaceholderDataSet() {
+ return instance.sigHolder.get() != null;
+ }
+
+ /**
+ * Bind a {@link SignaturePlaceholderData} to this thread.
+ * If the given data is null, the context will be cleared.
+ *
+ * @param data if null, clears the ThreadLocal, else binds the data to the current thread.
+ */
+ public static void setSignaturePlaceholderData(SignaturePlaceholderData data) {
+ instance.sigHolder.set(data);
+ }
+}
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
new file mode 100644
index 00000000..d068104a
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderData.java
@@ -0,0 +1,152 @@
+/**
+ * <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 at.knowcenter.wag.egov.egiz.pdf.TablePos;
+
+/**
+ * This class represents all the data which can be extracted from a placeholder image.
+ *
+ * @author exthex
+ *
+ */
+public class SignaturePlaceholderData {
+
+ public static final String ID_KEY = "id";
+
+ public static final String PROFILE_KEY = "profile";
+
+ public static final String TYPE_KEY = "type";
+
+ public static final String SIG_KEY_KEY = "key";
+
+ private String profile;
+
+ private String type;
+
+ private String key;
+
+ private String id;
+
+ private TablePos tablePos;
+
+ private String placeholderName;
+
+ /**
+ *
+ * @param profile
+ * @param type
+ * @param sigKey
+ * @param id
+ */
+ public SignaturePlaceholderData(String profile, String type, String sigKey, String id) {
+ this.profile = profile;
+ this.type = type;
+ this.key = sigKey;
+ this.id = id;
+ }
+
+ /**
+ * Get the table position for the signature block.<br/>
+ * The table position is created from the page number, the upper left corner and the width of the placeholder image.
+ *
+ * @return
+ */
+ public TablePos getTablePos() {
+ return tablePos;
+ }
+
+ void setTablePos(TablePos tablePos) {
+ this.tablePos = tablePos;
+ }
+
+ /**
+ * The profile name. Might be null if not included in the qr-code.
+ *
+ * @return
+ */
+ public String getProfile() {
+ return profile;
+ }
+
+ void setProfile(String profile) {
+ this.profile = profile;
+ }
+
+ /**
+ * The signature type: "textual" or "binary". Might be null if not included in the qr-code.
+ * @return
+ */
+ public String getType() {
+ return type;
+ }
+
+ void setType(String type) {
+ this.type = type;
+ }
+
+ /**
+ * The key identifier for MOA signature. Might be null if not included in the qr-code.
+ *
+ * @return
+ */
+ public String getKey() {
+ return key;
+ }
+
+ void setKey(String key) {
+ this.key = key;
+ }
+
+ public String toString() {
+ return getClass().toString() + ": profile=" + profile + "; type=" + type + "; sigKey=" + key + "; table pos=" + tablePos;
+ }
+
+ void setPlaceholderName(String name) {
+ this.placeholderName = name;
+ }
+
+ /**
+ * The name of the placeholder image.
+ *
+ * @return
+ */
+ public String getPlaceholderName() {
+ return placeholderName;
+ }
+
+ /**
+ * The id associated with this placeholder.
+ *
+ * @return
+ */
+ public String getId() {
+ return id;
+ }
+
+ 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
new file mode 100644
index 00000000..eabc27e2
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderExtractor.java
@@ -0,0 +1,351 @@
+/**
+ * <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.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 placeholders = new Vector();
+ 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(InputStream inputStream, String placeholderId, int matchMode)
+ throws PdfAsException {
+ SignaturePlaceholderContext.setSignaturePlaceholderData(null);
+ PDDocument doc = null;
+ try
+ {
+ try {
+ doc = PDDocument.load(inputStream);
+ } catch (IOException e) {
+ throw new PDFIOException("failed to read document", e);
+ }
+ SignaturePlaceholderExtractor extractor;
+ try
+ {
+ extractor = new SignaturePlaceholderExtractor(placeholderId, matchMode);
+ } catch (IOException e2) {
+ throw new PDFIOException("failed to read document", 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("failed to read document", 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("no suitable placeholder found and STRICT matching mode requested.");
+ }
+
+ return null;
+ } finally {
+ if (doc != null)
+ try {
+ doc.close();
+ } catch (IOException e) {
+ log.debug("Could not close document.", e);
+ }
+ }
+
+ }
+
+ private static SignaturePlaceholderData matchPlaceholderDocument(
+ List placeholders, String placeholderId, int matchMode) throws PlaceholderExtractionException {
+
+ if (matchMode == PLACEHOLDER_MATCH_MODE_STRICT)
+ throw new PlaceholderExtractionException("no suitable placeholder found and STRICT matching mode requested.");
+
+ if (placeholders.size() == 0)
+ return null;
+
+ for (int i = 0; i < placeholders.size(); i++)
+ {
+ SignaturePlaceholderData spd = (SignaturePlaceholderData)placeholders.get(i);
+ if (spd.getId() == null)
+ return spd;
+ }
+
+ if (matchMode == PLACEHOLDER_MATCH_MODE_LENIENT)
+ return (SignaturePlaceholderData)placeholders.get(0);
+
+ return null;
+ }
+
+ private static SignaturePlaceholderData matchPlaceholderPage(List placeholders,
+ String placeholderId, int matchMode) {
+ if (placeholders.size() == 0)
+ return null;
+ for (int i = 0; i < placeholders.size(); i++)
+ {
+ SignaturePlaceholderData data = (SignaturePlaceholderData)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;
+ }
+
+ protected void processOperator( PDFOperator operator, List 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 hints = new Hashtable();
+ Vector formats = new Vector();
+ 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/placeholder/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/package-info.java
new file mode 100644
index 00000000..815565da
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.lib.impl.placeholder; \ No newline at end of file
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java
index fce18ce7..5c84acfe 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java
@@ -9,7 +9,7 @@ import at.knowcenter.wag.egov.egiz.table.Table;
public interface IPDFStamper {
public IPDFVisualObject createVisualPDFObject(PDFObject pdf, Table table);
public byte[] writeVisualObject(IPDFVisualObject visualObject, PositioningInstruction positioningInstruction,
- byte[] pdfData) throws PdfAsException;
+ byte[] pdfData, String placeholderName) throws PdfAsException;
public void setSettings(ISettings settings);
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java
index 8bf56259..8ae8e377 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java
@@ -50,6 +50,10 @@ public class RequestedSignature {
return this.signatureProfile;
}
+ public void setSignatureProfileID(String signatureProfile) {
+ this.signatureProfile = signatureProfile;
+ }
+
public X509Certificate getCertificate() {
return this.certificate;
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifyFilter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifyFilter.java
index 7aca582b..53c2e342 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifyFilter.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifyFilter.java
@@ -3,9 +3,11 @@ package at.gv.egiz.pdfas.lib.impl.verify;
import java.util.List;
import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.lib.api.Configuration;
import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;
public interface IVerifyFilter {
+ public void setConfiguration(Configuration config);
public List<VerifyResult> verify(byte[] contentData, byte[] signatureContent) throws PdfAsException;
public List<FilterEntry> getFiters();
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BKUSLConnector.java b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BKUSLConnector.java
index 3381dca5..deecae21 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BKUSLConnector.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BKUSLConnector.java
@@ -130,7 +130,7 @@ public class BKUSLConnector extends BaseSLConnector {
try {
slRequest = SLMarschaller.marshalToString(of
.createCreateCMSSignatureRequest(request));
- logger.trace(slRequest);
+ logger.debug(slRequest);
String slResponse = performHttpRequestToBKU(slRequest);
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java
index 491c465a..8a7950a4 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java
@@ -47,7 +47,7 @@ public class ISignatureConnectorSLWrapper implements ISignatureConnector {
}
public byte[] sign(byte[] input, int[] byteRange) throws PdfAsException {
- CreateCMSSignatureRequestType request = connector.createCMSRequest(input, byteRange);
+ CreateCMSSignatureRequestType request = connector.createCMSRequest(input, byteRange);
CreateCMSSignatureResponseType response = connector.sendCMSRequest(request);
return response.getCMSSignature();
diff --git a/pdf-as-lib/src/main/resources/placeholder/empty.jpg b/pdf-as-lib/src/main/resources/placeholder/empty.jpg
new file mode 100644
index 00000000..7913177d
--- /dev/null
+++ b/pdf-as-lib/src/main/resources/placeholder/empty.jpg
Binary files differ
diff --git a/pdf-as-lib/src/main/resources/placeholder/pdfbox-reader.properties b/pdf-as-lib/src/main/resources/placeholder/pdfbox-reader.properties
new file mode 100644
index 00000000..a3decc96
--- /dev/null
+++ b/pdf-as-lib/src/main/resources/placeholder/pdfbox-reader.properties
@@ -0,0 +1,23 @@
+BT = org.apache.pdfbox.util.operator.BeginText
+cm = org.apache.pdfbox.util.operator.Concatenate
+Do = org.apache.pdfbox.util.operator.Invoke
+ET = org.apache.pdfbox.util.operator.EndText
+gs = org.apache.pdfbox.util.operator.SetGraphicsStateParameters
+q = org.apache.pdfbox.util.operator.GSave
+Q = org.apache.pdfbox.util.operator.GRestore
+T* = org.apache.pdfbox.util.operator.NextLine
+Tc = org.apache.pdfbox.util.operator.SetCharSpacing
+Td = org.apache.pdfbox.util.operator.MoveText
+TD = org.apache.pdfbox.util.operator.MoveTextSetLeading
+Tf = org.apache.pdfbox.util.operator.SetTextFont
+Tj = org.apache.pdfbox.util.operator.ShowText
+TJ = org.apache.pdfbox.util.operator.ShowTextGlyph
+TL = org.apache.pdfbox.util.operator.SetTextLeading
+Tm = org.apache.pdfbox.util.operator.SetMatrix
+Tr = org.apache.pdfbox.util.operator.SetTextRenderingMode
+Ts = org.apache.pdfbox.util.operator.SetTextRise
+Tw = org.apache.pdfbox.util.operator.SetWordSpacing
+Tz = org.apache.pdfbox.util.operator.SetHorizontalTextScaling
+w = org.apache.pdfbox.util.operator.SetLineWidth
+\' = org.apache.pdfbox.util.operator.MoveAndShow
+\" = org.apache.pdfbox.util.operator.SetMoveAndShow \ No newline at end of file
diff --git a/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESVerifier.java b/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESVerifier.java
index 71b24213..6af44b59 100644
--- a/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESVerifier.java
+++ b/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESVerifier.java
@@ -43,8 +43,6 @@ public class PAdESVerifier implements IVerifyFilter {
public PAdESVerifier(Configuration config) {
IAIK.getInstance();
ECCProvider.addAsProvider();
- this.moaEndpoint = config.getValue(MOA_VERIFY_URL);
- this.moaTrustProfile = config.getValue(MOA_VERIFY_TRUSTPROFILE);
}
@SuppressWarnings("rawtypes")
@@ -146,4 +144,9 @@ public class PAdESVerifier implements IVerifyFilter {
return result;
}
+ public void setConfiguration(Configuration config) {
+ this.moaEndpoint = config.getValue(MOA_VERIFY_URL);
+ this.moaTrustProfile = config.getValue(MOA_VERIFY_TRUSTPROFILE);
+ }
+
}
diff --git a/signature-standards/sigs-pcks7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedVerifier.java b/signature-standards/sigs-pcks7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedVerifier.java
index 7807850b..7e974f3f 100644
--- a/signature-standards/sigs-pcks7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedVerifier.java
+++ b/signature-standards/sigs-pcks7detached/src/main/java/at/gv/egiz/pdfas/sigs/pkcs7detached/PKCS7DetachedVerifier.java
@@ -14,6 +14,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.lib.api.Configuration;
import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;
import at.gv.egiz.pdfas.lib.impl.verify.FilterEntry;
import at.gv.egiz.pdfas.lib.impl.verify.IVerifyFilter;
@@ -71,4 +72,9 @@ public class PKCS7DetachedVerifier implements IVerifyFilter {
return result;
}
+ public void setConfiguration(Configuration config) {
+ // TODO Auto-generated method stub
+
+ }
+
}
diff --git a/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextStamper.java b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextStamper.java
index ff68dcd8..b0801a9c 100644
--- a/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextStamper.java
+++ b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextStamper.java
@@ -2,6 +2,7 @@ package at.gv.egiz.pdfas.stmp.itext;
import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderData;
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;
@@ -444,7 +445,7 @@ public class ITextStamper implements IPDFStamper {
}
public byte[] writeVisualObject(IPDFVisualObject visualObject, PositioningInstruction positioningInstruction,
- byte[] pdfData) throws PdfAsException {
+ byte[] pdfData, String placeholderName) throws PdfAsException {
try {
ITextVisualObject object = null;
@@ -479,14 +480,21 @@ public class ITextStamper implements IPDFStamper {
throw new PdfAsException("The provided page (=" +
positioningInstruction.getPage() + ") is out of range.");
}
-
+
+ if(placeholderName != null) {
+ ITextStamperAccess.replacePlaceholder(stamper, targetPage, placeholderName);
+ }
+
PdfContentByte content = stamper.getOverContent(targetPage);
PdfPTable table = object.getTable();
+ logger.info("Visual Object: " + visualObject.getWidth() + " x " + visualObject.getHeight());
+ //PdfTemplate table_template = content.createTemplate(visualObject.getWidth(), visualObject.getHeight());
+
table.writeSelectedRows(0, -1, positioningInstruction.getX(),
positioningInstruction.getY(), content);
-
+
stamper.close();
baos.close();
diff --git a/stamper/stmp-itext/src/main/java/com/lowagie/text/pdf/ITextStamperAccess.java b/stamper/stmp-itext/src/main/java/com/lowagie/text/pdf/ITextStamperAccess.java
new file mode 100644
index 00000000..65b4ba77
--- /dev/null
+++ b/stamper/stmp-itext/src/main/java/com/lowagie/text/pdf/ITextStamperAccess.java
@@ -0,0 +1,47 @@
+package com.lowagie.text.pdf;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.stmp.itext.ITextStamper;
+
+import com.lowagie.text.BadElementException;
+import com.lowagie.text.Image;
+
+public class ITextStamperAccess {
+
+ private static final Logger logger = LoggerFactory.getLogger(ITextStamperAccess.class);
+
+ public static void replacePlaceholder(PdfStamper stamper, int pageNr, String placeholderName)
+ throws BadElementException, MalformedURLException, IOException,
+ BadPdfFormatException, PdfAsException {
+ Image img = Image.getInstance(ITextStamper.class.getResource("/placeholder/empty.jpg"));
+ PdfImage pImg = new PdfImage(img, "Imwurscht", null);
+ PdfStamperImp stamperImp = (PdfStamperImp)stamper.getWriter();
+ PdfIndirectObject ind = stamperImp.addToBody(pImg);
+
+ PdfDictionary resources = stamper.getReader().getPageN(pageNr).getAsDict(PdfName.RESOURCES);
+ if (ind != null && resources != null)
+ {
+ PdfDictionary xobjDict = resources.getAsDict(PdfName.XOBJECT);
+ if (xobjDict != null)
+ {
+ xobjDict.put(new PdfName(placeholderName), ind.getIndirectReference());
+ stamperImp.markUsed(resources);
+ }
+ else
+ {
+ throw new PdfAsException("failed to write PDF", new NullPointerException("Image dictionary not found in document structure!"));
+ }
+ }
+ else
+ {
+ throw new PdfAsException("failed to write PDF", new NullPointerException("Resource dictionary not found in document structure!"));
+ }
+ }
+
+}
diff --git a/stamper/stmp-itext/src/main/java/com/lowagie/text/pdf/package-info.java b/stamper/stmp-itext/src/main/java/com/lowagie/text/pdf/package-info.java
new file mode 100644
index 00000000..131f9340
--- /dev/null
+++ b/stamper/stmp-itext/src/main/java/com/lowagie/text/pdf/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package com.lowagie.text.pdf; \ No newline at end of file