From d85cbb74b8fe9c2bcc31a4b55ad17ae889d6b578 Mon Sep 17 00:00:00 2001
From: Andreas Fitzek <andreas.fitzek@iaik.tugraz.at>
Date: Thu, 26 Sep 2013 15:49:26 +0200
Subject: forgotten changes for initial code commit

---
 .../gv/egiz/pdfas/lib/api/ByteArrayDataSource.java |  19 ++
 .../pdfas/lib/api/IConfigurationConstants.java     |   3 +-
 .../at/gv/egiz/pdfas/lib/api/PdfAsFactory.java     |  11 +-
 .../java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java  | 163 ++++++++---
 .../lib/impl/configuration/ConfigurationImpl.java  |  20 +-
 .../SignatureProfileConfiguration.java             |   5 +
 .../lib/impl/stamping/CertificateResolver.java     |  46 +++
 .../egiz/pdfas/lib/impl/stamping/IPDFStamper.java  |   3 +
 .../gv/egiz/pdfas/lib/impl/stamping/IResolver.java |  14 +
 .../pdfas/lib/impl/stamping/StamperFactory.java    |   7 +-
 .../egiz/pdfas/lib/impl/stamping/TableFactory.java | 307 +++++++++++++++++++++
 .../pdfas/lib/impl/stamping/ValueResolver.java     |  64 +++++
 .../pdfas/lib/impl/status/RequestedSignature.java  |   4 +
 13 files changed, 624 insertions(+), 42 deletions(-)
 create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/ByteArrayDataSource.java
 create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/CertificateResolver.java
 create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IResolver.java
 create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/TableFactory.java
 create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/ValueResolver.java

(limited to 'pdf-as-lib/src/main/java/at')

diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/ByteArrayDataSource.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/ByteArrayDataSource.java
new file mode 100644
index 00000000..72c02b08
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/ByteArrayDataSource.java
@@ -0,0 +1,19 @@
+package at.gv.egiz.pdfas.lib.api;
+
+public class ByteArrayDataSource implements IDataSource {
+
+    private byte[] byteData;
+
+    public ByteArrayDataSource(byte[] data)  {
+        this.byteData = data;
+    }
+
+    public String getMIMEType() {
+        return "application/pdf";
+    }
+
+    public byte[] getByteData() {
+        return this.byteData;
+    }
+
+}
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
index 9a8d773a..59515937 100644
--- 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
@@ -6,8 +6,9 @@ public interface IConfigurationConstants {
 	
 	public static final String SIG_OBJECT = "sig_obj";
 	public static final String TYPE = "type";
-	public static final String TABLE = "type";
+	public static final String TABLE = "table";
 	public static final String MAIN = "main";
+	public static final String POS = "pos";
 	public static final String DEFAULT = "default";
 	public static final String SEPERATOR = ".";
 	
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java
index ae9388eb..444480cf 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java
@@ -2,8 +2,17 @@ package at.gv.egiz.pdfas.lib.api;
 
 import java.io.File;
 
+import org.apache.log4j.PropertyConfigurator;
+
+import at.gv.egiz.pdfas.lib.impl.PdfAsImpl;
+
 public class PdfAsFactory {
+	
+	static {
+		PropertyConfigurator.configure(ClassLoader.getSystemResourceAsStream("resources/log4j.properties"));
+	}
+	
 	public static PdfAs createPdfAs(File configuration) {
-		return null;
+		return new PdfAsImpl(configuration);
 	}
 }
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java
index d7ed5f3a..e4132e91 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java
@@ -1,9 +1,18 @@
 package at.gv.egiz.pdfas.lib.impl;
 
+import java.io.ByteArrayInputStream;
+import java.io.File;
 import java.util.List;
 
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.exceptions.PdfAsSettingsException;
 import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.common.settings.Settings;
+import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings;
 import at.gv.egiz.pdfas.lib.api.Configuration;
 import at.gv.egiz.pdfas.lib.api.IConfigurationConstants;
 import at.gv.egiz.pdfas.lib.api.PdfAs;
@@ -13,48 +22,136 @@ 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.configuration.SignatureProfileConfiguration;
+import at.gv.egiz.pdfas.lib.impl.positioning.Positioning;
+import at.gv.egiz.pdfas.lib.impl.stamping.IPDFStamper;
+import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject;
+import at.gv.egiz.pdfas.lib.impl.stamping.StamperFactory;
+import at.gv.egiz.pdfas.lib.impl.stamping.TableFactory;
 import at.gv.egiz.pdfas.lib.impl.status.OperationStatus;
 import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;
+import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
+import at.knowcenter.wag.egov.egiz.pdf.TablePos;
+import at.knowcenter.wag.egov.egiz.table.Table;
 
 public class PdfAsImpl implements PdfAs, IConfigurationConstants {
 
+	 private static final Logger logger = LoggerFactory.getLogger(PdfAsImpl.class);
+	
+	private Settings settings;
+	
+	public PdfAsImpl(File cfgFile) {
+		logger.info("Initializing PDF-AS with config: " + cfgFile.getPath());
+		this.settings = new Settings(cfgFile);
+	}
+	
 	public SignResult sign(SignParameter parameter) throws PdfAsException {
-		// TODO: verify signParameter
+
+		logger.trace("sign started");
 		
-		// Status initialization
-		if(!(parameter.getConfiguration() instanceof ISettings)) {
+		// TODO: verify signParameter
+
+		try {
+			// Status initialization
+			if (!(parameter.getConfiguration() instanceof ISettings)) {
+				throw new PdfAsSettingsException("Invalid settings object!");
+			}
+						
+			ISettings settings = (ISettings) parameter.getConfiguration();
+			OperationStatus status = new OperationStatus(settings, parameter);
+			PlaceholderConfiguration placeholderConfiguration = status
+					.getPlaceholderConfiguration();
+
+			RequestedSignature requestedSignature = new RequestedSignature(
+					status);
+			// Only use this profileID because validation was done in
+			// RequestedSignature
+			String signatureProfileID = requestedSignature
+					.getSignatureProfileID();
+
+			logger.info("Selected signature Profile: " + signatureProfileID);
 			
-		}
-		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)
+			SignatureProfileConfiguration signatureProfileConfiguration = status
+					.getSignatureProfileConfiguration(signatureProfileID);
+
+			// set Original PDF Document Data
+			status.getPdfObject().setOriginalDocument(
+					parameter.getDataSource().getByteData());
 
-            // TODO:  PositioningStage (visual)  -> find position or use fixed position
+			// Placeholder search?
+			if (placeholderConfiguration.isGlobalPlaceholderEnabled()) {
+				// TODO: Do placeholder search
+			}
 
-            // TODO:  StampingStage (visual) -> stamp logical signature block to location (itext)
-		} else {
-			// Stamped Object is equal to original
-			status.getPdfObject().setStampedDocument(status.getPdfObject().getOriginalDocument());
+			// TODO get Certificate
+
+			if (requestedSignature.isVisual()) {
+				logger.info("Creating visual siganture block");
+				// ================================================================
+				// SignBlockCreationStage (visual) -> create visual signature
+				// block (logicaly)
+				SignatureProfileSettings signatureProfileSettings = TableFactory
+						.createProfile(signatureProfileID, settings);
+
+				Table main = TableFactory.createSigTable(
+						signatureProfileSettings, MAIN, settings);
+
+				IPDFStamper stamper = StamperFactory.createDefaultStamper(settings);
+				IPDFVisualObject visualObject = stamper.createVisualPDFObject(
+						status.getPdfObject(), main);
+
+				// ================================================================
+				// PositioningStage (visual) -> find position or use fixed
+				// position
+
+				String posString = status.getSignParamter()
+						.getSignaturePosition();
+
+				if (posString == null) {
+					posString = signatureProfileConfiguration
+							.getDefaultPositioning();
+				}
+
+				TablePos tablePos = null;
+
+				if (posString == null) {
+					tablePos = new TablePos();
+				} else {
+					tablePos = new TablePos(posString);
+				}
+
+				PDDocument originalDocument = PDDocument
+						.load(new ByteArrayInputStream(status.getPdfObject()
+								.getOriginalDocument()));
+
+				PositioningInstruction positioningInstruction = Positioning
+						.determineTablePositioning(tablePos, "",
+								originalDocument, visualObject);
+
+				// ================================================================
+				// StampingStage (visual) -> stamp logical signature block to
+				// location (itext)
+
+				byte[] incrementalUpdate = stamper.writeVisualObject(
+						visualObject, positioningInstruction, status
+								.getPdfObject().getOriginalDocument());
+				status.getPdfObject().setStampedDocument(incrementalUpdate);
+			} else {
+				logger.info("No visual siganture block");
+				// Stamped Object is equal to original
+				status.getPdfObject().setStampedDocument(
+						status.getPdfObject().getOriginalDocument());
+			}
+
+			// TODO: Create signature
+
+			return null;
+		} catch (Throwable e) {
+			logger.error("sign failed " + e.getMessage(), e);
+			throw new PdfAsException("sign Failed", e);
+		} finally {
+			logger.trace("sign done");
 		}
-		
-		// TODO: Create signature
-		
-		return null;
 	}
 
 	public List<VerifyResult> verify(VerifyParameter parameter) {
@@ -63,7 +160,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {
 	}
 
 	public Configuration getConfiguration() {
-		return new ConfigurationImpl();
+		return new ConfigurationImpl(this.settings);
 	}
-	
+
 }
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
index b901b597..9303036f 100644
--- 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
@@ -14,6 +14,12 @@ public class ConfigurationImpl implements ISettings, Configuration {
 
 	protected Properties overwrittenProperties = new Properties();
 	
+	protected Settings settings;
+	
+	public ConfigurationImpl(Settings settings) {
+		this.settings = settings;
+	}
+	
 	public void setValue(String key, String value) {
 		overwrittenProperties.setProperty(key, value);
 	}
@@ -22,7 +28,7 @@ public class ConfigurationImpl implements ISettings, Configuration {
 		if(overwrittenProperties.containsKey(key)) {
 			return overwrittenProperties.getProperty(key);
 		} else {
-			return Settings.getInstance().getValue(key);
+			return this.settings.getValue(key);
 		}
 	}
 
@@ -30,14 +36,14 @@ public class ConfigurationImpl implements ISettings, Configuration {
 		if(overwrittenProperties.containsKey(key)) {
 			return true;
 		} else {
-			return Settings.getInstance().hasValue(key);
+			return this.settings.hasValue(key);
 		}
 	}
 
 	public Map<String, String> getValuesPrefix(String prefix) {
 		
 		Map<String, String> valueMap = null;
-		valueMap = Settings.getInstance().getValuesPrefix(prefix);
+		valueMap = this.settings.getValuesPrefix(prefix);
 		if(valueMap == null) {
 			valueMap = new HashMap<String, String>();
 		}
@@ -61,7 +67,7 @@ public class ConfigurationImpl implements ISettings, Configuration {
 
 	public Vector<String> getFirstLevelKeys(String prefix) {
 		
-		Vector<String> valueMap = Settings.getInstance().getFirstLevelKeys(prefix);
+		Vector<String> valueMap = this.settings.getFirstLevelKeys(prefix);
 		if(valueMap == null) {
 			valueMap = new Vector<String>();
 		}
@@ -91,7 +97,7 @@ public class ConfigurationImpl implements ISettings, Configuration {
 
 	public boolean hasPrefix(String prefix) {
 		
-		if(Settings.getInstance().hasPrefix(prefix)) {
+		if(this.settings.hasPrefix(prefix)) {
 			return true;
 		}
 		
@@ -106,5 +112,9 @@ public class ConfigurationImpl implements ISettings, Configuration {
         return false;
 	}
 
+	public String getWorkingDirectory() {
+		return this.settings.getWorkingDirectory();
+	}
+
 	
 }
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
index d7792dca..8f09b495 100644
--- 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
@@ -18,4 +18,9 @@ public class SignatureProfileConfiguration extends SpecificBaseConfiguration
 		String key = SIG_OBJECT + SEPERATOR + profileID + SEPERATOR + TABLE + SEPERATOR + MAIN;
 		return this.configuration.hasPrefix(key);
 	}
+	
+	public String getDefaultPositioning() {
+		String key = SIG_OBJECT + SEPERATOR + profileID + SEPERATOR + TABLE + SEPERATOR + POS;
+		return this.configuration.getValue(key);
+	}
 }
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/CertificateResolver.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/CertificateResolver.java
new file mode 100644
index 00000000..f30c326d
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/CertificateResolver.java
@@ -0,0 +1,46 @@
+package at.gv.egiz.pdfas.lib.impl.stamping;
+
+import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings;
+import at.gv.egiz.pdfas.common.utils.DNUtils;
+import at.gv.egiz.pdfas.common.utils.OgnlUtils;
+import iaik.x509.X509Certificate;
+import ognl.OgnlContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.naming.InvalidNameException;
+import javax.naming.ldap.LdapName;
+import java.util.Map;
+
+public class CertificateResolver implements IResolver {
+
+    private static final Logger logger = LoggerFactory.getLogger(CertificateResolver.class);
+
+    private OgnlContext ctx;
+    private X509Certificate certificate;
+
+    public CertificateResolver(X509Certificate certificate) {
+        this.certificate = certificate;
+        this.ctx = new OgnlContext();
+
+        try {
+            Map<String, String> issuerDNMap = DNUtils.dnToMap(certificate.getIssuerDN().getName());
+            this.ctx.put("issuer", issuerDNMap);
+        } catch (InvalidNameException e) {
+            logger.error("Failed to build issuer Map", e);
+        }
+
+        try {
+            Map<String, String> subjectDNMap = DNUtils.dnToMap(certificate.getSubjectDN().getName());
+            this.ctx.put("subject", subjectDNMap);
+        } catch (InvalidNameException e) {
+            logger.error("Failed to build subject Map", e);
+        }
+
+    }
+
+    public String resolve(String key, String value, SignatureProfileSettings settings) {
+        return OgnlUtils.resolvsOgnlExpression(value, this.ctx);
+    }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java
index f1b59ceb..fce18ce7 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java
@@ -1,6 +1,7 @@
 package at.gv.egiz.pdfas.lib.impl.stamping;
 
 import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.settings.ISettings;
 import at.gv.egiz.pdfas.lib.impl.status.PDFObject;
 import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
 import at.knowcenter.wag.egov.egiz.table.Table;
@@ -9,4 +10,6 @@ public interface IPDFStamper {
     public IPDFVisualObject createVisualPDFObject(PDFObject pdf, Table table);
     public byte[] writeVisualObject(IPDFVisualObject visualObject, PositioningInstruction positioningInstruction,
                                     byte[] pdfData) throws PdfAsException;
+    
+    public void setSettings(ISettings settings);
 }
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IResolver.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IResolver.java
new file mode 100644
index 00000000..040daf33
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IResolver.java
@@ -0,0 +1,14 @@
+package at.gv.egiz.pdfas.lib.impl.stamping;
+
+import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: afitzek
+ * Date: 9/11/13
+ * Time: 1:44 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public interface IResolver {
+    public String resolve(String key, String value, SignatureProfileSettings settings);
+}
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
index 1720057a..f04a955a 100644
--- 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
@@ -1,16 +1,19 @@
 package at.gv.egiz.pdfas.lib.impl.stamping;
 
 import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.settings.ISettings;
 
 public class StamperFactory {
 
 	public static final String DEFAULT_STAMPER_CLASS = "at.gv.egiz.pdfas.stmp.itext.ITextStamper";
 
-	public static IPDFStamper createDefaultStamper() throws PdfAsException {
+	public static IPDFStamper createDefaultStamper(ISettings settings) throws PdfAsException {
 		try {
 			Class<? extends IPDFStamper> cls = (Class<? extends IPDFStamper>) 
 					Class.forName(DEFAULT_STAMPER_CLASS);
-			return cls.newInstance();
+			IPDFStamper stamper = cls.newInstance();
+			stamper.setSettings(settings);
+			return stamper;
 		} 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/TableFactory.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/TableFactory.java
new file mode 100644
index 00000000..45b8b711
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/TableFactory.java
@@ -0,0 +1,307 @@
+package at.gv.egiz.pdfas.lib.impl.stamping;
+
+import at.gv.egiz.pdfas.common.settings.IProfileConstants;
+import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings;
+import at.knowcenter.wag.egov.egiz.pdf.sig.SignatureEntry;
+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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+import static at.gv.egiz.pdfas.common.utils.StringUtils.extractLastID;
+
+public class TableFactory implements IProfileConstants {
+
+    private static final Logger logger = LoggerFactory.getLogger(TableFactory.class);
+
+    /**
+     * The default style definition for images.
+     */
+    private static Style defaultImageStyle_ = new Style();
+
+    /**
+     * The default style definition for captions.
+     */
+    private static Style defaultCaptionStyle_ = new Style();
+
+    /**
+     * The default style definition for values.
+     */
+    private static Style defaultValueStyle_ = new Style();
+
+    /**
+     * Reference from signature key to there corresponding value
+     */
+    private static Hashtable sigEntries_ = new Hashtable(8);
+
+    static {
+        setDefaultStyles();
+    }
+
+    /**
+     * This method set the default styles for images, captions and values.
+     */
+    private static void setDefaultStyles()
+    {
+        defaultImageStyle_.setPadding(3);
+        defaultImageStyle_.setHAlign(Style.CENTER);
+        defaultImageStyle_.setVAlign(Style.MIDDLE);
+
+        defaultCaptionStyle_.setHAlign(Style.CENTER);
+        defaultCaptionStyle_.setVAlign(Style.MIDDLE);
+
+        defaultValueStyle_.setHAlign(Style.LEFT);
+        defaultValueStyle_.setVAlign(Style.MIDDLE);
+    }
+
+    /**
+     * This method creates an abstract signature table object. It takes all keys
+     * and values set by the signature object to create the corresponding abstract
+     * table object. The table definition is read from the settings file.
+     *
+     * @param tableID
+     *          is the name of the table definition in the settings file
+     * @return a new abstract signature table
+     * @see at.knowcenter.wag.egov.egiz.table.Style
+     * @see at.knowcenter.wag.egov.egiz.table.Table
+     * @see at.knowcenter.wag.egov.egiz.table.Entry
+     */
+    public static Table createSigTable(SignatureProfileSettings profile, String tableID, ISettings configuration )
+    {
+        String table_key_prefix = SIG_OBJ + profile.getProfileID() + "." + TABLE;
+        String table_key = table_key_prefix + tableID;
+        // String caption_prefix = SignatureTypes.SIG_OBJ + getSignationType() +
+        // ".key.";
+        // String value_prefix = SignatureTypes.SIG_OBJ + getSignationType() +
+        // ".value.";
+        // ArrayList table_def_keys = settings_.getKeys(table_key);
+        Vector<String> table_defs = configuration.getFirstLevelKeys(table_key);
+        if (table_defs == null)
+        {
+            return null;
+        }
+        Table sig_table = new Table(tableID);
+        //SignatureProfileSettings profile = createProfile(profileID);
+        boolean found_style = false;
+        Iterator<String> table_def_iter = table_defs.iterator();
+        while(table_def_iter.hasNext())
+        {
+            String table_def_key = table_def_iter.next();
+            int dot_idx = (table_def_key.lastIndexOf(".") > 0 ? table_def_key.lastIndexOf(".") + 1 : table_def_key.length());
+            String table_def = table_def_key.substring(dot_idx);
+            String table_def_keys_prefix = table_def_key.substring(0, dot_idx-1);
+            String table_def_string = configuration.getValue(table_def_key);
+            if (table_def.matches("\\D*"))
+            {
+                // if the table key is not a number (row number index)
+                if (COLS_WITH.equals(table_def))
+                {
+                    String[] cols_s = table_def_string.split(" ");
+                    float[] cols_f = new float[cols_s.length];
+                    for (int i = 0; i < cols_s.length; i++)
+                    {
+                        cols_f[i] = Float.parseFloat(cols_s[i]);
+                    }
+                    sig_table.setColsRelativeWith(cols_f);
+                }
+                if (STYLE.equals(table_def) && !found_style)
+                {
+                    Style style = readStyle(table_def_key, configuration);
+                    sig_table.setStyle(style);
+                    found_style = true;
+                }
+                continue;
+            }
+            if (table_def_string != null)
+            {
+                // analyse the row definition
+                String[] elems = table_def_string.split("\\|");
+                ArrayList row = new ArrayList();
+                for (int elem_idx = 0; elem_idx < elems.length; elem_idx++)
+                {
+                    String elem = elems[elem_idx];
+                    String[] key_type = elem.split("-");
+                    if (key_type.length < 2)
+                    {
+                        return null;
+                    }
+                    String key = key_type[0];
+                    String type = key_type[1];
+                    if (TYPE_TABLE.equals(key))
+                    {
+                        // add a table entry
+                        Table table = createSigTable(profile, type, configuration);
+                        if (table != null)
+                        {
+                            Entry entry = new Entry(Entry.TYPE_TABLE, table, key);
+                            row.add(entry);
+                        }
+                    }
+                    if (TYPE_IMAGE.equals(type))
+                    {
+                        // add an image entry
+                        String value = profile.getValue(key);
+                        if (value != null)
+                        {
+                            Entry entry = new Entry(Entry.TYPE_IMAGE, value, key);
+                            entry.setStyle(defaultImageStyle_);
+                            row.add(entry);
+                        } else {
+                            Entry entry = new Entry(Entry.TYPE_VALUE, "IMG MISSING", key);
+                            entry.setStyle(defaultValueStyle_);
+                            row.add(entry);
+                        }
+                    }
+                    if (TYPE_VALUE.equals(type))
+                    {
+                        // add a single value entry
+                        String value = profile.getValue(key);
+                        Entry entry = new Entry(Entry.TYPE_VALUE, value, key);
+                        if (entry != null)
+                        {
+                            entry.setColSpan(2);
+                            entry.setStyle(defaultValueStyle_);
+                            row.add(entry);
+                        }
+                    }
+                    if ((TYPE_VALUE + TYPE_CAPTION).equals(type) || (TYPE_CAPTION + TYPE_VALUE).equals(type))
+                    {
+                        // add a caption value pair
+                        String caption = profile.getCaption(key);
+                        String value = profile.getValue(key);
+                        //String caption = getSigCaption(key);
+                        //String value = getSigValue(key);
+                        if (value != null)
+                        {
+                            Entry c_entry = new Entry(Entry.TYPE_CAPTION, caption, key);
+                            c_entry.setNoWrap(true);  // dferbas fix bug #331
+                            c_entry.setStyle(defaultCaptionStyle_);
+
+                            Entry v_entry = new Entry(Entry.TYPE_VALUE, value, key);
+                            v_entry.setStyle(defaultValueStyle_);
+                            if (c_entry != null && v_entry != null)
+                            {
+                                row.add(c_entry);
+                                row.add(v_entry);
+                            }
+                        } else {
+                            // RESOLV VALUE!!
+                            Entry c_entry = new Entry(Entry.TYPE_CAPTION, caption, key);
+                            c_entry.setNoWrap(true);  // dferbas fix bug #331
+                            c_entry.setStyle(defaultCaptionStyle_);
+
+                            ValueResolver resolver = new ValueResolver();
+
+                            Entry v_entry = new Entry(Entry.TYPE_VALUE,
+                                    resolver.resolve(key, value, profile), key);
+                            v_entry.setStyle(defaultValueStyle_);
+                            if (c_entry != null && v_entry != null)
+                            {
+                                row.add(c_entry);
+                                row.add(v_entry);
+                            }
+                        }
+                    }
+                }
+                sig_table.addRow(table_def, row);
+            }
+        }
+
+        return sig_table;
+    }
+
+    public static SignatureProfileSettings createProfile(String profileID, ISettings configuration) {
+        return new SignatureProfileSettings(profileID, configuration);
+    }
+
+    /**
+     * This method returns a value for a given signature key. If the key equals to
+     * <code>SIG_NORM</code> and the value is <code>null</code> the version
+     * string of the current normalizer is returned!
+     *
+     * @param key
+     *          the key to get the value for
+     * @return a value for the given key
+     */
+    public static String getSigValue(String key)
+    {
+
+        String value = null;
+        SignatureEntry sigEntry = null;
+        if (sigEntries_.containsKey(key))
+        {
+            sigEntry = (SignatureEntry) sigEntries_.get(key);
+            value = sigEntry.getValue();
+        }
+        /*
+        if (value == null && SignatureTypes.SIG_NORM.equals(key))
+        {
+            value = normalizer_.getVersion();
+        }
+         */  /*
+        String overrideVal = OverridePropertyHolder.getProperty(key);
+        if (value != null && sigEntry != null && !sigEntry.isPlaceholder &&  overrideVal != null) { // TODO this!! SignatureEntry.isPlaceholder
+            value = overrideVal;
+            if (logger.isDebugEnabled()) {
+                logger.debug("Using override property for key '" + key + "' = " + value);
+            }
+        }  */
+
+        return value;
+    }
+
+    /**
+     * This method returns a caption for a given signature key. If the key exists
+     * and the coresponding value is <code>null</code> the key itself is
+     * returned as caption! If the key does not exist the method returns
+     * <code>null</code>.
+     *
+     * @param key
+     *          the key to get the caption for
+     * @return a caption for the given key
+     */
+    private static String getSigCaption(String key)
+    {
+
+        String caption = null;
+        if (sigEntries_.containsKey(key))
+        {
+            caption = ((SignatureEntry) sigEntries_.get(key)).getCaption();
+            if (caption == null)
+            {
+                caption = key;
+            }
+        }
+        return caption;
+    }
+
+    /**
+     * This method read the style definitions from the settings file.
+     *
+     * @param styleKey
+     *          the key to read the style definitions
+     * @return the defined style informations
+     * @see at.knowcenter.wag.egov.egiz.table.Style
+     */
+    private static Style readStyle(String styleKey, ISettings configuration)
+    {
+        Map<String, String> styles = configuration.getValuesPrefix(styleKey);
+        Style style = new Style();
+        Iterator<String> keyStyleIt = styles.keySet().iterator();
+        while(keyStyleIt.hasNext())
+        {
+            String style_id_key = keyStyleIt.next();
+            String style_val = styles.get(style_id_key);
+            String style_id = extractLastID(style_id_key);
+
+            style.setStyle(style_id, style_val);
+        }
+        return style;
+    }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/ValueResolver.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/ValueResolver.java
new file mode 100644
index 00000000..9052a7eb
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/ValueResolver.java
@@ -0,0 +1,64 @@
+package at.gv.egiz.pdfas.lib.impl.stamping;
+
+import at.gv.egiz.pdfas.common.settings.IProfileConstants;
+import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings;
+import at.gv.egiz.pdfas.lib.impl.PdfAsImpl;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Created with IntelliJ IDEA. User: afitzek Date: 9/11/13 Time: 11:11 AM To
+ * change this template use File | Settings | File Templates.
+ */
+public class ValueResolver implements IProfileConstants {
+
+	private static final Logger logger = LoggerFactory
+			.getLogger(ValueResolver.class);
+
+	private static final String defaultDateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
+
+	public static final String EXP_START = "${";
+	public static final String EXP_END = "}";
+
+	// TODO: Currently just for proof of concept ...
+	// Should support Reading Fields from Certificate and DATETIME
+
+	// TODO: Use status in real implementation to get currently needed
+	// informations...
+	public String resolve(String key, String value,
+			SignatureProfileSettings settings) {
+
+		logger.debug("Resolving value for key: " + key);
+		logger.debug("Resolving value with value: " + value);
+
+		if (value != null) {
+			if (value.startsWith(EXP_START) && value.endsWith(EXP_END)) {
+				// TODO: handle OGNL expression for key and value
+				// TODO: Here we need the certificate
+				CertificateResolver certificateResolver = new CertificateResolver(
+						null);
+				String exp = value.substring(EXP_START.length(), value.length()
+						- EXP_END.length());
+				return certificateResolver.resolve(key, exp, settings);
+			}
+		}
+
+		if (key.equals(SIG_DATE)) {
+			if(value == null) {
+				value = defaultDateFormat;
+			}
+			// Value holds the date format!
+			SimpleDateFormat formater = new SimpleDateFormat(value);
+			Calendar cal = Calendar.getInstance();
+			return formater.format(cal.getTime());
+		}
+
+		return value;
+	}
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java
index a78828f3..a9065644 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java
@@ -41,6 +41,10 @@ public class RequestedSignature {
     public TablePos getTablePos() {
     	return this.signaturePosition;
     }
+    
+    public String getSignatureProfileID() {
+    	return this.signatureProfile;
+    }
 
 /*
     public IPlainSigner getSigner() {
-- 
cgit v1.2.3