From e96e9dd6bcab614a60fa491ef68017bea4862af3 Mon Sep 17 00:00:00 2001
From: Andreas Fitzek <andreas.fitzek@iaik.tugraz.at>
Date: Tue, 23 Oct 2012 15:46:53 +0200
Subject: + added Signator Placeholder generation for PDF-AS: check:
 SignatureParameter.getPlaceholder()

---
 .../at/asit/pdfover/signer/pdfas/PDFASHelper.java  |   4 +
 .../at/asit/pdfover/signer/pdfas/PDFASSigner.java  |  56 ++--
 .../signer/pdfas/PdfAsSignatureParameter.java      | 343 ++++++++++++++++++++-
 3 files changed, 373 insertions(+), 30 deletions(-)

(limited to 'trunk/pdf-over-signer/pdf-over-sigpdfas/src/main/java/at/asit')

diff --git a/trunk/pdf-over-signer/pdf-over-sigpdfas/src/main/java/at/asit/pdfover/signer/pdfas/PDFASHelper.java b/trunk/pdf-over-signer/pdf-over-sigpdfas/src/main/java/at/asit/pdfover/signer/pdfas/PDFASHelper.java
index ee3cc7a9..2553eaad 100644
--- a/trunk/pdf-over-signer/pdf-over-sigpdfas/src/main/java/at/asit/pdfover/signer/pdfas/PDFASHelper.java
+++ b/trunk/pdf-over-signer/pdf-over-sigpdfas/src/main/java/at/asit/pdfover/signer/pdfas/PDFASHelper.java
@@ -50,6 +50,10 @@ public class PDFASHelper {
 		return new at.gv.egiz.pdfas.impl.api.PdfAsObject();
 	}
 	
