aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authortknall <tknall@7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c>2007-02-07 10:08:21 +0000
committertknall <tknall@7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c>2007-02-07 10:08:21 +0000
commita0de2a3b2a5f4a99f280f5caebbca0d183ae109a (patch)
tree7479e30c10c3994cba18c6bf8784f61748bb6cd3 /src/main
parent8f7cebd9c2c5c0f6e33863ba57ad1c215f35605c (diff)
downloadpdf-as-3-a0de2a3b2a5f4a99f280f5caebbca0d183ae109a.tar.gz
pdf-as-3-a0de2a3b2a5f4a99f280f5caebbca0d183ae109a.tar.bz2
pdf-as-3-a0de2a3b2a5f4a99f280f5caebbca0d183ae109a.zip
Bugfix: Querformat, BKU 2.7.x, ...
git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@35 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java245
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java12
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/framework/VerificationFilter.java3
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java28
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_0_0.java29
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java286
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java70
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java34
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java12
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java131
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java20
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/LocalConnector.java12
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java175
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUConnector.java89
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUPostConnection.java54
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousDataResponder.java21
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousRedirectResponder.java6
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/web/LocalRequestHelper.java9
-rw-r--r--src/main/java/at/knowcenter/wag/egov/egiz/web/SessionInformation.java3
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfDictionary.java16
20 files changed, 984 insertions, 271 deletions
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java b/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java
index 0987b2d..f9ab652 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java
@@ -46,6 +46,7 @@ import at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation;
import at.knowcenter.wag.egov.egiz.pdf.PDFSignatureCreation;
import at.knowcenter.wag.egov.egiz.pdf.PDFSignatureObject;
import at.knowcenter.wag.egov.egiz.pdf.PDFUtilities;
+import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder;
import at.knowcenter.wag.egov.egiz.pdf.TextualSignatureHolder;
import at.knowcenter.wag.egov.egiz.pdf.TablePos;
@@ -57,6 +58,7 @@ import at.knowcenter.wag.egov.egiz.sig.SignatureResponse;
import at.knowcenter.wag.egov.egiz.sig.SignatureTypeDefinition;
import at.knowcenter.wag.egov.egiz.sig.SignatureTypes;
import at.knowcenter.wag.egov.egiz.tools.Normalizer;
+import at.knowcenter.wag.exactparser.ParseDocument;
import at.knowcenter.wag.exactparser.parsing.PDFUtils;
import at.knowcenter.wag.exactparser.parsing.results.HeaderParseResult;
@@ -152,7 +154,8 @@ public abstract class PdfAS
* is not 1.4.
*
* <p>
- * If strict mode is deactivated, this does simply nothing.
+ * Furthermore (independently of strict mode) the PDF is checked for
+ * parsability.
* </p>
*
* @param pdf
@@ -168,6 +171,15 @@ public abstract class PdfAS
throw new PDFDocumentException(201, "StrictMode: The pdf version is not 1.4 or lower.");
}
}
+ try
+ {
+ ParseDocument.parseDocument(pdf);
+ }
+ catch (Exception e)
+ {
+ logger_.debug("Error while parsing Document.", e);
+ throw new PDFDocumentException(201, e);
+ }
}
/**
@@ -232,7 +244,7 @@ public abstract class PdfAS
* @throws SignatureException
* F.e.
* @throws SignatureTypesException
- * @throws NormalizeException
+ * @throws NormalizeException
*/
public static List extractSignatureHoldersTextual(String raw_text,
boolean old_style) throws PDFDocumentException, SignatureException, SignatureTypesException, NormalizeException
@@ -267,7 +279,7 @@ public abstract class PdfAS
* found.
* @throws SignatureException
* @throws SignatureTypesException
- * @throws NormalizeException
+ * @throws NormalizeException
*/
public static SignatureHolder extractSignatureHolderTextual(String raw_text,
boolean old_style) throws SignatureException, SignatureTypesException, NormalizeException
@@ -343,7 +355,8 @@ public abstract class PdfAS
end_index = cur_key.getStartIndex();
}
- // this normalization is required to get rid of possible trailing newlines.
+ // this normalization is required to get rid of possible trailing
+ // newlines.
String normalized_text = normalizeText(signed_text);
SignatureHolder holder = new TextualSignatureHolder(normalized_text, signatureObject_);
return holder;
@@ -368,8 +381,6 @@ public abstract class PdfAS
public static List findBlockInText(String text,
SignatureTypeDefinition sig_type_def, boolean old_style)
{
- // FIXME[tknall]: AbsoluteTextSignature.java, method findEndOfValue(...) does not work properly for landscape documents because start_index of FoundKeys are not set correctly.
- // Hint: Captions and values of landscape documents are separated with " \n" and not only with " ".
Vector keys = sig_type_def.getRevertSortedKeys();
Vector captions = sig_type_def.getRevertSortedCaptions();
@@ -389,11 +400,12 @@ public abstract class PdfAS
String caption = (String) captions.get(key_idx);
- //int found_index = text.lastIndexOf(caption);
-// we're searching for captions that start at the beginning of the line.
- int found_index = text.lastIndexOf("\n" + caption) + 1; // the +1 compensates the \n
-
-
+ // int found_index = text.lastIndexOf(caption);
+ // we're searching for captions that start at the beginning of the line.
+ int found_index = text.lastIndexOf("\n" + caption) + 1; // the +1
+ // compensates the
+ // \n
+
if (key.equals(SignatureTypes.SIG_ID))
{
if (found_index < 0 || found_index >= last_index)
@@ -453,7 +465,7 @@ public abstract class PdfAS
}
});
}
-
+
/**
* Sorts the FoundKeys List ascendingly according to the start indices of the
* found keys (the first found key in the list will have the lowest start
@@ -475,7 +487,7 @@ public abstract class PdfAS
return fk0.start_index - fk1.start_index;
}
});
- }
+ }
/**
* Checks that the found keys are in correct order regarding SIG_ID as
@@ -763,7 +775,7 @@ public abstract class PdfAS
String connector) throws NormalizeException, PDFDocumentException, SignatureException
{
String text_to_be_verified = signature_holder.getSignedText();
-
+
SignatureObject so_to_be_verified = signature_holder.getSignatureObject();
if (text_to_be_verified == null)
@@ -774,7 +786,7 @@ public abstract class PdfAS
{
throw new SignatureException(311, "Document can not be verified because the length of the text to be verified is 0. (length = " + text_to_be_verified.length() + ")");
}
-
+
if (so_to_be_verified == null)
{
throw new SignatureException(312, "Document can not be verified because no signature object are set.");
@@ -816,8 +828,9 @@ public abstract class PdfAS
final String user_name, final String user_password) throws SignatureException, PDFDocumentException
{
logger_.info("User signed a document: " + user_name);
-
- if (text_to_sign == null) {
+
+ if (text_to_sign == null)
+ {
throw new SignatureException(301, "Signature can not be produced. Text is null.");
}
if (text_to_sign.length() <= 0)
@@ -907,10 +920,10 @@ public abstract class PdfAS
*/
public static String extractNormalizedTextTextual(final byte[] pdf) throws PresentableException
{
-// ByteArrayInputStream bais = new ByteArrayInputStream(pdf);
-// String raw_document_text = TextualSignature.extractTextTextual(bais);
-//
-// String document_text = normalizeText(raw_document_text);
+ // ByteArrayInputStream bais = new ByteArrayInputStream(pdf);
+ // String raw_document_text = TextualSignature.extractTextTextual(bais);
+ //
+ // String document_text = normalizeText(raw_document_text);
return extractNormalizedTextTextual(pdf, pdf.length);
}
@@ -927,7 +940,8 @@ public abstract class PdfAS
* @throws PresentableException
* F.e.
*/
- public static String extractNormalizedTextTextual(final byte[] pdf, final int length) throws PresentableException
+ public static String extractNormalizedTextTextual(final byte[] pdf,
+ final int length) throws PresentableException
{
ByteArrayInputStream bais = new ByteArrayInputStream(pdf, 0, length);
String raw_document_text = TextualSignature.extractTextTextual(bais);
@@ -975,6 +989,68 @@ public abstract class PdfAS
}
/**
+ * 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 pdf
+ * The pdf.
+ * @param pdf_table
+ * The pdf table to be written.
+ * @return Returns the PositioningInformation.
+ * @throws PDFDocumentException
+ * F.e.
+ * @throws SettingsException
+ * F.e.
+ */
+ public static PositioningInstruction determineTablePositioning(TablePos pos,
+ String signature_type, byte[] pdf, PdfPTable pdf_table) throws PDFDocumentException, SettingsException
+ {
+ 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 automatic algorithm.
+ return PdfAS.adjustTableAndCalculatePosition(pdf, pdf_table);
+ }
+
+ if (pos.page == -2)
+ {
+ // The automatic algorithm regarding the footer.
+ return PdfAS.adjustTableAndCalculatePositionRegardingFooter(pdf, pdf_table, pos.footer_line);
+ }
+
+ boolean make_new_page = false;
+ int page = pos.page;
+
+ if (pos.page == -1)
+ {
+ // Absolute positioning on a new page.
+ make_new_page = true;
+ PdfReader reader = PdfAS.readInPdfDocument(pdf);
+ page = reader.getNumberOfPages() + 1;
+ reader = null;
+ }
+
+ pdf_table.setTotalWidth(pos.width);
+ pdf_table.setLockedWidth(true);
+
+ return new PositioningInstruction(make_new_page, page, pos.pos_x, pos.pos_y);
+
+ }
+
+ /**
* Sets the width of the table according to the layout of the document and
* calculates the y position where the PDFPTable should be placed.
*
@@ -986,36 +1062,88 @@ public abstract class PdfAS
* @throws PDFDocumentException
* F.e.
*/
- public static TablePos adjustTableAndCalculatePosition(final byte[] pdf,
- PdfPTable pdf_table) throws PDFDocumentException
+ public static PositioningInstruction adjustTableAndCalculatePosition(
+ final byte[] pdf, PdfPTable pdf_table) throws PDFDocumentException
{
- TablePos pos = new TablePos();
+ boolean make_new_page = false;
PdfReader reader = readInPdfDocument(pdf);
- Rectangle psize = reader.getPageSizeWithRotation(reader.getNumberOfPages());
+ int page = reader.getNumberOfPages();
+ Rectangle psize = reader.getPageSizeWithRotation(page);
float page_width = psize.width();
float page_height = psize.height();
- pos.width = page_width - SIGNATURE_BORDER;
- pdf_table.setTotalWidth(pos.width);
+ final float width = page_width - SIGNATURE_BORDER;
+ pdf_table.setTotalWidth(width);
+ pdf_table.setLockedWidth(true);
+
+ final float pos_x = SIGNATURE_BORDER / 2;
+
+ final float table_height = pdf_table.getTotalHeight();
+ final float page_length = PDFUtilities.calculateLastPageLength(pdf, page_height);
+ float pos_y = page_height - page_length - SIGNATURE_MARGIN;
+
+ if (pos_y <= table_height)
+ {
+ make_new_page = true;
+ page++;
+
+ pos_y = page_height - SIGNATURE_BORDER / 2;
+ }
+
+ return new PositioningInstruction(make_new_page, page, pos_x, pos_y);
+ }
+
+ /**
+ * Sets the width of the table according to the layout of the document and
+ * calculates the y position where the PDFPTable should be placed.
+ *
+ * <p>
+ * This algorithm tries to position the table between the end of the text and
+ * the footer line.
+ * </p>
+ *
+ * @param pdf
+ * The PDF document.
+ * @param pdf_table
+ * The PDFPTable to be placed.
+ * @return Returns the position where the PDFPTable should be placed.
+ * @throws PDFDocumentException
+ * F.e.
+ */
+ public static PositioningInstruction adjustTableAndCalculatePositionRegardingFooter(
+ final byte[] pdf, PdfPTable pdf_table, float footer_line) throws PDFDocumentException
+ {
+ boolean make_new_page = false;
+
+ PdfReader reader = readInPdfDocument(pdf);
+
+ int page = reader.getNumberOfPages();
+ Rectangle psize = reader.getPageSizeWithRotation(page);
+ float page_width = psize.width();
+ float page_height = psize.height();
+
+ final float width = page_width - SIGNATURE_BORDER;
+ pdf_table.setTotalWidth(width);
pdf_table.setLockedWidth(true);
- pos.pos_x = SIGNATURE_BORDER / 2;
+ final float pos_x = SIGNATURE_BORDER / 2;
+
+ final float table_height = pdf_table.getTotalHeight();
- float table_height = pdf_table.getTotalHeight();
- float page_length = PDFUtilities.calculateLastPageLength(pdf);
- pos.pos_y = page_height - page_length - SIGNATURE_MARGIN;
+ final float page_length = PDFUtilities.calculateLastPageLength(pdf, page_height - footer_line);
+ float pos_y = page_height - page_length - SIGNATURE_MARGIN;
- pos.page = reader.getNumberOfPages();
- if (pos.pos_y <= table_height)
+ if (pos_y - footer_line <= table_height)
{
- pos.page = -1;
- // negative means to add a new page
- pos.pos_y = page_height - SIGNATURE_BORDER / 2;
+ make_new_page = true;
+ page++;
+
+ pos_y = page_height - SIGNATURE_BORDER / 2;
}
- return pos;
+ return new PositioningInstruction(make_new_page, page, pos_x, pos_y);
}
/**
@@ -1055,27 +1183,46 @@ public abstract class PdfAS
public static TablePos parsePositionFromPosString(String pos_string) throws PDFDocumentException
{
String[] strs = pos_string.split(";");
- if (strs.length != 4)
- {
- throw new PDFDocumentException(224, "Pos string (=" + pos_string + ") is invalid.");
- }
try
{
TablePos pos = new TablePos();
pos.page = Integer.parseInt(strs[0]);
- pos.pos_x = Float.parseFloat(strs[1]);
- pos.pos_y = Float.parseFloat(strs[2]);
- pos.width = Float.parseFloat(strs[3]);
- if (pos.page < 1 && pos.page != -1)
+ if (pos.page < 1 && pos.page != -1 && pos.page != -2)
{
- throw new PDFDocumentException(225, "pos.page (=" + pos.page + ") must not be lower than -1 and must not be 0.");
+ throw new PDFDocumentException(225, "Page (=" + pos.page + ") must not be lower than -2 and must not be 0.");
}
- if (pos.width <= 0.0f)
+ if (pos.page == -2)
{
- throw new PDFDocumentException(226, "pos.width (=" + pos.width + ") must not be lower or equal 0.");
+ if (strs.length != 2)
+ {
+ throw new PDFDocumentException(224, "Pos string (=" + pos_string + ") is invalid.");
+ }
+
+ pos.footer_line = Float.parseFloat(strs[1]);
+ }
+ else
+ {
+ if (strs.length != 4)
+ {
+ throw new PDFDocumentException(224, "Pos string (=" + pos_string + ") is invalid.");
+ }
+
+ pos.pos_x = Float.parseFloat(strs[1]);
+ pos.pos_y = Float.parseFloat(strs[2]);
+ pos.width = Float.parseFloat(strs[3]);
+
+ if (pos.page < 1 && pos.page != -1)
+ {
+ throw new PDFDocumentException(225, "pos.page (=" + pos.page + ") must not be lower than -1 and must not be 0.");
+ }
+
+ if (pos.width <= 0.0f)
+ {
+ throw new PDFDocumentException(226, "pos.width (=" + pos.width + ") must not be lower or equal 0.");
+ }
}
return pos;
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java b/src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java
index 7f5242b..bcfb6b4 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java
@@ -753,21 +753,19 @@ public abstract class Main
writer.println(" " + type + " ... " + (type.equals(default_type) ? "(default) " : "") + type_descr);
}
- writer.println(" " + PARAMETER_USER_NAME + " <user_name> ... the user name");
- writer.println(" " + PARAMETER_USER_PASSWORD + " <password> ... the user password");
+ writer.println(" " + PARAMETER_USER_NAME + " <user_name> ... [optional] the user name");
+ writer.println(" " + PARAMETER_USER_PASSWORD + " <password> ... [optional] the user password");
- writer.println(" " + PARAMETER_POS + " <position> ... [optional] the absolute position of the signature block");
- writer.println(" position has the format <pagenr>;<x>;<y>;<width>");
- writer.println(" ... e.g. -pos=1;20.0;400.0;500.0");
+ writer.println(" " + PARAMETER_POS + " <position> ... [optional] the position of the signature block");
+ writer.println(" position has the format <pagenr>;<x>;<y>;<width> or -2;<footer_line>");
writer.println(" OPTIONS for verification:");
writer.println(" " + PARAMETER_VERIFY_WHICH + " <number> ... [optional] zero based number of the signature");
writer.println(" to be verified. If omitted, all signatures are verified.");
writer.println(" Example usage:");
- writer.println(" pdf-as " + PARAMETER_MODE + " " + VALUE_MODE_SIGN + " " + PARAMETER_CONNECTOR + " moa " + PARAMETER_USER_NAME + " name " + PARAMETER_USER_PASSWORD + " pwd some_document.pdf");
+ writer.println(" pdf-as " + PARAMETER_MODE + " " + VALUE_MODE_SIGN + " " + PARAMETER_CONNECTOR + " moa some_document.pdf");
writer.println(" pdf-as " + PARAMETER_MODE + " " + VALUE_MODE_VERIFY + " some_document.pdf_out.pdf");
-
}
/**
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/VerificationFilter.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/VerificationFilter.java
index dd7a742..26f46e8 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/VerificationFilter.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/VerificationFilter.java
@@ -107,7 +107,8 @@ public class VerificationFilter
}
catch (Exception e)
{
- throw new PDFDocumentException(201);
+ logger_.debug("Error while parsing Document.", e);
+ throw new PDFDocumentException(201, e);
}
// for (int i = 0; i < blocks.size(); i++)
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java
index d28ac3b..6f167c8 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/BinarySignator_1_0_0.java
@@ -22,11 +22,8 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-import com.lowagie.text.pdf.PdfPTable;
-
import at.knowcenter.wag.egov.egiz.PdfAS;
import at.knowcenter.wag.egov.egiz.PdfASID;
-import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException;
import at.knowcenter.wag.egov.egiz.exceptions.PresentableException;
import at.knowcenter.wag.egov.egiz.framework.SignResult;
@@ -34,6 +31,7 @@ import at.knowcenter.wag.egov.egiz.framework.Signator;
import at.knowcenter.wag.egov.egiz.framework.SignatorFactory;
import at.knowcenter.wag.egov.egiz.pdf.BinarySignature;
import at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation;
+import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
import at.knowcenter.wag.egov.egiz.pdf.ReplaceInfo;
import at.knowcenter.wag.egov.egiz.pdf.StringInfo;
import at.knowcenter.wag.egov.egiz.pdf.TablePos;
@@ -42,6 +40,8 @@ import at.knowcenter.wag.egov.egiz.sig.SignatureObject;
import at.knowcenter.wag.egov.egiz.sig.SignatureTypes;
import at.knowcenter.wag.exactparser.ByteArrayUtils;
+import com.lowagie.text.pdf.PdfPTable;
+
/**
* Signs the document binary.
*
@@ -90,25 +90,7 @@ public class BinarySignator_1_0_0 implements Signator
PdfPTable pdf_table = PdfAS.createPdfPTableFromSignatureObject(signature_object);
- 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);
- pdf_table.setTotalWidth(pos.width);
- pdf_table.setLockedWidth(true);
- }
- else
- {
- pos = PdfAS.adjustTableAndCalculatePosition(pdf, pdf_table);
- }
- }
- else
- {
- pdf_table.setTotalWidth(pos.width);
- pdf_table.setLockedWidth(true);
- }
+ PositioningInstruction pi = PdfAS.determineTablePositioning(pos, signature_type, pdf, pdf_table);
List all_field_definitions = signature_object.getSignatureTypeDefinition().getFieldDefinitions();
List variable_field_definitions = new ArrayList();
@@ -124,7 +106,7 @@ public class BinarySignator_1_0_0 implements Signator
variable_field_definitions.add(sfd);
}
}
- IncrementalUpdateInformation iui = BinarySignature.writeIncrementalUpdate(pdf, pdf_table, pos, variable_field_definitions, all_field_definitions);
+ IncrementalUpdateInformation iui = BinarySignature.writeIncrementalUpdate(pdf, pdf_table, pi, variable_field_definitions, all_field_definitions);
String temp_string = iui.temp_ir_number + " " + iui.temp_ir_generation + " obj";
byte[] temp_bytes = temp_string.getBytes("US-ASCII");
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_0_0.java b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_0_0.java
index 6e605ff..8cdcf63 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_0_0.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/framework/signators/TextualSignator_1_0_0.java
@@ -17,19 +17,18 @@
*/
package at.knowcenter.wag.egov.egiz.framework.signators;
-import com.lowagie.text.pdf.PdfPTable;
-
import at.knowcenter.wag.egov.egiz.PdfAS;
import at.knowcenter.wag.egov.egiz.PdfASID;
-import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
import at.knowcenter.wag.egov.egiz.exceptions.PresentableException;
import at.knowcenter.wag.egov.egiz.framework.SignResult;
import at.knowcenter.wag.egov.egiz.framework.Signator;
import at.knowcenter.wag.egov.egiz.framework.SignatorFactory;
import at.knowcenter.wag.egov.egiz.pdf.BinarySignature;
import at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation;
+import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
import at.knowcenter.wag.egov.egiz.pdf.TablePos;
-import at.knowcenter.wag.egov.egiz.sig.SignatureTypes;
+
+import com.lowagie.text.pdf.PdfPTable;
/**
* Signs a document textually.
@@ -93,27 +92,9 @@ public class TextualSignator_1_0_0 implements Signator
PdfPTable pdf_table = PdfAS.createPdfPTableFromSignatureObject(iui.signed_signature_object);
- if (iui.pos == null)
- {
- String pos_string = SettingsReader.getInstance().getSetting(SignatureTypes.SIG_OBJ + iui.signature_type + ".pos", null);
- if (pos_string != null)
- {
- iui.pos = PdfAS.parsePositionFromPosString(pos_string);
- pdf_table.setTotalWidth(iui.pos.width);
- pdf_table.setLockedWidth(true);
- }
- else
- {
- iui.pos = PdfAS.adjustTableAndCalculatePosition(iui.original_document, pdf_table);
- }
- }
- else
- {
- pdf_table.setTotalWidth(iui.pos.width);
- pdf_table.setLockedWidth(true);
- }
+ PositioningInstruction pi = PdfAS.determineTablePositioning(iui.pos, iui.signature_type, iui.original_document, pdf_table);
- IncrementalUpdateInformation signed_iui = BinarySignature.writeIncrementalUpdate(iui.original_document, pdf_table, iui.pos, null, null);
+ IncrementalUpdateInformation signed_iui = BinarySignature.writeIncrementalUpdate(iui.original_document, pdf_table, pi, null, null);
SignResult sign_result = new SignResult(PdfAS.PDF_MIME_TYPE, signed_iui.signed_pdf);
return sign_result;
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java
index b3c2e24..85673b5 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/AbsoluteTextSignature.java
@@ -151,69 +151,89 @@ public class AbsoluteTextSignature
SignatureTypes sig_types = SignatureTypes.getInstance();
List signatureTypes_ = sig_types.getSignatureTypeDefinitions();
- List found_candidates = new ArrayList();
+ List found_potential_candidates = new ArrayList();
for (int i = 0; i < signatureTypes_.size(); i++)
{
SignatureTypeDefinition block_type = (SignatureTypeDefinition) signatureTypes_.get(i);
List found_candidates_for_type = findPotentialSignaturesForProfile(text, block_type);
- found_candidates.addAll(found_candidates_for_type);
+ found_potential_candidates.addAll(found_candidates_for_type);
}
- if (found_candidates.isEmpty())
+ if (found_potential_candidates.isEmpty())
{
logger.debug("no candidates found at all");
return null;
}
+ List found_candidates = new ArrayList();
logger.debug("checking block integrity");
- for (int i = 0; i < found_candidates.size(); i++)
+ for (int i = 0; i < found_potential_candidates.size(); i++)
{
- FoundBlock found_block = (FoundBlock) found_candidates.get(i);
+ FoundBlock found_block = (FoundBlock) found_potential_candidates.get(i);
String date_value = getDateValue(text, found_block);
logger.debug("date_value = " + date_value);
- EGIZDate date = EGIZDate.parseFromString(date_value);
+ try
+ {
+ EGIZDate date = EGIZDate.parseFromString(date_value);
+
+ logger.debug("found_block = " + date + " - " + found_block);
- logger.debug("found_block = " + date + " - " + found_block);
+ checkBlockIntegrity(text, found_block);
- checkBlockIntegrity(text, found_block);
+ found_candidates.add(found_block);
+ }
+ catch (Exception e)
+ {
+ logger.debug("Exception while checking the integrity of the found block " + found_block + ". Ignoring this block.", e);
+ }
}
sortFoundBlocksByDate(text, found_candidates);
-
- logger.debug("sorted blocks:");
- for (int i = 0; i < found_candidates.size(); i++)
+ if (logger.isDebugEnabled())
{
- FoundBlock found_block = (FoundBlock) found_candidates.get(i);
+ logger.debug("sorted blocks:");
+ for (int i = 0; i < found_candidates.size(); i++)
+ {
+ FoundBlock found_block = (FoundBlock) found_candidates.get(i);
- String date_value = getDateValue(text, found_block);
- EGIZDate date = EGIZDate.parseFromString(date_value);
+ String date_value = getDateValue(text, found_block);
+ EGIZDate date = EGIZDate.parseFromString(date_value);
- logger.debug(" #" + i + ": " + date + " - " + found_block);
+ logger.debug(" #" + i + ": " + date + " - " + found_block);
+ }
}
List latest_blocks = filterLastDateEqualBlocks(text, found_candidates);
- logger.debug("latest blocks:");
- for (int i = 0; i < latest_blocks.size(); i++)
+ if (logger.isDebugEnabled())
{
- FoundBlock found_block = (FoundBlock) latest_blocks.get(i);
+ logger.debug("latest blocks:");
+ for (int i = 0; i < latest_blocks.size(); i++)
+ {
+ FoundBlock found_block = (FoundBlock) latest_blocks.get(i);
- String date_value = getDateValue(text, found_block);
- EGIZDate date = EGIZDate.parseFromString(date_value);
+ String date_value = getDateValue(text, found_block);
+ EGIZDate date = EGIZDate.parseFromString(date_value);
- logger.debug(" #" + i + ": " + date + " - " + found_block);
+ logger.debug(" #" + i + ": " + date + " - " + found_block);
+ }
}
- boolean semantic_equality = PdfAS.checkForSemanticEquality(latest_blocks);
- logger.debug("semantic_equality = " + semantic_equality);
- if (!semantic_equality)
- {
- throw new SignatureException(314, "The latest blocks weren't semantically equal.");
- }
+ // The semantic equality check has been outdated by the
+ // advanced choosing algorithm.
+ // boolean semantic_equality =
+ // PdfAS.checkForSemanticEquality(latest_blocks);
+ // logger.debug("semantic_equality = " + semantic_equality);
+ // if (!semantic_equality)
+ // {
+ // throw new SignatureException(314, "The latest blocks weren't semantically
+ // equal.");
+ // }
+
+ FoundBlock latest_block = chooseMostPossibleBlock(latest_blocks);
- FoundBlock latest_block = chooseMostPossibleSemanticallyEqualBlock(latest_blocks);
logger.debug("latest block = " + latest_block);
return latest_block;
}
@@ -269,7 +289,6 @@ public class AbsoluteTextSignature
}
}
-
for (int lci = 0; lci < found_last_captions.size(); lci++)
{
int last_caption_index = ((Integer) found_last_captions.get(lci)).intValue();
@@ -470,8 +489,6 @@ public class AbsoluteTextSignature
*/
public static int findEndOfValue(String text, int start_index)
{
- // FIXME[tknall]: this method does not work properly for landscape documents because <text> always starts with "\n". Look for errors in PdfAS.java, method findBlockInText(...) to set the start_index accordingly.
- // Hint: Captions and values of landscape documents are separated with " \n" and not only with " ".
int newline_index = text.indexOf('\n', start_index);
if (newline_index < 0)
{
@@ -685,44 +702,213 @@ public class AbsoluteTextSignature
}
/**
- * Chooses the most possible (best choice) block of the list of semantically
- * equal blocks.
+ * Chooses the most possible (best choice) block of the list of blocks.
*
* <p>
- * Thus blocks are considered semantically equal if their required keys are
- * semantically equal, semantically equal blocks may still differ in the
- * number of their non required fields. This may lead to multiple found blocks
- * of the same size in characters, but where some blocks' elements swallow
- * elements found by other blocks.
+ * The strategy to find the most possible block is to choose the very one
+ * block with the maximum number of captions. This block has extracted most
+ * information from the text.
* </p>
* <p>
- * The strategy to avoid this is to choose the very one block with the maximum
- * number of captions. This block has extracted most information from the
- * text.
+ * If there are still multiple blocks with the same number of cations, the
+ * blocks are compared caption-wise. The block with all captions being longer
+ * or equal to all other blocks' captions wins.
* </p>
*
* @param found_blocks
* The List of semantically equal blocks.
* @return Returns the best choice FoundBlock.
+ * @throws SignatureException
+ */
+ public static FoundBlock chooseMostPossibleBlock(List found_blocks) throws SignatureException
+ {
+ // int largest_block_index = 0;
+ // FoundBlock largest_block = (FoundBlock) found_blocks.get(0);
+ //
+ // for (int i = 1; i < found_blocks.size(); i++)
+ // {
+ // FoundBlock current_block = (FoundBlock) found_blocks.get(i);
+ //
+ // if (current_block.found_keys.size() > largest_block.found_keys.size())
+ // {
+ // largest_block = current_block;
+ // largest_block_index = i;
+ // }
+ // }
+
+ List vertically_largest = filterVerticallyLargestBlocks(found_blocks);
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("vertically largest blocks:");
+ for (int i = 0; i < vertically_largest.size(); i++)
+ {
+ FoundBlock found_block = (FoundBlock) vertically_largest.get(i);
+
+ logger.debug(" #" + i + ": " + found_block);
+ }
+ }
+
+ List horizontally_largest = filterHorizontallyLargestBlocks(vertically_largest);
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("horizontally largest blocks:");
+ for (int i = 0; i < horizontally_largest.size(); i++)
+ {
+ FoundBlock found_block = (FoundBlock) horizontally_largest.get(i);
+
+ logger.debug(" #" + i + ": " + found_block);
+ }
+ }
+
+ FoundBlock largest_block = (FoundBlock) horizontally_largest.get(0);
+
+ logger.debug("Chose largest block: " + largest_block);
+ return largest_block;
+ }
+
+ /**
+ * Filters out all blocks but the vertically largest ones.
+ *
+ * <p>
+ * A vertically largest block has the most found keys.
+ * </p>
+ *
+ * @param found_blocks
+ * The List of FoundBlock objects to be filtered.
+ * @return Returns the List of the vertically largest FoundBlock objects.
*/
- public static FoundBlock chooseMostPossibleSemanticallyEqualBlock(
- List found_blocks)
+ public static List filterVerticallyLargestBlocks(List found_blocks)
{
- int largest_block_index = 0;
+ // determine the size of the largest block(s)
+ int largest_size = Integer.MIN_VALUE;
+ for (int i = 1; i < found_blocks.size(); i++)
+ {
+ FoundBlock fb = (FoundBlock) found_blocks.get(i);
+ final int current_size = fb.found_keys.size();
+ if (current_size > largest_size)
+ {
+ largest_size = current_size;
+ }
+ }
+
+ // keep all blocks that have the largest_size
+ List largest_blocks = new ArrayList();
+ for (int i = 0; i < found_blocks.size(); i++)
+ {
+ FoundBlock fb = (FoundBlock) found_blocks.get(i);
+ if (fb.found_keys.size() < largest_size)
+ {
+ continue;
+ }
+ largest_blocks.add(fb);
+ }
+
+ return largest_blocks;
+ }
+
+ /**
+ * Filters out all blocks but the horizonally largest ones.
+ *
+ * <p>
+ * A vertically largest block has the most found keys.
+ * </p>
+ *
+ * @param found_blocks
+ * The List of FoundBlock objects to be filtered. All of these
+ * FoundBlock objects must have the same number of found keys.
+ * @return Returns the List of the horizontally largest FoundBlock objects.
+ * @throws SignatureException
+ */
+ public static List filterHorizontallyLargestBlocks(List found_blocks) throws SignatureException
+ {
+ List horizontally_largest = new ArrayList();
FoundBlock largest_block = (FoundBlock) found_blocks.get(0);
+ horizontally_largest.add(largest_block);
for (int i = 1; i < found_blocks.size(); i++)
{
- FoundBlock current_block = (FoundBlock) found_blocks.get(i);
+ FoundBlock fb = (FoundBlock) found_blocks.get(i);
+
+ if (isHorizontallyEqual(fb, largest_block))
+ {
+ horizontally_largest.add(fb);
+ continue;
+ }
- if (current_block.found_keys.size() > largest_block.found_keys.size())
+ if (isHorizontallyLarger(fb, largest_block))
+ {
+ horizontally_largest = new ArrayList();
+ largest_block = fb;
+ horizontally_largest.add(largest_block);
+ }
+ else
{
- largest_block = current_block;
- largest_block_index = i;
+ if (!isHorizontallyLarger(largest_block, fb))
+ {
+ // The block is neither equal nor larger nor lower.
+ // We cannot exactly determine which one to use.
+ throw new SignatureException(315, "The blocks are neither larger nor lower nor equal. Cannot decide which one to pick. fb = " + fb + ", largest_block = " + largest_block);
+ }
}
+
}
- logger.debug("Chose largest block with index #" + largest_block_index + ": " + largest_block);
- return largest_block;
+ return horizontally_largest;
}
+
+ protected static boolean isHorizontallyEqual(FoundBlock fb0, FoundBlock fb1)
+ {
+ final int num_keys = fb0.found_keys.size();
+ if (num_keys != fb1.found_keys.size())
+ {
+ throw new IllegalArgumentException("Cannot compare FoundBlock keys: fb0 doesn't have the same number of keys as fb1. " + fb0.found_keys.size() + " vs. " + fb1.found_keys.size());
+ }
+
+ for (int i = 0; i < num_keys; i++)
+ {
+ FoundKey fk0 = (FoundKey) fb0.found_keys.get(i);
+ FoundKey fk1 = (FoundKey) fb1.found_keys.get(i);
+
+ if (fk0.caption.length() != fk1.caption.length())
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ protected static boolean isHorizontallyLarger(FoundBlock fb0, FoundBlock fb1)
+ {
+ final int num_keys = fb0.found_keys.size();
+ if (num_keys != fb1.found_keys.size())
+ {
+ throw new IllegalArgumentException("Cannot compare FoundBlock keys: fb0 doesn't have the same number of keys as fb1. " + fb0.found_keys.size() + " vs. " + fb1.found_keys.size());
+ }
+
+ boolean larger = false;
+
+ for (int i = 0; i < num_keys; i++)
+ {
+ FoundKey fk0 = (FoundKey) fb0.found_keys.get(i);
+ FoundKey fk1 = (FoundKey) fb1.found_keys.get(i);
+
+ if (fk0.caption.length() == fk1.caption.length())
+ {
+ continue;
+ }
+
+ if (fk0.caption.length() > fk1.caption.length())
+ {
+ larger = true;
+ continue;
+ }
+
+ // if (fk0.caption.length() < fk1.caption.length())
+ return false;
+ }
+
+ return larger;
+ }
+
}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java
index c5acbc4..e10061c 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/BinarySignature.java
@@ -667,17 +667,15 @@ public abstract class BinarySignature
* The original document.
* @param pdf_table
* The PdfPTable that contains the signature block.
- * @param pos
- * The Position object giving the exact location where to place the
- * table. if page is -1, a new page will be appended to the document.
- * Then the table will be inserted on that new page using the
- * coordinates.
+ * @param pi
+ * The PositioningInstruction telling the algorithm where to place
+ * the signature block.
* @return Returns the new document.
* @throws PresentableException
* Forwarded exception.
*/
public static IncrementalUpdateInformation writeIncrementalUpdate(
- byte[] original_document, PdfPTable pdf_table, TablePos pos,
+ byte[] original_document, PdfPTable pdf_table, PositioningInstruction pi,
List variable_field_definitions, List all_field_definitions) throws PresentableException
{
try
@@ -697,30 +695,20 @@ public abstract class BinarySignature
// The stamper allows this by setting append = true
PdfStamper stamper = new PdfStamper(reader, baos, '\0', true);
- int pdf_page_num = reader.getNumberOfPages();
-
- // int signature_page = -1;
- //
- // if (pos_y >= 0)
- // {
- // signature_page = pdf_page_num;
- // }
- if (pos.page == -1)
+ if (pi.isMakeNewPage())
{
- pos.page = pdf_page_num + 1;
+ int pdf_page_num = reader.getNumberOfPages();
Rectangle psize = reader.getPageSizeWithRotation(pdf_page_num);
Rectangle rect = new Rectangle(psize);
- stamper.insertPage(pos.page, rect);
-
- // pos_y *= -1;
+ stamper.insertPage(pdf_page_num + 1, rect);
}
- if (pos.page < 1 || pos.page > stamper.getReader().getNumberOfPages())
+ if (pi.getPage() < 1 || pi.getPage() > stamper.getReader().getNumberOfPages())
{
- throw new PDFDocumentException(224, "The provided pos.page (=" + pos.page + ") is out of range.");
+ throw new PDFDocumentException(224, "The provided page (=" + pi.getPage() + ") is out of range.");
}
- PdfContentByte content = stamper.getOverContent(pos.page);
+ PdfContentByte content = stamper.getOverContent(pi.getPage());
// content = StampContent einer PageStamp.
// System.out.println("table_width = " + pdf_table.getTotalWidth() + ",
@@ -741,27 +729,27 @@ public abstract class BinarySignature
// pdf_table.writeSelectedRows(0, -1, SIGNATURE_BORDER / 2,
// table_position, content);
- content.addTemplate(table_template, pos.pos_x, pos.pos_y - pdf_table.getTotalHeight());
+ content.addTemplate(table_template, pi.getX(), pi.getY() - pdf_table.getTotalHeight());
// For debugging print a 100x100 grid
-// {
-// Rectangle psize = reader.getPageSizeWithRotation(pos.page);
-// float page_width = psize.width();
-// float page_height = psize.height();
-// for (float x = 0; x < page_width; x += 100)
-// {
-// content.moveTo(x, 0);
-// content.lineTo(x, page_height);
-// content.stroke();
-// }
-// for (float y = 0; y < page_height; y += 100)
-// {
-// content.moveTo(0, y);
-// content.lineTo(page_width, y);
-// content.stroke();
-// }
-// }
-
+ // {
+ // Rectangle psize = reader.getPageSizeWithRotation(pos.page);
+ // float page_width = psize.width();
+ // float page_height = psize.height();
+ // for (float x = 0; x < page_width; x += 100)
+ // {
+ // content.moveTo(x, 0);
+ // content.lineTo(x, page_height);
+ // content.stroke();
+ // }
+ // for (float y = 0; y < page_height; y += 100)
+ // {
+ // content.moveTo(0, y);
+ // content.lineTo(page_width, y);
+ // content.stroke();
+ // }
+ // }
+
// content.setLineWidth(10.0f);
// content.moveTo(0, 0);
// content.lineTo(100, 100);
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java
index c98aee8..c1d6681 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java
@@ -66,14 +66,23 @@ public class PDFPage extends PDFTextStripper
protected float max_image_ypos = Float.NEGATIVE_INFINITY;
/**
- * The empty constructor.
+ * The y coordinate of the footer line. PDF elements below this footer line will not be regarded.
+ */
+ protected float footer_line = 0.0f;
+
+ /**
+ * Constructor.
+ *
+ * @param footer_line The y coordinate of the footer line. PDF elements below this footer line will not be regarded.
*
* @throws IOException
*/
- public PDFPage() throws IOException
+ public PDFPage(float footer_line) throws IOException
{
super();
+ this.footer_line = footer_line;
+
OperatorProcessor newInvoke = new MyInvoke();
newInvoke.setContext(this);
operators.put("Do", newInvoke);
@@ -341,17 +350,24 @@ public class PDFPage extends PDFTextStripper
*/
protected void showCharacter(TextPosition text)
{
- float current_y = text.getY();
- String character = text.getCharacter();
+ final float current_y = text.getY();
+ final String character = text.getCharacter();
+
+// if (current_y > this.footer_line)
+// {
+// 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;
- //logger_.debug("text.character=" + character + ", y=" + current_y);
+ logger_.debug("text.character=" + character + ", y=" + current_y);
// System.err.println(character + "|" + current_y);
}
- // logger_.debug("text.character=" + character + ", y=" + current_y);
+ logger_.debug("text.character=" + character + ", y=" + current_y);
// System.err.println(character + "|" + current_y);
}
@@ -454,6 +470,12 @@ public class PDFPage extends PDFTextStripper
logger_.debug("actual_lowest_point = " + actual_lowest_point);
+ if (actual_lowest_point > PDFPage.this.footer_line)
+ {
+ logger_.debug("image is below footer_line. footer_line = " + PDFPage.this.footer_line);
+ return;
+ }
+
if (actual_lowest_point > PDFPage.this.max_image_ypos)
{
PDFPage.this.max_image_ypos = actual_lowest_point;
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java
index 8fa3b35..05854dd 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java
@@ -38,7 +38,7 @@ import com.lowagie.text.DocumentException;
*/
public abstract class PDFUtilities
{
- public static float calculateLastPageLength(final byte[] pdf) throws PDFDocumentException
+ public static float calculateLastPageLength(final byte[] pdf, float footer_line) throws PDFDocumentException
{
try
{
@@ -53,7 +53,7 @@ public abstract class PDFUtilities
parser.parse();
PDDocument pdfDocument_ = parser.getPDDocument();
- float last_page_length = calculateLastPageLength(pdfDocument_);
+ float last_page_length = calculateLastPageLength(pdfDocument_, footer_line);
pdfDocument_.close();
return last_page_length;
@@ -68,20 +68,20 @@ public abstract class PDFUtilities
}
}
- public static float calculateLastPageLength(PDDocument document) throws IOException
+ public static float calculateLastPageLength(PDDocument document, float footer_line) throws IOException
{
int last_page_id = document.getNumberOfPages();
List allPages = document.getDocumentCatalog().getAllPages();
PDPage last_page = (PDPage) allPages.get(last_page_id - 1);
- return calculatePageLength(last_page);
+ return calculatePageLength(last_page, footer_line);
}
- public static float calculatePageLength(PDPage page) throws IOException
+ public static float calculatePageLength(PDPage page, float footer_line) throws IOException
{
// logger_.debug("Last Page id:" + last_page_id);
// PDPage last_page = (PDPage) allPages.get(0);
- PDFPage my_page = new PDFPage();
+ PDFPage my_page = new PDFPage(footer_line);
my_page.processStream(page, page.findResources(), page.getContents().getStream());
return my_page.getMaxPageLength();
}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java
new file mode 100644
index 0000000..c04177b
--- /dev/null
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java
@@ -0,0 +1,131 @@
+/**
+ * <copyright> Copyright (c) 2006 by Know-Center, Graz, Austria </copyright>
+ *
+ * This software is the confidential and proprietary information of Know-Center,
+ * Graz, Austria. You shall not disclose such Confidential Information and shall
+ * use it only in accordance with the terms of the license agreement you entered
+ * into with Know-Center.
+ *
+ * KNOW-CENTER MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ * NON-INFRINGEMENT. KNOW-CENTER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY
+ * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES.
+ *
+ * $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;
+ }
+
+}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java
index ba55cdf..6cfdded 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java
@@ -35,6 +35,22 @@ public class TablePos implements Serializable
/**
* The page on which the block should be displayed.
+ *
+ * <p>
+ * A value greater than or equal 1 means to absolutely position the signature
+ * on that page.
+ * </p>
+ * <p>
+ * A value of -1 means to append a new page to the document and absolutely
+ * position the signature on the new page.
+ * </p>
+ * <p>
+ * A value of -2 means to determine the length of the last page as without
+ * absolute positioning, but ignore all text below a certain footer line. If
+ * there is enough space between the end of the text and this footer line, the
+ * signature should be positioned automatically in there. Otherwise it should
+ * be placed on a new page.
+ * </p>
*/
public int page = 0;
@@ -53,4 +69,8 @@ public class TablePos implements Serializable
*/
public float width = 0.0f;
+ /**
+ * The top y position of the footer line.
+ */
+ public float footer_line = 0.0f;
}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/LocalConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/LocalConnector.java
index 13e0b65..65c79a9 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/LocalConnector.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/LocalConnector.java
@@ -17,6 +17,8 @@
*/
package at.knowcenter.wag.egov.egiz.sig;
+import java.util.Properties;
+
import at.knowcenter.wag.egov.egiz.exceptions.SignatureException;
/**
@@ -74,27 +76,25 @@ public interface LocalConnector extends Connector
/**
* Analyzes the sign response string.
*
- * @param response_string
- * The response string from the local service.
* @param signature_type
* The type of the signature.
* @return Returns the SignatureObject of the sign request.
* @throws SignatureException
* F.e.
*/
- public SignatureObject analyzeSignResponse(String response_string,
+ // TODO hotfix
+ public SignatureObject analyzeSignResponse(Properties response_properties,
String signature_type) throws SignatureException;
/**
* Analyzes the verify response string.
*
- * @param response_string
- * The response string from the local service.
* @return Returns the SignatureResponse of the verify request.
* @throws SignatureException
* F.e.
*/
- public SignatureResponse analyzeVerifyResponse(String response_string) throws SignatureException;
+ // TODO hotfix
+ public SignatureResponse analyzeVerifyResponse(Properties response_properties) throws SignatureException;
/**
* Returns the sign URL of the local service.
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java
index 9a7a036..ae50c5e 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java
@@ -31,6 +31,7 @@ import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
import java.util.Set;
import java.util.Vector;
@@ -41,13 +42,14 @@ import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger;
import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
import at.knowcenter.wag.egov.egiz.exceptions.InvalidIDException;
import at.knowcenter.wag.egov.egiz.exceptions.NormalizeException;
+import at.knowcenter.wag.egov.egiz.exceptions.SettingNotFoundException;
import at.knowcenter.wag.egov.egiz.exceptions.SettingsException;
import at.knowcenter.wag.egov.egiz.exceptions.SignatureException;
import at.knowcenter.wag.egov.egiz.exceptions.SignatureTypesException;
-import at.knowcenter.wag.egov.egiz.framework.SignatorFactory;
import at.knowcenter.wag.egov.egiz.ldap.api.LDAPAPIException;
import at.knowcenter.wag.egov.egiz.ldap.api.LDAPAPIFactory;
import at.knowcenter.wag.egov.egiz.ldap.client.LDAPIssuerNameFilter;
+import at.knowcenter.wag.egov.egiz.framework.SignatorFactory;
import at.knowcenter.wag.egov.egiz.table.Entry;
import at.knowcenter.wag.egov.egiz.table.Style;
import at.knowcenter.wag.egov.egiz.table.Table;
@@ -181,7 +183,7 @@ public class SignatureObject implements Serializable
* </p>
*/
protected String raw_signature_response = null;
-
+
/**
* Filters the issuer name in order to find matches.
* @author tknall
@@ -199,8 +201,6 @@ public class SignatureObject implements Serializable
}
};
-
-
/**
* The empty constructor. It initilize the normlizer, load the settings and
* set the default styles.
@@ -270,7 +270,6 @@ public class SignatureObject implements Serializable
defaultImageStyle_.setPadding(3);
defaultImageStyle_.setHAlign(Style.CENTER);
defaultImageStyle_.setVAlign(Style.MIDDLE);
-// defaultImageStyle_.setBgColor(new Color(255, 255, 255));
defaultImageStyle_.setBgColor(null);
defaultCaptionStyle_.setHAlign(Style.CENTER);
@@ -737,20 +736,42 @@ public class SignatureObject implements Serializable
setSigValue(SignatureTypes.SIG_ID, sigIds);
}
- /**
- * Set the signation id's build by a BKU signated SignatureObject.
- *
- * @param sigIds
- * The sination id's are defined into five parts, that have the same
- * base as prefix. Therefore the ids's are reduced by the base prefix
- * and stored in the SignatureObject.
- */
- public void setSignationIDs(String[] sigIds)
+ // /**
+ // * Set the signation id's build by a BKU signated SignatureObject.
+ // *
+ // * @param sigIds
+ // * The sination id's are defined into five parts, that have the same
+ // * base as prefix. Therefore the ids's are reduced by the base prefix
+ // * and stored in the SignatureObject.
+ // */
+ // public void setSignationIDs(String[] sigIds)
+ // {
+ // String join = "";
+ // String base = null;
+ // for (int arr_idx = 0; arr_idx < sigIds.length; arr_idx++)
+ // {
+ // String id = sigIds[arr_idx];
+ // if (logger_.isDebugEnabled())
+ // {
+ // logger_.debug("Set BKU id:" + id);
+ // }
+ // int id_idx = id.lastIndexOf("-");
+ // if (arr_idx == 0)
+ // {
+ // base = id.substring(0, id_idx);
+ // }
+ // String cur_id = id.substring(id_idx + 1);
+ // join += "-" + cur_id;
+ // }
+ // setSignationIDs(base + "@" + join.substring(1));
+ // }
+
+ // TODO hotfix
+ public static String formatSigIds(Properties response_properties,
+ String[] sigIds) throws SignatureException
{
-
- // FIXME[tknall]: implement workaround resp. failsafe behaviour for ids like "Signature-123456789"
-
- String join = "";
+ // ids algorithm:
+ String join = "";
String base = null;
for (int arr_idx = 0; arr_idx < sigIds.length; arr_idx++)
{
@@ -767,7 +788,47 @@ public class SignatureObject implements Serializable
String cur_id = id.substring(id_idx + 1);
join += "-" + cur_id;
}
- setSignationIDs(base + "@" + join.substring(1));
+ // setSignationIDs(base + "@" + join.substring(1));
+ String ids = base + "@" + join.substring(1);
+ // :ids algorithm
+
+ String productName = response_properties.getProperty("productName");
+ logger_.debug("productName = " + productName);
+ if (!productName.equals("trustDeskbasic"))
+ {
+ final String msg = "The BKU environment " + productName + " is not trustDeskbasic and therefore the productVersion cannot be decided.";
+ logger_.error(msg);
+ throw new SignatureException(0, msg);
+ }
+
+ String productVersion = response_properties.getProperty("productVersion");
+ logger_.debug("productVersion = " + productVersion);
+ boolean new_etsi = decideNewEtsiByBKUVersion(productVersion);
+ logger_.debug("verwende neue etsi properties = " + new_etsi);
+
+ String etsi_prefix = "";
+ if (new_etsi)
+ {
+ // TODO hotfix
+ etsi_prefix = "etsi-bka-1.0@";
+ }
+
+ String final_ids = etsi_prefix + ids;
+ logger_.debug("final_ids = " + final_ids);
+
+ return final_ids;
+ }
+
+ // TODO hotfix
+ public static boolean decideNewEtsiByBKUVersion(String productVersion)
+ {
+ boolean new_etsi = true;
+ // TODO make better
+ if (productVersion.startsWith("2.5") || productVersion.startsWith("2.4") || productVersion.startsWith("2.3") || productVersion.startsWith("2.2") || productVersion.startsWith("2.1") || productVersion.startsWith("1") || productVersion.startsWith("0"))
+ {
+ new_etsi = false;
+ }
+ return new_etsi;
}
/**
@@ -837,9 +898,51 @@ public class SignatureObject implements Serializable
*
* @return the id array
*/
- public String[] getSignationIds()
+ // TODO hotifx
+ public String getSignationIds()
{
String sig_ids = getSigValue(SignatureTypes.SIG_ID);
+ return sig_ids;
+
+ // if (sig_ids == null || sig_ids.length() == 0)
+ // {
+ // return null;
+ // }
+ //
+ // // int index = sig_ids.indexOf(PdfAS.IDS);
+ // // if (index < 0)
+ // // {
+ // // return null;
+ // // }
+ // // sig_ids = sig_ids.substring(index + PdfAS.IDS.length());
+ // //
+ // // if (sig_ids == null || sig_ids.length() == 0)
+ // // {
+ // // return null;
+ // // }
+ //
+ // String[] ids_str = sig_ids.split("@");
+ // String base = ids_str[0];
+ // String[] ids = ids_str[1].split("-");
+ // String[] real_ids = new String[5];
+ // real_ids[0] = base + "-" + ids[0];
+ // real_ids[1] = "0-" + base + "-" + ids[1];
+ // real_ids[2] = "0-" + base + "-" + ids[2];
+ // real_ids[3] = "0-" + base + "-" + ids[3];
+ // real_ids[4] = "0-" + base + "-" + ids[4];
+ // if (logger_.isDebugEnabled())
+ // {
+ // for (int id_idx = 0; id_idx < real_ids.length; id_idx++)
+ // {
+ // logger_.debug("Set BKU id:" + real_ids[id_idx]);
+ // }
+ // }
+ // return real_ids;
+ }
+
+ // TODO hotfix
+ public static String[] parseSigIds(String sig_ids)
+ {
if (sig_ids == null || sig_ids.length() == 0)
{
return null;
@@ -858,21 +961,33 @@ public class SignatureObject implements Serializable
// }
String[] ids_str = sig_ids.split("@");
+
+ String etsi_string = null;
+ if (ids_str.length == 3)
+ {
+ etsi_string = ids_str[0];
+ String[] rest_ids = new String[] { ids_str[1], ids_str[2] };
+ ids_str = rest_ids;
+ }
+
String base = ids_str[0];
String[] ids = ids_str[1].split("-");
- String[] real_ids = new String[5];
+ String[] real_ids = new String[6]; // the last one contains the etsi string
real_ids[0] = base + "-" + ids[0];
real_ids[1] = "0-" + base + "-" + ids[1];
real_ids[2] = "0-" + base + "-" + ids[2];
real_ids[3] = "0-" + base + "-" + ids[3];
real_ids[4] = "0-" + base + "-" + ids[4];
+ real_ids[5] = etsi_string;
+
if (logger_.isDebugEnabled())
{
for (int id_idx = 0; id_idx < real_ids.length; id_idx++)
{
- logger_.debug("Set BKU id:" + real_ids[id_idx]);
+ logger_.debug("real_ids[" + id_idx + "] = " + real_ids[id_idx]);
}
}
+
return real_ids;
}
@@ -1364,6 +1479,12 @@ public class SignatureObject implements Serializable
}
SignatureTypes sig_types = SignatureTypes.getInstance();
signatureDefinition_ = sig_types.getSignatureTypeDefinition(sigType_);
+ if (signatureDefinition_ == null)
+ {
+ final String msg = "The SignatureObject's sigType '" + sigType_ + "' wasn't found in the configuration file's specified signature profiles. This usually happens if the sig_obj.type.default object has been turned off or is misspelled.";
+ logger_.error(msg);
+ throw new SignatureTypesException(msg);
+ }
Map key_cap_map = signatureDefinition_.getKeyCaptionMap();
if (key_cap_map != null)
{
@@ -1409,10 +1530,10 @@ public class SignatureObject implements Serializable
}
}
// value = new String(CodingHelper.encodeUTF8(value));
-// if (logger_.isDebugEnabled())
-// {
-// logger_.debug("key:" + key + " value:" + value);
-// }
+ // if (logger_.isDebugEnabled())
+ // {
+ // logger_.debug("key:" + key + " value:" + value);
+ // }
setSigValue(key, value);
}
}
@@ -1534,6 +1655,4 @@ public class SignatureObject implements Serializable
return strg;
}
-
-
} \ No newline at end of file
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUConnector.java
index 3b672f1..6327a11 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUConnector.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUConnector.java
@@ -18,6 +18,7 @@
package at.knowcenter.wag.egov.egiz.sig.connectors;
import java.io.UnsupportedEncodingException;
+import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -116,9 +117,9 @@ public class BKUConnector implements LocalConnector
String request_string = prepareSignRequest(userName, signText, sigType);
String sign_url = getSignURL(sigType);
- String response_string = sendRequest(sign_url, request_string);
+ Properties response_properties = sendRequest(sign_url, request_string);
- return analyzeSignResponse(response_string, sigType);
+ return analyzeSignResponse(response_properties, sigType);
}
/**
@@ -140,9 +141,9 @@ public class BKUConnector implements LocalConnector
String request_string = prepareVerifyRequest(normalizedText, sigObject);
String verify_url = getVerifyURL(sigObject.getSignationType());
- String response_string = sendRequest(verify_url, request_string);
+ Properties response_properties = sendRequest(verify_url, request_string);
- return analyzeVerifyResponse(response_string);
+ return analyzeVerifyResponse(response_properties);
}
/**
@@ -162,8 +163,10 @@ public class BKUConnector implements LocalConnector
* @see CodingHelper
* @see X509Cert
*/
- private void parseCreateXMLResponse(String xmlResponse, SignatureObject sigObj) throws SignatureException
+ private void parseCreateXMLResponse(Properties response_properties, SignatureObject sigObj) throws SignatureException
{
+ String xmlResponse = response_properties.getProperty("response_string");
+
Pattern sig_val_p_s = Pattern.compile("<[\\w]*:?SignatureValue>");
Pattern sig_val_p_e = Pattern.compile("</[\\w]*:?SignatureValue>");
Pattern iss_nam_p_s = Pattern.compile("<[\\w]*:?X509IssuerName>");
@@ -266,7 +269,11 @@ public class BKUConnector implements LocalConnector
ids[2] = extractId(xmlResponse, "signed-data-object-");
ids[3] = extractId(xmlResponse, "etsi-data-reference-");
ids[4] = extractId(xmlResponse, "etsi-data-object-");
- sigObj.setSignationIDs(ids);
+
+ //TODO hotfix
+ String final_ids =SignatureObject.formatSigIds(response_properties, ids);
+ //sigObj.setSignationIDs(ids);
+ sigObj.setSignationIDs(final_ids);
}
/**
@@ -283,6 +290,13 @@ public class BKUConnector implements LocalConnector
String id = null;
int start_idx = text.indexOf(name) + name.length();
int end_idx = text.indexOf("\"", start_idx);
+
+ // TODO hotfix!
+ final int quot_end_idx = end_idx;
+ final int squot_end_idx = text.indexOf("'", start_idx);
+ end_idx = Math.min(quot_end_idx, squot_end_idx);
+ // TODO hotfix end!
+
id = text.substring(start_idx, end_idx);
if (logger_.isDebugEnabled())
{
@@ -324,6 +338,21 @@ public class BKUConnector implements LocalConnector
String verify_template = getVerifyTemplateFileName(sigObject.getSignationType());
String sig_prop_filename = getSigPropFileName(sigObject.getSignationType());
+ String ids_string = sigObject.getSignationIds();
+ logger_.debug("ids_string = " + ids_string);
+ String[] ids = SignatureObject.parseSigIds(ids_string);
+
+ // TODO hotfix
+ final boolean neue_bku = ids[5] != null;
+ logger_.debug("ids[5] = " + ids[5]);
+ logger_.debug("neue_bku = " + neue_bku);
+ if (neue_bku)
+ {
+ verify_template = getConnectorValueFromProfile(sigObject.getSignationType(), "bku.verify.template2"); //"./templates/BKUVerifyTemplateB64_neueBKU.xml";
+ sig_prop_filename = getConnectorValueFromProfile(sigObject.getSignationType(), "bku.verify.template2.SP"); //"./templates/BKUVerifyTemplateSP_neueBKU.xml";
+ }
+
+
String ver_temp_str = FileHelper.readFromFile(SettingsReader.relocateFile(verify_template));
String sig_prop_str = FileHelper.readFromFile(SettingsReader.relocateFile(sig_prop_filename));
if (logger_.isDebugEnabled())
@@ -345,8 +374,7 @@ public class BKUConnector implements LocalConnector
cert_alg = settings_.getValueFromKey("cert.alg.rsa");
}
- String[] ids = sigObject.getSignationIds();
- sig_prop_str = sig_prop_str.replaceFirst("SigningTimeReplace", sigObject.getSignationDate());
+ sig_prop_str = sig_prop_str.replaceFirst("SigningTimeReplace", sigObject.getSignationDate());
String issuer_name = sigObject.getSignationIssuer();
// The issuer is already unicode, so it mustn't be encoded again.
@@ -362,6 +390,26 @@ public class BKUConnector implements LocalConnector
ver_temp_str = ver_temp_str.replaceFirst("CertAlgReplace", cert_alg);
ver_temp_str = ver_temp_str.replaceFirst("TemplateQualifyingPropertiesReplace", sig_prop_str);
byte[] sig_prop_code = CodingHelper.buildDigest(sig_prop_str.getBytes("UTF-8"));
+
+ // TODO hotfix
+ if (neue_bku)
+ {
+ final String ETSI_SIGNED_PROPERTIES_START_TAG = "<etsi:SignedProperties"; // xml name spaces follow, so this is not a complete tag...
+ final String ETSI_SIGNED_PROPERTIES_END_TAG = "</etsi:SignedProperties>";
+
+ final int hash_start = sig_prop_str.indexOf(ETSI_SIGNED_PROPERTIES_START_TAG);
+ assert hash_start >= 0;
+ final int hash_end = sig_prop_str.indexOf(ETSI_SIGNED_PROPERTIES_END_TAG, hash_start) + ETSI_SIGNED_PROPERTIES_END_TAG.length();
+ assert hash_end - ETSI_SIGNED_PROPERTIES_END_TAG.length() >= 0;
+ assert hash_end > hash_start;
+
+ final String string_to_be_hashed = sig_prop_str.substring(hash_start, hash_end);
+ logger_.debug("etsi:SignedProperties string to be hashed: " + string_to_be_hashed);
+
+ final byte [] bytes_to_be_hashed = string_to_be_hashed.getBytes("UTF-8");
+ sig_prop_code = CodingHelper.buildDigest(bytes_to_be_hashed);
+ }
+
String sig_prop_hash = CodingHelper.encodeBase64(sig_prop_code);
ver_temp_str = ver_temp_str.replaceFirst("DigestValueSignedPropertiesReplace", sig_prop_hash);
if (logger_.isDebugEnabled())
@@ -445,7 +493,7 @@ public class BKUConnector implements LocalConnector
Pattern cert_qualified_p = Pattern.compile("<sl:QualifiedCertificate/>");
Matcher cert_qualified_m = cert_qualified_p.matcher(xmlResponse);
// [tknall] stop qualified certificate
-
+
Pattern code_p_s = Pattern.compile("<sl:Code>");
Pattern code_p_e = Pattern.compile("</sl:Code>");
Pattern info_p_s = Pattern.compile("<sl:Info>");
@@ -472,7 +520,7 @@ public class BKUConnector implements LocalConnector
Matcher cert_m_e = cert_p_e.matcher(xmlResponse);
SignatureResponse sig_res = new SignatureResponse();
-
+
// [tknall] start qualified certificate
sig_res.setQualifiedCertificate(cert_qualified_m.find());
// [tknall] stop qualified certificate
@@ -613,7 +661,7 @@ public class BKUConnector implements LocalConnector
verify_req_str = verify_req_str.replaceFirst("XMLContentReplace", verify_template_str);
if (logger_.isDebugEnabled())
{
- //logger_.debug(verify_request + "_request.xml : " + verify_req_str);
+ logger_.debug("verify_req_str.xml : " + verify_req_str);
}
return verify_req_str;
@@ -630,12 +678,12 @@ public class BKUConnector implements LocalConnector
* @throws SignatureException
* F.e.
*/
- protected String sendRequest(String url, String request_string) throws SignatureException
+ protected Properties sendRequest(String url, String request_string) throws SignatureException
{
try
{
- String response_string = BKUPostConnection.doPostRequest(url, request_string);
- return response_string;
+ Properties response_properties = BKUPostConnection.doPostRequest(url, request_string);
+ return response_properties;
}
catch (Exception e)
{
@@ -644,11 +692,14 @@ public class BKUConnector implements LocalConnector
}
}
- public SignatureObject analyzeSignResponse(String response_string,
+ public SignatureObject analyzeSignResponse(Properties response_properties,
String sigType) throws SignatureException
{
//String sign_request_filename = getSignRequestTemplateFileName(sigType);
+ // TODO hotfix
+ String response_string = response_properties.getProperty("response_string");
+
SignatureObject sig_obj = new SignatureObject();
sig_obj.setRawSignatureResponse(response_string);
try
@@ -699,17 +750,19 @@ public class BKUConnector implements LocalConnector
{
if (logger_.isDebugEnabled())
{
- //logger_.debug(sign_request_filename + "_response.xml : " + response_string);
+ logger_.debug("signature_response_string: " + response_string);
}
- parseCreateXMLResponse(response_string, sig_obj);
+ parseCreateXMLResponse(response_properties, sig_obj);
}
}
sig_obj.setSigResponse(response_string);
return sig_obj;
}
- public SignatureResponse analyzeVerifyResponse(String response_string) throws SignatureException
+ public SignatureResponse analyzeVerifyResponse(Properties response_properties) throws SignatureException
{
+ String response_string = response_properties.getProperty("response_string");
+
if (!response_string.equals(""))
{
Pattern erc_p_s = Pattern.compile("<[\\w]*:?ErrorCode>");
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUPostConnection.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUPostConnection.java
index 773b248..1ddef5f 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUPostConnection.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/BKUPostConnection.java
@@ -18,7 +18,11 @@
package at.knowcenter.wag.egov.egiz.sig.connectors;
import java.io.IOException;
+import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.NameValuePair;
@@ -52,7 +56,7 @@ public abstract class BKUPostConnection
* @throws HttpException
* ErrorCode:320
*/
- public static String doPostRequest(String url, String request) throws HttpException, IOException
+ public static Properties doPostRequest(String url, String request) throws HttpException, IOException
{
PostMethod post_method = new PostMethod(url);
@@ -81,6 +85,23 @@ public abstract class BKUPostConnection
int method_response = http_client.executeMethod(post_method);
logger_.debug("method_response = " + method_response);
+ Properties response_properties = new Properties();
+
+ if (logger_.isDebugEnabled())
+ {
+ Header[] response_headers = post_method.getResponseHeaders();
+ logger_.debug("#" + response_headers.length + " headers in response:");
+ for (int i = 0; i < response_headers.length; i++)
+ {
+ logger_.debug(" response_header[" + i + "]: name = " + response_headers[i].getName() + ", value = " + response_headers[i].getValue());
+ }
+ }
+
+ Header server_header = post_method.getResponseHeader("Server");
+ logger_.debug("server_header: name = " + server_header.getName() + ", value = " + server_header.getValue());
+ parseBKUVersion(server_header.getValue(), response_properties);
+
+
byte[] response_body = post_method.getResponseBody();
String response_string = new String(response_body, "UTF-8");
@@ -89,7 +110,36 @@ public abstract class BKUPostConnection
// response.
// String response_string = post.getResponseBodyAsString();
- return response_string;
+ response_properties.setProperty("response_string", response_string);
+
+ return response_properties;
}
+ // TODO hotfix
+ public static void parseBKUVersion(String header_value, Properties properties)
+ {
+ Pattern pattern = Pattern.compile("^citizen-card-environment/(\\d+\\.\\d+) (.+)/(\\d+\\.\\d+\\.\\d+)$");
+ Matcher m = pattern.matcher(header_value);
+
+ m.matches();
+
+ logger_.debug("group count = " + m.groupCount());
+
+ for (int i = 0; i <= m.groupCount(); i++)
+ {
+ logger_.debug(" group[" + i + "] = " + m.group(i));
+ }
+
+ final String cceVersion = m.group(1);
+ final String productName = m.group(2);
+ final String productVersion = m.group(3);
+
+ logger_.debug("cceVersion = " + cceVersion);
+ logger_.debug("productName = " + productName);
+ logger_.debug("productVersion = " + productVersion);
+
+ properties.setProperty("cceVersion", cceVersion);
+ properties.setProperty("productName", productName);
+ properties.setProperty("productVersion", productVersion);
+ }
}
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousDataResponder.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousDataResponder.java
index 847bbcf..52846f5 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousDataResponder.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousDataResponder.java
@@ -18,7 +18,9 @@
package at.knowcenter.wag.egov.egiz.web;
import java.io.IOException;
+import java.util.Enumeration;
import java.util.List;
+import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@@ -34,6 +36,7 @@ import org.apache.log4j.Logger;
import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger;
import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
+import at.knowcenter.wag.egov.egiz.sig.connectors.BKUPostConnection;
/**
* Servlet that responds to the data post requests of the local service (e.g.
@@ -143,7 +146,23 @@ public class AsynchronousDataResponder extends HttpServlet
}
- si.response_string[si.current_operation] = resp_string; //request.getParameter("XMLResponse");
+ // TODO hotfix
+ if (logger_.isDebugEnabled())
+ {
+ Enumeration header_names = request.getHeaderNames();
+ while (header_names.hasMoreElements())
+ {
+ String header_name = (String)header_names.nextElement();
+ String header_value = request.getHeader(header_name);
+ logger_.debug("header: name = " + header_name + ", value = " +header_value);
+ }
+ }
+ String user_agent = request.getHeader("User-Agent");
+ logger_.debug("User-Agent header = " + user_agent);
+ Properties response_properties = new Properties();
+ BKUPostConnection.parseBKUVersion(user_agent, response_properties);
+ response_properties.setProperty("response_string", resp_string);
+ si.response_properties[si.current_operation] = response_properties; //request.getParameter("XMLResponse");
//logger_.debug("AsyncDataResponder: si.response_string[si.current_operation] = " + si.response_string[si.current_operation]);
si.current_operation++;
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousRedirectResponder.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousRedirectResponder.java
index b79dd87..031b03c 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousRedirectResponder.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/AsynchronousRedirectResponder.java
@@ -147,9 +147,9 @@ public class AsynchronousRedirectResponder extends HttpServlet
{
List results = new ArrayList();
- for (int i = 0; i < si.response_string.length; i++)
+ for (int i = 0; i < si.response_properties.length; i++)
{
- SignatureResponse sig_resp = local_conn.analyzeVerifyResponse(si.response_string[i]);
+ SignatureResponse sig_resp = local_conn.analyzeVerifyResponse(si.response_properties[i]);
results.add(sig_resp);
}
@@ -176,7 +176,7 @@ public class AsynchronousRedirectResponder extends HttpServlet
// has already been computed - don't recompute it.
if (si.sign_result == null)
{
- si.iui.signed_signature_object = local_conn.analyzeSignResponse(si.response_string[0], si.type);
+ si.iui.signed_signature_object = local_conn.analyzeSignResponse(si.response_properties[0], si.type);
PdfASID algorithm = FormFields.translateSignatureModeToPdfASID(si.mode);
Signator signator = SignatorFactory.createSignator(algorithm);
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/LocalRequestHelper.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/LocalRequestHelper.java
index 50bea41..95f72ef 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/web/LocalRequestHelper.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/LocalRequestHelper.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
+import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -82,8 +83,8 @@ public abstract class LocalRequestHelper
si.requests = new LocalRequest[1];
si.requests[0] = new LocalRequest(local_conn.getSignURL(si.type), request_string);
si.current_operation = 0;
- si.response_string = new String[1];
- si.response_string[0] = null;
+ si.response_properties = new Properties[1];
+ si.response_properties[0] = null;
// SessionTable.put(si);
request.getSession().setAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION, si);
@@ -113,7 +114,7 @@ public abstract class LocalRequestHelper
HttpServletResponse response) throws SignatureException, NormalizeException, IOException, ConnectorFactoryException
{
si.requests = new LocalRequest[holders_to_verify.size()];
- si.response_string = new String[si.requests.length];
+ si.response_properties = new Properties[si.requests.length];
si.current_operation = 0;
si.finished = false;
@@ -134,7 +135,7 @@ public abstract class LocalRequestHelper
LocalRequest local_request = new LocalRequest(local_conn.getVerifyURL(holder.getSignatureObject().getSignationType()), request_string);
si.requests[i] = local_request;
- si.response_string[i] = null;
+ si.response_properties[i] = null;
}
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/SessionInformation.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/SessionInformation.java
index f3c34d3..52a51a3 100644
--- a/src/main/java/at/knowcenter/wag/egov/egiz/web/SessionInformation.java
+++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/SessionInformation.java
@@ -19,6 +19,7 @@ package at.knowcenter.wag.egov.egiz.web;
import java.io.Serializable;
import java.util.List;
+import java.util.Properties;
import at.knowcenter.wag.egov.egiz.framework.SignResult;
import at.knowcenter.wag.egov.egiz.pdf.IncrementalUpdateInformation;
@@ -91,7 +92,7 @@ public class SessionInformation implements Serializable
/**
* An array of response strings of the local requests.
*/
- public String[] response_string = null;
+ public Properties[] response_properties = null;
/**
* Tells, if the current local request has been finished.
diff --git a/src/main/java/com/lowagie/text/pdf/PdfDictionary.java b/src/main/java/com/lowagie/text/pdf/PdfDictionary.java
index f7310e4..acf84d5 100644
--- a/src/main/java/com/lowagie/text/pdf/PdfDictionary.java
+++ b/src/main/java/com/lowagie/text/pdf/PdfDictionary.java
@@ -105,11 +105,20 @@ public class PdfDictionary extends PdfObject {
/** This is the hashmap that contains all the values and keys of the dictionary */
protected HashMap hashMap;
+
+ // EGIZ various modifications
/**
* This list preserves the order of the elements.
+ *
+ * <p>
+ * If an element to be added to the list already exists in the list,
+ * it sould not be added as the contents of this new element
+ * overwrites the contents of the old element in the hash map.
+ * </p>
*/
protected List list;
+
// constructors
/**
@@ -175,8 +184,13 @@ public class PdfDictionary extends PdfObject {
*/
public void put(PdfName key, PdfObject value) {
+ if (!hashMap.containsKey(key))
+ {
+ // If the key is new, add it to the ordered list.
+ // If not, it already has a position in the list.
+ list.add(key);
+ }
hashMap.put(key, value);
- list.add(key);
}
/**