aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pdf-as-cli/.gitignore1
-rw-r--r--pdf-as-cli/build.gradle31
-rw-r--r--pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java41
-rw-r--r--pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/package-info.java8
-rw-r--r--pdf-as-common/.gitignore1
-rw-r--r--pdf-as-common/build.gradle32
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PDFIOException.java20
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsException.java31
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSettingsException.java20
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/package-info.java8
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/MessageResolver.java42
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/package-info.java8
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/package-info.java8
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/IProfileConstants.java65
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/ISettings.java13
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/Settings.java124
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileEntry.java39
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileSettings.java121
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/package-info.java8
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/DNUtils.java34
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/OgnlUtils.java22
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/PDFUtils.java94
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StreamUtils.java28
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StringUtils.java33
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/package-info.java8
-rw-r--r--pdf-as-common/src/main/resources/resources/log4j.properties15
-rw-r--r--pdf-as-common/src/main/resources/resources/messages/common.properties8
-rw-r--r--pdf-as-lib/build.gradle4
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/Configuration.java7
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IConfigurationConstants.java16
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IDataSource.java6
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java40
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java9
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsParameter.java32
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/package-info.java8
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignParameter.java37
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignResult.java5
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/package-info.java8
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/SignatureCheck.java19
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyParameter.java14
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyResult.java50
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/package-info.java8
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java69
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigurationImpl.java110
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/GlobalConfiguration.java21
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderConfiguration.java23
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SignatureProfileConfiguration.java21
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SpecificBaseConfiguration.java13
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/package-info.java8
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/package-info.java8
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/Positioning.java251
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/package-info.java8
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java12
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFVisualObject.java12
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/StamperFactory.java18
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/package-info.java8
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java76
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/PDFObject.java31
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java53
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/package-info.java1
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/package-info.java4
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java502
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java72
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/Pos.java70
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java182
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java261
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathConstructionOperatorProcessor.java61
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java42
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java67
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java84
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java81
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java83
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java70
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java72
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java58
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java59
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java59
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java67
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java71
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java71
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java70
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java71
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java69
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/sig/SignatureEntry.java163
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Entry.java235
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Style.java630
-rw-r--r--pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Table.java223
-rw-r--r--settings.gradle2
-rw-r--r--signature-standards/sigs-pades/build.gradle1
-rw-r--r--stamper/stmp-itext/.gitignore1
-rw-r--r--stamper/stmp-itext/build.gradle32
-rw-r--r--stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextStamper.java506
-rw-r--r--stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextVisualObject.java61
-rw-r--r--stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/package-info.java2
94 files changed, 5970 insertions, 1 deletions
diff --git a/pdf-as-cli/.gitignore b/pdf-as-cli/.gitignore
new file mode 100644
index 00000000..5e56e040
--- /dev/null
+++ b/pdf-as-cli/.gitignore
@@ -0,0 +1 @@
+/bin
diff --git a/pdf-as-cli/build.gradle b/pdf-as-cli/build.gradle
new file mode 100644
index 00000000..48a9b659
--- /dev/null
+++ b/pdf-as-cli/build.gradle
@@ -0,0 +1,31 @@
+apply plugin: 'java'
+apply plugin: 'eclipse'
+
+jar {
+ manifest {
+ attributes 'Implementation-Title': 'PDF-AS CLI', 'Implementation-Version': version
+ }
+}
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ compile project (':pdf-as-lib')
+ compile project (':stamper:stmp-itext')
+ compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
+ testCompile group: 'junit', name: 'junit', version: '4.+'
+}
+
+test {
+ systemProperties 'property': 'value'
+}
+
+uploadArchives {
+ repositories {
+ flatDir {
+ dirs 'repos'
+ }
+ }
+}
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
new file mode 100644
index 00000000..6e0118e4
--- /dev/null
+++ b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java
@@ -0,0 +1,41 @@
+package at.gv.egiz.pdfas.cli;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+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.PdfAs;
+import at.gv.egiz.pdfas.lib.api.PdfAsFactory;
+import at.gv.egiz.pdfas.lib.api.sign.SignParameter;
+
+public class DeveloperMain {
+
+ public static void main(String[] args) {
+ String user_home = System.getProperty("user.home");
+ String pdfas_dir = user_home + File.separator + "PDF-AS";
+ PdfAs pdfas = PdfAsFactory.createPdfAs(new File(pdfas_dir));
+ Configuration config = pdfas.getConfiguration();
+
+ byte[] data;
+ try {
+ data = StreamUtils.inputStreamToByteArray(new FileInputStream("/home/afitzek/devel/pdfas_neu/simple.pdf"));
+ SignParameter parameter = new SignParameter(config, new ByteArrayDataSource(data));
+ pdfas.sign(parameter);
+ } catch (FileNotFoundException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ } catch (IOException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }catch (PdfAsException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/package-info.java b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/package-info.java
new file mode 100644
index 00000000..6dbf3f3e
--- /dev/null
+++ b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.cli; \ No newline at end of file
diff --git a/pdf-as-common/.gitignore b/pdf-as-common/.gitignore
new file mode 100644
index 00000000..5e56e040
--- /dev/null
+++ b/pdf-as-common/.gitignore
@@ -0,0 +1 @@
+/bin
diff --git a/pdf-as-common/build.gradle b/pdf-as-common/build.gradle
new file mode 100644
index 00000000..19d3dc90
--- /dev/null
+++ b/pdf-as-common/build.gradle
@@ -0,0 +1,32 @@
+apply plugin: 'java'
+apply plugin: 'eclipse'
+
+jar {
+ manifest {
+ attributes 'Implementation-Title': 'PDF-AS-4 Commons', 'Implementation-Version': version
+ }
+}
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ compile group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.5'
+ compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '1.8.2'
+ compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
+ compile group: 'ognl', name: 'ognl', version: '3.0.6'
+ testCompile group: 'junit', name: 'junit', version: '4.+'
+}
+
+test {
+ systemProperties 'property': 'value'
+}
+
+uploadArchives {
+ repositories {
+ flatDir {
+ dirs 'repos'
+ }
+ }
+}
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PDFIOException.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PDFIOException.java
new file mode 100644
index 00000000..57c1e7ab
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PDFIOException.java
@@ -0,0 +1,20 @@
+package at.gv.egiz.pdfas.common.exceptions;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: afitzek
+ * Date: 8/28/13
+ * Time: 12:04 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class PDFIOException extends PdfAsException {
+
+ public PDFIOException(String msgId) {
+ super(msgId);
+ }
+
+
+ public PDFIOException(String msgId, Throwable e) {
+ super(msgId, e);
+ }
+}
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsException.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsException.java
new file mode 100644
index 00000000..e36aa082
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsException.java
@@ -0,0 +1,31 @@
+package at.gv.egiz.pdfas.common.exceptions;
+
+import at.gv.egiz.pdfas.common.messages.MessageResolver;
+
+public class PdfAsException extends Exception {
+ public PdfAsException() {
+ super();
+ }
+
+ public PdfAsException(String msgId) {
+ super(msgId);
+ }
+
+ public PdfAsException(String msgId, Throwable e) {
+ super(msgId, e);
+ }
+
+ @Override
+ public String getMessage() {
+ return localizeMessage(super.getMessage());
+ }
+
+ @Override
+ public String getLocalizedMessage() {
+ return localizeMessage(super.getMessage());
+ }
+
+ protected String localizeMessage(String msgId) {
+ return MessageResolver.resolveMessage(msgId);
+ }
+}
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSettingsException.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSettingsException.java
new file mode 100644
index 00000000..431ffa5d
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSettingsException.java
@@ -0,0 +1,20 @@
+package at.gv.egiz.pdfas.common.exceptions;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: afitzek
+ * Date: 9/10/13
+ * Time: 10:54 AM
+ * To change this template use File | Settings | File Templates.
+ */
+public class PdfAsSettingsException extends PdfAsException {
+
+ public PdfAsSettingsException(String msgId) {
+ super(msgId);
+ }
+
+
+ public PdfAsSettingsException(String msgId, Throwable e) {
+ super(msgId, e);
+ }
+}
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/package-info.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/package-info.java
new file mode 100644
index 00000000..cfd6a993
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.common.exceptions; \ No newline at end of file
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/MessageResolver.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/MessageResolver.java
new file mode 100644
index 00000000..0bc1bab7
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/MessageResolver.java
@@ -0,0 +1,42 @@
+package at.gv.egiz.pdfas.common.messages;
+
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MessageResolver {
+ private static final String messageResource = "resources.messages.common";
+ private static final String missingMsg = "Please add message ";
+
+ private static final Logger logger = LoggerFactory.getLogger(MessageResolver.class);
+
+ private static ResourceBundle bundle;
+
+ static {
+ ResourceBundle bundle = ResourceBundle.getBundle(messageResource);
+ if(bundle == null) {
+ logger.error("Failed to load resource bundle!!");
+ Runtime.getRuntime().exit(-1);
+ }
+ }
+
+ public static void forceLocale(Locale locale) {
+ bundle = ResourceBundle.getBundle(messageResource, locale);
+ }
+
+ public static String resolveMessage(String msgId) {
+ if(bundle == null) {
+ return missingMsg + msgId;
+ }
+ if(bundle.containsKey(msgId)) {
+ String value = bundle.getString(msgId);
+ if(value == null) {
+ return missingMsg + msgId;
+ }
+ return value;
+ }
+ return missingMsg + msgId;
+ }
+}
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/package-info.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/package-info.java
new file mode 100644
index 00000000..0ac78c22
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.common.messages; \ No newline at end of file
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/package-info.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/package-info.java
new file mode 100644
index 00000000..58c99dad
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.common; \ No newline at end of file
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/IProfileConstants.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/IProfileConstants.java
new file mode 100644
index 00000000..2e2ee024
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/IProfileConstants.java
@@ -0,0 +1,65 @@
+package at.gv.egiz.pdfas.common.settings;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: afitzek
+ * Date: 9/10/13
+ * Time: 12:58 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public interface IProfileConstants {
+ /**
+ * The settings key prefix for signature definitions. <code>"sig_obj."</code>
+ */
+ public static final String SIG_OBJ = "sig_obj.";
+
+ public static final String SIG_DATE = "SIG_DATE";
+
+ /**
+ * The settings key prefix for the signature table object definition
+ */
+ public static final String TABLE = "table.";
+
+ /**
+ * The settings value refering to a table
+ */
+ public final static String TYPE_TABLE = "TABLE";
+
+ /**
+ * The settings value refering to an image
+ */
+ public final static String TYPE_IMAGE = "i";
+
+ /**
+ * The settings value refering to a text caption
+ */
+ public final static String TYPE_CAPTION = "c";
+
+ /**
+ * The settings value refering to a text value
+ */
+ public final static String TYPE_VALUE = "v";
+
+ /**
+ * The settings key sub prefix getting the width of columns for a table
+ * definition
+ */
+ public final static String COLS_WITH = "ColsWidth";
+
+ /**
+ * The settings key sub prefix getting the style definition
+ */
+ public final static String STYLE = "Style";
+
+ public final static String PROFILE_VALUE = "value";
+
+ public final static String PROFILE_KEY = "key";
+
+ public final static String KEY_SEPARATOR = ".";
+
+ public final static String INCLUDE = "include";
+
+ public final static String CFG_DIR = "cfg";
+ public final static String CFG_FILE = "config.properties";
+
+}
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/ISettings.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/ISettings.java
new file mode 100644
index 00000000..9e3291d2
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/ISettings.java
@@ -0,0 +1,13 @@
+package at.gv.egiz.pdfas.common.settings;
+
+import java.util.Map;
+import java.util.Vector;
+
+public interface ISettings {
+ public String getValue(String key);
+ public boolean hasValue(String key);
+ public boolean hasPrefix(String prefix);
+ public Map<String, String> getValuesPrefix(String prefix);
+ public Vector<String> getFirstLevelKeys(String prefix);
+ public String getWorkingDirectory();
+}
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/Settings.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/Settings.java
new file mode 100644
index 00000000..da946215
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/Settings.java
@@ -0,0 +1,124 @@
+package at.gv.egiz.pdfas.common.settings;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsSettingsException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.*;
+
+public class Settings implements ISettings, IProfileConstants{
+
+ private static final Logger logger = LoggerFactory.getLogger(Settings.class);
+
+ protected Properties properties = new Properties();
+
+ protected File workDirectory;
+
+ public Settings(File workDirectory) {
+ try {
+ this.workDirectory = workDirectory;
+ loadSettings(workDirectory);
+ } catch (PdfAsSettingsException e) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+
+ public void loadSettings(File workDirectory) throws PdfAsSettingsException {
+ try {
+
+ String configDir = workDirectory.getAbsolutePath() + File.separator + CFG_DIR;
+ String configFile = configDir + File.separator + CFG_FILE;
+ logger.debug("Loading cfg file: " + configFile);
+ properties.load(new FileInputStream(configFile));
+
+ Map<String, String> includes = this.getValuesPrefix(INCLUDE);
+
+ if(includes != null) {
+ Iterator<String> includeIterator = includes.values().iterator();
+ while(includeIterator.hasNext()) {
+ String includeFile = configDir + File.separator + includeIterator.next();
+ logger.debug("Loading included cfg file: " + includeFile);
+ properties.load(new FileInputStream(includeFile));
+ }
+ }
+
+ logger.debug("Configured Properties:");
+ if(logger.isDebugEnabled()) {
+ properties.list(System.out);
+ }
+
+ } catch (IOException e) {
+ throw new PdfAsSettingsException("Failed to read settings!", e);
+ }
+ }
+
+ public String getValue(String key) {
+ return properties.getProperty(key);
+ }
+
+ public boolean hasValue(String key) {
+ return properties.containsKey(key);
+ }
+
+ public Map<String, String> getValuesPrefix(String prefix) {
+ Iterator<Object> keyIterator = properties.keySet().iterator();
+ Map<String, String> valueMap = new HashMap<String, String>();
+ while(keyIterator.hasNext()) {
+ String key = keyIterator.next().toString();
+
+ if(key.startsWith(prefix)) {
+ valueMap.put(key, properties.getProperty(key));
+ }
+ }
+
+ if(valueMap.isEmpty()) {
+ return null;
+ }
+
+ return valueMap;
+ }
+
+ public Vector<String> getFirstLevelKeys(String prefix) {
+ String mPrefix = prefix.endsWith(".")?prefix:prefix+".";
+ Iterator<Object> keyIterator = properties.keySet().iterator();
+ Vector<String> valueMap = new Vector<String>();
+ while(keyIterator.hasNext()) {
+ String key = keyIterator.next().toString();
+
+ if(key.startsWith(prefix)) {
+ int keyIdx = key.indexOf('.', mPrefix.length()) > 0 ? key.indexOf('.', mPrefix.length()) : key.length();
+ String firstLevels = key.substring(0, keyIdx);
+ if(!valueMap.contains(firstLevels)) {
+ valueMap.add(firstLevels);
+ }
+ }
+ }
+
+ if(valueMap.isEmpty()) {
+ return null;
+ }
+
+ return valueMap;
+ }
+
+ public boolean hasPrefix(String prefix) {
+ Iterator<Object> keyIterator = properties.keySet().iterator();
+ while(keyIterator.hasNext()) {
+ String key = keyIterator.next().toString();
+
+ if(key.startsWith(prefix)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public String getWorkingDirectory() {
+ return this.workDirectory.getAbsolutePath();
+ }
+
+}
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileEntry.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileEntry.java
new file mode 100644
index 00000000..3df929b1
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileEntry.java
@@ -0,0 +1,39 @@
+package at.gv.egiz.pdfas.common.settings;
+
+public class SignatureProfileEntry {
+ private String key = null;
+ private String caption = null;
+ private String value = null;
+
+ public SignatureProfileEntry() {
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public String getCaption() {
+ return caption;
+ }
+
+ public void setCaption(String caption) {
+ this.caption = caption;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return getKey() + "[ " + getCaption() + " : " + getValue() + " ]";
+ }
+}
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileSettings.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileSettings.java
new file mode 100644
index 00000000..46f2ed09
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileSettings.java
@@ -0,0 +1,121 @@
+package at.gv.egiz.pdfas.common.settings;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+public class SignatureProfileSettings implements IProfileConstants {
+
+ private static final Logger logger = LoggerFactory.getLogger(SignatureProfileSettings.class);
+
+ private Map<String, SignatureProfileEntry> profileInformations = new HashMap<String, SignatureProfileEntry>();
+
+ private Map<String, String> profileSettings = new HashMap<String, String>();
+
+ private String profileID;
+
+ public SignatureProfileSettings(String profileID, ISettings configuration) {
+ this.profileID = profileID;
+ String profilePrefix = SIG_OBJ + profileID + KEY_SEPARATOR;
+ String keysPrefix = profilePrefix + PROFILE_KEY;
+ String valuesPrefix = profilePrefix + PROFILE_VALUE;
+ String tablePrefix = profilePrefix + TABLE;
+
+ logger.debug("Reading Profile: " + profileID);
+ logger.debug("Keys Prefix: " + keysPrefix);
+ logger.debug("Values Prefix: " + valuesPrefix);
+ logger.debug("Table Prefix: " + tablePrefix);
+
+ Map<String, String> keys = configuration.getValuesPrefix(keysPrefix);
+ Map<String, String> values = configuration.getValuesPrefix(valuesPrefix);
+
+ Iterator<String> keyIterator = keys.keySet().iterator();
+
+ while(keyIterator.hasNext()) {
+ String key = keyIterator.next();
+ key = key.substring(key.lastIndexOf('.') + 1);
+ String valueKey = keys.get(keysPrefix + KEY_SEPARATOR + key);
+
+ String valueValue = values.get(valuesPrefix + KEY_SEPARATOR + key);
+
+
+ SignatureProfileEntry entry = new SignatureProfileEntry();
+ entry.setKey(key);
+ entry.setCaption(valueKey);
+ entry.setValue(valueValue);
+ profileInformations.put(key, entry);
+ logger.debug(" " + entry.toString());
+ }
+
+ // Find entries where only values exists
+ Iterator<String> valuesIterator = values.keySet().iterator();
+
+ while(valuesIterator.hasNext()) {
+ String key = valuesIterator.next();
+ key = key.substring(key.lastIndexOf('.') + 1);
+
+ String valueValue = values.get(valuesPrefix + KEY_SEPARATOR + key);
+
+ SignatureProfileEntry entry = profileInformations.get(key);
+ if(entry == null) {
+ entry = new SignatureProfileEntry();
+ entry.setKey(key);
+ entry.setCaption(null);
+ entry.setValue(valueValue);
+ profileInformations.put(key, entry);
+ }
+
+ logger.debug(" " + entry.toString());
+ }
+
+ Map<String, String> others = configuration.getValuesPrefix(profilePrefix);
+
+ Iterator<String> otherIterator = others.keySet().iterator();
+
+ while(otherIterator.hasNext()) {
+ String key = otherIterator.next();
+
+ logger.trace("Checking key " + key);
+ if( key.startsWith(keysPrefix) ||
+ key.startsWith(valuesPrefix) ||
+ key.startsWith(tablePrefix)) {
+ continue;
+ }
+
+ String value = others.get(key);
+ key = key.substring(key.lastIndexOf('.') + 1);
+
+ profileSettings.put(key, others.get(value));
+
+ logger.debug(" Settings: " + key + " : " + value);
+ }
+ }
+
+ public String getCaption(String key) {
+ SignatureProfileEntry entry = profileInformations.get(key);
+ if(entry != null) {
+ return entry.getCaption();
+ }
+ return null;
+ }
+
+ public String getValue(String key) {
+ SignatureProfileEntry entry = profileInformations.get(key);
+ if(entry != null) {
+ String value = entry.getValue();
+
+ if(value == null) {
+ // TODO: try to find default value for key!
+ }
+
+ return value;
+ }
+ // TODO: try to find default value for key!
+ return null;
+ }
+
+ public String getProfileID() {
+ return profileID;
+ }
+}
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/package-info.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/package-info.java
new file mode 100644
index 00000000..c2b123e2
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.common.settings; \ No newline at end of file
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/DNUtils.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/DNUtils.java
new file mode 100644
index 00000000..429151ee
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/DNUtils.java
@@ -0,0 +1,34 @@
+package at.gv.egiz.pdfas.common.utils;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.naming.InvalidNameException;
+import javax.naming.ldap.LdapName;
+import javax.naming.ldap.Rdn;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DNUtils {
+ private static final Logger logger = LoggerFactory.getLogger(DNUtils.class);
+
+
+ public static Map<String, String> dnToMap(String dn) throws InvalidNameException {
+ Map<String, String> map = new HashMap<String, String>();
+
+ LdapName ldapName = new LdapName(dn);
+
+ Iterator<Rdn> rdnIterator = ldapName.getRdns().iterator();
+
+ while(rdnIterator.hasNext()) {
+ Rdn rdn = rdnIterator.next();
+
+ logger.debug(rdn.getType() + " = " + rdn.getValue().toString());
+ map.put(rdn.getType(), rdn.getValue().toString());
+ }
+
+ return map;
+ }
+}
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/OgnlUtils.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/OgnlUtils.java
new file mode 100644
index 00000000..e98cb124
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/OgnlUtils.java
@@ -0,0 +1,22 @@
+package at.gv.egiz.pdfas.common.utils;
+
+import ognl.OgnlContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: afitzek
+ * Date: 9/11/13
+ * Time: 1:05 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class OgnlUtils {
+
+ private static final Logger logger = LoggerFactory.getLogger(OgnlUtils.class);
+
+ public static String resolvsOgnlExpression(String expression, OgnlContext ctx) {
+ // TODO!
+ return expression;
+ }
+}
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/PDFUtils.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/PDFUtils.java
new file mode 100644
index 00000000..155f9cfb
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/PDFUtils.java
@@ -0,0 +1,94 @@
+package at.gv.egiz.pdfas.common.utils;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class PDFUtils {
+
+ private static final Logger logger = LoggerFactory.getLogger(PDFUtils.class);
+
+
+ private static final byte[] signature_pattern = new byte[] {
+ (byte) 0x0A, (byte) 0x2F, (byte) 0x43, (byte) 0x6F, // ./Co
+ (byte) 0x6E, (byte) 0x74, (byte) 0x65, (byte) 0x6E, // nten
+ (byte) 0x74, (byte) 0x73, (byte) 0x20, (byte) 0x0A, // ts .
+ (byte) 0x2F, (byte) 0x42, (byte) 0x79, (byte) 0x74, // /Byt
+ (byte) 0x65, (byte) 0x52, (byte) 0x61, (byte) 0x6E, // eRan
+ (byte) 0x67, (byte) 0x65, (byte) 0x20, (byte) 0x5B, // ge [
+
+ };
+
+ private static final byte range_seperation = (byte) 0x20;
+ private static final byte range_end = (byte) 0x5D;
+
+ private static int extractASCIIInteger(byte[] data, int offset) {
+ int nextsepp = nextSeperator(data, offset);
+
+ if(nextsepp < offset) {
+ return -1;
+ }
+
+ String asciiString = new String(data, offset, nextsepp - offset);
+
+ logger.debug("Extracted " + asciiString);
+
+ return Integer.parseInt(asciiString);
+ }
+
+ private static int nextSeperator(byte[] data, int offset) {
+ for(int i = offset; i < data.length; i++) {
+ if(data[i] == range_seperation) {
+ return i;
+ } else if(data[i] == range_end) {
+ return i;
+ }
+ }
+ return -2;
+ }
+
+ public static int[] extractSignatureByteRange(byte[] rawPdfData) {
+ int i = 0;
+ for(i = rawPdfData.length - 1; i >= 0; i--) {
+ if(rawPdfData[i] == signature_pattern[0] &&
+ i+signature_pattern.length < rawPdfData.length) {
+ boolean match = true;
+ for(int j = 0; j < signature_pattern.length; j++) {
+
+ if(rawPdfData[i+j] != signature_pattern[j]) {
+ match = false;
+ break;
+ }
+ }
+
+ if(match) {
+
+ int offset = i + signature_pattern.length;
+ List<Integer> byteRange = new ArrayList<Integer>();
+ while(offset > 0) {
+ byteRange.add(extractASCIIInteger(rawPdfData, offset));
+ offset = nextSeperator(rawPdfData, offset);
+ if(rawPdfData[offset] == range_end) {
+ break;
+ }
+ offset++;
+ }
+ int[] range = new int[byteRange.size()];
+ for(int j = 0; j < byteRange.size(); j++) {
+ range[j] = byteRange.get(j);
+ }
+ return range;
+ }
+ }
+ }
+ return null;
+ }
+
+ public static void checkPDFPermissions(PDDocument doc) {
+ // TODO: Check permission for document
+ }
+}
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StreamUtils.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StreamUtils.java
new file mode 100644
index 00000000..0b15d700
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StreamUtils.java
@@ -0,0 +1,28 @@
+package at.gv.egiz.pdfas.common.utils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: afitzek
+ * Date: 8/29/13
+ * Time: 9:54 AM
+ * To change this template use File | Settings | File Templates.
+ */
+public class StreamUtils {
+
+ public static byte[] inputStreamToByteArray(InputStream stream) throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] buffer = new byte[4096];
+ int readBytes = 0;
+
+ while((readBytes = stream.read(buffer)) != -1) {
+ bos.write(buffer, 0, readBytes);
+ }
+ stream.close();
+ bos.close();
+ return bos.toByteArray();
+ }
+}
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StringUtils.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StringUtils.java
new file mode 100644
index 00000000..63aae211
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StringUtils.java
@@ -0,0 +1,33 @@
+package at.gv.egiz.pdfas.common.utils;
+
+import java.util.Formatter;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: afitzek
+ * Date: 8/28/13
+ * Time: 12:42 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class StringUtils {
+
+ public static String bytesToHexString(byte[] bytes) {
+ StringBuilder sb = new StringBuilder(bytes.length * 2);
+
+ Formatter formatter = new Formatter(sb);
+ for (byte b : bytes) {
+ formatter.format("%02x", b);
+ }
+
+ return sb.toString();
+ }
+
+ public static String extractLastID(String id) {
+ int lastIDX = id.lastIndexOf('.');
+ String result = id;
+ if(lastIDX > 0) {
+ result = id.substring(lastIDX+1);
+ }
+ return result;
+ }
+}
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/package-info.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/package-info.java
new file mode 100644
index 00000000..91b05145
--- /dev/null
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.common.utils; \ No newline at end of file
diff --git a/pdf-as-common/src/main/resources/resources/log4j.properties b/pdf-as-common/src/main/resources/resources/log4j.properties
new file mode 100644
index 00000000..696db3ef
--- /dev/null
+++ b/pdf-as-common/src/main/resources/resources/log4j.properties
@@ -0,0 +1,15 @@
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=INFO, A1
+
+log4j.logger.at.gv.egiz=DEBUG
+#log4j.A1.at.gv.egiz=true
+
+log4j.logger.developer=DEBUG
+#log4j.A1.developer=true
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n \ No newline at end of file
diff --git a/pdf-as-common/src/main/resources/resources/messages/common.properties b/pdf-as-common/src/main/resources/resources/messages/common.properties
new file mode 100644
index 00000000..a2729e21
--- /dev/null
+++ b/pdf-as-common/src/main/resources/resources/messages/common.properties
@@ -0,0 +1,8 @@
+# PDF Permission Errors
+error.pdf.perm.01=You do not have permission to extract images.
+
+#PDF IO Errors
+error.pdf.io.01=Failed to read original PDF Document into PDDocument.
+
+#Signature errors
+error.pdf.sig.01=Failed to create signature! \ No newline at end of file
diff --git a/pdf-as-lib/build.gradle b/pdf-as-lib/build.gradle
index 41c9a3ba..b5601f3a 100644
--- a/pdf-as-lib/build.gradle
+++ b/pdf-as-lib/build.gradle
@@ -12,6 +12,10 @@ repositories {
}
dependencies {
+ compile project (':pdf-as-common')
+ compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '1.8.2'
+ compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.1'
+ compile group: 'org.apache.commons', name: 'commons-io', version: '1.3.2'
compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
testCompile group: 'junit', name: 'junit', version: '4.+'
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/Configuration.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/Configuration.java
new file mode 100644
index 00000000..89acc747
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/Configuration.java
@@ -0,0 +1,7 @@
+package at.gv.egiz.pdfas.lib.api;
+
+public interface Configuration {
+ public String getValue(String key);
+ public boolean hasValue(String key);
+ public void setValue(String key, String value);
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IConfigurationConstants.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IConfigurationConstants.java
new file mode 100644
index 00000000..9a8d773a
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IConfigurationConstants.java
@@ -0,0 +1,16 @@
+package at.gv.egiz.pdfas.lib.api;
+
+public interface IConfigurationConstants {
+
+ public static final String TRUE = "true";
+
+ public static final String SIG_OBJECT = "sig_obj";
+ public static final String TYPE = "type";
+ public static final String TABLE = "type";
+ public static final String MAIN = "main";
+ public static final String DEFAULT = "default";
+ public static final String SEPERATOR = ".";
+
+ public static final String PLACEHOLDER_SEARCH_ENABLED = "enable_placeholder_search";
+ public static final String DEFAULT_SIGNATURE_PROFILE = SIG_OBJECT + SEPERATOR + TYPE + SEPERATOR + DEFAULT;
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IDataSource.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IDataSource.java
new file mode 100644
index 00000000..6fea788c
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IDataSource.java
@@ -0,0 +1,6 @@
+package at.gv.egiz.pdfas.lib.api;
+
+public interface IDataSource {
+ public String getMIMEType();
+ public byte[] getByteData();
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java
new file mode 100644
index 00000000..4b491064
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java
@@ -0,0 +1,40 @@
+package at.gv.egiz.pdfas.lib.api;
+
+import java.util.List;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+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;
+
+public interface PdfAs {
+
+ // Sign
+ // Verify
+ // Get Configuration
+
+ /**
+ * Signs a PDF document using PDF-AS.
+ *
+ * @param parameter
+ * @return
+ */
+ public SignResult sign(SignParameter parameter) throws PdfAsException;
+
+ /**
+ * Verifies a document with (potentially multiple) PDF-AS signatures.
+ *
+ * @param parameter The verification parameter
+ * @return A list of verification Results
+ */
+ public List<VerifyResult> verify(VerifyParameter parameter);
+
+ /**
+ * Gets a copy of the PDF-AS configuration, to allow the application to
+ * override configuration parameters at runtime.
+ *
+ * @return A private copy of the pdf as configuration
+ */
+ public Configuration getConfiguration();
+}
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
new file mode 100644
index 00000000..ae9388eb
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java
@@ -0,0 +1,9 @@
+package at.gv.egiz.pdfas.lib.api;
+
+import java.io.File;
+
+public class PdfAsFactory {
+ public static PdfAs createPdfAs(File configuration) {
+ return null;
+ }
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsParameter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsParameter.java
new file mode 100644
index 00000000..999c91bc
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsParameter.java
@@ -0,0 +1,32 @@
+package at.gv.egiz.pdfas.lib.api;
+
+public abstract class PdfAsParameter {
+
+ protected Configuration configuration;
+
+ protected IDataSource dataSource;
+
+ public PdfAsParameter(Configuration configuration,
+ IDataSource dataSource) {
+ this.configuration = configuration;
+ this.dataSource = dataSource;
+ }
+
+ public Configuration getConfiguration() {
+ return configuration;
+ }
+
+ public void setConfiguration(Configuration configuration) {
+ this.configuration = configuration;
+ }
+
+ public IDataSource getDataSource() {
+ return dataSource;
+ }
+
+ public void setDataSource(IDataSource dataSource) {
+ this.dataSource = dataSource;
+ }
+
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/package-info.java
new file mode 100644
index 00000000..debc6d4f
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.lib.api; \ No newline at end of file
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignParameter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignParameter.java
new file mode 100644
index 00000000..1eee841a
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignParameter.java
@@ -0,0 +1,37 @@
+package at.gv.egiz.pdfas.lib.api.sign;
+
+import at.gv.egiz.pdfas.lib.api.Configuration;
+import at.gv.egiz.pdfas.lib.api.IDataSource;
+import at.gv.egiz.pdfas.lib.api.PdfAsParameter;
+
+public class SignParameter extends PdfAsParameter {
+
+ protected String signatureProfileId = null;
+ protected String signaturePosition = null;
+
+ public SignParameter(Configuration configuration,
+ IDataSource dataSource) {
+ super(configuration, dataSource);
+ }
+
+ // ========================================================================
+
+ public String getSignatureProfileId() {
+ return signatureProfileId;
+ }
+
+ public void setSignatureProfileId(String signatureProfileId) {
+ this.signatureProfileId = signatureProfileId;
+ }
+
+ public String getSignaturePosition() {
+ return signaturePosition;
+ }
+
+ public void setSignaturePosition(String signaturePosition) {
+ this.signaturePosition = signaturePosition;
+ }
+
+
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignResult.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignResult.java
new file mode 100644
index 00000000..91da083e
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignResult.java
@@ -0,0 +1,5 @@
+package at.gv.egiz.pdfas.lib.api.sign;
+
+public class SignResult {
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/package-info.java
new file mode 100644
index 00000000..2052ad71
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.lib.api.sign; \ No newline at end of file
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/SignatureCheck.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/SignatureCheck.java
new file mode 100644
index 00000000..a021eb2a
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/SignatureCheck.java
@@ -0,0 +1,19 @@
+package at.gv.egiz.pdfas.lib.api.verify;
+
+public interface SignatureCheck {
+ /**
+ * Returns the response code of the check.
+ *
+ * @return Returns the response code of the check.
+ */
+ public int getCode();
+
+ /**
+ * Returns the textual response message of the check (corresponding to the
+ * code).
+ *
+ * @return Returns the textual response message of the check (corresponding
+ * to the code).
+ */
+ public String getMessage();
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyParameter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyParameter.java
new file mode 100644
index 00000000..8c53ad47
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyParameter.java
@@ -0,0 +1,14 @@
+package at.gv.egiz.pdfas.lib.api.verify;
+
+import at.gv.egiz.pdfas.lib.api.Configuration;
+import at.gv.egiz.pdfas.lib.api.IDataSource;
+import at.gv.egiz.pdfas.lib.api.PdfAsParameter;
+
+public class VerifyParameter extends PdfAsParameter {
+
+ public VerifyParameter(Configuration configuration,
+ IDataSource dataSource) {
+ super(configuration, dataSource);
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyResult.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyResult.java
new file mode 100644
index 00000000..339f7b15
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyResult.java
@@ -0,0 +1,50 @@
+package at.gv.egiz.pdfas.lib.api.verify;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+
+public interface VerifyResult {
+ /**
+ * Returns if the verification was possible or could not even be startet.
+ * see {@link #getVerificationException()} for details.
+ *
+ * @return
+ */
+ public boolean isVerificationDone();
+
+ /**
+ * Returns a verification exception if any. Shows that the verification
+ * could not be started. See {@link #isVerificationDone()}.
+ *
+ * @return
+ */
+ public PdfAsException getVerificationException();
+
+ /**
+ * Returns the result of the certificate check.
+ *
+ * @return Returns the result of the certificate check.
+ */
+ public SignatureCheck getCertificateCheck();
+
+ /**
+ * Returns the result of the value (and hash) check.
+ *
+ * @return Returns the result of the value (and hash) check.
+ */
+ public SignatureCheck getValueCheckCode();
+
+ /**
+ * Returns the result of the manifest check.
+ *
+ * @return Returns the result of the manifest check.
+ */
+ public SignatureCheck getManifestCheckCode();
+
+ /**
+ * Returns true, if the signer's certificate is a qualified certificate.
+ *
+ * @return Returns true, if the signer's certificate is a qualified
+ * certificate.
+ */
+ public boolean isQualifiedCertificate();
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/package-info.java
new file mode 100644
index 00000000..68dda721
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.lib.api.verify; \ No newline at end of file
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
new file mode 100644
index 00000000..d7ed5f3a
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java
@@ -0,0 +1,69 @@
+package at.gv.egiz.pdfas.lib.impl;
+
+import java.util.List;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.lib.api.Configuration;
+import at.gv.egiz.pdfas.lib.api.IConfigurationConstants;
+import at.gv.egiz.pdfas.lib.api.PdfAs;
+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.impl.configuration.ConfigurationImpl;
+import at.gv.egiz.pdfas.lib.impl.configuration.PlaceholderConfiguration;
+import at.gv.egiz.pdfas.lib.impl.status.OperationStatus;
+import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;
+
+public class PdfAsImpl implements PdfAs, IConfigurationConstants {
+
+ public SignResult sign(SignParameter parameter) throws PdfAsException {
+ // TODO: verify signParameter
+
+ // Status initialization
+ if(!(parameter.getConfiguration() instanceof ISettings)) {
+
+ }
+ ISettings settings = (ISettings) parameter.getConfiguration();
+ OperationStatus status = new OperationStatus(settings, parameter);
+ PlaceholderConfiguration placeholderConfiguration = status.getPlaceholderConfiguration();
+ // set Original PDF Document Data
+ status.getPdfObject().setOriginalDocument(parameter.getDataSource().getByteData());
+
+
+ // Placeholder search?
+ if(placeholderConfiguration.isGlobalPlaceholderEnabled()) {
+ // TODO: Do placeholder search
+ }
+
+ RequestedSignature requestedSignature = new RequestedSignature(status);
+
+ // TODO get Certificate
+
+ if(requestedSignature.isVisual()) {
+ // TODO: SignBlockCreationStage (visual) -> create visual signature block (logicaly)
+
+ // TODO: PositioningStage (visual) -> find position or use fixed position
+
+ // TODO: StampingStage (visual) -> stamp logical signature block to location (itext)
+ } else {
+ // Stamped Object is equal to original
+ status.getPdfObject().setStampedDocument(status.getPdfObject().getOriginalDocument());
+ }
+
+ // TODO: Create signature
+
+ return null;
+ }
+
+ public List<VerifyResult> verify(VerifyParameter parameter) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Configuration getConfiguration() {
+ return new ConfigurationImpl();
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigurationImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigurationImpl.java
new file mode 100644
index 00000000..b901b597
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigurationImpl.java
@@ -0,0 +1,110 @@
+package at.gv.egiz.pdfas.lib.impl.configuration;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Vector;
+
+import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.common.settings.Settings;
+import at.gv.egiz.pdfas.lib.api.Configuration;
+
+public class ConfigurationImpl implements ISettings, Configuration {
+
+ protected Properties overwrittenProperties = new Properties();
+
+ public void setValue(String key, String value) {
+ overwrittenProperties.setProperty(key, value);
+ }
+
+ public String getValue(String key) {
+ if(overwrittenProperties.containsKey(key)) {
+ return overwrittenProperties.getProperty(key);
+ } else {
+ return Settings.getInstance().getValue(key);
+ }
+ }
+
+ public boolean hasValue(String key) {
+ if(overwrittenProperties.containsKey(key)) {
+ return true;
+ } else {
+ return Settings.getInstance().hasValue(key);
+ }
+ }
+
+ public Map<String, String> getValuesPrefix(String prefix) {
+
+ Map<String, String> valueMap = null;
+ valueMap = Settings.getInstance().getValuesPrefix(prefix);
+ if(valueMap == null) {
+ valueMap = new HashMap<String, String>();
+ }
+
+ Iterator<Object> keyIterator = overwrittenProperties.keySet().iterator();
+
+ while(keyIterator.hasNext()) {
+ String key = keyIterator.next().toString();
+
+ if(key.startsWith(prefix)) {
+ valueMap.put(key, overwrittenProperties.getProperty(key));
+ }
+ }
+
+ if(valueMap.isEmpty()) {
+ return null;
+ }
+
+ return valueMap;
+ }
+
+ public Vector<String> getFirstLevelKeys(String prefix) {
+
+ Vector<String> valueMap = Settings.getInstance().getFirstLevelKeys(prefix);
+ if(valueMap == null) {
+ valueMap = new Vector<String>();
+ }
+
+
+ String mPrefix = prefix.endsWith(".")?prefix:prefix+".";
+ Iterator<Object> keyIterator = overwrittenProperties.keySet().iterator();
+
+ while(keyIterator.hasNext()) {
+ String key = keyIterator.next().toString();
+
+ if(key.startsWith(prefix)) {
+ int keyIdx = key.indexOf('.', mPrefix.length()) > 0 ? key.indexOf('.', mPrefix.length()) : key.length();
+ String firstLevels = key.substring(0, keyIdx);
+ if(!valueMap.contains(firstLevels)) {
+ valueMap.add(firstLevels);
+ }
+ }
+ }
+
+ if(valueMap.isEmpty()) {
+ return null;
+ }
+
+ return valueMap;
+ }
+
+ public boolean hasPrefix(String prefix) {
+
+ if(Settings.getInstance().hasPrefix(prefix)) {
+ return true;
+ }
+
+ Iterator<Object> keyIterator = overwrittenProperties.keySet().iterator();
+ while(keyIterator.hasNext()) {
+ String key = keyIterator.next().toString();
+
+ if(key.startsWith(prefix)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/GlobalConfiguration.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/GlobalConfiguration.java
new file mode 100644
index 00000000..2124f63e
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/GlobalConfiguration.java
@@ -0,0 +1,21 @@
+package at.gv.egiz.pdfas.lib.impl.configuration;
+
+import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.lib.api.Configuration;
+import at.gv.egiz.pdfas.lib.api.IConfigurationConstants;
+
+public class GlobalConfiguration extends SpecificBaseConfiguration
+ implements IConfigurationConstants {
+
+ public GlobalConfiguration(ISettings configuration) {
+ super(configuration);
+ }
+
+ public String getDefaultSignatureProfile() {
+ if(this.configuration.hasValue(DEFAULT_SIGNATURE_PROFILE)) {
+ return this.configuration.getValue(DEFAULT_SIGNATURE_PROFILE);
+ }
+ return null;
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderConfiguration.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderConfiguration.java
new file mode 100644
index 00000000..7d3beb5c
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderConfiguration.java
@@ -0,0 +1,23 @@
+package at.gv.egiz.pdfas.lib.impl.configuration;
+
+import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.lib.api.IConfigurationConstants;
+
+public class PlaceholderConfiguration extends SpecificBaseConfiguration
+ implements IConfigurationConstants {
+
+ public PlaceholderConfiguration(ISettings configuration) {
+ super(configuration);
+ }
+
+ public boolean isGlobalPlaceholderEnabled() {
+ if(configuration.hasValue(PLACEHOLDER_SEARCH_ENABLED)) {
+ String value = configuration.getValue(PLACEHOLDER_SEARCH_ENABLED);
+ if(value.equalsIgnoreCase(TRUE)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SignatureProfileConfiguration.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SignatureProfileConfiguration.java
new file mode 100644
index 00000000..d7792dca
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SignatureProfileConfiguration.java
@@ -0,0 +1,21 @@
+package at.gv.egiz.pdfas.lib.impl.configuration;
+
+import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.lib.api.IConfigurationConstants;
+
+public class SignatureProfileConfiguration extends SpecificBaseConfiguration
+ implements IConfigurationConstants {
+
+ protected String profileID;
+
+ public SignatureProfileConfiguration(ISettings configuration,
+ String profileID) {
+ super(configuration);
+ this.profileID = profileID;
+ }
+
+ public boolean isVisualSignature() {
+ String key = SIG_OBJECT + SEPERATOR + profileID + SEPERATOR + TABLE + SEPERATOR + MAIN;
+ return this.configuration.hasPrefix(key);
+ }
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SpecificBaseConfiguration.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SpecificBaseConfiguration.java
new file mode 100644
index 00000000..88c7b3d7
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SpecificBaseConfiguration.java
@@ -0,0 +1,13 @@
+package at.gv.egiz.pdfas.lib.impl.configuration;
+
+import at.gv.egiz.pdfas.common.settings.ISettings;
+
+public abstract class SpecificBaseConfiguration {
+
+ protected ISettings configuration;
+
+ public SpecificBaseConfiguration(ISettings configuration) {
+ this.configuration = configuration;
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/package-info.java
new file mode 100644
index 00000000..d766824e
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.lib.impl.configuration; \ No newline at end of file
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/package-info.java
new file mode 100644
index 00000000..aba811aa
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.lib.impl; \ No newline at end of file
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
new file mode 100644
index 00000000..340ba0bb
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/Positioning.java
@@ -0,0 +1,251 @@
+package at.gv.egiz.pdfas.lib.impl.positioning;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject;
+import at.gv.egiz.pdfas.common.utils.PDFUtils;
+import at.knowcenter.wag.egov.egiz.pdf.PDFUtilities;
+import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
+import at.knowcenter.wag.egov.egiz.pdf.TablePos;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
+
+/**
+ * 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 {
+
+ /**
+ * 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) throws PdfAsException
+ {
+ boolean legacy32 = false;
+
+ //TODO: settings reader ...
+
+ /*
+ if (pos == null)
+ {
+ String pos_string = SettingsReader.getInstance().getSetting(SignatureTypes.SIG_OBJ + signature_type + ".pos", null);
+ if (pos_string != null)
+ {
+ pos = PdfAS.parsePositionFromPosString(pos_string);
+ }
+ }
+ if (pos == null)
+ {
+ // The default algorithm. x,y,w =auto ,p=lastpage, f:ignored because
+ // y:auto
+ pos = new TablePos();
+ }
+
+ // afitzek
+ // Allow legacy positioning (3.2) for BRZ Templates ...
+ boolean legacy32 = false;
+ String leg = SettingsReader.getInstance().getSetting(SignatureTypes.SIG_OBJ + signature_type + ".legacy.pos", "false");
+ if (leg != null) {
+ if ("true".equals(leg.trim())) {
+ legacy32 = true;
+ }
+ }
+ */
+ // System.out.println("Tablepos="+pos);
+ 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
+ {
+
+ try {
+ 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();
+
+ if(cropBox == null) {
+ cropBox = pdPage.findCropBox();
+ }
+
+
+ if(cropBox == null) {
+ cropBox = pdPage.findMediaBox();
+ }
+
+ //TODO: fallback to MediaBox if Cropbox not available!
+
+ // 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_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);
+ }
+ // 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);
+ }
+ 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);
+ } finally {
+ if (pdfDataSource != null) {
+ try {
+ pdfDataSource.close();
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/package-info.java
new file mode 100644
index 00000000..5b209e06
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.lib.impl.positioning; \ 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
new file mode 100644
index 00000000..f1b59ceb
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java
@@ -0,0 +1,12 @@
+package at.gv.egiz.pdfas.lib.impl.stamping;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+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 interface IPDFStamper {
+ public IPDFVisualObject createVisualPDFObject(PDFObject pdf, Table table);
+ public byte[] writeVisualObject(IPDFVisualObject visualObject, PositioningInstruction positioningInstruction,
+ byte[] pdfData) throws PdfAsException;
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFVisualObject.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFVisualObject.java
new file mode 100644
index 00000000..fd7cac5c
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFVisualObject.java
@@ -0,0 +1,12 @@
+package at.gv.egiz.pdfas.lib.impl.stamping;
+
+public interface IPDFVisualObject {
+ public void setWidth(float width);
+ public void fixWidth();
+ public float getHeight();
+ public float getWidth();
+ public void setXPos(float x);
+ public void setYPos(float x);
+ public int getPage();
+ public void setPage(int page);
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/StamperFactory.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/StamperFactory.java
new file mode 100644
index 00000000..1720057a
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/StamperFactory.java
@@ -0,0 +1,18 @@
+package at.gv.egiz.pdfas.lib.impl.stamping;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+
+public class StamperFactory {
+
+ public static final String DEFAULT_STAMPER_CLASS = "at.gv.egiz.pdfas.stmp.itext.ITextStamper";
+
+ public static IPDFStamper createDefaultStamper() throws PdfAsException {
+ try {
+ Class<? extends IPDFStamper> cls = (Class<? extends IPDFStamper>)
+ Class.forName(DEFAULT_STAMPER_CLASS);
+ return cls.newInstance();
+ } catch (Throwable e) {
+ throw new PdfAsException("NO STAMPER!", e);
+ }
+ }
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/package-info.java
new file mode 100644
index 00000000..496f592f
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author afitzek
+ *
+ */
+package at.gv.egiz.pdfas.lib.impl.stamping; \ No newline at end of file
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
new file mode 100644
index 00000000..d7b956a7
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java
@@ -0,0 +1,76 @@
+package at.gv.egiz.pdfas.lib.impl.status;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.lib.api.sign.SignParameter;
+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;
+
+public class OperationStatus {
+
+ private SignParameter signParamter;
+ private PDFObject pdfObject = new PDFObject();
+
+
+ private ISettings configuration;
+ private PlaceholderConfiguration placeholderConfiguration = null;
+ private GlobalConfiguration gloablConfiguration = null;
+ private Map<String, SignatureProfileConfiguration> signatureProfiles =
+ new HashMap<String, SignatureProfileConfiguration>();
+
+ public OperationStatus(ISettings configuration, SignParameter signParameter) {
+ this.configuration = configuration;
+ this.signParamter = signParameter;
+ }
+
+ // ========================================================================
+
+ public PlaceholderConfiguration getPlaceholderConfiguration() {
+ if(this.placeholderConfiguration == null) {
+ this.placeholderConfiguration =
+ new PlaceholderConfiguration(this.configuration);
+ }
+ return this.placeholderConfiguration;
+ }
+
+ public GlobalConfiguration getGlobalConfiguration() {
+ if(this.gloablConfiguration == null) {
+ this.gloablConfiguration =
+ new GlobalConfiguration(this.configuration);
+ }
+ return this.gloablConfiguration;
+ }
+
+ public SignatureProfileConfiguration getSignatureProfileConfiguration(String profileID) {
+
+ SignatureProfileConfiguration signatureProfileConfiguration = signatureProfiles.get(profileID);
+ if(signatureProfileConfiguration == null) {
+ signatureProfileConfiguration = new SignatureProfileConfiguration(this.configuration, profileID);
+ signatureProfiles.put(profileID, signatureProfileConfiguration);
+ }
+
+ return signatureProfileConfiguration;
+ }
+
+ // ========================================================================
+
+ public PDFObject getPdfObject() {
+ return pdfObject;
+ }
+
+ public void setPdfObject(PDFObject pdfObject) {
+ this.pdfObject = pdfObject;
+ }
+
+ public SignParameter getSignParamter() {
+ return signParamter;
+ }
+
+ public void setSignParamter(SignParameter signParamter) {
+ this.signParamter = signParamter;
+ }
+
+}
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
new file mode 100644
index 00000000..1fe64bee
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/PDFObject.java
@@ -0,0 +1,31 @@
+package at.gv.egiz.pdfas.lib.impl.status;
+
+public class PDFObject {
+ private byte[] originalDocument;
+ private byte[] stampedDocument;
+ private byte[] signedDocument;
+
+ public byte[] getOriginalDocument() {
+ return originalDocument;
+ }
+
+ public void setOriginalDocument(byte[] originalDocument) {
+ this.originalDocument = originalDocument;
+ }
+
+ public byte[] getStampedDocument() {
+ return stampedDocument;
+ }
+
+ public void setStampedDocument(byte[] stampedDocument) {
+ this.stampedDocument = stampedDocument;
+ }
+
+ public byte[] getSignedDocument() {
+ return signedDocument;
+ }
+
+ public void setSignedDocument(byte[] signedDocument) {
+ this.signedDocument = signedDocument;
+ }
+}
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
new file mode 100644
index 00000000..a78828f3
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java
@@ -0,0 +1,53 @@
+package at.gv.egiz.pdfas.lib.impl.status;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.exceptions.PdfAsSettingsException;
+import at.knowcenter.wag.egov.egiz.pdf.TablePos;
+
+
+public class RequestedSignature {
+ private String signatureProfile;
+ private TablePos signaturePosition;
+ private OperationStatus status;
+ //private IPlainSigner signer = null;
+
+ public RequestedSignature(OperationStatus status) throws PdfAsException {
+
+ this.status = status;
+
+ String profileID = status.getSignParamter().getSignatureProfileId();
+
+ if(profileID == null) {
+ profileID = status.getGlobalConfiguration().getDefaultSignatureProfile();
+
+ if(profileID == null) {
+ throw new PdfAsSettingsException("Failed to determine Signature Profile!");
+ }
+ }
+
+ this.signatureProfile = profileID;
+
+ if(status.getSignParamter().getSignaturePosition() == null) {
+ this.signaturePosition = new TablePos();
+ } else {
+ this.signaturePosition = new TablePos(status.getSignParamter().getSignaturePosition());
+ }
+ }
+
+ public boolean isVisual() {
+ return this.status.getSignatureProfileConfiguration(signatureProfile).isVisualSignature();
+ }
+
+ public TablePos getTablePos() {
+ return this.signaturePosition;
+ }
+
+/*
+ public IPlainSigner getSigner() {
+ return signer;
+ }
+
+ public void setSigner(IPlainSigner signer) {
+ this.signer = signer;
+ }*/
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/package-info.java
new file mode 100644
index 00000000..4321a9b5
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/package-info.java
@@ -0,0 +1 @@
+package at.gv.egiz.pdfas.lib.impl.status; \ No newline at end of file
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/package-info.java
new file mode 100644
index 00000000..62eb0d25
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/package-info.java
@@ -0,0 +1,4 @@
+/**
+ *
+ */
+package at.gv.egiz.pdfas.lib; \ No newline at end of file
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java
new file mode 100644
index 00000000..b5928406
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java
@@ -0,0 +1,502 @@
+/**
+ * <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.
+ *
+ * $Id: PDFPage.java,v 1.5 2006/10/31 08:09:33 wprinz Exp $
+ */
+package at.knowcenter.wag.egov.egiz.pdf;
+
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.construction.*;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.*;
+
+import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSStream;
+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.PDXObject;
+import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectForm;
+import org.apache.pdfbox.util.Matrix;
+import org.apache.pdfbox.util.PDFOperator;
+import org.apache.pdfbox.util.PDFTextStripper;
+import org.apache.pdfbox.util.TextPosition;
+import org.apache.pdfbox.util.operator.OperatorProcessor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.awt.*;
+import java.awt.geom.GeneralPath;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * PDFPage is an inner class that is used to calculate the page length of a PDF
+ * Document page. It extends the PDFTextStripper class and implement one
+ * interested method: {@link at.knowcenter.wag.egov.egiz.pdf.PDFPage#showCharacter(TextPosition)}<br>
+ * This method is called when processing the FileStream. By calling the method
+ * {@link org.apache.pdfbox.util.PDFStreamEngine#processStream(org.apache.pdfbox.pdmodel.PDPage, org.apache.pdfbox.pdmodel.PDResources, org.pdfbox.cos.COSStream)}
+ * the implemented method showCharacter is called.
+ *
+ * @author wlackner
+ * @see PDFTextStripper
+ */
+public class PDFPage extends PDFTextStripper {
+ /**
+ * The logger definition.
+ */
+ private static final Logger logger = LoggerFactory.getLogger(PDFPage.class);
+
+ /**
+ * The maximum (lowest) y position of a character.
+ */
+ protected float max_character_ypos = Float.NEGATIVE_INFINITY;
+
+ /**
+ * The maximum (lowest y position of an image.
+ */
+ protected float max_image_ypos = Float.NEGATIVE_INFINITY;
+
+ /**
+ * The effective page height.
+ */
+ protected float effectivePageHeight;
+
+ /**
+ * The path currently being constructed.
+ */
+ private GeneralPath currentPath = new GeneralPath();
+
+ /**
+ * The lowest position of a drawn path (originating from top).
+ */
+ private float maxPathRelatedYPositionFromTop = Float.NEGATIVE_INFINITY;
+
+ /**
+ * Constructor.
+ *
+ * @param effectivePageHeight
+ * The height of the page to be evaluated. PDF elements outside
+ * this height will not be considered.
+ *
+ * @throws java.io.IOException
+ */
+ public PDFPage(float effectivePageHeight, boolean legacy32) throws IOException {
+ super();
+
+ this.effectivePageHeight = effectivePageHeight;
+
+ OperatorProcessor newInvoke = new MyInvoke(this);
+ newInvoke.setContext(this);
+ this.registerOperatorProcessor("Do", newInvoke);
+
+ if (!legacy32) {
+ registerCustomPathOperators();
+ }
+ }
+
+ /**
+ * Registers operators responsible for path construction and painting in
+ * order to fix auto positioning on pages with path elements.
+ *
+ * @author Datentechnik Innovation GmbH
+ */
+ @SuppressWarnings("unchecked")
+ private void registerCustomPathOperators() {
+
+ // *** path construction
+
+ this.registerOperatorProcessor("m", new MoveTo(this));
+ this.registerOperatorProcessor("l", new LineTo(this));
+ this.registerOperatorProcessor("c", new CurveTo(this));
+ this.registerOperatorProcessor("y", new CurveToReplicateFinalPoint(this));
+ this.registerOperatorProcessor("v", new CurveToReplicateInitialPoint(this));
+ this.registerOperatorProcessor("h", new ClosePath(this));
+
+ // *** path painting
+
+ // "S": stroke path
+ this.registerOperatorProcessor("S", new StrokePath(this));
+ this.registerOperatorProcessor("s", new CloseAndStrokePath(this));
+ this.registerOperatorProcessor("f", new FillPathNonZeroWindingNumberRule(this));
+ this.registerOperatorProcessor("F", new FillPathNonZeroWindingNumberRule(this));
+ this.registerOperatorProcessor("f*", new FillPathEvenOddRule(this));
+ this.registerOperatorProcessor("b", new CloseFillNonZeroAndStrokePath(this));
+ this.registerOperatorProcessor("B", new FillNonZeroAndStrokePath(this));
+ this.registerOperatorProcessor("b*", new CloseFillEvenOddAndStrokePath(this));
+ this.registerOperatorProcessor("B*", new FillEvenOddAndStrokePath(this));
+ this.registerOperatorProcessor("n", new EndPath(this));
+
+ // Note: The graphic context
+ // (org.pdfbox.pdmodel.graphics.PDGraphicsState) of the underlying
+ // pdfbox library does
+ // not yet support clipping. This prevents feasible usage of clipping
+ // operators (W, W*).
+ // operators.put("W", new ...(this));
+ // operators.put("W*", new ...(this));
+
+ }
+
+ /**
+ * Returns the path currently being constructed.
+ *
+ * @return The path currently being constructed.
+ */
+ public GeneralPath getCurrentPath() {
+ return currentPath;
+ }
+
+ /**
+ * Sets the current path.
+ *
+ * @param currentPath
+ * The new current path.
+ */
+ public void setCurrentPath(GeneralPath currentPath) {
+ this.currentPath = currentPath;
+ }
+
+ /**
+ * Registers a rectangle that bounds the path currently being drawn.
+ *
+ * @param bounds
+ * A rectangle depicting the bounds (coordinates originating from
+ * bottom left).
+ * @author Datentechnik Innovation GmbH
+ */
+ public void registerPathBounds(Rectangle bounds) {
+ if (!bounds.isEmpty()) {
+ logger.debug("Registering path bounds: " + bounds);
+
+ // vertical start of rectangle (counting from top of page)
+ float upperBoundYPositionFromTop;
+
+ // vertical end of rectangle (counting from top of page)
+ // this depicts the current end of path-related page content
+ float lowerBoundYPositionFromTop;
+
+ PDRectangle boundaryBox = this.getCurrentPage().findMediaBox();
+ float pageHeight;
+
+ switch (this.getCurrentPage().findRotation()) {
+ case 90: // CW
+ pageHeight = boundaryBox.getWidth();
+ upperBoundYPositionFromTop = (float) bounds.getMinX();
+ lowerBoundYPositionFromTop = (float) bounds.getMaxX();
+ break;
+ case 180:
+ pageHeight = boundaryBox.getHeight();
+ upperBoundYPositionFromTop = (float) bounds.getMinY();
+ lowerBoundYPositionFromTop = (float) bounds.getMaxY();
+ break;
+ case 270: // CCW
+ pageHeight = boundaryBox.getWidth();
+ upperBoundYPositionFromTop = pageHeight
+ - (float) bounds.getMaxX();
+ lowerBoundYPositionFromTop = pageHeight
+ - (float) bounds.getMinX();
+ break;
+ default:
+ pageHeight = boundaryBox.getHeight();
+ upperBoundYPositionFromTop = pageHeight
+ - (float) bounds.getMaxY();
+ lowerBoundYPositionFromTop = pageHeight
+ - (float) bounds.getMinY();
+ break;
+ }
+
+ // new maximum ?
+ if (lowerBoundYPositionFromTop > maxPathRelatedYPositionFromTop) {
+ // Is the rectangle (at least partly) located above the footer
+ // line?
+ // (effective page height := page height - footer line)
+ if (upperBoundYPositionFromTop <= effectivePageHeight) {
+ // yes: update current end of path-related page content
+ maxPathRelatedYPositionFromTop = lowerBoundYPositionFromTop;
+ logger.trace("New max path related y position (from top): "
+ + maxPathRelatedYPositionFromTop);
+ } else {
+ // no: rectangle is fully located below the footer line ->
+ // ignore
+ logger.trace("Ignoring path bound below the footer line.");
+ }
+ }
+ }
+ }
+
+ protected void processOperator(PDFOperator operator, List arguments)
+ throws IOException {
+ logger.trace("operator = " + operator);
+ super.processOperator(operator, arguments);
+ }
+
+ @Override
+ protected void processTextPosition(TextPosition text) {
+ showCharacter(text);
+ }
+
+ // exthex
+ /**
+ * A method provided as an event interface to allow a subclass to perform
+ * some specific functionality when a character needs to be displayed. This
+ * method is used to calculate the latest position of a text in the page.
+ * Sorry for this missinterpretation of the method, but it is the only way
+ * to do this (provided by PDFBox)!!!
+ *
+ * @param text
+ * the character to be displayed -> calculate there y position.
+ */
+ protected void showCharacter(TextPosition text) {
+ float current_y = text.getY();
+ final String character = text.getCharacter();
+
+ int pageRotation = this.getCurrentPage().findRotation();
+ // logger_.debug("PageRotation = " + pageRotation);
+ if (pageRotation == 0) {
+ current_y = text.getY();
+ }
+ if (pageRotation == 90) {
+ current_y = text.getX();
+ }
+ if (pageRotation == 180) {
+ float page_height = this.getCurrentPage().findMediaBox().getHeight();
+ current_y = page_height - text.getY();
+ }
+ if (pageRotation == 270) {
+ float page_height = this.getCurrentPage().findMediaBox().getHeight();
+ current_y = page_height - text.getX();
+ }
+
+ if (current_y > this.effectivePageHeight) {
+ // logger_.debug("character is below footer_line. footer_line = " +
+ // this.footer_line + ", text.character=" + character + ", y=" +
+ // current_y);
+ return;
+ }
+
+ // store ypos of the char if it is not empty
+ if (!character.equals(" ") && current_y > this.max_character_ypos) {
+ this.max_character_ypos = current_y;
+ }
+
+ }
+
+ // use this funtion getting an unsorted text output
+ // public void showString(byte[] string) {
+ // logger_.debug(new String(string));
+ // }
+
+ /**
+ * Returns the calculated page length.
+ *
+ * @return the max page length value
+ */
+ public float getMaxPageLength() {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Determining page content length: text="
+ + max_character_ypos + ", image=" + max_image_ypos
+ + ", path=" + maxPathRelatedYPositionFromTop);
+ }
+ return NumberUtils.max(max_character_ypos, max_image_ypos,
+ maxPathRelatedYPositionFromTop);
+ }
+
+ public class MyInvoke extends OperatorProcessor {
+
+ private PDFPage mypage;
+
+ public MyInvoke(PDFPage page) {
+ this.mypage = page;
+ }
+
+ public void process(PDFOperator operator, List arguments)
+ throws IOException {
+ COSName name = (COSName) arguments.get(0);
+
+ // PDResources res = context.getResources();
+
+ Map xobjects = context.getXObjects();
+ PDXObject xobject = (PDXObject) xobjects.get(name.getName());
+
+ PDStream stream = xobject.getPDStream();
+ COSStream cos_stream = stream.getStream();
+
+ COSName subtype = (COSName) cos_stream
+ .getDictionaryObject(COSName.SUBTYPE);
+ if (subtype.equals(COSName.IMAGE)) {
+ logger.debug("XObject Image");
+
+ Matrix ctm = context.getGraphicsState()
+ .getCurrentTransformationMatrix();
+ logger.debug("ctm = " + ctm);
+
+ Pos[] coordinates = new Pos[] { new Pos(0, 0, 1),
+ new Pos(1, 0, 1), new Pos(0, 1, 1), new Pos(1, 1, 1) };
+
+ Pos[] transformed_coordinates = transtormCoordinates(
+ coordinates, ctm);
+
+ /**********************************************************
+ * pdf-as fix: calculating min and max point of an image to look
+ * where the signature should be placed fix solves problems with
+ * footer and images and placement of the signature in an image
+ * only pdf document
+ **********************************************************/
+
+ float actual_lowest_point = Float.NaN;
+ float actual_starting_point = Float.NaN;
+
+ int pageRotation = this.mypage.getCurrentPage().findRotation();
+ logger.debug("PageRotation = " + pageRotation);
+ if (pageRotation == 0) {
+ float min_y = findMinY(transformed_coordinates);
+ logger.debug("min_y = " + min_y);
+ float page_height = this.mypage.getCurrentPage().findMediaBox().getHeight();
+ logger.debug("page_height = " + page_height);
+
+ actual_lowest_point = page_height - min_y;
+ actual_starting_point = page_height
+ - findMaxY(transformed_coordinates);
+ }
+ if (pageRotation == 90) {
+ float max_x = findMaxX(transformed_coordinates);
+ logger.debug("max_x = " + max_x);
+ float page_width = this.mypage.getCurrentPage().findMediaBox().getWidth();
+ logger.debug("page_width = " + page_width);
+
+ actual_lowest_point = max_x;
+ actual_starting_point = findMinX(transformed_coordinates);
+ }
+ if (pageRotation == 180) {
+ float min_y = findMinY(transformed_coordinates);
+ logger.debug("min_y = " + min_y);
+ float page_height = this.mypage.getCurrentPage().findMediaBox().getHeight();
+ actual_lowest_point = page_height
+ - findMaxY(transformed_coordinates);
+ actual_starting_point = page_height - min_y;
+ }
+ if (pageRotation == 270) {
+ float min_x = findMinX(transformed_coordinates);
+ logger.debug("min_x = " + min_x);
+
+ float page_width = this.mypage.getCurrentPage().findMediaBox().getWidth();
+ logger.debug("page_width = " + page_width);
+
+ actual_lowest_point = page_width - min_x;
+ actual_starting_point = page_width
+ - findMaxX(transformed_coordinates);
+ }
+
+ logger.debug("actual_lowest_point = " + actual_lowest_point);
+
+ if (actual_lowest_point > PDFPage.this.effectivePageHeight
+ && actual_starting_point > PDFPage.this.effectivePageHeight) {
+ logger.debug("image is below footer_line");
+ return;
+ }
+
+ if (actual_lowest_point > PDFPage.this.max_image_ypos) {
+ PDFPage.this.max_image_ypos = actual_lowest_point;
+ }
+
+ return;
+ }
+
+ if (xobject instanceof PDXObjectForm) {
+ PDXObjectForm form = (PDXObjectForm) xobject;
+ COSStream invoke = (COSStream) form.getCOSObject();
+ PDResources pdResources = form.getResources();
+ PDPage page = context.getCurrentPage();
+ if (pdResources == null) {
+ pdResources = page.findResources();
+ }
+
+ getContext().processSubStream(page, pdResources, invoke);
+ }
+ }
+ }
+
+ public static Pos[] transtormCoordinates(Pos[] coordinates, Matrix m) {
+ Pos[] transformed = new Pos[coordinates.length];
+ for (int i = 0; i < coordinates.length; i++) {
+ transformed[i] = transtormCoordinate(coordinates[i], m);
+ }
+ return transformed;
+ }
+
+ public static Pos transtormCoordinate(Pos pos, Matrix m) {
+ Pos transformed = new Pos();
+ transformed.x = pos.x * m.getValue(0, 0) + pos.y * m.getValue(1, 0)
+ + pos.z * m.getValue(2, 0);
+ transformed.y = pos.x * m.getValue(0, 1) + pos.y * m.getValue(1, 1)
+ + pos.z * m.getValue(2, 1);
+ transformed.z = pos.x * m.getValue(0, 2) + pos.y * m.getValue(1, 2)
+ + pos.z * m.getValue(2, 2);
+
+ logger.debug(" transformed " + pos + " --> " + transformed);
+ return transformed;
+ }
+
+ public static float findMinY(Pos[] coordinates) {
+ float min = Float.POSITIVE_INFINITY;
+ for (int i = 0; i < coordinates.length; i++) {
+ if (coordinates[i].y < min) {
+ min = coordinates[i].y;
+ }
+ }
+ return min;
+ }
+
+ public static float findMaxY(Pos[] coordinates) {
+ float max = 0;
+ for (int i = 0; i < coordinates.length; i++) {
+ if (coordinates[i].y > max) {
+ max = coordinates[i].y;
+ }
+ }
+ return max;
+ }
+
+ public static float findMaxX(Pos[] coordinates) {
+ float max = Float.NEGATIVE_INFINITY;
+ for (int i = 0; i < coordinates.length; i++) {
+ if (coordinates[i].x > max) {
+ max = coordinates[i].x;
+ }
+ }
+ return max;
+ }
+
+ public static float findMinX(Pos[] coordinates) {
+ float min = Float.POSITIVE_INFINITY;
+ for (int i = 0; i < coordinates.length; i++) {
+ if (coordinates[i].x < min) {
+ min = coordinates[i].x;
+ }
+ }
+ return min;
+ }
+
+} \ No newline at end of file
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java
new file mode 100644
index 00000000..7f223b40
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.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.
+ *
+ * $Id: PDFUtilities.java,v 1.3 2006/10/31 08:09:33 wprinz Exp $
+ */
+package at.knowcenter.wag.egov.egiz.pdf;
+
+import java.io.IOException;
+import java.util.List;
+
+import at.gv.egiz.pdfas.common.exceptions.PDFIOException;
+import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDResources;
+import org.apache.pdfbox.pdmodel.interactive.pagenavigation.PDThreadBead;
+
+
+/**
+ * Contains useful helpers for accessing PDF documents.
+ *
+ * @author wprinz
+ * @author mruhmer
+ */
+public abstract class PDFUtilities
+{
+ public static float calculatePageLength(PDDocument document, int page, float effectivePageHeight, /*int pagerotation,*/ boolean legacy32) throws PDFIOException {
+ //int last_page_id = document.getNumberOfPages();
+ List allPages = document.getDocumentCatalog().getAllPages();
+ PDPage pdpage = (PDPage) allPages.get(page);
+ //pdpage.setRotation(pagerotation);
+ return calculatePageLength(pdpage, effectivePageHeight, legacy32);
+ }
+
+ public static float calculatePageLength(PDPage page, float effectivePageHeight, boolean legacy32) throws PDFIOException
+ {
+ try{
+ PDFPage my_page = new PDFPage(effectivePageHeight, legacy32);
+ PDResources resources = page.findResources();
+ COSStream stream = page.getContents().getStream();
+ //List<PDThreadBead> articles = page.getThreadBeads();
+ //my_page.processMyPage(page);
+ my_page.processStream(page, resources, stream);
+ return my_page.getMaxPageLength();
+ }
+ catch (IOException e)
+ {
+ throw new PDFIOException("calculatePageLength", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/Pos.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/Pos.java
new file mode 100644
index 00000000..6f03fed4
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/Pos.java
@@ -0,0 +1,70 @@
+/**
+ * <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.
+ *
+ * $Id: Pos.java,v 1.1 2006/08/25 17:10:08 wprinz Exp $
+ */
+package at.knowcenter.wag.egov.egiz.pdf;
+
+/**
+ * Encapsulation of a position on a PDF page.
+ *
+ * @author wprinz
+ */
+public class Pos
+{
+
+ public float x;
+
+ public float y;
+
+ public float z;
+
+ /**
+ * Default constructor.
+ */
+ public Pos()
+ {
+ }
+
+ /**
+ * Constructor that sets the coordinates.
+ * @param xx
+ * @param yy
+ * @param zz
+ */
+ public Pos(float xx, float yy, float zz)
+ {
+ this.x = xx;
+ this.y = yy;
+ this.z = zz;
+ }
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ return "(" + this.x + "," + this.y + "," + this.z + ")";
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java
new file mode 100644
index 00000000..0fe399c4
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java
@@ -0,0 +1,182 @@
+/**
+ * <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.
+ *
+ * $Id: $
+ */
+package at.knowcenter.wag.egov.egiz.pdf;
+
+/**
+ * The positioning instruction holds information of where to place the signature
+ * block.
+ *
+ * <p>
+ * This instruction is given to the PDF writer in order to place the signature.
+ * </p>
+ *
+ * @author wprinz
+ */
+public class PositioningInstruction
+{
+
+ /**
+ * Tells, if a new plain page should be appended.
+ *
+ * <p>
+ * This command is executed before the signature block is positioned according
+ * to page, x and y.
+ * </p>
+ */
+ protected boolean make_new_page = false;
+
+ /**
+ * The number of the page on which the signature block is to be placed. If
+ * specified to make a new page, the number of this newly created page can be
+ * used here as well.
+ */
+ protected int page = 0;
+
+ /**
+ * The x coordinate where the upper left corner of the signature block should
+ * be placed.
+ */
+ protected float x = 0.0f;
+
+ /**
+ * The y coordinate where the upper left corner of the signature block should
+ * be placed.
+ */
+ protected float y = 0.0f;
+
+ /**
+ *
+ * @param make_new_page
+ * Tells, if a new plain page should be appended. This command is
+ * executed before the signature block is positioned according to
+ * page, x and y.
+ * @param page
+ * The number of the page on which the signature block is to be
+ * placed. If specified to make a new page, the number of this newly
+ * created page can be used here as well.
+ * @param x
+ * The x coordinate where the upper left corner of the signature
+ * block should be placed.
+ * @param y
+ * The y coordinate where the upper left corner of the signature
+ * block should be placed.
+ */
+ public PositioningInstruction(boolean make_new_page, int page, float x, float y)
+ {
+ this.make_new_page = make_new_page;
+ this.page = page;
+ this.x = x;
+ this.y = y;
+ }
+
+ /**
+ * Tells, if a new plain page should be appended to the document.
+ *
+ * @return Returns true, if a new plain page should be appended.
+ */
+ public boolean isMakeNewPage()
+ {
+ return this.make_new_page;
+ }
+
+ /**
+ * Returns the page on which the signature is to be printed.
+ *
+ * @return Returns the page on which the signature is to be printed.
+ */
+ public int getPage()
+ {
+ return this.page;
+ }
+
+ /**
+ * Returns the x coordinate where the upper left corner of the signature block
+ * should be placed.
+ *
+ * @return Returns the x coordinate where the upper left corner of the
+ * signature block should be placed.
+ */
+ public float getX()
+ {
+ return this.x;
+ }
+
+ /**
+ * Returns the y coordinate where the upper left corner of the signature block
+ * should be placed.
+ *
+ * @return Returns the y coordinate where the upper left corner of the
+ * signature block should be placed.
+ */
+ public float getY()
+ {
+ return this.y;
+ }
+
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (make_new_page ? 1231 : 1237);
+ result = prime * result + page;
+ result = prime * result + Float.floatToIntBits(x);
+ result = prime * result + Float.floatToIntBits(y);
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof PositioningInstruction))
+ return false;
+ PositioningInstruction other = (PositioningInstruction) obj;
+ if (make_new_page != other.make_new_page)
+ return false;
+ if (page != other.page)
+ return false;
+ if (Float.floatToIntBits(x) != Float.floatToIntBits(other.x))
+ return false;
+ if (Float.floatToIntBits(y) != Float.floatToIntBits(other.y))
+ return false;
+ return true;
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("PositioningInstruction [page=");
+ buffer.append(page);
+ buffer.append(", make_new_page=");
+ buffer.append(make_new_page);
+ buffer.append(", x=");
+ buffer.append(x);
+ buffer.append(", y=");
+ buffer.append(y);
+ buffer.append("]");
+ return buffer.toString();
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java
new file mode 100644
index 00000000..92afaf98
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java
@@ -0,0 +1,261 @@
+/**
+ * <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.
+ *
+ * $Id: TablePos.java,v 1.1 2006/08/25 17:10:08 wprinz Exp $
+ */
+package at.knowcenter.wag.egov.egiz.pdf;
+
+import java.io.Serializable;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+
+/**
+ * Class that holds the exact position where the table should be written to the
+ * document.
+ *
+ * @author wprinz
+ * @author mruhmer
+ */
+public class TablePos implements Serializable
+{
+
+ /**
+ * SVUID.
+ */
+ private static final long serialVersionUID = -5299027706623518059L;
+
+ /**
+ * The page on which the block should be displayed.
+ *
+ */
+ private int page = 0;
+
+ /**
+ * The x position.
+ */
+ private float pos_x = 0.0f;
+
+ /**
+ * The y position.
+ */
+ private float pos_y = 0.0f;
+
+ /**
+ * The width of the block.
+ */
+ private float width = 0.0f;
+ /**
+ * The top y position of the footer line.
+ */
+ public float footer_line = 0.0f;
+
+ /**
+ * The y position.
+ */
+ public String myposstring = "";
+
+ private boolean newpage = false;
+ private boolean autoX = true;
+ private boolean autoY = true;
+ private boolean autoW = true;
+ private boolean autoP = true;
+
+ public boolean isXauto()
+ {
+ return this.autoX;
+ }
+ public boolean isYauto()
+ {
+ return this.autoY;
+ }
+ public boolean isWauto()
+ {
+ return this.autoW;
+ }
+ public boolean isPauto()
+ {
+ return this.autoP;
+ }
+ public boolean isNewPage()
+ {
+ return this.newpage;
+ }
+ public int getPage()
+ {
+ return this.page;
+ }
+ public float getFooterLine()
+ {
+ //ignore if newpage and y is not auto
+ if (!this.autoY || this.newpage)
+ {
+ return 0.0f;
+ }
+ return this.footer_line;
+ }
+ public float getPosX()
+ {
+ return this.pos_x;
+ }
+ public float getPosY()
+ {
+ return this.pos_y;
+ }
+ public float getWidth()
+ {
+ return this.width;
+ }
+ public TablePos()
+ {
+ //nothing to do --> default
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param pos_string The pos instruction.
+ * format : [x:x_algo];[y:y_algo];[w:w_algo][p:p_algo];[f:f_algo]
+ * x_algo:='auto' ... automatic positioning x
+ * floatvalue ... absolute x
+ * y_algo:='auto' ... automatic positioning y
+ * floatvalue ... absolute y
+ * w_algo:='auto' ... automatic width
+ * floatvalue ... absolute width
+ * p_algo:='auto' ... automatic last page
+ * 'new' ... new page
+ * intvalue ... pagenumber
+ * f_algo floatvalue ... consider footerline (only if y_algo is auto and p_algo is not 'new')
+ * @throws PdfAsException
+ */
+ public TablePos(String pos_string) throws PdfAsException
+ {
+ //parse posstring and throw exception
+ //[x:x_algo];[y:y_algo];[w:w_algo][p:p_algo];[f:f_algo]
+
+ String[] strs = pos_string.split(";");
+ try
+ {
+ for (int cmds = 0;cmds<strs.length;cmds++)
+ {
+
+ String cmd_kvstring = strs[cmds];
+ String[] cmd_kv = cmd_kvstring.split(":");
+ if (cmd_kv.length != 2)
+ {
+ throw new PdfAsException("Pos string (=" + pos_string + ") is invalid.");
+ }
+ String cmdstr = cmd_kv[0];
+ if (cmdstr.length() != 1)
+ {
+ throw new PdfAsException("Pos string (=" + pos_string + ") is invalid.");
+ }
+ char command = cmdstr.charAt(0);
+ String commandval= cmd_kv[1];
+ switch (command)
+ {
+ case 'x': {
+ if (!commandval.equalsIgnoreCase("auto"))
+ {
+ float xval= Float.parseFloat(commandval);
+ if (xval<0)
+ {
+ throw new PdfAsException("Pos string (x:" + xval + ") is invalid.");
+ }
+ this.pos_x = xval;
+ this.autoX = false;
+ }
+ break;
+ }
+ case 'y': {
+ if (!commandval.equalsIgnoreCase("auto"))
+ {
+ float yval= Float.parseFloat(commandval);
+ if (yval<0)
+ {
+ throw new PdfAsException("Pos string (y:" + yval + ") is invalid.");
+ }
+ this.pos_y = yval;
+ this.autoY = false;
+ }
+ break;
+ }
+ case 'w': {
+ if (!commandval.equalsIgnoreCase("auto"))
+ {
+ float wval= Float.parseFloat(commandval);
+ if (wval<=0)
+ {
+ throw new PdfAsException("pos.width (w:" + wval + ") must not be lower or equal 0.");
+ }
+ this.width = wval;
+ this.autoW = false;
+ }
+ break;
+ }
+ case 'p': {
+ if (!commandval.equalsIgnoreCase("auto"))
+ {
+ if (commandval.equalsIgnoreCase("new"))
+ {
+ this.newpage = true;
+ }
+ else
+ {
+ int pval = Integer.parseInt(commandval);
+ if (pval<1)
+ {
+ throw new PdfAsException("Page (p:" + pval + ") must not be lower than 1.");
+ }
+ this.page = pval;
+ this.autoP = false;
+ }
+ }
+ break;
+ }
+ case 'f': {
+ float flval=Float.parseFloat(commandval);
+ if (flval<0)
+ {
+ throw new PdfAsException("Pos string (=" + pos_string + ") is invalid.");
+ }
+ this.footer_line = flval;
+ break;
+ }
+ default : {
+ throw new PdfAsException("Pos string (=" + pos_string + ") is invalid.");
+ }
+ }
+ }
+ this.myposstring=pos_string;
+ }
+ catch (NumberFormatException e)
+ {
+ throw new PdfAsException("Pos string (=" + pos_string + ") cannot be parsed.");
+ }
+ }
+ public String toString()
+ {
+ String thatsme = "cmd:"+this.myposstring+" pos_x:"+this.pos_x+" pos_y:"+this.pos_y+" page:"+this.page+" width:"+this.width+" footer:"+this.footer_line+"\n "+" autoX:"+this.autoX+" autoY:"+this.autoY+" autoW:"+this.autoW+" Newpage:"+this.newpage+" autoP:"+this.autoP;
+ return thatsme;
+ }
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathConstructionOperatorProcessor.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathConstructionOperatorProcessor.java
new file mode 100644
index 00000000..63bd9481
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathConstructionOperatorProcessor.java
@@ -0,0 +1,61 @@
+/**
+ * <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.knowcenter.wag.egov.egiz.pdf.operator.path;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import org.apache.pdfbox.util.operator.OperatorProcessor;
+
+import java.awt.geom.Point2D;
+
+/**
+ * Provides functions for path construction operators.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author Datentechnik Innovation GmbH
+ *
+ */
+public abstract class PathConstructionOperatorProcessor extends OperatorProcessor {
+
+ public PathConstructionOperatorProcessor(PDFPage context) {
+ setContext(context);
+ }
+
+ /**
+ * Transforms the given point from user space coordinates to device space coordinates based on the current
+ * transition matrix.
+ *
+ * @param x
+ * The x axis value of the user space coordinates.
+ * @param y
+ * The y axis value of the user space coordinates.
+ * @return The transformed point.
+ */
+ public Point2D transform(double x, double y) {
+ double[] position = { x, y };
+ context.getGraphicsState().getCurrentTransformationMatrix().createAffineTransform()
+ .transform(position, 0, position, 0, 1);
+ return new Point2D.Double(position[0], position[1]);
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java
new file mode 100644
index 00000000..a0b73015
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java
@@ -0,0 +1,42 @@
+/**
+ * <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.knowcenter.wag.egov.egiz.pdf.operator.path;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import org.apache.pdfbox.util.operator.OperatorProcessor;
+
+/**
+ * Provides functions for path painting operators.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author Datentechnik Innovation GmbH
+ *
+ */
+public abstract class PathPaintingOperatorProcessor extends OperatorProcessor {
+
+ public PathPaintingOperatorProcessor(PDFPage context) {
+ setContext(context);
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java
new file mode 100644
index 00000000..c663fb5d
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java
@@ -0,0 +1,67 @@
+/**
+ * <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.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Close the current subpath by appending a straight line segment from the current point to the starting point of the
+ * subpath. If the current subpath is already closed, h shall donothing. This operator terminates the current subpath.
+ * Appending another segment to the current path shall begin a new subpath, even if the new segment begins at the
+ * endpoint reached by the h operation.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class ClosePath extends PathConstructionOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public ClosePath(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ pdfPage.getCurrentPath().closePath();
+
+ if (log.isTraceEnabled()) {
+ log.trace("Closing current path.");
+ }
+ } catch (Exception e) {
+ log.warn("Error processing operator 'h'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java
new file mode 100644
index 00000000..70f5ab20
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java
@@ -0,0 +1,84 @@
+/**
+ * <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.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSNumber;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Append a cubic Bezier curve to the current path. The curve shall extend from the current point to the point (x3, y3),
+ * using (x1, y1) and (x2, y2) as the Bezier control points (see 8.5.2.2, "Cubic Bezier Curves"). The new current point
+ * shall be (x3, y3).
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CurveTo extends PathConstructionOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public CurveTo(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ COSNumber x1 = (COSNumber) operands.get(0);
+ COSNumber y1 = (COSNumber) operands.get(1);
+ COSNumber x2 = (COSNumber) operands.get(2);
+ COSNumber y2 = (COSNumber) operands.get(3);
+ COSNumber x3 = (COSNumber) operands.get(4);
+ COSNumber y3 = (COSNumber) operands.get(5);
+
+ Point2D p1 = transform(x1.doubleValue(), y1.doubleValue());
+ Point2D p2 = transform(x2.doubleValue(), y2.doubleValue());
+ Point2D p3 = transform(x3.doubleValue(), y3.doubleValue());
+
+ pdfPage.getCurrentPath().curveTo(
+ (float) p1.getX(), (float) p1.getY(),
+ (float) p2.getX(), (float) p2.getY(),
+ (float) p3.getX(), (float) p3.getY()
+ );
+
+ if (log.isTraceEnabled()) {
+ log.trace("Appending cubic Bezier curve with x1:" + p1.getX() + ",y1:" + p1.getY() + ", x2:"
+ + p2.getX() + ",y2:" + p2.getY() + ", x3:" + p3.getX() + ",y3:" + p3.getY());
+ }
+ } catch (Exception e) {
+ log.warn("Error processing operator 'c'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java
new file mode 100644
index 00000000..c6125751
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java
@@ -0,0 +1,81 @@
+/**
+ * <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.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSNumber;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Append a cubic Bezier curve to the current path. The curve shall extend from the current point to the point (x3, y3),
+ * using (x1, y1) and (x3, y3) as the Bezier control points (see 8.5.2.2, "Cubic Bezier Curves"). The new current point
+ * shall be (x3, y3).
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CurveToReplicateFinalPoint extends PathConstructionOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public CurveToReplicateFinalPoint(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ COSNumber x1 = (COSNumber) operands.get(0);
+ COSNumber y1 = (COSNumber) operands.get(1);
+ COSNumber x3 = (COSNumber) operands.get(2);
+ COSNumber y3 = (COSNumber) operands.get(3);
+
+ Point2D p1 = transform(x1.doubleValue(), y1.doubleValue());
+ Point2D p3 = transform(x3.doubleValue(), y3.doubleValue());
+
+ pdfPage.getCurrentPath().curveTo(
+ (float) p1.getX(), (float) p1.getY(),
+ (float) p3.getX(), (float) p3.getY(),
+ (float) p3.getX(), (float) p3.getY()
+ );
+
+ if (log.isTraceEnabled()) {
+ log.trace("Appending cubic Bezier curve with x1:" + p1.getX() + ",y1:" + p1.getY() + ", x3:"
+ + p3.getX() + ",y3:" + p3.getY());
+ }
+ } catch (Exception e) {
+ log.warn("Error processing operator 'y'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java
new file mode 100644
index 00000000..1479bc7d
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java
@@ -0,0 +1,83 @@
+/**
+ * <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.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSNumber;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Append a cubic Bezier curve to the current path. The curve shall extend from the current point to the point (x3, y3),
+ * using the current point and (x2, y2) as the Bezier control points (see 8.5.2.2, "Cubic Bezier Curves"). The new
+ * current point shall be (x3, y3).
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CurveToReplicateInitialPoint extends PathConstructionOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public CurveToReplicateInitialPoint(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ COSNumber x2 = (COSNumber) operands.get(0);
+ COSNumber y2 = (COSNumber) operands.get(1);
+ COSNumber x3 = (COSNumber) operands.get(2);
+ COSNumber y3 = (COSNumber) operands.get(3);
+
+ Point2D currentPoint = pdfPage.getCurrentPath().getCurrentPoint();
+ Point2D p2 = transform(x2.doubleValue(), y2.doubleValue());
+ Point2D p3 = transform(x3.doubleValue(), y3.doubleValue());
+
+ pdfPage.getCurrentPath().curveTo(
+ (float)currentPoint.getX(), (float)currentPoint.getY(),
+ (float) p2.getX(), (float) p2.getY(),
+ (float) p3.getX(), (float) p3.getY()
+ );
+
+ if (log.isTraceEnabled()) {
+ log.trace("Appending cubic Bezier curve with x2:" + p2.getX() + ",y2:" + p2.getY() + ", x3:"
+ + p3.getX() + ",y3:" + p3.getY() + ", using current point x:" + currentPoint.getX() + ",y:"
+ + currentPoint.getY());
+ }
+ } catch (Exception e) {
+ log.warn("Error processing operator 'v'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java
new file mode 100644
index 00000000..94f16b7f
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java
@@ -0,0 +1,70 @@
+/**
+ * <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.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSNumber;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Append a straight line segment from the current point to the point (x, y). The new current point shall be (x, y).
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class LineTo extends PathConstructionOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public LineTo(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ COSNumber x = (COSNumber) operands.get(0);
+ COSNumber y = (COSNumber) operands.get(1);
+ Point2D p = transform(x.doubleValue(), y.doubleValue());
+
+ pdfPage.getCurrentPath().lineTo((float) p.getX(), (float) p.getY());
+
+ if (log.isTraceEnabled()) {
+ log.trace("Adding line to x:" + p.getX() + ",y:" + p.getY());
+ }
+ } catch (Exception e) {
+ log.warn("Error processing operator 'l'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java
new file mode 100644
index 00000000..97424e93
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.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.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSNumber;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Begin a new subpath by moving the current point to coordinates (x, y), omitting any connecting line segment. If the
+ * previous path construction operator in the current path was also m, the new m overrides it; no vestige of the
+ * previous m operation remains in the path.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class MoveTo extends PathConstructionOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public MoveTo(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ COSNumber x = (COSNumber) operands.get(0);
+ COSNumber y = (COSNumber) operands.get(1);
+ Point2D p = transform(x.doubleValue(), y.doubleValue());
+
+ pdfPage.getCurrentPath().moveTo((float) p.getX(), (float) p.getY());
+
+ if (log.isTraceEnabled()) {
+ log.trace("Moving current path to x:" + p.getX() + ",y:" + p.getY());
+ }
+ } catch (Exception e) {
+ log.warn("Error processing operator 'm'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java
new file mode 100644
index 00000000..5a8de9d0
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java
@@ -0,0 +1,58 @@
+/**
+ * <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.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Close and stroke the path. This operator shall have the same effect as the sequence <code>h S</code>.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CloseAndStrokePath extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public CloseAndStrokePath(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ if (log.isTraceEnabled()) {
+ log.trace("Closing and stroking path.");
+ }
+ context.processOperator("h", operands);
+ context.processOperator("S", operands);
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java
new file mode 100644
index 00000000..bdaaaa4a
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java
@@ -0,0 +1,59 @@
+/**
+ * <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.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Close, fill, and then stroke the path, using the even-odd rule to determine the region to fill. This operator shall
+ * have the same effect as the sequence <code>h B*</code>.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CloseFillEvenOddAndStrokePath extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public CloseFillEvenOddAndStrokePath(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ if (log.isTraceEnabled()) {
+ log.trace("Closing, filling (even odd rule) and stroking path.");
+ }
+ context.processOperator("h", operands);
+ context.processOperator("B*", operands);
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java
new file mode 100644
index 00000000..4d4f3b68
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java
@@ -0,0 +1,59 @@
+/**
+ * <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.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Close, fill, and then stroke the path, using the nonzero winding number rule to determine the region to fill. This
+ * operator shall have the same effect as the sequence <code>h B</code>.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CloseFillNonZeroAndStrokePath extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public CloseFillNonZeroAndStrokePath(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ if (log.isTraceEnabled()) {
+ log.trace("Closing, filling (non zero rule) and stroking path.");
+ }
+ context.processOperator("h", operands);
+ context.processOperator("B", operands);
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java
new file mode 100644
index 00000000..291175aa
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java
@@ -0,0 +1,67 @@
+/**
+ * <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.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * End the path object without filling or stroking it. This operator shall be a path-painting no-op, used primarily for
+ * the side effect of changing the current clipping path.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class EndPath extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public EndPath(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ log.debug("Ending path " + pdfPage.getCurrentPath());
+ pdfPage.getCurrentPath().reset();
+
+ if (log.isTraceEnabled()) {
+ log.trace("End path without filling or stroking.");
+ }
+
+ } catch (Exception e) {
+ log.warn("Error processing operator 'n'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java
new file mode 100644
index 00000000..b1e836d5
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java
@@ -0,0 +1,71 @@
+/**
+ * <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.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.geom.GeneralPath;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Fill and then stroke the path, using the even-odd rule to determine the region to fill. This operator shall produce
+ * the same result as <code>B</code>, except that the path is filled as if with <code>f*</code> instead of
+ * <code>f</code>.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class FillEvenOddAndStrokePath extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public FillEvenOddAndStrokePath(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ if (log.isTraceEnabled()) {
+ log.trace("Filling (even odd rule) and stroking path.");
+ }
+
+ GeneralPath currentPath = (GeneralPath) pdfPage.getCurrentPath().clone();
+ context.processOperator("f*", operands);
+ pdfPage.setCurrentPath(currentPath);
+ context.processOperator("S", operands);
+
+ } catch (Exception e) {
+ log.warn("Error processing operator 'B*'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java
new file mode 100644
index 00000000..72719ec3
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java
@@ -0,0 +1,71 @@
+/**
+ * <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.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.geom.GeneralPath;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Fill and then stroke the path, using the nonzero winding number rule to determine the region to fill. This operator
+ * shall produce the same result as constructing two identical path objects, painting the first with <code>f</code> and
+ * the second with <code>S</code>.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class FillNonZeroAndStrokePath extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public FillNonZeroAndStrokePath(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ if (log.isTraceEnabled()) {
+ log.trace("Filling (non zero rule) and stroking path.");
+ }
+
+ GeneralPath currentPath = (GeneralPath) pdfPage.getCurrentPath().clone();
+ context.processOperator("f", operands);
+ pdfPage.setCurrentPath(currentPath);
+ context.processOperator("S", operands);
+
+ } catch (Exception e) {
+ log.warn("Error processing operator 'B'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java
new file mode 100644
index 00000000..28343c5a
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java
@@ -0,0 +1,70 @@
+/**
+ * <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.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.*;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Fill the path, using the even-odd rule to determine the region to fill.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class FillPathEvenOddRule extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public FillPathEvenOddRule(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ pdfPage.getCurrentPath().setWindingRule(java.awt.geom.GeneralPath.WIND_EVEN_ODD);
+ Rectangle bounds = pdfPage.getCurrentPath().getBounds();
+ pdfPage.getCurrentPath().reset();
+
+ if (log.isTraceEnabled()) {
+ log.trace("Filling path, using even-odd rule.");
+ }
+
+ pdfPage.registerPathBounds(bounds);
+
+ } catch (Exception e) {
+ log.warn("Error processing operator 'f*'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java
new file mode 100644
index 00000000..28e5c373
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java
@@ -0,0 +1,71 @@
+/**
+ * <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.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.*;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Fill the path, using the nonzero winding number rule to determine the region to fill. Any subpaths that are open
+ * shall be implicitly closed before being filled.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class FillPathNonZeroWindingNumberRule extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public FillPathNonZeroWindingNumberRule(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ pdfPage.getCurrentPath().setWindingRule(java.awt.geom.GeneralPath.WIND_NON_ZERO);
+ Rectangle bounds = pdfPage.getCurrentPath().getBounds();
+ pdfPage.getCurrentPath().reset();
+
+ if (log.isTraceEnabled()) {
+ log.trace("Filling path, using nonzero winding number rule.");
+ }
+
+ pdfPage.registerPathBounds(bounds);
+
+ } catch (Exception e) {
+ log.warn("Error processing operator 'f/F'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java
new file mode 100644
index 00000000..0530a925
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java
@@ -0,0 +1,69 @@
+/**
+ * <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.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.*;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Strokes the path.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class StrokePath extends PathPaintingOperatorProcessor {
+
+ private Log log = LogFactory.getLog(getClass());
+
+ public StrokePath(PDFPage context) {
+ super(context);
+ }
+
+ @Override
+ public void process(PDFOperator operator, List operands) throws IOException {
+ try {
+ PDFPage pdfPage = (PDFPage) context;
+
+ Rectangle bounds = pdfPage.getCurrentPath().getBounds();
+ pdfPage.getCurrentPath().reset();
+
+ if (log.isTraceEnabled()) {
+ log.trace("Stroking path.");
+ }
+
+ pdfPage.registerPathBounds(bounds);
+
+ } catch (Exception e) {
+ log.warn("Error processing operator 'S'.", e);
+ }
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/sig/SignatureEntry.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/sig/SignatureEntry.java
new file mode 100644
index 00000000..957e947f
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/sig/SignatureEntry.java
@@ -0,0 +1,163 @@
+/**
+ * <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.
+ *
+ * $Id: SignatureEntry.java,v 1.3 2006/08/25 17:09:41 wprinz Exp $
+ */
+package at.knowcenter.wag.egov.egiz.pdf.sig;
+
+import java.io.Serializable;
+
+/**
+ * This class is to store a signature entry. The signature entry is 3-tupel. A key that is defined
+ * or declarated in the settings file, an optional caption or a value. <br>
+ * An additional helper value is a marker for the start index of the key, if the key is found in an
+ * analysing process extracting captions and values from a raw signature text.
+ *
+ * @author wlackner
+ * @see at.knowcenter.wag.egov.egiz.sig.SignatureObject
+ */
+public class SignatureEntry implements Serializable {
+
+ /**
+ * SVUID.
+ */
+ private static final long serialVersionUID = 4640380069301731879L;
+
+ /**
+ * The signature key.
+ */
+ private String key_ = null;
+ /**
+ * The signature caption for the key found or set in the signature text.
+ */
+ private String caption_ = null;
+ /**
+ * The signature value for the key found or set in the signature text.
+ */
+ private String value_ = null;
+ /**
+ * The starting index position of the key if it is found in the signature text.
+ */
+ private int startIndex_ = -1;
+
+ public boolean isPlaceholder = false;
+
+ /**
+ * The empty constructor.
+ */
+ public SignatureEntry() {
+ }
+
+ /**
+ * A new <code>SignatureEntry</code> init with the key.
+ *
+ * @param key
+ */
+ public SignatureEntry(String key) {
+ key_ = key;
+ }
+
+ /**
+ * Returns the caption off the current key.
+ *
+ * @return Returns the caption.
+ */
+ public String getCaption() {
+ return caption_;
+ }
+
+ /**
+ * Set the caption of the current key.
+ *
+ * @param caption The caption to set.
+ */
+ public void setCaption(String caption) {
+ caption_ = caption;
+ }
+
+ /**
+ * Return the current key.
+ *
+ * @return Returns the key.
+ */
+ public String getKey() {
+ return key_;
+ }
+
+ /**
+ * Set the current key.
+ *
+ * @param key The key to set.
+ */
+ public void setKey(String key) {
+ key_ = key;
+ }
+
+ /**
+ * Return the start position of the key that caption is found in the signature text.
+ *
+ * @return Returns the startIndex.
+ */
+ public int getStartIndex() {
+ return startIndex_;
+ }
+
+ /**
+ * Set the start position of the current key.
+ *
+ * @param startIndex The startIndex to set.
+ */
+ public void setStartIndex(int startIndex) {
+ startIndex_ = startIndex;
+ }
+
+ /**
+ * Return the value of the current key.
+ *
+ * @return Returns the value.
+ */
+ public String getValue() {
+ return value_;
+ }
+
+ /**
+ * Set the value of the current key.
+ *
+ * @param value The value to set.
+ */
+ public void setValue(String value) {
+ value_ = value;
+ }
+
+ /**
+ * The toString method, used for tests or debugging.
+ */
+ public String toString() {
+ String the_string = "";
+ the_string += "\n Key:" + key_;
+ the_string += "\nCaption:" + caption_;
+ the_string += "\n Value:" + value_;
+// the_string += "\nStart I:" + startIndex_;
+ return the_string;
+ }
+} \ No newline at end of file
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Entry.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Entry.java
new file mode 100644
index 00000000..289a7f6f
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Entry.java
@@ -0,0 +1,235 @@
+/**
+ * <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.
+ *
+ * $Id: Entry.java,v 1.3 2006/08/25 17:08:19 wprinz Exp $
+ */
+package at.knowcenter.wag.egov.egiz.table;
+
+import java.io.Serializable;
+
+/**
+ * This class implements a table entry for different types. A table entry can be
+ * styled and setting there column dimensions. The default value for the column
+ * dimension is 1. To declare the type of the entry use the public
+ * <code>TYPE_</code> definitions.
+ *
+ * @author wlackner
+ */
+public class Entry implements Serializable
+{
+
+ /**
+ * SVUID.
+ */
+ private static final long serialVersionUID = -7952755200668528348L;
+
+ /**
+ * Type for a text entry.
+ */
+ public final static int TYPE_CAPTION = 0;
+
+ /**
+ * Type for a text entry.
+ */
+ public final static int TYPE_VALUE = 1;
+
+ /**
+ * Type for an image entry.
+ */
+ public final static int TYPE_IMAGE = 2;
+
+ /**
+ * Type for a table entry.
+ */
+ public final static int TYPE_TABLE = 3;
+
+ /**
+ * The type info holder, default value is 0!
+ */
+ private int type_ = 0;
+
+ /**
+ * The entry value.
+ */
+ private Object value_ = null;
+
+ /**
+ * The key value
+ */
+ private String key_ = null;
+
+ /**
+ * The entry style information.
+ */
+ private Style style_ = null;
+
+ /**
+ * The column dimension.
+ */
+ private int colSpan_ = 1;
+
+ /**
+ * Text wrap indicator, default is <code>false</code>.
+ */
+ private boolean noWrap_ = false;
+
+ /**
+ * The empty constructor.
+ */
+ public Entry()
+ {
+ }
+
+ /**
+ * A constructor setting the type and the value.
+ *
+ * @param type
+ * the entry type to set
+ * @param value
+ * the entry value to set
+ */
+ public Entry(int type, Object value, String key)
+ {
+ type_ = type;
+ value_ = value;
+ key_ = key;
+ }
+
+ /**
+ * @return Returns the entry style.
+ */
+ public Style getStyle()
+ {
+ return style_;
+ }
+
+ /**
+ * @param style
+ * The style to set.
+ */
+ public void setStyle(Style style)
+ {
+ style_ = style;
+ }
+
+ /**
+ * @return Returns the entry type.
+ */
+ public int getType()
+ {
+ return type_;
+ }
+
+ /**
+ * @param type
+ * The type to set.
+ */
+ public void setType(int type)
+ {
+ type_ = type;
+ }
+
+ /**
+ * @return Returns the entry value.
+ */
+ public Object getValue()
+ {
+ return value_;
+ }
+
+ /**
+ * @param value
+ * The value to set.
+ */
+ public void setValue(Object value)
+ {
+ value_ = value;
+ }
+
+ /**
+ * @return Returns the key.
+ */
+
+ public String getKey()
+ {
+ return key_;
+ }
+
+ /**
+ * @param key
+ * The key to set.
+ */
+ public void setKey(String key)
+ {
+ key_ = key;
+ }
+
+ /**
+ * @return Returns the colSpan.
+ */
+ public int getColSpan()
+ {
+ return colSpan_;
+ }
+
+ /**
+ * @param colSpan
+ * The colSpan to set.
+ */
+ public void setColSpan(int colSpan)
+ {
+ colSpan_ = colSpan;
+ }
+
+ /**
+ * @return Returns the wrap indicator.
+ */
+ public boolean isNoWrap()
+ {
+ return noWrap_;
+ }
+
+ /**
+ * @param noWrap
+ * The wrap indicator to set.
+ */
+ public void setNoWrap(boolean noWrap)
+ {
+ noWrap_ = noWrap;
+ }
+
+ /**
+ * The toString method, used for tests or debugging.
+ */
+ public String toString()
+ {
+ Object obj = getValue();
+ String value = null;
+ if (obj != null)
+ {
+ value = obj.toString();
+ }
+ return "Type:" + getType() + " Value:" + value + " ColSpan:" + getColSpan();
+ }
+
+} \ No newline at end of file
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Style.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Style.java
new file mode 100644
index 00000000..489c9419
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Style.java
@@ -0,0 +1,630 @@
+/**
+ * <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.
+ *
+ * $Id: Style.java,v 1.3 2006/08/25 17:08:19 wprinz Exp $
+ */
+package at.knowcenter.wag.egov.egiz.table;
+
+import java.awt.Color;
+import java.io.Serializable;
+
+/**
+ * This class implements an abstract style definiton used in tables or table entrys. Predefined
+ * values exists for valign and halign. Color definitions uses the native awt color declarations.
+ * <br>
+ * The predefined keys are used in the setting definition file to style tables and table entries.
+ * <br>
+ * It provides an static method to inherit style informations from a given style object.
+ * {@link Style#doInherit}
+ *
+ *
+ * @author wlackner
+ * @see java.awt.Color
+ */
+public class Style implements Serializable {
+
+// 03.11.2010 changed by exthex - added valuevalign and valuehalign to allow separate layout for value and non-value cells.
+// Also the hardcoded default values for halign and valign were removed to allow proper inheritment.
+// 04.11.2010 changed by exthex - added imagevalign and imagehalign analog to valuevalign/valuehalign
+
+ /**
+ * SVUID.
+ */
+ private static final long serialVersionUID = 5855722896712428387L;
+
+ /**
+ * valign statement key top
+ */
+ public final static String TOP = "top";
+ /**
+ * valign statement key middle
+ */
+ public final static String MIDDLE = "middle";
+ /**
+ * valign statement key bottom
+ */
+ public final static String BOTTOM = "bottom";
+ /**
+ * halign statement key left
+ */
+ public final static String LEFT = "left";
+ /**
+ * halign statement key center
+ */
+ public final static String CENTER = "center";
+ /**
+ * halign statement key right
+ */
+ public final static String RIGHT = "right";
+
+ /**
+ * bgcolor key
+ */
+ public final static String BGCOLOR = "bgcolor";
+ /**
+ * halign key
+ */
+ public final static String HALIGN = "halign";
+ /**
+ * valign key
+ */
+ public final static String VALIGN = "valign";
+
+ /**
+ * value halign key
+ */
+ public final static String VALUEHALIGN = "valuehalign";
+ /**
+ * value valign key
+ */
+ public final static String VALUEVALIGN = "valuevalign";
+
+ /**
+ * image halign key
+ */
+ public final static String IMAGEHALIGN = "imagehalign";
+ /**
+ * image valign key
+ */
+ public final static String IMAGEVALIGN = "imagevalign";
+ /**
+ * padding key, default padding = 1
+ */
+ public final static String PADDING = "padding";
+ /**
+ * border key, default border = 1;<br>
+ * The border value is one value for all border lines of an entry or table! <br>
+ * No separte definitions for top, right, bottom or left are possible.
+ */
+ public final static String BORDER = "border";
+
+ /**
+ * Font key
+ */
+ public final static String FONT = "font";
+
+ /**
+ * The value font key.
+ */
+ public final static String VALUEFONT = "valuefont";
+
+ /**
+ * The imageScaleToFit key.
+ */
+ public final static String IMAGE_SCALE_TO_FIT = "imagescaletofit";
+
+ /**
+ * Font name HELVETICA
+ */
+ public final static String HELVETICA = "HELVETICA";
+ /**
+ * Font name TIMES_ROMAN
+ */
+ public final static String TIMES_ROMAN = "TIMES_ROMAN";
+ /**
+ * Font name COURIER
+ */
+ public final static String COURIER = "COURIER";
+ /**
+ * Font type NORMAL
+ */
+ public final static String NORMAL = "NORMAL";
+ /**
+ * Font type BOLD
+ */
+ public final static String BOLD = "BOLD";
+ /**
+ * Font type ITALIC
+ */
+ public final static String ITALIC = "ITALIC";
+ /**
+ * Font type BOLDITALIC
+ */
+ public final static String BOLDITALIC = "BOLDITALIC";
+ /**
+ * Font type UNDERLINE
+ */
+ public final static String UNDERLINE = "UNDERLINE";
+ /**
+ * Font type STRIKETHRU
+ */
+ public final static String STRIKETHRU = "STRIKETHRU";
+
+
+ /**
+ * all paddings initialized with the default padding value (1)
+ */
+ private static final float DEFAULT_PADDING = 1;
+ /**
+ * all borders initialized with the default border value (1)
+ */
+ private static final float DEFAULT_BORDER = 1;
+ /**
+ * The background color definition.
+ */
+ private Color bgColor_ = null;
+ /**
+ * The current padding value -> initialized with the default padding value
+ */
+ private float padding_ = DEFAULT_PADDING;
+ /**
+ * The current halign value
+ */
+ private String hAlign_ = null;
+ /**
+ * The current valign value
+ */
+ private String vAlign_ = null;
+ /**
+ * The current valuehalign value
+ */
+ private String valueHAlign_ = null;
+ /**
+ * The current valuevalign value
+ */
+ private String valueVAlign_ = null;
+ /**
+ * The current imagehalign value
+ */
+ private String imageHAlign_ = null;
+ /**
+ * The current imagevalign value
+ */
+ private String imageVAlign_ = null;
+ /**
+ * The current border value -> initialized with the default border value
+ */
+ private float border_ = DEFAULT_BORDER;
+ /**
+ * The font string of the style definition
+ */
+ private String font_ = null;
+ /**
+ * The font string of the value font.
+ */
+ private String valuefont_ = null;
+ /**
+ * The scaleToFit dimensions to be applied for image-cells.
+ */
+ private ImageScaleToFit imageScaleToFit_ = null;
+
+ /**
+ * The empty constructor.
+ */
+ public Style() {
+ }
+
+ /**
+ * Set a style attribute. The style attribute must be one of the public definitions
+ *
+ * @param id the style attribute to set
+ * @param value the style value to set for the given attribute
+ */
+ public void setStyle(String id, String value) {
+ if (BGCOLOR.equals(id)) {
+ String[] col_strg = value.split(" ");
+ if (col_strg.length == 3) {
+ int r = Integer.parseInt(col_strg[0]);
+ int g = Integer.parseInt(col_strg[1]);
+ int b = Integer.parseInt(col_strg[2]);
+ if (r < 256 && g < 256 && b < 256 && r >= 0 && g >= 0 && b >= 0) {
+ bgColor_ = new Color(r, g, b);
+ }
+ }
+ }
+ if (HALIGN.equals(id)) {
+ if (LEFT.equals(value) || CENTER.equals(value) || RIGHT.equals(value)) {
+ hAlign_ = value;
+ }
+ }
+ if (VALIGN.equals(id)) {
+ if (TOP.equals(value) || MIDDLE.equals(value) || BOTTOM.equals(value)) {
+ vAlign_ = value;
+ }
+ }
+ if (VALUEHALIGN.equals(id)) {
+ if (LEFT.equals(value) || CENTER.equals(value) || RIGHT.equals(value)) {
+ valueHAlign_ = value;
+ }
+ }
+ if (VALUEVALIGN.equals(id)) {
+ if (TOP.equals(value) || MIDDLE.equals(value) || BOTTOM.equals(value)) {
+ valueVAlign_ = value;
+ }
+ }
+ if (IMAGEHALIGN.equals(id)) {
+ if (LEFT.equals(value) || CENTER.equals(value) || RIGHT.equals(value)) {
+ imageHAlign_ = value;
+ }
+ }
+ if (IMAGEVALIGN.equals(id)) {
+ if (TOP.equals(value) || MIDDLE.equals(value) || BOTTOM.equals(value)) {
+ imageVAlign_ = value;
+ }
+ }
+ if (PADDING.equals(id)) {
+ padding_ = Float.parseFloat(value);
+ }
+ if (BORDER.equals(id)) {
+ border_ = Float.parseFloat(value);
+ }
+ if (FONT.equals(id)) {
+ font_ = value;
+ }
+ if (VALUEFONT.equals(id)) {
+ valuefont_ = value;
+ }
+ if (IMAGE_SCALE_TO_FIT.equals(id))
+ {
+ imageScaleToFit_ = parseImageScaleToFit(value);
+ }
+ }
+
+ /**
+ * @return Returns the bgColor.
+ */
+ public Color getBgColor() {
+ return bgColor_;
+ }
+
+ /**
+ * @param bgColor The bgColor to set.
+ */
+ public void setBgColor(Color bgColor) {
+ bgColor_ = bgColor;
+ }
+
+ /**
+ * @return Returns the hAlign.
+ */
+ public String getHAlign() {
+ return hAlign_;
+ }
+
+ /**
+ * @param align The hAlign to set.
+ */
+ public void setHAlign(String align) {
+ hAlign_ = align;
+ }
+
+ /**
+ * @return Returns the padding.
+ */
+ public float getPadding() {
+ return padding_;
+ }
+
+ /**
+ * @param padding The padding to set.
+ */
+ public void setPadding(float padding) {
+ padding_ = padding;
+ }
+
+ /**
+ * @return Returns the vAlign.
+ */
+ public String getVAlign() {
+ return vAlign_;
+ }
+
+ /**
+ * @param align The vAlign to set.
+ */
+ public void setVAlign(String align) {
+ vAlign_ = align;
+ }
+
+ /**
+ * @return Returns the border.
+ */
+ public float getBorder() {
+ return border_;
+ }
+
+ /**
+ * @param border The border to set.
+ */
+ public void setBorder(float border) {
+ border_ = border;
+ }
+
+
+ /**
+ * @return Returns the font.
+ */
+ public String getFont() {
+ return font_;
+ }
+
+ /**
+ * @param font The font to set.
+ */
+ public void setFont(String font) {
+ font_ = font;
+ }
+
+
+ /**
+ * Returns the value font.
+ * @return Returns the value font.
+ */
+ public String getValueFont()
+ {
+ return valuefont_;
+ }
+
+ /**
+ * Sets the value font.
+ * @param valuefont The value font to be set.
+ */
+ public void setValueFont(String valuefont)
+ {
+ this.valuefont_ = valuefont;
+ }
+
+ /**
+ * @param align The valueHAlign to set.
+ */
+ public void setValueHAlign(String align) {
+ valueHAlign_ = align;
+ }
+
+ /**
+ * Returns the value halign
+ * @return Returns the value halign
+ */
+ public String getValueHAlign() {
+ return valueHAlign_;
+ }
+
+ /**
+ * @param align The valueVAlign to set.
+ */
+ public void setValueVAlign(String align) {
+ valueVAlign_ = align;
+ }
+
+ /**
+ * Returns the value valign
+ * @return Returns the value valign
+ */
+ public String getValueVAlign() {
+ return valueVAlign_;
+ }
+
+ /**
+ * @param align The imageHAlign to set.
+ */
+ public void setImageHAlign(String align) {
+ imageHAlign_ = align;
+ }
+
+ /**
+ * Returns the image halign
+ * @return Returns the image halign
+ */
+ public String getImageHAlign() {
+ return imageHAlign_;
+ }
+
+ /**
+ * @param align The imageVAlign to set.
+ */
+ public void setImageVAlign(String align) {
+ imageVAlign_ = align;
+ }
+
+ /**
+ * Returns the image valign
+ * @return Returns the image valign
+ */
+ public String getImageVAlign() {
+ return imageVAlign_;
+ }
+
+ /**
+ * Returns the scaleToFit dimensions to be applied for image-cells.
+ * @return Returns the scaleToFit dimensions to be applied for image-cells.
+ */
+ public ImageScaleToFit getImageScaleToFit()
+ {
+ return this.imageScaleToFit_;
+ }
+
+ /**
+ * Sets the scaleToFit dimensions to be applied for image-cells.
+ * @param imageScaleToFit_ The scaleToFit dimensions to be applied for image-cells.
+ */
+ public void setImageScaleToFit(ImageScaleToFit imageScaleToFit)
+ {
+ this.imageScaleToFit_ = imageScaleToFit;
+ }
+
+ /**
+ * The toString method, used for tests or debugging.
+ */
+ public String toString() {
+ return "bgcolor:" + getBgColor() + " halign:" + getHAlign() + " valign:" + getVAlign() + " padding:" + getPadding() + " border:" + getBorder() + " font:" + getFont() + " valuefont:" + getValueFont() + " imageScaleToFit:" + getImageScaleToFit();
+ }
+
+ /**
+ * This method inherits all style attributes (values) from a given style object.
+ *
+ * <p>
+ * A new style object is created that receives the properly inherited styles.
+ * </p>
+ * <p>
+ * If a value is not defined in the <code>baseStyle</code> object it would be inhert from the <code>inheritStyle</code> object.
+ * </p>
+ *
+ * @param baseStyle the style object that serves as a primary style source.
+ * @param inheritStyle the style object that serves as a secondary style source in case a style attribute is not defined on the primary style source.
+ * @param isValue
+ * @return Returns a new Style object being fully equipped with styles.
+ */
+ public static Style doInherit(Style baseStyle, Style inheritStyle) {
+ Style newStyle = new Style();
+
+ if (baseStyle != null)
+ {
+ newStyle.setBgColor(baseStyle.getBgColor());
+ newStyle.setBorder(baseStyle.getBorder());
+ newStyle.setFont(baseStyle.getFont());
+ newStyle.setHAlign(baseStyle.getHAlign());
+ newStyle.setImageHAlign(baseStyle.getImageHAlign());
+ newStyle.setImageVAlign(baseStyle.getImageVAlign());
+ newStyle.setPadding(baseStyle.getPadding());
+ newStyle.setVAlign(baseStyle.getVAlign());
+ newStyle.setValueFont(baseStyle.getValueFont());
+ newStyle.setValueHAlign(baseStyle.getValueHAlign());
+ newStyle.setValueVAlign(baseStyle.getValueVAlign());
+ newStyle.setImageScaleToFit(baseStyle.getImageScaleToFit());
+ }
+
+ if (inheritStyle != null)
+ {
+ if (newStyle.getBgColor() == null) { newStyle.setBgColor(inheritStyle.getBgColor()); }
+ if (newStyle.getBorder() == DEFAULT_BORDER) { newStyle.setBorder(inheritStyle.getBorder()); }
+ if (newStyle.getFont() == null) { newStyle.setFont(inheritStyle.getFont()); }
+ if (newStyle.getHAlign() == null) { newStyle.setHAlign(inheritStyle.getHAlign()); }
+ if (newStyle.getImageHAlign() == null) { newStyle.setImageHAlign(inheritStyle.getImageHAlign()); }
+ if (newStyle.getImageVAlign() == null) { newStyle.setImageVAlign(inheritStyle.getImageVAlign()); }
+ if (newStyle.getPadding() == DEFAULT_PADDING) { newStyle.setPadding(inheritStyle.getPadding()); }
+ if (newStyle.getVAlign() == null) { newStyle.setVAlign(inheritStyle.getVAlign()); }
+ if (newStyle.getValueFont() == null) { newStyle.setValueFont(inheritStyle.getValueFont()); }
+ if (newStyle.getValueHAlign() == null) { newStyle.setValueHAlign(inheritStyle.getValueHAlign()); }
+ if (newStyle.getValueVAlign() == null) { newStyle.setValueVAlign(inheritStyle.getValueVAlign()); }
+ if (newStyle.getImageScaleToFit() == null) { newStyle.setImageScaleToFit(inheritStyle.getImageScaleToFit()); }
+ }
+
+ return newStyle;
+ }
+
+ protected static ImageScaleToFit parseImageScaleToFit (String imageScaleToFit)
+ {
+ if (imageScaleToFit == null || imageScaleToFit.length() == 0 || imageScaleToFit.trim().length() == 0)
+ {
+ return null;
+ }
+
+ String [] dimensions = imageScaleToFit.split(";");
+ if (dimensions.length != 2)
+ {
+ return null;
+ }
+
+ float width = Float.parseFloat(dimensions[0]);
+ float height = Float.parseFloat(dimensions[0]);
+
+ return new ImageScaleToFit(width, height);
+ }
+
+ /**
+ * Holds the width and the height an image can be scaled to fit.
+ *
+ * @author wprinz
+ */
+ public static class ImageScaleToFit
+ {
+ /**
+ * The width.
+ */
+ protected float width;
+
+ /**
+ * The height.
+ */
+ protected float height;
+
+ /**
+ * Constructor.
+ *
+ * @param width The width.
+ * @param height The height.
+ */
+ public ImageScaleToFit(float width, float height)
+ {
+ this.width = width;
+ this.height = height;
+ }
+
+ /**
+ * Returns the width.
+ * @return Returns the width.
+ */
+ public float getWidth()
+ {
+ return this.width;
+ }
+
+ /**
+ * Sets the width.
+ * @param width The width to set.
+ */
+ public void setWidth(float width)
+ {
+ this.width = width;
+ }
+
+ /**
+ * Returns the height.
+ * @return Returns the height.
+ */
+ public float getHeight()
+ {
+ return this.height;
+ }
+
+ /**
+ * Sets the height.
+ * @param height The height to set.
+ */
+ public void setHeight(float height)
+ {
+ this.height = height;
+ }
+
+ }
+} \ No newline at end of file
diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Table.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Table.java
new file mode 100644
index 00000000..c5a0c58f
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Table.java
@@ -0,0 +1,223 @@
+/**
+ * <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.
+ *
+ * $Id: Table.java,v 1.2 2006/08/25 17:08:19 wprinz Exp $
+ */
+package at.knowcenter.wag.egov.egiz.table;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.ArrayList;
+
+/**
+ * This class implements an abstract table definition. The table contains table
+ * rows and the table rows contains the table entries. A table can be styled and
+ * a relative column width can be set.
+ *
+ * @author wlackner
+ * @see Style
+ * @see at.knowcenter.wag.egov.egiz.table.Entry
+ */
+public class Table implements Serializable
+{
+
+ /**
+ * SVUID.
+ */
+ private static final long serialVersionUID = 8488947943674086618L;
+
+ /**
+ * The table column settings.
+ */
+ private float[] colsRelativeWith_ = null;
+
+ /**
+ * The row definitions.
+ */
+ private Map rows_ = new HashMap();
+
+ /**
+ * The table width.
+ */
+ private float width_ = 100;
+
+ /**
+ * The table style.
+ */
+ private Style style_ = null;
+
+ /**
+ * Number of columns that are defined for the current table.
+ */
+ private int maxCols_ = 0;
+
+ /**
+ * A table name.
+ */
+ private String name_ = null;
+
+ /**
+ * The table constructor init by a table name.
+ *
+ * @param name
+ * the name for the table.
+ */
+ public Table(String name)
+ {
+ name_ = name;
+ }
+
+ /**
+ * The width of the columns are relative to each other. This means the values
+ * are summarized and divided into portions of columns used. <br>
+ * Example: <code>[1,4]</code> means the second column is four times wider
+ * than the first column.
+ *
+ * @return Returns the relative width of the columns
+ */
+ public float[] getColsRelativeWith()
+ {
+ return colsRelativeWith_;
+ }
+
+ /**
+ * The width of the columns are relative to each other. This means the values
+ * are summarized and divided into portions of columns used. <br>
+ * Example: <code>[10,90]</code> means the first colum consumes 10% and the
+ * second column consumes 90% of the table width. <br>
+ * The relative width of the columns to set.
+ */
+ public void setColsRelativeWith(float[] cols)
+ {
+ colsRelativeWith_ = cols;
+ }
+
+ /**
+ * @return Returns the style.
+ */
+ public Style getStyle()
+ {
+ return style_;
+ }
+
+ /**
+ * @param style
+ * The style to set.
+ */
+ public void setStyle(Style style)
+ {
+ style_ = style;
+ }
+
+ /**
+ * @return Returns the width.
+ */
+ public float getWidth()
+ {
+ return width_;
+ }
+
+ /**
+ * @param width
+ * The width to set.
+ */
+ public void setWidth(float width)
+ {
+ width_ = width;
+ }
+
+ /**
+ * @return Returns the maxCols.
+ */
+ public int getMaxCols()
+ {
+ return maxCols_;
+ }
+
+ /**
+ * @return Returns the name.
+ */
+ public String getName()
+ {
+ return name_;
+ }
+
+ /**
+ * This method returns a sorted row list beginning with the row number 1. The
+ * entrys in a row also stored in a <code>{@link java.util.ArrayList}</code>.
+ *
+ * @return Returns the sorted (by row number) table rows.
+ */
+ public ArrayList getRows()
+ {
+ ArrayList rows = new ArrayList();
+ for (int row_idx = 1; row_idx <= rows_.size(); row_idx++)
+ {
+ ArrayList row = (ArrayList) rows_.get("" + row_idx);
+ rows.add(row);
+ }
+ return rows;
+ }
+
+ /**
+ * Add a comlete table row to the current table. Be carefull usding the
+ * correct row number because no check is done if a row with the given row
+ * number does exist! In that case the stored row would be replaced!
+ *
+ * @param rowNumber
+ * the row number to store the row entries
+ * @param row
+ * the entry list to store
+ */
+ public void addRow(String rowNumber, ArrayList row)
+ {
+ rows_.put(rowNumber, row);
+ if (row.size() > maxCols_)
+ {
+ maxCols_ = row.size();
+ }
+ }
+
+ /**
+ * The toString method, used for tests or debugging.
+ */
+ public String toString()
+ {
+ String the_string = "\n#### TABLE " + name_ + " BEGIN #####";
+ the_string += " Width:" + width_ + " max cols:" + maxCols_ + " cols:" + colsRelativeWith_;
+ the_string += "\nStyle:" + style_;
+ ArrayList rows = getRows();
+ for (int row_idx = 0; row_idx < rows.size(); row_idx++)
+ {
+ ArrayList row = (ArrayList) rows.get(row_idx);
+ String row_prefix = "\n ++ ROW " + row_idx + " ++ ";
+ for (int entry_idx = 0; entry_idx < row.size(); entry_idx++)
+ {
+ the_string += row_prefix + ((Entry) row.get(entry_idx)).toString();
+ }
+ }
+ the_string += "\n#### TABLE " + name_ + " END #####";
+ return the_string;
+ }
+} \ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index e9bc3cf7..f439cf3c 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,2 +1,2 @@
-include "signature-standards:sigs-pades", "pdf-as-lib"
+include "pdf-as-common", "stamper:stmp-itext", "signature-standards:sigs-pades", "pdf-as-lib", "pdf-as-cli"
diff --git a/signature-standards/sigs-pades/build.gradle b/signature-standards/sigs-pades/build.gradle
index 4aee14ee..58151a7e 100644
--- a/signature-standards/sigs-pades/build.gradle
+++ b/signature-standards/sigs-pades/build.gradle
@@ -13,6 +13,7 @@ repositories {
dependencies {
compile project (':pdf-as-lib')
+ compile project (':pdf-as-common')
compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
testCompile group: 'junit', name: 'junit', version: '4.+'
}
diff --git a/stamper/stmp-itext/.gitignore b/stamper/stmp-itext/.gitignore
new file mode 100644
index 00000000..5e56e040
--- /dev/null
+++ b/stamper/stmp-itext/.gitignore
@@ -0,0 +1 @@
+/bin
diff --git a/stamper/stmp-itext/build.gradle b/stamper/stmp-itext/build.gradle
new file mode 100644
index 00000000..1495d8af
--- /dev/null
+++ b/stamper/stmp-itext/build.gradle
@@ -0,0 +1,32 @@
+apply plugin: 'java'
+apply plugin: 'eclipse'
+
+jar {
+ manifest {
+ attributes 'Implementation-Title': 'PDF-AS Stamper with itext', 'Implementation-Version': version
+ }
+}
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ compile project (':pdf-as-lib')
+ compile project (':pdf-as-common')
+ compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
+ compile group: 'com.lowagie', name: 'itext', version: '4.2.0'
+ testCompile group: 'junit', name: 'junit', version: '4.+'
+}
+
+test {
+ systemProperties 'property': 'value'
+}
+
+uploadArchives {
+ repositories {
+ flatDir {
+ dirs 'repos'
+ }
+ }
+}
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
new file mode 100644
index 00000000..5c0fb7df
--- /dev/null
+++ b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextStamper.java
@@ -0,0 +1,506 @@
+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.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.Entry;
+import at.knowcenter.wag.egov.egiz.table.Style;
+import at.knowcenter.wag.egov.egiz.table.Table;
+
+import com.lowagie.text.*;
+import com.lowagie.text.pdf.*;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class ITextStamper implements IPDFStamper {
+
+ private static final Logger logger = LoggerFactory.getLogger(ITextStamper.class);
+
+ /**
+ * The default font definition
+ */
+ private static Font DEFAULT_FONT = new Font(Font.HELVETICA, 8, Font.NORMAL);
+
+ private ISettings settings;
+
+ /**
+ * This method visualize an abstract table into a corresponding pdf table. The
+ * new pdf table is redered and get the style information from the abstract
+ * cell.
+ *
+ * @param abstractTable
+ * the abstract table definition
+ * @return the new redererd pdf table cell
+ * @throws PdfAsException
+ * ErrorCode:220, 221, 222, 223
+ * @see com.lowagie.text.pdf.PdfPTable
+ * @see at.knowcenter.wag.egov.egiz.table.Table
+ */
+ private PdfPTable renderTable(Table abstractTable) throws PdfAsException
+ {
+ if (abstractTable == null)
+ {
+ PdfAsException pde = new PdfAsException("Table is not defined.");
+ throw pde;
+ }
+ PdfPTable pdf_table = null;
+ float[] cols = abstractTable.getColsRelativeWith();
+ int max_cols = abstractTable.getMaxCols();
+ if (cols == null)
+ {
+ cols = new float[max_cols];
+ // set the column ratio for all columns to 1
+ for (int cols_idx = 0; cols_idx < cols.length; cols_idx++)
+ {
+ cols[cols_idx] = 1;
+ }
+ }
+ pdf_table = new PdfPTable(cols);
+ pdf_table.setWidthPercentage(abstractTable.getWidth());
+ Style table_style = abstractTable.getStyle();
+ setCellStyle(pdf_table.getDefaultCell(), table_style, Entry.TYPE_TABLE);
+
+ ArrayList rows = abstractTable.getRows();
+ for (int row_idx = 0; row_idx < rows.size(); row_idx++)
+ {
+ ArrayList row = (ArrayList) rows.get(row_idx);
+ logger.debug("## Row:" + row_idx + " ## of table:" + abstractTable.getName());
+ for (int entry_idx = 0; entry_idx < row.size(); entry_idx++)
+ {
+ Entry cell = (Entry) row.get(entry_idx);
+ // 03.11.2010 changed by exthex - swapped the two params, was probably a bug
+ Style inherit_style = Style.doInherit(table_style, cell.getStyle());
+ cell.setStyle(inherit_style);
+ logger.debug(cell.toString());
+ PdfPCell pdf_cell = renderCell(cell);
+ if (cell.getColSpan() > 1)
+ {
+ pdf_cell.setColspan(cell.getColSpan());
+ }
+ if (cell.isNoWrap())
+ {
+ pdf_cell.setNoWrap(true);
+ }
+ // System.err.println("valign:" + pdf_cell.getVerticalAlignment() + "
+ // halign:" +
+ // pdf_cell.getHorizontalAlignment());
+ pdf_table.addCell(pdf_cell);
+ }
+ pdf_table.completeRow();
+ }
+ logger.debug("render table:" + abstractTable.getName());
+ return pdf_table;
+ }
+
+ /**
+ * Map the style align definitions to IText's align statements
+ */
+ private static HashMap<String, Integer> alignMap_ = new HashMap<String, Integer>();
+
+ /**
+ * Map the font definitions to IText's font statements
+ */
+ private static HashMap<String, Integer> fontMap_ = new HashMap<String, Integer>();
+
+ static {
+ initStyleMaps();
+ }
+
+ /**
+ * This method initialize the style maps. It maps the style style definitions
+ * to IText styles.
+ */
+ private static void initStyleMaps()
+ {
+ alignMap_.put(Style.TOP, new Integer(Element.ALIGN_TOP));
+ alignMap_.put(Style.MIDDLE, new Integer(Element.ALIGN_MIDDLE));
+ alignMap_.put(Style.BOTTOM, new Integer(Element.ALIGN_BOTTOM));
+ alignMap_.put(Style.LEFT, new Integer(Element.ALIGN_LEFT));
+ alignMap_.put(Style.CENTER, new Integer(Element.ALIGN_CENTER));
+ alignMap_.put(Style.RIGHT, new Integer(Element.ALIGN_RIGHT));
+
+ fontMap_.put(Style.HELVETICA, new Integer(Font.HELVETICA));
+ fontMap_.put(Style.TIMES_ROMAN, new Integer(Font.TIMES_ROMAN));
+ fontMap_.put(Style.COURIER, new Integer(Font.COURIER));
+ fontMap_.put(Style.NORMAL, new Integer(Font.NORMAL));
+ fontMap_.put(Style.BOLD, new Integer(Font.BOLD));
+ fontMap_.put(Style.ITALIC, new Integer(Font.ITALIC));
+ fontMap_.put(Style.BOLDITALIC, new Integer(Font.BOLDITALIC));
+ fontMap_.put(Style.UNDERLINE, new Integer(Font.UNDERLINE));
+ fontMap_.put(Style.STRIKETHRU, new Integer(Font.STRIKETHRU));
+ }
+
+ /**
+ * This method maps the table cell definitions to the pdfCell element.
+ *
+ * @param pdfCell
+ * the pdf cell to be styled
+ * @param cellStyle
+ * the abstract style definition
+ * @param type
+ * type of the cell to render - the appropriate style will be set
+ * @see com.lowagie.text.pdf.PdfPCell
+ * @see at.knowcenter.wag.egov.egiz.table.Style
+ */
+ private void setCellStyle(PdfPCell pdfCell, Style cellStyle, int type)
+ {
+ if (cellStyle != null)
+ {
+ if (cellStyle.getBgColor() != null)
+ {
+ pdfCell.setBackgroundColor(cellStyle.getBgColor());
+ }
+ pdfCell.setPadding(cellStyle.getPadding());
+ //exthex - fix for not exactly vertically centered text
+ pdfCell.setUseAscender(true);
+
+ if (cellStyle.getBorder() > 0)
+ {
+ pdfCell.setBorderWidth(cellStyle.getBorder());
+ }
+ else
+ {
+ pdfCell.setBorder(0);
+ }
+ int align = -1;
+ if (type == Entry.TYPE_VALUE && cellStyle.getValueVAlign() != null)
+ align = ((Integer) alignMap_.get(cellStyle.getValueVAlign())).intValue();
+ //Note: to change the default valign of images to those of values, change the if construct below
+ else if (type == Entry.TYPE_IMAGE && cellStyle.getImageVAlign() != null)
+ align = ((Integer) alignMap_.get(cellStyle.getImageVAlign())).intValue();
+ else if (cellStyle.getVAlign() != null)
+
+ if(alignMap_.get(cellStyle.getVAlign()) == null) {
+ align = -1;
+ } else {
+ align = alignMap_.get(cellStyle.getVAlign()).intValue();
+ }
+ if (align != -1)
+ pdfCell.setVerticalAlignment(align);
+
+ align = -1;
+ if (type == Entry.TYPE_VALUE && cellStyle.getValueHAlign() != null)
+ align = ((Integer) alignMap_.get(cellStyle.getValueHAlign())).intValue();
+ //Note: to change the default halign of images to those of values, change the if construct below
+ else if (type == Entry.TYPE_IMAGE && cellStyle.getImageHAlign() != null)
+ align = ((Integer) alignMap_.get(cellStyle.getImageHAlign())).intValue();
+ else if (cellStyle.getHAlign() != null)
+ align = ((Integer) alignMap_.get(cellStyle.getHAlign())).intValue();
+ if (align != -1)
+ pdfCell.setHorizontalAlignment(align);
+ }
+ }
+
+ /**
+ * Creates a custom
+ * @param fontString
+ * @return
+ * @throws PdfAsException
+ */
+ private Font getCellTrueTypeFont(String fontString) throws PdfAsException {
+ float fontSize=8;
+ String fontName = fontString.replaceFirst("TTF:", "");
+ String[] split = fontName.split(",");
+ if(split.length>1)
+ {
+ fontName = split[0].trim();
+ try
+ {
+ fontSize = Float.parseFloat(split[1].trim());
+ }catch (NumberFormatException e)
+ {
+ logger.error("Unable to parse fontsize:"+fontString);
+ }
+ }
+ logger.debug("TrueType Font detected:"+fontName +" ("+fontSize+")");
+
+ //try {
+
+ Font font = new Font(fontMap_.get(fontString));
+ //Font font = (Font) fontMap_.get(fontString);
+
+ // TODO: implement FONT resources via settings path!
+ /*if (font == null) {
+ logger.debug("Font \"" + fontString + "\" not in cache. Instantiating font.");
+ String fontPath = SettingsReader.RESOURCES_PATH + "fonts" + File.separator + fontName;
+ logger.debug("Instantiating \"" + fontPath + "\".");
+
+ font = new Font(BaseFont.createFont(fontPath, BaseFont.WINANSI, true), fontSize);
+ fontMap_.put(fontString, font);
+ } */
+ return font;
+ // } catch (DocumentException e) {
+ // throw new PdfAsException(e.getMessage());
+ //} catch (IOException e) {
+ // throw new PdfAsException(e.getMessage());
+ //}
+ }
+
+
+ /**
+ * This method maps the cell font definition to the iText Font Object
+ *
+ * @param fontString
+ * @return the corresponding iText Font Object
+ * @see com.lowagie.text.Font
+ */
+ private Font getCellFont(String fontString)
+ {
+ Font font = DEFAULT_FONT;
+ if (fontString == null)
+ {
+ return font;
+ }
+ Object cache_font = fontMap_.get(fontString);
+ if (cache_font != null)
+ {
+ return (Font) cache_font;
+ }
+ String[] font_arr = fontString.split(",");
+ if (font_arr.length != 3)
+ {
+ return font;
+ }
+ Object font_face = fontMap_.get(font_arr[0]);
+ if (font_face == null)
+ {
+ return font;
+ }
+ Object font_weight = fontMap_.get(font_arr[2]);
+ if (font_weight == null)
+ {
+ return font;
+ }
+ int face = ((Integer) font_face).intValue();
+ float height = Float.parseFloat(font_arr[1]);
+ int weight = ((Integer) font_weight).intValue();
+
+ font = new Font(face, height, weight);
+ //fontMap_.put(fontString, font);
+ return font;
+ }
+
+ /**
+ * This method visualize an abstract table cell into a corresponding pdf table
+ * cell. The new pdf table cell is redered and get the style information from
+ * the abstract cell. Following types can be rendered:
+ * <ul>
+ * <li>text statements</li>
+ * <li>images</li>
+ * <li>tables</li>
+ * </ul>
+ *
+ * @param abstractCell
+ * the abstract cell definition
+ * @return the new redererd pdf table cell
+ * @throws PdfAsException
+ * ErrorCode:220, 221, 222
+ * @see com.lowagie.text.pdf.PdfPCell
+ * @see at.knowcenter.wag.egov.egiz.table.Entry
+ */
+ private PdfPCell renderCell(Entry abstractCell) throws PdfAsException
+ {
+ // TODO: read if signature should be PDF/A compatible!!
+ boolean pdfaValid = false;//PDFASUtils.isPdfAEnabled(sigObject_.getSignatureTypeDefinition().getType());
+
+ PdfPCell pdf_cell = null;
+ Style cell_style = abstractCell.getStyle();
+ boolean isValue = true;
+ switch (abstractCell.getType())
+ {
+ case Entry.TYPE_CAPTION:
+ isValue = false;
+ case Entry.TYPE_VALUE:
+ String text = (String) abstractCell.getValue();
+ if (text == null)
+ {
+ text = "";
+ }
+ String font_string = cell_style.getFont();
+ if (abstractCell.getType() == Entry.TYPE_VALUE && cell_style.getValueFont() != null)
+ {
+ font_string = cell_style.getValueFont();
+ }
+
+ logger.trace("using cell font: "+font_string);
+
+ Font cell_font;
+ if(font_string.startsWith("TTF:"))
+ {
+ cell_font = getCellTrueTypeFont(font_string);
+ }
+ else
+ {
+ if (pdfaValid) {
+ throw new PdfAsException("PDF/A modus requires an embedable true type font");
+ }
+ cell_font = getCellFont(font_string);
+
+ }
+ //TODO: check and maybe remove ...
+ // exthex
+ //if (pdfaValid && abstractCell.getType() == Entry.TYPE_VALUE) {
+ // SubsetLocal.addNonSubsetFont(cell_font.getBaseFont());
+ //}
+ Phrase text_phrase = new Phrase(text, cell_font);
+ pdf_cell = new PdfPCell(text_phrase);
+ setCellStyle(pdf_cell, cell_style, (isValue?Entry.TYPE_VALUE:Entry.TYPE_CAPTION));
+ break;
+ case Entry.TYPE_IMAGE:
+ try
+ {
+ String img_ref = (String) abstractCell.getValue();
+ // fixed by tknall start
+ File img_file = new File(img_ref);
+ if (!img_file.isAbsolute()) {
+ logger.debug("Image file declaration is relative. Prepending path of resources directory.");
+ //TODO: implement settings ....
+ img_file = new File(settings.getWorkingDirectory() + File.separator + img_ref);
+ } else {
+ logger.debug("Image file declaration is absolute. Skipping file relocation.");
+ }
+// String img_location = SettingsReader.relocateFile(img_ref);
+// File img_file = new File (img_location);
+ if (!img_file.exists())
+ {
+ logger.debug("Image file \"" + img_file.getCanonicalPath() + "\" doesn't exist.");
+ throw new PdfAsException("Image file \"" + img_file.getCanonicalPath() + "\" doesn't exist.");
+ }
+ Image image = Image.getInstance(img_file.getCanonicalPath());
+ logger.debug("Using image file \"" + img_file.getCanonicalPath() + "\".");
+
+ image.scaleToFit(80.0f, 80.0f);
+ boolean fit = true;
+ Style.ImageScaleToFit istf = cell_style.getImageScaleToFit();
+ if (istf != null)
+ {
+ image.scaleToFit(istf.getWidth(), istf.getHeight());
+ fit = false;
+ }
+ pdf_cell = new PdfPCell(image, fit);
+ setCellStyle(pdf_cell, cell_style, Entry.TYPE_IMAGE);
+ }
+ catch (BadElementException e)
+ {
+ logger.error("BadElementException:" + e.getMessage());
+ PdfAsException pde = new PdfAsException("Unable to create PDF table.");
+ throw pde;
+ }
+ catch (MalformedURLException e)
+ {
+ logger.error("MalformedURLException:" + e.getMessage());
+ PdfAsException pde = new PdfAsException("Unable to create PDF table.");
+ throw pde;
+ }
+ catch (IOException e)
+ {
+ logger.error("Error Code: 222, IOException:" + e.getMessage());
+ PdfAsException pde = new PdfAsException("Unable to create PDF table, unable to load image.");
+ throw pde;
+ }
+ break;
+ case Entry.TYPE_TABLE:
+ Table table = (Table) abstractCell.getValue();
+ // inherit the style from the parent table
+ Style inherit_style = Style.doInherit(table.getStyle(), cell_style);
+ table.setStyle(inherit_style);
+ PdfPTable pdf_table = renderTable(table);
+ pdf_cell = new PdfPCell(pdf_table);
+ // The default new PdfPCell has a default border of 15.
+ // For blocks without border and subtables this results
+ // in a border to be drawn around the cell.
+ // ==> no border on default
+ pdf_cell.setBorder(0);
+ break;
+ }
+ return pdf_cell;
+ }
+
+ public IPDFVisualObject createVisualPDFObject(PDFObject pdf, Table table) {
+
+ // TODO: Adapt PDFSignatureObjectIText to render PDFPTable to iTextVisualObject from table
+ try {
+ PdfPTable pdfPTable = renderTable(table);
+
+ ITextVisualObject iTextVisualObject = new ITextVisualObject(pdfPTable);
+
+ return iTextVisualObject;
+ } catch (PdfAsException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public byte[] writeVisualObject(IPDFVisualObject visualObject, PositioningInstruction positioningInstruction,
+ byte[] pdfData) throws PdfAsException {
+ try {
+
+ ITextVisualObject object = null;
+ if(visualObject instanceof ITextVisualObject) {
+ object = (ITextVisualObject)visualObject;
+ }
+
+ if(object == null) {
+ //TODO: exception!
+ return null;
+ }
+
+ PdfReader reader = new PdfReader(pdfData);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ PdfStamper stamper = new PdfStamper(reader, baos, reader.getPdfVersion(), true);
+
+ int pages = reader.getNumberOfPages();
+ int targetPage = positioningInstruction.getPage();
+
+ // TODO: maybe add new page ...
+ if(positioningInstruction.isMakeNewPage()) {
+ Rectangle rect = reader.getPageSize(pages);
+ stamper.insertPage(pages + 1, new Rectangle(rect));
+ targetPage = pages + 1;
+ }
+
+ if (positioningInstruction.getPage() < 1 ||
+ positioningInstruction.getPage() > stamper.getReader().getNumberOfPages())
+ {
+ throw new PdfAsException("The provided page (=" +
+ positioningInstruction.getPage() + ") is out of range.");
+ }
+
+ PdfContentByte content = stamper.getOverContent(targetPage);
+
+ PdfPTable table = object.getTable();
+
+ table.writeSelectedRows(0, -1, positioningInstruction.getX(),
+ positioningInstruction.getY(), content);
+
+ stamper.close();
+
+ baos.close();
+
+ return baos.toByteArray();
+
+ } catch (IOException e) {
+ logger.error(e.getMessage(), e);
+ } catch (DocumentException e) {
+ logger.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ public void setSettings(ISettings settings) {
+ this.settings = settings;
+ }
+} \ No newline at end of file
diff --git a/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextVisualObject.java b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextVisualObject.java
new file mode 100644
index 00000000..76b8b0fc
--- /dev/null
+++ b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextVisualObject.java
@@ -0,0 +1,61 @@
+package at.gv.egiz.pdfas.stmp.itext;
+
+import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject;
+import at.knowcenter.wag.egov.egiz.pdf.Pos;
+import com.lowagie.text.pdf.PdfPTable;
+
+public class ITextVisualObject implements IPDFVisualObject {
+
+ private PdfPTable table;
+ private float x;
+ private float y;
+ private int page;
+
+ public ITextVisualObject(PdfPTable table) {
+ this.table = table;
+ }
+
+ public void setWidth(float width) {
+ table.setTotalWidth(width);
+ }
+
+ public void fixWidth() {
+ table.setLockedWidth(true);
+ }
+
+ public float getHeight() {
+ return this.table.getTotalHeight();
+ }
+
+ public float getWidth() {
+ return this.table.getTotalWidth();
+ }
+
+ 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 PdfPTable getTable() {
+ return table;
+ }
+}
diff --git a/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/package-info.java b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/package-info.java
new file mode 100644
index 00000000..53f799b4
--- /dev/null
+++ b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/package-info.java
@@ -0,0 +1,2 @@
+
+package at.gv.egiz.pdfas.stmp.itext; \ No newline at end of file