+	public static String getWorkDir() {
+		return System.getProperty("user.home")+"/.pdfover";
+	}
+	
 	/**
 	 * Creates a PDF-AS Internal object
 	 * @return the PDF-AS Internal object
diff --git a/trunk/pdf-over-signer/pdf-over-sigpdfas/src/main/java/at/asit/pdfover/signer/pdfas/PDFASSigner.java b/trunk/pdf-over-signer/pdf-over-sigpdfas/src/main/java/at/asit/pdfover/signer/pdfas/PDFASSigner.java
index 1b058553..91581a17 100644
--- a/trunk/pdf-over-signer/pdf-over-sigpdfas/src/main/java/at/asit/pdfover/signer/pdfas/PDFASSigner.java
+++ b/trunk/pdf-over-signer/pdf-over-sigpdfas/src/main/java/at/asit/pdfover/signer/pdfas/PDFASSigner.java
@@ -1,5 +1,11 @@
 package at.asit.pdfover.signer.pdfas;
 
+import java.util.Iterator;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import at.asit.pdfover.signator.BKUs;
 import at.asit.pdfover.signator.ByteArrayDocumentSource;
 import at.asit.pdfover.signator.SLResponse;
@@ -19,12 +25,18 @@ import at.gv.egiz.pdfas.api.commons.Constants;
 import at.gv.egiz.pdfas.api.exceptions.PdfAsException;
 import at.gv.egiz.pdfas.api.internal.LocalBKUParams;
 import at.gv.egiz.pdfas.api.internal.PdfAsInternal;
+import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
 
 /**
  * PDF AS Signer Implementation
  */
 public class PDFASSigner implements Signer {
 
+	/**
+	 * SFL4J Logger instance
+	 **/
+	static final Logger log = LoggerFactory.getLogger(PDFASSigner.class);
+
 	/**
 	 * The profile ID
 	 */
@@ -38,8 +50,9 @@ public class PDFASSigner implements Signer {
 	/**
 	 * Location reference string
 	 */
-	protected static final String LOC_REF = "<sl:LocRefContent>" + URL_TEMPLATE + "</sl:LocRefContent>";
-	
+	protected static final String LOC_REF = "<sl:LocRefContent>" + URL_TEMPLATE
+			+ "</sl:LocRefContent>";
+
 	@Override
 	public SigningState prepare(SignatureParameter parameter)
 			throws SignatureException {
@@ -60,12 +73,12 @@ public class PDFASSigner implements Signer {
 
 			SignParameters params = new SignParameters();
 			params.setSignaturePositioning(sign_para.getPDFASPositioning());
-			
-			if(parameter.getSignatureDevice() == BKUs.LOCAL) {
+
+			if (parameter.getSignatureDevice() == BKUs.LOCAL) {
 				params.setSignatureDevice(Constants.SIGNATURE_DEVICE_BKU);
-			} else if(parameter.getSignatureDevice() == BKUs.MOBILE) {
+			} else if (parameter.getSignatureDevice() == BKUs.MOBILE) {
 				params.setSignatureDevice(Constants.SIGNATURE_DEVICE_MOBILE);
-				//params.setSignatureDevice(Constants.SIGNATURE_DEVICE_MOBILETEST);
+				// params.setSignatureDevice(Constants.SIGNATURE_DEVICE_MOBILETEST);
 			}
 			params.setSignatureType(Constants.SIGNATURE_TYPE_BINARY);
 			params.setSignatureProfileId(PROFILE_ID);
@@ -75,7 +88,7 @@ public class PDFASSigner implements Signer {
 				params.setProfileOverrideValue("SIG_LABEL", parameter
 						.getEmblem().getFileName());
 			}
-			
+
 			// Prepare Output sink
 			state.setOutput(new ByteArrayDataSink());
 			params.setOutput(state.getOutput());
@@ -95,17 +108,18 @@ public class PDFASSigner implements Signer {
 			String slRequest = pdfasInternal.prepareLocalSignRequest(params,
 					false, URL_TEMPLATE, sdi);
 
-			at.gv.egiz.pdfas.api.io.DataSource sig_data = sdi.getSignatureData();
-			
-			PDFASSLRequest request = new PDFASSLRequest(slRequest, sig_data.getAsByteArray());
+			at.gv.egiz.pdfas.api.io.DataSource sig_data = sdi
+					.getSignatureData();
+
+			PDFASSLRequest request = new PDFASSLRequest(slRequest,
+					sig_data.getAsByteArray());
 
 			state.setSignatureRequest(request);
 
 			return state;
-		} catch(PDFASSLRequestException e) {
+		} catch (PDFASSLRequestException e) {
 			throw new SignatureException(e);
-		}
-		catch (PdfAsException e) {
+		} catch (PdfAsException e) {
 			throw new SignatureException(e);
 		}
 	}
@@ -130,13 +144,14 @@ public class PDFASSigner implements Signer {
 
 			SignParameters params = sstate.getSignParameters();
 
-			
 			SignatureDetailInformation sdi = sstate
 					.getSignatureDetailInformation();
 
 			SLResponse slResponse = sstate.getSignatureResponse();
-			
-			LocalBKUParams bkuParams = new LocalBKUParams(slResponse.getServer(), slResponse.getUserAgent(), slResponse.getSignaturLayout());
+
+			LocalBKUParams bkuParams = new LocalBKUParams(
+					slResponse.getServer(), slResponse.getUserAgent(),
+					slResponse.getSignaturLayout());
 
 			// Perform signature
 			at.gv.egiz.pdfas.api.sign.SignResult signResult = pdfasInternal
@@ -154,12 +169,15 @@ public class PDFASSigner implements Signer {
 			// Set Signature position
 			SignaturePosition pos = new SignaturePosition(pdfasPos.getX(),
 					pdfasPos.getY(), pdfasPos.getPage());
-/*			pos.SetAuto(sstate.getPDFAsSignatureParameter()
-					.getSignaturePosition().useAutoPositioning());*/
+			/*
+			 * pos.SetAuto(sstate.getPDFAsSignatureParameter()
+			 * .getSignaturePosition().useAutoPositioning());
+			 */
 			result.setSignaturePosition(pos);
 
 			// Set signed Document
-			result.setSignedDocument(new ByteArrayDocumentSource(((ByteArrayDataSink)sstate.getOutput()).getData()));
+			result.setSignedDocument(new ByteArrayDocumentSource(
+					((ByteArrayDataSink) sstate.getOutput()).getData()));
 
 			return result;
 		} catch (PdfAsException e) {
diff --git a/trunk/pdf-over-signer/pdf-over-sigpdfas/src/main/java/at/asit/pdfover/signer/pdfas/PdfAsSignatureParameter.java b/trunk/pdf-over-signer/pdf-over-sigpdfas/src/main/java/at/asit/pdfover/signer/pdfas/PdfAsSignatureParameter.java
index fa1572e9..eb598f07 100644
--- a/trunk/pdf-over-signer/pdf-over-sigpdfas/src/main/java/at/asit/pdfover/signer/pdfas/PdfAsSignatureParameter.java
+++ b/trunk/pdf-over-signer/pdf-over-sigpdfas/src/main/java/at/asit/pdfover/signer/pdfas/PdfAsSignatureParameter.java
@@ -16,53 +16,87 @@
 package at.asit.pdfover.signer.pdfas;
 
 //Imports
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.ImageCapabilities;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashMap;
 
+import javax.imageio.ImageIO;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import at.asit.pdfover.signator.SignatureDimension;
+import at.asit.pdfover.signator.SignatureException;
 import at.asit.pdfover.signator.SignatureParameter;
 import at.asit.pdfover.signator.SignaturePosition;
+import at.asit.pdfover.signer.pdfas.exceptions.PDFASSLRequestException;
 import at.gv.egiz.pdfas.api.io.DataSource;
 import at.gv.egiz.pdfas.api.sign.pos.SignaturePositioning;
+import at.gv.egiz.pdfas.impl.signator.binary.BinarySignator_1_1_0;
 import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException;
+import at.knowcenter.wag.egov.egiz.sig.SignatureObject;
+import at.knowcenter.wag.egov.egiz.table.Entry;
+import at.knowcenter.wag.egov.egiz.table.Style;
+import at.knowcenter.wag.egov.egiz.table.Table;
 
 /**
  * Implementation of SignatureParameter specific for PDF - AS Library
  */
 public class PdfAsSignatureParameter extends SignatureParameter {
 
-	private HashMap<String, String> genericProperties = new HashMap<String, String>(); 
-	
+	/**
+	 * SFL4J Logger instance
+	 **/
+	static final Logger log = LoggerFactory
+			.getLogger(PdfAsSignatureParameter.class);
+
+	private HashMap<String, String> genericProperties = new HashMap<String, String>();
+
 	@Override
 	public SignatureDimension getPlaceholderDimension() {
-		return new SignatureDimension(487, 206);
+		// return new SignatureDimension(487, 206);
+
+		return new SignatureDimension(976, 329);
 	}
 
 	/**
 	 * Gets the PDFAS Positioning
+	 * 
 	 * @return SignaturePositioning
-	 * @throws PDFDocumentException 
+	 * @throws PDFDocumentException
 	 */
-	public SignaturePositioning getPDFASPositioning() throws PDFDocumentException {
+	public SignaturePositioning getPDFASPositioning()
+			throws PDFDocumentException {
 		SignaturePosition position = this.getSignaturePosition();
 		position.useAutoPositioning();
-		
+
 		SignaturePositioning positioning = null;
-		if(!position.useAutoPositioning()) {
-			positioning = new SignaturePositioning(String.format("p:%d;x:%f;y:%f", 
-					position.getPage(), position.getX(), position.getY()));
+		if (!position.useAutoPositioning()) {
+			positioning = new SignaturePositioning(String.format(
+					"p:%d;x:%f;y:%f", position.getPage(), position.getX(),
+					position.getY()));
 		} else {
 			positioning = new SignaturePositioning();
 		}
-		
+
 		return positioning;
 	}
 
 	/**
 	 * Gets PDF - AS specific data source
+	 * 
 	 * @return ByteArrayPDFASDataSource
 	 */
 	public DataSource getPDFASDataSource() {
-		return new ByteArrayPDFASDataSource(this.getInputDocument().getByteArray());
+		return new ByteArrayPDFASDataSource(this.getInputDocument()
+				.getByteArray());
 	}
 
 	@Override
@@ -74,4 +108,291 @@ public class PdfAsSignatureParameter extends SignatureParameter {
 	public String getProperty(String key) {
 		return this.genericProperties.get(key);
 	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see at.asit.pdfover.signator.SignatureParameter#getPlaceholder()
+	 */
+	@Override
+	public Image getPlaceholder() throws SignatureException {
+
+		try
+		{
+		PDFASHelper.getPdfAs();
+
+		SignatureObject sign_obj = at.knowcenter.wag.egov.egiz.PdfAS
+				.createSignatureObjectFromType(PDFASSigner.PROFILE_ID);
+
+		sign_obj.fillValues(' ', true, false);
+		sign_obj.setKZ(BinarySignator_1_1_0.MY_ID);
+
+		float width = getPlaceholderDimension().getWidth();
+		float height = getPlaceholderDimension().getHeight();
+
+		Table table = sign_obj.getAbstractTable();
+
+		table.getStyle().getBgColor();
+
+		log.info(table.toString());
+
+		float[] heights = this.getTableHeights(table, table.getStyle(), height);
+
+		log.info("Width: " + width + " Height: " + height);
+		BufferedImage image = new BufferedImage((int) width, (int) height,
+				BufferedImage.TYPE_INT_RGB);
+		Graphics graphic = image.getGraphics();
+
+		graphic.setColor(table.getStyle().getBgColor());
+		graphic.fillRect(0, 0, (int) width, (int) height);
+
+		graphic.setColor(Color.black);
+		graphic.drawRect(0, 0, (int) width, (int) height);
+
+		this.drawTable(0, 0, (int) width, (int) height, table,
+				table.getStyle(), graphic, heights);
+
+		save(image, "jpg");
+
+		return image;
+		}
+		catch (Exception ex) {
+			log.error("Failed to create Placeholder!", ex);
+			throw new SignatureException(ex.getMessage());
+		}
+	}
+
+	private static void save(BufferedImage image, String ext) {
+		String fileName = "savingAnImage";
+		File file = new File(fileName + "." + ext);
+		try {
+			ImageIO.write(image, ext, file); // ignore returned boolean
+			log.debug("Saved as: " + file.getAbsolutePath());
+		} catch (IOException e) {
+			System.out.println("Write error for " + file.getPath() + ": "
+					+ e.getMessage());
+		}
+	}
+
+	private Font getFont(Style style) {
+		String def = "COURIER-NORMAL-8";
+		String fontString = style.getFont();
+		String[] font_arr = fontString.split(",");
+		if (font_arr.length != 3) {
+			return Font.decode(def);
+		}
+		return Font.decode(String.format("%s-%s-%s", font_arr[0], font_arr[2],
+				font_arr[1]));
+
+	}
+
+	private Font getValueFont(Style style) {
+		String def = "COURIER-NORMAL-8";
+		String fontString = style.getValueFont();
+		String[] font_arr = fontString.split(",");
+		if (font_arr.length != 3) {
+			return Font.decode(def);
+		}
+		return Font.decode(String.format("%s-%s-%s", font_arr[0], font_arr[2],
+				font_arr[1]));
+	}
+
+	private int drawTable(int xoff, int yoff, int width, int height,
+			Table table, Style parentstyle, Graphics graphic, float[] heights) {
+		Style style = parentstyle;
+		if (table.getStyle() != null) {
+			style = table.getStyle();
+		}
+
+		log.debug(String.format("Table@ %dx%d", xoff, yoff));
+
+		Font oldFont = graphic.getFont();
+		Font font = this.getFont(style);
+		Font valuefont = this.getValueFont(style);
+
+		// draw background
+		// graphic.setColor(style.getBgColor());
+		// graphic.fillRect(xoff, yoff, width, height);
+
+		graphic.setColor(Color.black);
+
+		// draw border
+		if (style.getBorder() > 0) {
+			graphic.setColor(Color.black);
+			graphic.drawRect(xoff, yoff, width, height);
+		}
+		float[] colWidths = table.getColsRelativeWith();
+		float sum = 0;
+
+		for (int i = 0; i < colWidths.length; i++) {
+			sum += colWidths[i];
+		}
+
+		float perUnit = width / sum;
+
+		int padding = (int) (style.getPadding() * this.perUnitHeight);
+
+		ArrayList rows = table.getRows();
+		float roffset = 0;
+		for (int rowidx = 0; rowidx < rows.size(); rowidx++) {
+			ArrayList cols = (ArrayList) rows.get(rowidx);
+			int rsize = (int) heights[rowidx];
+			for (int j = 0; j < cols.size(); j++) {
+				Entry entry = (Entry) cols.get(j);
+				float offset = 0;
+				for (int k = 0; k < j; k++) {
+					offset += colWidths[k] * perUnit;
+				}
+				if (entry.getType() == 0 || entry.getType() == 1) {
+					// Text
+					graphic.drawRect((int) (xoff + offset),
+							(int) (yoff + roffset),
+							(int) (colWidths[j] * perUnit), rsize);
+
+					graphic.drawString(entry.getValue().toString(), (int) (xoff
+							+ offset + padding), (int) (yoff + padding
+							+ roffset + font.getSize() * this.perUnitHeight));
+				} else if (entry.getType() == 2) {
+					// Image ...
+					BufferedImage image;
+					try {
+						if (this.getEmblem() != null
+								&& this.getEmblem().getFileName() != null
+								&& new File(this.getEmblem().getFileName())
+										.exists()) {
+							image = ImageIO.read(new File(this.getEmblem()
+									.getFileName()));
+						} else {
+							image = ImageIO.read(new File(PDFASHelper
+									.getWorkDir()
+									+ "/"
+									+ entry.getValue().toString()));
+						}
+						Image img = image.getScaledInstance(80, 80,
+								Image.SCALE_DEFAULT);
+
+						graphic.drawImage(
+								img,
+								(int) (xoff + offset + padding + (((colWidths[j] * perUnit) - 80 - padding)) / 2),
+								(int) (yoff + roffset + padding + ((rsize - 80 - padding) / 2)),
+								null);
+					} catch (IOException e) {
+						log.warn("Failed to paint emblem to placeholder image");
+					}
+				} else {
+					// Table
+
+					float[] cheights = this.getTableHeights(
+							(Table) entry.getValue(), style, rsize);
+
+					int tsize = this.drawTable(
+							(int) (xoff + offset),
+							(int) (yoff + roffset),
+							(int) (colWidths[j] * perUnit),
+							// (int)this.getTableHeight((Table)
+							// entry.getValue(), style),
+							rsize, (Table) entry.getValue(), style, graphic,
+							cheights);
+					/*
+					 * if (rsize < tsize) { rsize = tsize; }
+					 */
+				}
+			}
+			roffset += rsize;
+		}
+
+		graphic.setFont(oldFont);
+
+		return (int) roffset;
+	}
+
+	private float perUnitHeight = 0;
+
+	private float[] getTableHeights(Table table, Style parentstyle, float height) {
+		ArrayList rows = table.getRows();
+		float[] sizes = new float[rows.size()];
+
+		float total_height = this.getTableHeight(table, parentstyle);
+
+		float perUnit = height / total_height;
+
+		this.perUnitHeight = perUnit;
+
+		Style style = parentstyle;
+		if (table.getStyle() != null) {
+			style = table.getStyle();
+		}
+
+		for (int i = 0; i < rows.size(); i++) {
+			Object robj = rows.get(i);
+			ArrayList cols = (ArrayList) robj;
+			float tsize = 0;
+			float rsize = 0;
+			for (int j = 0; j < cols.size(); j++) {
+				Entry entry = (Entry) cols.get(j);
+				if (entry.getType() == 0 || entry.getType() == 1) {
+					String fontString = style.getFont();
+					String[] font_arr = fontString.split(",");
+					int fontSize = 8;
+
+					if (font_arr.length == 3) {
+						fontSize = Integer.parseInt(font_arr[1]);
+					}
+
+					if (rsize < ((style.getPadding() * 2) + fontSize)) {
+						rsize = ((style.getPadding() * 2) + fontSize);
+					}
+				} else if (entry.getType() == 3) {
+					tsize = this
+							.getTableHeight((Table) entry.getValue(), style);
+					if (rsize < tsize) {
+						rsize = tsize;
+					}
+				}
+			}
+			sizes[i] = perUnit * rsize;
+		}
+
+		return sizes;
+	}
+
+	private float getTableHeight(Table table, Style parentstyle) {
+		ArrayList rows = table.getRows();
+		Style style = parentstyle;
+		if (table.getStyle() != null) {
+			style = table.getStyle();
+		}
+		float size = 0;
+		for (int i = 0; i < rows.size(); i++) {
+			Object robj = rows.get(i);
+			ArrayList cols = (ArrayList) robj;
+			float tsize = 0;
+			float rsize = 0;
+			for (int j = 0; j < cols.size(); j++) {
+				Entry entry = (Entry) cols.get(j);
+				if (entry.getType() == 0 || entry.getType() == 1) {
+					String fontString = style.getFont();
+					String[] font_arr = fontString.split(",");
+					int fontSize = 8;
+
+					if (font_arr.length == 3) {
+						fontSize = Integer.parseInt(font_arr[1]);
+					}
+
+					if (rsize < ((style.getPadding() * 2) + fontSize)) {
+						rsize = ((style.getPadding() * 2) + fontSize);
+					}
+				} else if (entry.getType() == 3) {
+					tsize = this
+							.getTableHeight((Table) entry.getValue(), style);
+					if (rsize < tsize) {
+						rsize = tsize;
+					}
+				}
+			}
+			size += rsize;
+		}
+
+		return size;
+	}
 }
-- 
cgit v1.2.3