aboutsummaryrefslogtreecommitdiff
path: root/pdf-as-lib/src/main/java/at/gv/egiz
diff options
context:
space:
mode:
Diffstat (limited to 'pdf-as-lib/src/main/java/at/gv/egiz')
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/Constants.java33
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/DynamicSignatureProfileImpl.java8
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/SignatureProfile.java11
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/sign/SignParameters.java78
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/commandline/Main.java123
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java13
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/CsvStatisticLogger.java105
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticData.java314
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticLogFactory.java63
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticLogger.java47
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java441
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/DataSinkAdapter.java6
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/SignatureProfileImpl.java49
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/input/correction/InternalCorrector.java9
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java16
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/detached/DetachedTextualSignator_1_0_0.java7
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java218
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java19
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/FileBasedTextBasedDataSource.java3
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/StringTextBasedDataSource.java5
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/placeholder/SignaturePlaceholderExtractor.java37
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/CsvUtils.java82
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/PDFASUtils.java268
23 files changed, 1488 insertions, 467 deletions
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/Constants.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/Constants.java
index b351d50..4afec65 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/Constants.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/Constants.java
@@ -27,7 +27,7 @@ import at.knowcenter.wag.egov.egiz.pdf.AdobeSignatureHelper;
/**
* Contains commonly used constants.
- *
+ *
* @author wprinz
*/
public final class Constants
@@ -52,7 +52,7 @@ public final class Constants
* This value should not be modified due to external dependencies!
*/
public static final String SIGNATURE_TYPE_TEXTUAL = "textual";
-
+
/**
* The default signature type (one of "textual", "binary", "detachedtextual").
*/
@@ -60,7 +60,7 @@ public final class Constants
/**
* A "detached" textual signature.
- *
+ *
* <p>
* The document text is signed, but instead of returning the pdf with the signature block,
* the sign result XML of the connector is returned.
@@ -98,14 +98,14 @@ public final class Constants
* This value should not be modified due to external dependencies!
*/
public static final String SIGNATURE_DEVICE_MOBILE = "mobile";
-
+
/**
* Added by rpiazzi
* The signature device MOBILETEST for the test version of the MOBILE CCS.
* This value should not be modified due to external dependencies!
*/
public static final String SIGNATURE_DEVICE_MOBILETEST = "mobiletest";
-
+
/**
* Only binary signatures are verified.
*/
@@ -113,7 +113,7 @@ public final class Constants
/**
* Binary and textual signatures are verified with time optimization.
- *
+ *
* <p>
* This mode of operation tries to minimize the numbers of text extractions,
* which are very time intensive, at the cost of some rare cases, in which some
@@ -141,19 +141,19 @@ public final class Constants
* The zip file containing the default configuration.
*/
public static final String DEFAULT_CONFIGURATION_ZIP_RESOURCE = "DefaultConfiguration.zip";
-
+
/**
* The configuration folder for pdf-as within the user's home folder.
*/
public static final String USERHOME_CONFIG_FOLDER = "PDF-AS";
-
+
/**
* The name of the directory, where temporary files are stored.
*/
public static final String TEMP_DIR_NAME = "pdfastmp";
-
+
public static final String BKU_HEADER_SIGNATURE_LAYOUT = "SignatureLayout";
-
+
public static final String ADOBE_SIG_FILTER = AdobeSignatureHelper.ADOBE_SIG_FILTER;
/**
@@ -161,25 +161,30 @@ public final class Constants
* If the placeholder with the given id is not found in the document, an exception will be thrown.
*/
public static final int PLACEHOLDER_MATCH_MODE_STRICT = 0;
-
+
/**
* A moderate matching mode for placeholder extraction.<br/>
* If the placeholder with the given id is not found in the document, the first placeholder without an id will be taken.<br/>
* If there is no such placeholder, the signature will be placed as usual, according to the pos parameter of the signature profile used.
*/
public static final int PLACEHOLDER_MATCH_MODE_MODERATE = 1;
-
+
/**
* A more lenient matching mode for placeholder extraction.<br/>
* If the placeholder with the given id is not found in the document, the first found placeholder will be taken, regardless if it has an id set, or not.<br/>
* If there is no placeholder at all, the signature will be placed as usual, according to the pos parameter of the signature profile used.
*/
public static final int PLACEHOLDER_MATCH_MODE_LENIENT = 2;
-
+
/**
* Identifier for QR based placeholders.
*/
public static final String QR_PLACEHOLDER_IDENTIFIER = "PDF-AS-POS";
-
+
+ /**
+ * The name of a logger used for statistical logging.
+ */
+ public static final String STATISTIC_LOGGER_NAME = "statistic";
+
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/DynamicSignatureProfileImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/DynamicSignatureProfileImpl.java
index 7e1672a..e1f31f7 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/DynamicSignatureProfileImpl.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/DynamicSignatureProfileImpl.java
@@ -159,8 +159,10 @@ public class DynamicSignatureProfileImpl implements DynamicSignatureProfile {
cfg = SettingsReader.getInstance();
- Properties props = cfg.getProperties();
- for (Enumeration e = props.keys(); e.hasMoreElements();) {
+ Properties props = cfg.getProperties();
+ // DTI: props.keys() does not support default properties, therefore we should better use props.propertyNames()
+// for (Enumeration e = props.keys(); e.hasMoreElements();) {
+ for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
String oldKey = (String) e.nextElement();
if (oldKey.startsWith("sig_obj." + parentProfile + ".")) {
String newKey = StringUtils.replace(oldKey, parentProfile, name);
@@ -168,7 +170,7 @@ public class DynamicSignatureProfileImpl implements DynamicSignatureProfile {
this.newProps.put(newKey, val);
}
}
- this.newProps.put("sig_obj.types." + name, "on");
+ this.newProps.put("sig_obj.types." + name, "on");
} catch (Exception e) {
throw new RuntimeException(e);
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/SignatureProfile.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/SignatureProfile.java
index 8cd3108..1325d04 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/SignatureProfile.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/commons/SignatureProfile.java
@@ -25,6 +25,8 @@ package at.gv.egiz.pdfas.api.commons;
import java.util.Properties;
+import at.knowcenter.wag.egov.egiz.sig.SignatureTypes.State;
+
/**
* Definition of a signature profile.
*
@@ -73,4 +75,13 @@ public interface SignatureProfile {
* @return
*/
public boolean isDefault();
+
+ /**
+ * Returns the state of the signature profile. Signature profiles may be restricted to signature (
+ * {@link State#SIGN_ONLY}) or to verification ({@link State#VERIFY_ONLY}).
+ *
+ * @return The state of the profile.
+ */
+ public State getState();
+
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/sign/SignParameters.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/sign/SignParameters.java
index 8834481..5533b8b 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/sign/SignParameters.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/api/sign/SignParameters.java
@@ -34,16 +34,16 @@ import at.knowcenter.wag.egov.egiz.sig.SignatureTypes;
/**
* Parameter object that holds the sign parameters.
- *
+ *
* @author wprinz
*/
public class SignParameters
{
// 23.11.2010 changed by exthex - added parameters for placeholder handling
-
+
/**
* The document to be signed.
- *
+ *
* <p>
* The DataSource implementation encapsulates the actual representaion of the
* data. E.g. the DataSource may be File based or byte array based. See
@@ -54,7 +54,7 @@ public class SignParameters
/**
* The type of the signature.
- *
+ *
* <p>
* May be {@link Constants#SIGNATURE_TYPE_BINARY} or
* {@link Constants#SIGNATURE_TYPE_TEXTUAL}.
@@ -64,7 +64,7 @@ public class SignParameters
/**
* The signature device to perform the actual signature.
- *
+ *
* <p>
* May be {@link Constants#SIGNATURE_DEVICE_MOA} or
* {@link Constants#SIGNATURE_DEVICE_BKU}.
@@ -75,18 +75,18 @@ public class SignParameters
/**
* The signature profile identifier identifying the profile to be used in the
* config file.
- *
+ *
* <p>
* Note: In near future it will be possible to provide a full specified
* profile here instead of the profile id.
* </p>
*/
protected String signatureProfileId = null;
-
+
/**
* The signature key identifier specifying which signature key should be used
* by the signature device to perform the signature.
- *
+ *
* <p>
* Providing a null value (default) means that no explicit signature key
* identifier is provided. The selected signature device will then use its
@@ -122,7 +122,7 @@ public class SignParameters
* The output DataSink that will receive the signed document.
*/
protected DataSink output = null;
-
+
protected TimeStamper timeStamperImpl;
/**
@@ -142,12 +142,12 @@ public class SignParameters
* Defaults to {@link Constants#PLACEHOLDER_MATCH_MODE_MODERATE}.
*/
protected int placeholderMatchMode = Constants.PLACEHOLDER_MATCH_MODE_MODERATE;
-
+
protected Properties overrideProps = new Properties();
-
-
+
+
/**
* {@link #setTimeStamperImpl(TimeStamper)}
@@ -158,7 +158,7 @@ public class SignParameters
}
/**
- * Set a {@link TimeStamper} to create a timestamp on the signature value. Will be
+ * Set a {@link TimeStamper} to create a timestamp on the signature value. Will be
* called after sign. For binary signatures only. Timestamp will be embedded in egiz dict /TimeStamp.
* @param timeStamperImpl
*/
@@ -285,21 +285,21 @@ public class SignParameters
}
/**
- * Override user defined values from the used signature profile like "value.SIG_META".
- * You cannot override pre defined values like SIG_VALUE, SIG_DATE {@link SignatureTypes#REQUIRED_SIG_KEYS}.
+ * Override user defined values from the used signature profile like "value.SIG_META".
+ * You cannot override pre defined values like SIG_VALUE, SIG_DATE {@link SignatureTypes#REQUIRED_SIG_KEYS}.
* The override values are bound to the {@link SignParameters} instance.
* <p>
* Sample usage:
* <pre>
SignParameters sp = new SignParameters();
. . .
-
- sp.setSignatureProfileId("SIGNATURBLOCK_DE");
-
+
+ sp.setSignatureProfileId("SIGNATURBLOCK_DE");
+
// expressions do not work on binary signature fields without phlength setting!!
sp.setProfileOverrideValue("SIG_META", "It's nice to be important, but it is more important to be nice ${subject.L}");;
- sp.setProfileOverrideValue("SIG_LABEL", "./images/signatur-logo_en.png");
-
+ sp.setProfileOverrideValue("SIG_LABEL", "./images/signatur-logo_en.png");
+
// execute sign using the overrides
pdfAs.sign(sp);
</pre>
@@ -311,51 +311,51 @@ public class SignParameters
if (SignatureTypes.isRequredSigTypeKey(key)) {
throw new RuntimeException("cannot set value for pre defined signature field names");
}
- this.overrideProps.put(key, value);
+ this.overrideProps.put(key, value);
}
-
+
/**
* Get override values created via {@link #setProfileOverrideValue(String, String)}
* @return
*/
public Properties getProfileOverrideProperties() {
return this.overrideProps;
-
+
}
/**
* Get the value of the checkForPlaceholder flag.
- *
+ *
* @return
*/
public Boolean isCheckForPlaceholder() {
return this.checkForPlaceholder;
}
-
+
/**
- * Set this to true, if you want a search for placeholder images to be performed and
+ * Set this to true, if you want a search for placeholder images to be performed and
* appropriate images to be replaced.
* If this is not set, a search will only be performed if the configuration property "enable_placeholder_search" is set to true.
- *
+ *
* @param check
*/
- public void setCheckForPlaceholder(boolean check) {
- this.checkForPlaceholder = Boolean.valueOf(check);
+ public void setCheckForPlaceholder(Boolean searchForPlaceHolder) {
+ this.checkForPlaceholder = searchForPlaceHolder;
}
/**
- * Set an explicit placeholder id.
+ * Set an explicit placeholder id.
* Only placeholder images that have a matching ID property embedded will be considered for replacement.
- *
+ *
* @param placeholderId
*/
public void setPlaceholderId(String placeholderId) {
- this.placeholderId = placeholderId;
+ this.placeholderId = placeholderId;
}
-
+
/**
* The id of the placeholder to replace.
- *
+ *
* @return the placeholderId
*/
public String getPlaceholderId() {
@@ -367,13 +367,13 @@ public class SignParameters
* Exactly matching meaning:<br/>
* <ul><li>If a placeholderId is set: a placeholder which has exactly this id embedded</li>
* <li>If no placeholderId is set: a placeholder without an embedded id is found</li></ul>
- *
+ *
* @see Constants#PLACEHOLDER_MATCH_MODE_LENIENT
* @see Constants#PLACEHOLDER_MATCH_MODE_MODERATE
* @see Constants#PLACEHOLDER_MATCH_MODE_STRICT
- *
+ *
* Defaults to {@link Constants#PLACEHOLDER_MATCH_MODE_MODERATE}.
- *
+ *
* @param placeholderMatchMode
*/
public void setPlaceholderMatchMode(int placeholderMatchMode) {
@@ -382,12 +382,12 @@ public class SignParameters
/**
* Get the placeholder matching mode.
- *
+ *
* @see SignParameters#getPlaceholderMatchMode()
* @return the placeholderMatchMode
*/
public int getPlaceholderMatchMode() {
return this.placeholderMatchMode;
}
-
+
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/commandline/Main.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/commandline/Main.java
index 52355f8..d5f7e2f 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/commandline/Main.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/commandline/Main.java
@@ -36,6 +36,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -78,11 +79,11 @@ import at.knowcenter.wag.egov.egiz.sig.SignatureTypes;
/**
* The main program entry point of the commandline tool.
- *
+ *
* <p>
* The commandline uses the PDF-AS API.
* </p>
- *
+ *
* @author wprinz
*/
public abstract class Main
@@ -127,12 +128,12 @@ public abstract class Main
* Command line parameter signaling to search the source document for a placeholder for the signature
*/
protected static final String PARAMETER_PLACEHOLDER_SEARCH = "-searchplaceholder";
-
+
/**
* Command line parameter selecting the id of the placeholder to use
*/
protected static final String PARAMETER_PLACEHOLDER_ID = "-placeholder_id";
-
+
/**
* Command line parameter selecting the match mode for the placeholder
*/
@@ -143,7 +144,7 @@ public abstract class Main
* verified.
*/
protected static final String PARAMETER_VERIFY_WHICH = "-verify_which";
-
+
/**
* Command line parameter that starts the deployment of the default configuration to the current
* user's home folder.
@@ -195,7 +196,7 @@ public abstract class Main
* The placeholder match mode STRICT
*/
public static final String VALUE_PLACEHOLDER_MATCH_MODE_LENIENT = "lenient";
-
+
/**
* The log.
*/
@@ -203,7 +204,7 @@ public abstract class Main
/**
* Main program entry point.
- *
+ *
* @param args
* The commandline arguments.
* @throws IOException
@@ -216,7 +217,7 @@ public abstract class Main
for (int i = 0; i < args.length; i++) {
if (args[i].trim().equals(PARAMETER_DEPLOY_DEFAULT_CONFIGURATION)) {
try {
- String defaultConfigurationDeployedTo = ConfigUtils.deployDefaultConfiguration();
+ String defaultConfigurationDeployedTo = ConfigUtils.deployDefaultConfiguration();
if (defaultConfigurationDeployedTo != null) {
System.out.println("Default configuration successfully deployed to \"" + defaultConfigurationDeployedTo + "\".");
} else {
@@ -229,7 +230,7 @@ public abstract class Main
} catch (ConfigUtilsException e) {
System.err.println("Deployment of default configuration failed: " + e.getMessage());
System.exit(1);
- }
+ }
}
}
@@ -247,7 +248,8 @@ public abstract class Main
String user_password = null;
String pos_string = null;
- boolean search_placeholder = true;
+ // DTI: fixed searchplaceholder parameter handling preventing consideration of respective configuration parameter
+ Boolean searchPlaceHolder = null;
String placeholderId = null;
int placeholderMatchMode = Constants.PLACEHOLDER_MATCH_MODE_MODERATE;
@@ -274,7 +276,7 @@ public abstract class Main
// already applied
continue;
}
-
+
if (cur_arg.equals(PARAMETER_MODE))
{
i++;
@@ -351,7 +353,8 @@ public abstract class Main
printNoValue(PARAMETER_PLACEHOLDER_SEARCH);
return;
}
- search_placeholder = Boolean.valueOf(args[i]).booleanValue();
+// search_placeholder = Boolean.valueOf(args[i]).booleanValue();
+ searchPlaceHolder = BooleanUtils.toBooleanObject(args[i]);
continue;
}
@@ -522,7 +525,7 @@ public abstract class Main
output = generateOutputFileNameFromInput(input, signature_mode);
}
- carryOutCommand(mode, signature_mode, connector, signature_type, user_name, user_password, verify_which, input, output, pos_string, search_placeholder, placeholderId, placeholderMatchMode);
+ carryOutCommand(mode, signature_mode, connector, signature_type, user_name, user_password, verify_which, input, output, pos_string, searchPlaceHolder, placeholderId, placeholderMatchMode);
}
catch (PdfAsException e)
@@ -549,7 +552,7 @@ public abstract class Main
}
protected static void carryOutCommand(final String mode, final String signature_mode, final String connector, final String signature_type, final String user_name, final String user_password,
- final int verify_which, final String input, String output, final String pos_string, boolean search_placeholder, String placeholderId, int placeholderMatchMode) throws PdfAsException
+ final int verify_which, final String input, String output, final String pos_string, Boolean searchPlaceHolder, String placeholderId, int placeholderMatchMode) throws PdfAsException
{
// File file = new File(input);
//
@@ -570,7 +573,7 @@ public abstract class Main
if (mode.equals(VALUE_MODE_SIGN))
{
- carryOutSign(input, connector, signature_mode, signature_type, pos_string, user_name, user_password, output, messageOutput, search_placeholder, placeholderId, placeholderMatchMode);
+ carryOutSign(input, connector, signature_mode, signature_type, pos_string, user_name, user_password, output, messageOutput, searchPlaceHolder, placeholderId, placeholderMatchMode);
}
else
{
@@ -580,7 +583,7 @@ public abstract class Main
}
public static void carryOutSign(String input, String connector, String signature_mode, String signature_type, String pos_string, String user_name, String user_password, String output,
- PrintWriter messageOutput, boolean search_placeholder, String placeholderId, int placeholderMatchMode) throws PdfAsException
+ PrintWriter messageOutput, Boolean searchPlaceHolder, String placeholderId, int placeholderMatchMode) throws PdfAsException
{
messageOutput.println("Signing " + input + "...");
@@ -621,7 +624,7 @@ public abstract class Main
}
try {
- processSign(dataSource, connector, signature_mode, signature_type, pos_string, search_placeholder, placeholderId, placeholderMatchMode, dataSink);
+ processSign(dataSource, connector, signature_mode, signature_type, pos_string, searchPlaceHolder, placeholderId, placeholderMatchMode, dataSink);
} catch (Exception e) {
// Exception caught in order to delete file based datasink
if (outputFile != null && outputFile.exists())
@@ -641,14 +644,6 @@ public abstract class Main
}
}
- // for performance measurement
- if (logger_.isInfoEnabled())
- {
- long endTime = System.currentTimeMillis();
- String toReport = "SIGN;" + signature_mode + ";" + input + ";" + fileSize + ";" + (endTime - startTime);
- logger_.info(toReport);
- }
-
messageOutput.println("Signing was successful (" + output + ").");
}
@@ -656,22 +651,10 @@ public abstract class Main
{
messageOutput.println("Verifying " + input + "...");
- // for performance measurement
- long startTime = 0;
- long fileSize = 0;
- if (logger_.isInfoEnabled())
- {
- startTime = System.currentTimeMillis();
- }
-
DataSource dataSource = null;
try
{
File file = new File(input);
- if (logger_.isDebugEnabled())
- {
- fileSize = file.length();
- }
String extension = extractExtension(input);
if (extension != null && extension.equals("txt"))
{
@@ -705,23 +688,15 @@ public abstract class Main
messageOutput.println("Verification results:");
formatVerifyResults(results, messageOutput);
- // for performance measurement
- if (logger_.isInfoEnabled())
- {
- long endTime = System.currentTimeMillis();
- String toReport = "VERIFY;" + input + ";" + fileSize + ";" + (endTime - startTime) + ";" + debugVerifyResults(results);
- logger_.info(toReport);
- }
-
}
-
+
/**
* Extracts the extension from a file name string.
- *
+ *
* <p>
* The extension of a file name is whatever text follows the last '.'.
* </p>
- *
+ *
* @param file_name
* The file name.
* @return Returns the extension. If the file name ends with the '.', then an
@@ -743,7 +718,7 @@ public abstract class Main
return file_name.substring(dot_index + 1);
}
- public static void processSign(DataSource dataSource, String connector, String signature_mode, String signature_type, String pos_string, boolean search_placeholder, String placeholderId, int placeholderMatchMode, DataSink dataSink) throws PdfAsException
+ public static void processSign(DataSource dataSource, String connector, String signature_mode, String signature_type, String pos_string, Boolean searchPlaceHolder, String placeholderId, int placeholderMatchMode, DataSink dataSink) throws PdfAsException
{
TablePos pos = null;
if (pos_string != null)
@@ -795,7 +770,7 @@ public abstract class Main
sp.setSignatureDevice(connector);
sp.setSignatureProfileId(signature_type);
sp.setSignaturePositioning(posi);
- sp.setCheckForPlaceholder(search_placeholder);
+ sp.setCheckForPlaceholder(searchPlaceHolder);
sp.setPlaceholderId(placeholderId);
sp.setPlaceholderMatchMode(placeholderMatchMode);
pdfAs.sign(sp);
@@ -853,7 +828,7 @@ public abstract class Main
/**
* Prints that the provided option was unrecognized.
- *
+ *
* @param option
* The unrecognized option.
* @throws PresentableException
@@ -867,7 +842,7 @@ public abstract class Main
/**
* Prints that the provided value was unrecognized.
- *
+ *
* @param parameter
* The parameter, which is missing a value.
* @throws PresentableException
@@ -881,7 +856,7 @@ public abstract class Main
/**
* Prints that the provided value was unrecognized.
- *
+ *
* @param value
* The unrecognized value.
* @throws PresentableException
@@ -895,7 +870,7 @@ public abstract class Main
/**
* Prints that the provided additional commandline argument was unrecognized.
- *
+ *
* @param argument
* The unrecognized argument.
* @throws PresentableException
@@ -909,7 +884,7 @@ public abstract class Main
/**
* Prints that a certain parameter was missing.
- *
+ *
* @param missing_term
* A description of the missing parameter ("e.g. a mode").
* @param parameter
@@ -924,7 +899,7 @@ public abstract class Main
/**
* Prints that something is missing.
- *
+ *
* @param missing_term
* A descriptive message of the missing thing.
* @throws PresentableException
@@ -938,7 +913,7 @@ public abstract class Main
/**
* Prints out the ErrorCodeException in a descriptive form.
- *
+ *
* @param ece
* The ErrorCodeException to be printed.
*/
@@ -974,7 +949,7 @@ public abstract class Main
/**
* Prints the usage text.
- *
+ *
* @param writer
* The writer to print the text to.
* @throws PresentableException
@@ -991,7 +966,7 @@ public abstract class Main
writer.print(" " + PARAMETER_CONNECTOR + " ");
ConnectorInformation[] ci = ConnectorFactory.getConnectorInformationArray();
-
+
// prepare list of connectors available for commandline
ArrayList ciList = new ArrayList();
for (int i = 0; i < ci.length; i++) {
@@ -1000,7 +975,7 @@ public abstract class Main
ciList.add(ci[i]);
}
}
-
+
// list available connectors wrapped in <...|...>
Iterator ciIt = ciList.iterator();
writer.print("<");
@@ -1012,7 +987,7 @@ public abstract class Main
}
writer.print(">");
writer.println();
-
+
// for (int i = 0; i < ci.length; i++)
// {
// String id = ci[i].getIdentifier();
@@ -1046,7 +1021,7 @@ public abstract class Main
writer.println(" " + PARAMETER_DEPLOY_DEFAULT_CONFIGURATION + " ... deploys the default configuration to the current user's home");
- writer.println(" OPTIONS for signation:");
+ writer.println(" OPTIONS for signature:");
writer.println(" " + PARAMETER_SIGNATURE_MODE + " <" + VALUE_SIGNATURE_MODE_BINARY + "|" + VALUE_SIGNATURE_MODE_TEXTUAL + "> [optional]");
writer.println(" " + VALUE_SIGNATURE_MODE_BINARY + " ... signs the complete binary document" + (Constants.DEFAULT_SIGNATURE_TYPE.equals(VALUE_SIGNATURE_MODE_BINARY) ? " (default)" : ""));
@@ -1056,7 +1031,9 @@ public abstract class Main
writer.print(" " + PARAMETER_SIGNATURE_TYPE + " <");
SignatureTypes sig_types = SignatureTypes.getInstance();
SettingsReader settings = SettingsReader.getInstance();
- Set types_array = sig_types.getSignatureTypes();
+ // show only signature profiles that can be used for signature
+// Set types_array = sig_types.getSignatureTypes();
+ Set types_array = sig_types.getSignatureTypesForSignature();
Iterator it = types_array.iterator();
while (it.hasNext())
{
@@ -1117,7 +1094,7 @@ public abstract class Main
/**
* Checks the value for correctness.
- *
+ *
* @param mode
* The parameter's value.
* @return Returns true, if the value is correct, false otherwise.
@@ -1129,7 +1106,7 @@ public abstract class Main
/**
* Checks the value for correctness.
- *
+ *
* @param signature_mode
* The parameter's value.
* @return Returns true, if the value is correct, false otherwise.
@@ -1143,7 +1120,7 @@ public abstract class Main
/**
* Checks the value for correctness.
- *
+ *
* @param connector
* The parameter's value.
* @return Returns true, if the value is correct, false otherwise.
@@ -1157,7 +1134,7 @@ public abstract class Main
/**
* Checks the value for correctness (meaning if it exists)
- *
+ *
* @param signature_type
* The parameter's value.
* @return Returns true, if the value is correct, false otherwise.
@@ -1166,10 +1143,10 @@ public abstract class Main
{
return SignatureTypes.getInstance().getSignatureTypes().contains(signature_type);
}
-
+
/**
* Translates the commandline argument to a PDF-AS-ID.
- *
+ *
* @param signature_mode
* The signator mode commandline argument.
* @return Returns the corresponding PDFASID.
@@ -1197,7 +1174,7 @@ public abstract class Main
/**
* Formats the verification results.
- *
+ *
* @param results
* The List of SignatureResponse verification results.
* @param writer
@@ -1223,9 +1200,9 @@ public abstract class Main
/**
* Formats the verification results for debugging. Returns 0 if no error
* occurs or the sum of all error-codes.
- *
+ *
* @param results
- *
+ *
* @param writer
* The output sink to write the formatted text to.
* @throws SettingNotFoundException
@@ -1259,7 +1236,7 @@ public abstract class Main
String public_property = (String) it.next();
writer.println(" Eigenschaft: " + public_property);
}
-
+
writer.println(" Zertifikat-Check:");
writer.println(" " + result.getCertificateCheck().getCode() + " - " + result.getCertificateCheck().getMessage());
writer.println(" Signatur-Check:");
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java
index e0ddbf2..e7d2b47 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/exceptions/ErrorCode.java
@@ -23,6 +23,8 @@
*/
package at.gv.egiz.pdfas.exceptions;
+import at.knowcenter.wag.egov.egiz.exceptions.SignatureException;
+
/**
* Contains constants for the error codes.
*
@@ -44,6 +46,8 @@ public final class ErrorCode
public static final int NO_EMBEDABLE_TTF_CONFIGURED_FOR_PDFA = 103;
public static final int INVALID_SIGNATURE_LAYOUT_IMPL_CONFIGURED = 104;
public static final int MISSING_HEADER_SERVER_USER_AGENT = 105;
+ public static final int CIRCULAR_INCLUDE_INSTRUCTION_DETECTED = 106;
+ public static final int UNABLE_TO_LOAD_DEFAULT_CONFIG = 107;
public static final int DOCUMENT_CANNOT_BE_READ = 201;
public static final int TEXT_EXTRACTION_EXCEPTION = 202;
@@ -56,6 +60,15 @@ public final class ErrorCode
//23.11.2010 changed by exthex - added error code for failed extraction
public static final int SIGNATURE_PLACEHOLDER_EXTRACTION_FAILED = 233;
+ /**
+ * Error code for {@code SignatureException}s occurring when trying to sign with a certain signature profile that
+ * is not allowed to be used for signature, e.g. because ist has been set to
+ * <p/>
+ * {@code sig_obj.types.<PROFILE_ID> = verify_only}
+ * @author Datentechnik Innovation GmbH
+ */
+ public static final int SIGNATURE_PROFILE_IS_NOT_ALLOWED_FOR_SIGNATURE = 234;
+
public static final int INVALID_SIGNATURE_POSITION = 224;
public static final int NO_TEXTUAL_CONTENT = 251;
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/CsvStatisticLogger.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/CsvStatisticLogger.java
new file mode 100644
index 0000000..a295a7b
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/CsvStatisticLogger.java
@@ -0,0 +1,105 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egiz.pdfas.framework.logging;
+
+import org.apache.commons.logging.Log;
+
+import at.gv.egiz.pdfas.api.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.exceptions.external.ExternalErrorException;
+import at.gv.egiz.pdfas.utils.CsvUtils;
+
+/**
+ * A statistic logger implementation that prodoces csv based logging entries.
+ *
+ * @author Datentechnik Innovation GmbH
+ */
+public class CsvStatisticLogger implements StatisticLogger {
+
+ /**
+ * The underlying logging implementation.
+ */
+ private Log log;
+
+ /**
+ * A csv value indication error conditions.
+ */
+ private static final String VALUE_ERROR = "ERROR";
+
+ /**
+ * A csv value indication success conditions.
+ */
+ private static final String VALUE_OK = "OK";
+
+ /**
+ * Creates a new instance.
+ *
+ * @param log
+ * The underlying logger.
+ */
+ CsvStatisticLogger(Log log) {
+ this.log = log;
+ }
+
+ public void log(StatisticData data) {
+ if (isEnabled()) {
+ StringBuffer msg = new StringBuffer();
+
+ // add escapted fields
+ msg.append(CsvUtils.escapeCsvValue(data.operation)).append(CsvUtils.DEFAULT_DELIMITER);
+ msg.append(CsvUtils.escapeCsvValue(data.signatureMode)).append(CsvUtils.DEFAULT_DELIMITER);
+ msg.append(CsvUtils.escapeCsvValue(data.connector)).append(CsvUtils.DEFAULT_DELIMITER);
+ msg.append(CsvUtils.escapeCsvValue(data.signatureProfileId)).append(CsvUtils.DEFAULT_DELIMITER);
+ msg.append(CsvUtils.escapeCsvValue(data.fileSize)).append(CsvUtils.DEFAULT_DELIMITER);
+ msg.append(CsvUtils.escapeCsvValue(data.userAgent)).append(CsvUtils.DEFAULT_DELIMITER);
+
+ // handle error conditions
+ Integer errorCode = null;
+ String externalErrorCode = null;
+ if (data.exception != null) {
+ msg.append(VALUE_ERROR).append(CsvUtils.DEFAULT_DELIMITER);
+ if (data.exception instanceof PdfAsException) {
+ PdfAsException pdfAsException = (PdfAsException) data.exception;
+ errorCode = pdfAsException.getErrorCode();
+ if (pdfAsException instanceof ExternalErrorException) {
+ externalErrorCode = ((ExternalErrorException) pdfAsException).getExternalErrorCode();
+ }
+ }
+ msg.append(CsvUtils.escapeCsvValue(data.exception.getClass().getName())).append(CsvUtils.DEFAULT_DELIMITER);
+ } else {
+ msg.append(VALUE_OK).append(CsvUtils.DEFAULT_DELIMITER).append(CsvUtils.DEFAULT_DELIMITER);
+ }
+ msg.append(CsvUtils.escapeCsvValue(errorCode)).append(CsvUtils.DEFAULT_DELIMITER);
+ msg.append(CsvUtils.escapeCsvValue(externalErrorCode)).append(CsvUtils.DEFAULT_DELIMITER);
+
+ msg.append(CsvUtils.escapeCsvValue(data.duration));
+
+ log.info(msg);
+ }
+ }
+
+ public boolean isEnabled() {
+ return log.isInfoEnabled();
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticData.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticData.java
new file mode 100644
index 0000000..3cb1c66
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticData.java
@@ -0,0 +1,314 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egiz.pdfas.framework.logging;
+
+import at.gv.egiz.pdfas.api.analyze.AnalyzeParameters;
+import at.gv.egiz.pdfas.api.commons.Constants;
+import at.gv.egiz.pdfas.api.sign.SignParameters;
+import at.gv.egiz.pdfas.api.verify.VerifyAfterAnalysisParameters;
+import at.gv.egiz.pdfas.api.verify.VerifyAfterReconstructXMLDsigParameters;
+import at.gv.egiz.pdfas.api.verify.VerifyParameters;
+import at.gv.egiz.pdfas.api.xmldsig.ReconstructXMLDsigAfterAnalysisParameters;
+import at.gv.egiz.pdfas.api.xmldsig.ReconstructXMLDsigParameters;
+
+public class StatisticData {
+
+ String operation;
+ String connector;
+ String signatureMode;
+ String signatureProfileId;
+ Integer fileSize;
+ Long duration;
+ String userAgent;
+ Exception exception;
+
+ /**
+ * Creates new data for statistical logging purposes.
+ */
+ public StatisticData() {
+ }
+
+ /**
+ * Creates new data for statistical logging purposes.
+ *
+ * @param operation
+ * The operation (one of 'SIGN' and 'VERIFY').
+ * @param connector
+ * The connector being used for the certain operation (one of {@link Constants#SIGNATURE_DEVICE_BKU},
+ * {@link Constants#SIGNATURE_DEVICE_MOA}, {@link Constants#SIGNATURE_DEVICE_MOC},
+ * {@link Constants#SIGNATURE_DEVICE_MOBILE}...)
+ * @param fileSize
+ * The size of the file being processed.
+ * @param signatureMode
+ * The signature mode (one of {@link Constants#SIGNATURE_TYPE_BINARY},
+ * {@link Constants#SIGNATURE_TYPE_BINARY} or {@code null} in case of verification.
+ * @param duration
+ * The duration the certain operation took (in ms).
+ * @param userAgent
+ * The user agent String.
+ * @param errorCode
+ * The error code resulting from the current operation (0 means no error).
+ */
+ public StatisticData(String operation, String connector, Integer fileSize, String signatureMode, Long duration,
+ String userAgent, Integer errorCode) {
+ this();
+ this.operation = operation;
+ this.connector = connector;
+ this.signatureMode = signatureMode;
+ this.fileSize = fileSize;
+ this.duration = duration;
+ this.userAgent = userAgent;
+ }
+
+ /**
+ * Creates new data for statistical logging purposes.
+ *
+ * @param operation
+ * The operation (one of 'SIGN' and 'VERIFY').
+ * @param connector
+ * The connector being used for the certain operation (one of {@link Constants#SIGNATURE_DEVICE_BKU},
+ * {@link Constants#SIGNATURE_DEVICE_MOA}, {@link Constants#SIGNATURE_DEVICE_MOC},
+ * {@link Constants#SIGNATURE_DEVICE_MOBILE}...)
+ * @param fileSize
+ * The size of the file being processed.
+ */
+ public StatisticData(String operation, String connector, Integer fileSize) {
+ this();
+ this.operation = operation;
+ this.connector = connector;
+ this.fileSize = fileSize;
+ }
+
+ /**
+ * Creates new data for statistical logging purposes.
+ *
+ * @param operation
+ * The operation (one of 'SIGN' and 'VERIFY').
+ * @param connector
+ * The connector being used for the certain operation (one of {@link Constants#SIGNATURE_DEVICE_BKU},
+ * {@link Constants#SIGNATURE_DEVICE_MOA}, {@link Constants#SIGNATURE_DEVICE_MOC},
+ * {@link Constants#SIGNATURE_DEVICE_MOBILE}...)
+ * @param fileSize
+ * The size of the file being processed.
+ * @param signatureMode
+ * The signature mode (one of {@link Constants#SIGNATURE_TYPE_BINARY},
+ * {@link Constants#SIGNATURE_TYPE_BINARY} or {@code null} in case of verification.
+ * @param duration
+ * The duration the certain operation took (in ms).
+ * @param userAgent
+ * The user agent String.
+ */
+ public StatisticData(String operation, String connector, Integer fileSize, String signatureMode, Long duration,
+ String userAgent) {
+ this(operation, connector, fileSize, signatureMode, duration, userAgent, null);
+ }
+
+ /**
+ * Creates statistical data based on given sign parameters.
+ *
+ * @param signParameters
+ * The given sign parameters.
+ */
+ public StatisticData(SignParameters signParameters) {
+ this();
+ operation = "SIGN";
+ connector = signParameters.getSignatureDevice();
+ signatureMode = signParameters.getSignatureType();
+ fileSize = signParameters.getDocument().getLength();
+ signatureProfileId = signParameters.getSignatureProfileId();
+ }
+
+ /**
+ * Creates statistical data based on given verify parameters.
+ *
+ * @param verifyParameters
+ * The given verify parameters.
+ */
+ public StatisticData(VerifyParameters verifyParameters) {
+ this();
+ operation = "VERIFY";
+ connector = verifyParameters.getSignatureDevice();
+ fileSize = verifyParameters.getDocument().getLength();
+ }
+
+ /**
+ * Creates statistical data based on given analyze parameters.
+ *
+ * @param varxdp
+ * The given analyze parameters.
+ */
+ public StatisticData(AnalyzeParameters analyzeParameters) {
+ this();
+ operation = "ANALYZE";
+ fileSize = analyzeParameters.getDocument().getLength();
+ }
+
+ /**
+ * Creates statistical data based on given reconstruction parameters.
+ *
+ * @param rxdaap
+ * The given reconstruction parameters.
+ */
+ public StatisticData(ReconstructXMLDsigAfterAnalysisParameters rxdaap) {
+ this();
+ operation = "RECONSTRUCT";
+ connector = rxdaap.getSignatureDevice();
+ }
+
+ /**
+ * Creates statistical data based on given reconstruction parameters.
+ *
+ * @param reconstructParameters
+ * The given reconstruction parameters.
+ */
+ public StatisticData(ReconstructXMLDsigParameters reconstructParameters) {
+ this();
+ operation = "RECONSTRUCT";
+ fileSize = reconstructParameters.getDocument().getLength();
+ connector = reconstructParameters.getSignatureDevice();
+ }
+
+ /**
+ * Creates statistical data based on given parameters.
+ *
+ * @param vaaParameters
+ * The given verify parameters after analysis.
+ */
+ public StatisticData(VerifyAfterAnalysisParameters vaaParameters) {
+ this();
+ operation = "VERIFY";
+ connector = vaaParameters.getSignatureDevice();
+ }
+
+ /**
+ * Creates statistical data based on given verify parameters after reconstruction.
+ *
+ * @param varxdp
+ * The given verify parameters after reconstruction.
+ */
+ public StatisticData(VerifyAfterReconstructXMLDsigParameters varxdp) {
+ this();
+ operation = "VERIFY";
+ connector = varxdp.getSignatureDevice();
+ }
+
+ /**
+ * Sets the current operation name.
+ *
+ * @param operation
+ * The operation name.
+ */
+ public StatisticData setOperation(String operation) {
+ this.operation = operation;
+ return this;
+ }
+
+ /**
+ * Sets the connector.
+ *
+ * @param connector
+ * The connector.
+ */
+ public StatisticData setConnector(String connector) {
+ this.connector = connector;
+ return this;
+ }
+
+ /**
+ * Sets the file size of the processed document.
+ *
+ * @param fileSize
+ * The file size in bytes.
+ */
+ public StatisticData setFileSize(Integer fileSize) {
+ this.fileSize = fileSize;
+ return this;
+ }
+
+ /**
+ * Sets the duration of the performed operation.
+ *
+ * @param duration
+ * The duration in ms.
+ */
+ public StatisticData setDuration(Long duration) {
+ this.duration = duration;
+ return this;
+ }
+
+ /**
+ * Sets the user agent identifier.
+ *
+ * @param userAgent
+ * The user agent identifier.
+ */
+ public StatisticData setUserAgent(String userAgent) {
+ this.userAgent = userAgent;
+ return this;
+ }
+
+ /**
+ * Sets the signature mode.
+ *
+ * @param signatureMode
+ * The signature mode (one of {@link Constants#SIGNATURE_TYPE_TEXTUAL} and
+ * {@link Constants#SIGNATURE_TYPE_BINARY}).
+ */
+ public StatisticData setSignatureMode(String signatureMode) {
+ this.signatureMode = signatureMode;
+ return this;
+ }
+
+ /**
+ * Sets the profile id.
+ *
+ * @param profileId
+ * The profile id.
+ */
+ public StatisticData setSignatureProfileId(String signatureProfileId) {
+ this.signatureProfileId = signatureProfileId;
+ return this;
+ }
+
+ /**
+ * Sets the exception that has been thrown.
+ *
+ * @param exception
+ * The exception.
+ */
+ public StatisticData setException(Exception exception) {
+ this.exception = exception;
+ return this;
+ }
+
+ /**
+ * Returns {@code true} if an error condition has been set, {@code false} otherwise.
+ *
+ * @return {@code true} in case of an error, {@code false} if not.
+ */
+ public boolean isError() {
+ return exception != null;
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticLogFactory.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticLogFactory.java
new file mode 100644
index 0000000..2b6671c
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticLogFactory.java
@@ -0,0 +1,63 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egiz.pdfas.framework.logging;
+
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * This factory creates statistic logger implementations.<br/>
+ * Note that it exclusively creates {@link CsvStatisticLogger} implementations at the moment. It should just be regarded
+ * as template for further factory implementations. Strictly speaking this factory does not fulfil the respective GoF
+ * pattern.
+ *
+ * @see StatisticLogger
+ * @author Datentechnik Innovation GmbH
+ */
+public class StatisticLogFactory {
+
+ /**
+ * Returns a statistic logger implementation.
+ *
+ * @param clazz
+ * The class.
+ * @return A statistic logger implementation.
+ */
+ public static StatisticLogger getLog(Class<?> clazz) {
+ return getLog(clazz.getName());
+ }
+
+ /**
+ * Returns a statistic logger implementation.
+ *
+ * @param name
+ * The name of the logger.
+ * @return A statistic logger implementation.
+ */
+ public static StatisticLogger getLog(String name) {
+
+ // to be changed some day, producing various logger implementations
+ return new CsvStatisticLogger(LogFactory.getLog(name));
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticLogger.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticLogger.java
new file mode 100644
index 0000000..6e2c587
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/framework/logging/StatisticLogger.java
@@ -0,0 +1,47 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egiz.pdfas.framework.logging;
+
+/**
+ *
+ * @author Datentechnik Innovation GmbH
+ */
+public interface StatisticLogger {
+
+ /**
+ * Creates a log entry with the given statistical data.
+ *
+ * @param statisticData
+ * The statistical data.
+ */
+ public void log(StatisticData statisticData);
+
+ /**
+ * Returns {@code true} in case the logger is enabled, {@code false} if not.
+ *
+ * @return {@code true} in case the logger is enabled, {@code false} if not.
+ */
+ public boolean isEnabled();
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java
index eda94c0..a2bcd15 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java
@@ -33,6 +33,7 @@ import java.util.Properties;
import java.util.Vector;
import org.apache.commons.lang.math.NumberUtils;
+import org.apache.commons.lang.time.StopWatch;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -66,6 +67,9 @@ import at.gv.egiz.pdfas.framework.DataSourceHolder;
import at.gv.egiz.pdfas.framework.config.SettingsHelper;
import at.gv.egiz.pdfas.framework.input.ExtractionStage;
import at.gv.egiz.pdfas.framework.input.PdfDataSource;
+import at.gv.egiz.pdfas.framework.logging.StatisticData;
+import at.gv.egiz.pdfas.framework.logging.StatisticLogFactory;
+import at.gv.egiz.pdfas.framework.logging.StatisticLogger;
import at.gv.egiz.pdfas.framework.signator.Signator;
import at.gv.egiz.pdfas.framework.signator.SignatorInformation;
import at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters;
@@ -87,6 +91,7 @@ import at.gv.egiz.pdfas.placeholder.SignaturePlaceholderContext;
import at.gv.egiz.pdfas.placeholder.SignaturePlaceholderData;
import at.gv.egiz.pdfas.placeholder.SignaturePlaceholderExtractor;
import at.gv.egiz.pdfas.utils.ConfigUtils;
+import at.gv.egiz.pdfas.utils.PDFASUtils;
import at.knowcenter.wag.egov.egiz.PdfAS;
import at.knowcenter.wag.egov.egiz.PdfASID;
import at.knowcenter.wag.egov.egiz.cfg.OverridePropertyHolder;
@@ -111,12 +116,13 @@ import at.knowcenter.wag.egov.egiz.sig.SignatureDataImpl;
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.sig.SignatureTypes.State;
import at.knowcenter.wag.egov.egiz.sig.connectors.Connector;
import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject;
/**
* Implementation of the {@link PdfAs} interface.
- *
+ *
* @author wprinz
*/
public class PdfAsObject implements PdfAs
@@ -127,25 +133,26 @@ public class PdfAsObject implements PdfAs
* The log.
*/
private static Log log = LogFactory.getLog(PdfAsObject.class);
-
+ private static StatisticLogger statLog = StatisticLogFactory.getLog(Constants.STATISTIC_LOGGER_NAME);
+
private static final String ENABLE_PLACEHOLDER_SEARCH_KEY = "enable_placeholder_search";
-
+
/**
* Configuration key for minimal signature block width threshold. Any width below this certain value will lead to a warning log entry."
*/
private static final String SIGNATURE_BLOCK_WIDTH_THRESHOLD_FOR_WARNING_KEY = "signature_block_width_warning_threshold";
-
+
/**
* Minimal signature block width. If a width below that value is defined (by parameter, by placeholder or by configuration) a warning log entry is created.
*/
public static final float DEFAULT_SIGNATURE_BLOCK_WIDTH_THRESHOLD = 150;
-
+
/**
* This constructor is for internal use only - use
* {@link at.gv.egiz.pdfas.PdfAsFactory} instead.
* Note: IAIK JCE and IAIK ECC security providers are automatically registered.
- *
+ *
* @param workDirectory
* The work directory.
* @throws PdfAsException
@@ -155,16 +162,16 @@ public class PdfAsObject implements PdfAs
{
this(workDirectory, SettingsReader.REGISTER_IAIK_PROVIDERS_ON_DEFAULT);
}
-
+
/**
* This constructor is for internal use only - use
* {@link at.gv.egiz.pdfas.PdfAsFactory} instead.
- *
+ *
* @param workDirectory
* The work directory.
* @param registerProvider <code>true</code>: automatically registers IAIK JCE and ECC Provider;
* <code>false</code>: providers will NOT be automatically registered, providers
- * needed have to be registered by the API user
+ * needed have to be registered by the API user
* @throws PdfAsException
* Thrown, if the configuration cannot be processed.
*/
@@ -174,12 +181,12 @@ public class PdfAsObject implements PdfAs
SettingsReader.initialize(path, path);
reloadConfig(registerProvider);
}
-
+
/**
* This constructor is for internal use only - use
* {@link at.gv.egiz.pdfas.PdfAsFactory} instead.
* Note: IAIK JCE and IAIK ECC security providers are automatically registered.
- *
+ *
* @throws PdfAsException
* Thrown, if the configuration cannot be processed.
*/
@@ -187,7 +194,7 @@ public class PdfAsObject implements PdfAs
{
this(null);
}
-
+
/**
* @see at.gv.egiz.pdfas.api.PdfAs#reloadConfig()
*/
@@ -197,11 +204,11 @@ public class PdfAsObject implements PdfAs
SettingsReader.createInstance();
SignatureTypes.createInstance();
}
-
+
/**
* @param registerProvider <code>true</code>: automatically registers IAIK JCE and ECC Provider;
* <code>false</code>: providers will NOT be automatically registered, providers
- * needed have to be registered by the API user
+ * needed have to be registered by the API user
* @see at.gv.egiz.pdfas.api.PdfAs#reloadConfig()
*/
private void reloadConfig(boolean registerProvider) throws PdfAsException
@@ -228,7 +235,7 @@ public class PdfAsObject implements PdfAs
List profileInformation = new ArrayList(profiles.size());
String default_type = settings.getValueFromKey(SignatureTypes.DEFAULT_TYPE);
-
+
Iterator it = profiles.iterator();
while (it.hasNext())
{
@@ -240,14 +247,17 @@ public class PdfAsObject implements PdfAs
final String profileDescription = settings.getSetting("sig_obj." + profileId + "." + SignatureTypes.SIG_DESCR, null);
boolean isDefault = (default_type != null && default_type.equals(profileId));
+
+ State state = State.fromString(settings.getSetting(SignatureTypes.TYPES + "." + profileId));
+
// modified by tknall
- SignatureProfileImpl signatureProfile = new SignatureProfileImpl(profileId, profileDescription, moaKeyIdentifier, isDefault);
+ SignatureProfileImpl signatureProfile = new SignatureProfileImpl(profileId, state, profileDescription, moaKeyIdentifier, isDefault);
// start - added by tknall
-
+
// signature entries relevant to the search algorithm
Properties signatureEntries = new Properties();
-
+
// search for table entries
String parentPropertyKey = "sig_obj." + profileId + ".table";
log.debug("Looking for subkeys of \"" + parentPropertyKey + "\".");
@@ -275,7 +285,7 @@ public class PdfAsObject implements PdfAs
}
}
}
-
+
// search for table entries
parentPropertyKey = "sig_obj." + profileId + ".key";
log.debug("Looking for subkeys of \"" + parentPropertyKey + "\".");
@@ -295,46 +305,89 @@ public class PdfAsObject implements PdfAs
}
}
}
-
+
// set properties
signatureProfile.setSignatureBlockEntries(signatureEntries);
// stop - added by tknall
-
+
profileInformation.add(signatureProfile);
}
return profileInformation;
}
- /**
- * @see at.gv.egiz.pdfas.api.PdfAs#sign(at.gv.egiz.pdfas.api.sign.SignParameters)
- */
- public SignResult sign(SignParameters signParameters) throws PdfAsException
+ public SignResult sign(SignParameters signParameters) throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(signParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performSign(signParameters);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ statLog.log(sd);
+ }
+ }
+
+ private SignResult performSign(SignParameters signParameters) throws PdfAsException
{
CheckHelper.checkSignParameters(signParameters, false);
-
+
+ // make sure that the selected profile is allowed to be used for signature
+ SettingsReader settings = SettingsReader.getInstance();
+ if (!State.fromString(settings.getSetting(SignatureTypes.TYPES + "." + signParameters.getSignatureProfileId()))
+ .canSign()) {
+ throw new SignatureException(ErrorCode.SIGNATURE_PROFILE_IS_NOT_ALLOWED_FOR_SIGNATURE,
+ "The signature profile '" + signParameters.getSignatureProfileId()
+ + "' is not allowed to be used for signature.");
+ }
+
try {
- SignatureDetailInformation signatorInfo = prepareSign(signParameters);
-
- return sign(signParameters, signatorInfo);
-
+
+ SignatureDetailInformation signatorInfo = performPrepareSign(signParameters);
+ return performSign(signParameters, signatorInfo);
+
} catch (java.lang.OutOfMemoryError e) {
throw new OutOfMemoryException(ErrorCode.OUT_OF_MEMORY_ERROR, "Insufficient memory allocated to virtual machine. Start Java with parameters \"-Xms128m -Xmx786m -XX:MaxPermSize=256m\".", e);
}
}
- /**
- * @see at.gv.egiz.pdfas.api.PdfAs#verify(at.gv.egiz.pdfas.api.verify.VerifyParameters)
- */
- public VerifyResults verify(VerifyParameters verifyParameters) throws PdfAsException
+ public VerifyResults verify(VerifyParameters verifyParameters) throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(verifyParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performVerify(verifyParameters);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ statLog.log(sd);
+ }
+ }
+
+ private VerifyResults performVerify(VerifyParameters verifyParameters) throws PdfAsException
{
CheckHelper.checkVerifyParameters(verifyParameters);
AnalyzeParameters ap = new AnalyzeParameters();
fillAnalyzeParametersWithVerifyParameters(ap, verifyParameters);
- AnalyzeResult analyzeResult = analyze(ap);
+ AnalyzeResult analyzeResult = performAnalyze(ap);
if (verifyParameters.getSignatureToVerify() != Constants.VERIFY_ALL)
{
@@ -352,17 +405,17 @@ public class PdfAsObject implements PdfAs
VerifyAfterAnalysisParameters vaap = new VerifyAfterAnalysisParameters();
vaap.setAnalyzeResult(analyzeResult);
fillVerifyAfterAnalysisParametersWithVerifyParameters(vaap, verifyParameters);
- VerifyResults res = verify(vaap);
-
+ VerifyResults res = performVerify(vaap);
+
return res;
-
+
}
-
+
/**
* Copies all adequate parameters from the {@link VerifyParameters} to the
* {@link AnalyzeParameters}.
- *
+ *
* @param ap
* The {@link AnalyzeParameters}.
* @param vp
@@ -385,7 +438,7 @@ public class PdfAsObject implements PdfAs
/**
* Copies all adequate parameters from the {@link VerifyParameters} to the
* {@link VerifyAfterAnalysisParameters}.
- *
+ *
* @param vaap
* The {@link VerifyAfterAnalysisParameters}.
* @param vp
@@ -406,10 +459,30 @@ public class PdfAsObject implements PdfAs
reconstructParams.setSignatureDevice(verifyAfterAnalysisParameters.getSignatureDevice());
}
- /**
- * @see at.gv.egiz.pdfas.api.PdfAs#analyze(at.gv.egiz.pdfas.api.analyze.AnalyzeParameters)
- */
- public AnalyzeResult analyze(AnalyzeParameters analyzeParameters) throws PdfAsException
+ public AnalyzeResult analyze(AnalyzeParameters analyzeParameters) throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(analyzeParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performAnalyze(analyzeParameters);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ // only log in case of error
+ if (sd.isError()) {
+ statLog.log(sd);
+ }
+ }
+ }
+
+ private AnalyzeResult performAnalyze(AnalyzeParameters analyzeParameters) throws PdfAsException
{
CheckHelper.checkAnalyzeParameters(analyzeParameters);
@@ -429,10 +502,12 @@ public class PdfAsObject implements PdfAs
assumeOnlySB = false;
}
VerificationFilterParameters parameters = new VerificationFilterParametersImpl(binaryOnly, assumeOnlySB, parametersConfig.scanForOldSignatures());
-
+
at.gv.egiz.pdfas.framework.input.DataSource inputDataSource = null;
if (analyzeParameters.getDocument().getMimeType().equals("application/pdf"))
{
+ // check document permissions
+ PDFASUtils.createPdfReaderCheckingPermissions(analyzeParameters.getDocument());
inputDataSource = new PdfDataSourceAdapter(analyzeParameters.getDocument());
}
else
@@ -447,13 +522,13 @@ public class PdfAsObject implements PdfAs
}
}
assert inputDataSource != null;
-
+
try {
ExtractionStage es = new ExtractionStage();
DataSourceHolder dsh = new DataSourceHolder(inputDataSource);
List signature_holders = es.extractSignatureHolders(dsh, parameters);
-
-
+
+
// List sigInfs = new ArrayList(signature_holders.size());
List sigInfs = new ArrayList();
List noSigs = new ArrayList();
@@ -461,24 +536,24 @@ public class PdfAsObject implements PdfAs
while (it.hasNext())
{
SignatureHolder sh = (SignatureHolder)it.next();
-
+
if(sh instanceof NoSignatureHolder) {
noSigs.add(sh);
} else {
-
+
SignatureInformation si = new SignatureInformationAdapter(sh);
sigInfs.add(si);
- if (analyzeParameters.isReturnNonTextualObjects()) {
- si.setNonTextualObjects(doExtractNonTexualObjects(sh, (PdfDataSource) dsh.getDataSource()));
- }
-
+ if (analyzeParameters.isReturnNonTextualObjects()) {
+ si.setNonTextualObjects(doExtractNonTexualObjects(sh, (PdfDataSource) dsh.getDataSource()));
+ }
+
}
}
return new AnalyzeResultImpl(sigInfs, noSigs, parameters.hasBeenCorrected());
} catch (java.lang.OutOfMemoryError e) {
throw new OutOfMemoryException(ErrorCode.OUT_OF_MEMORY_ERROR, "Insufficient memory allocated to virtual machine. Start Java with parameters \"-Xms128m -Xmx786m -XX:MaxPermSize=256m\".", e);
}
-
+
}
private List doExtractNonTexualObjects(SignatureHolder sh, PdfDataSource pdfDataSource) {
@@ -499,30 +574,47 @@ public class PdfAsObject implements PdfAs
}
}
-/**
- * @see at.gv.egiz.pdfas.api.PdfAs#verify(at.gv.egiz.pdfas.api.verify.VerifyAfterAnalysisParameters)
- */
- public VerifyResults verify(VerifyAfterAnalysisParameters verifyAfterAnalysisParameters) throws PdfAsException
+ public VerifyResults verify(VerifyAfterAnalysisParameters verifyAfterAnalysisParameters) throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(verifyAfterAnalysisParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performVerify(verifyAfterAnalysisParameters);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ statLog.log(sd);
+ }
+ }
+
+ private VerifyResults performVerify(VerifyAfterAnalysisParameters verifyAfterAnalysisParameters) throws PdfAsException
{
CheckHelper.checkVerifyAfterAnalysisParameters(verifyAfterAnalysisParameters);
List signatures = verifyAfterAnalysisParameters.getAnalyzeResult().getSignatures();
-
+
// added by tknall
if (signatures == null || signatures.isEmpty()) {
throw new PDFDocumentException(ErrorCode.DOCUMENT_NOT_SIGNED, "PDF document not signed."); //$NON-NLS-1$
}
-
+
ReconstructXMLDsigAfterAnalysisParameters rxaap = new ReconstructXMLDsigAfterAnalysisParameters();
fillReconstructXMLDsigAfterAnalysisParametersWithVerifyAfterAnalysisParameters(rxaap, verifyAfterAnalysisParameters);
- ReconstructXMLDsigResult reconstructResult = reconstructXMLDSIG(rxaap);
-
+ ReconstructXMLDsigResult reconstructResult = performReconstructXMLDSIG(rxaap);
+
VerifyAfterReconstructXMLDsigParameters varxp = new VerifyAfterReconstructXMLDsigParameters();
fillVerifyAfterReconstructXMLDsigParametersWithVerifyAfterAnalysisParameters(varxp, verifyAfterAnalysisParameters);
varxp.setReconstructXMLDsigResult(reconstructResult);
-
- return verify(varxp);
-
+
+ return performVerify(varxp);
+
}
protected void fillVerifyAfterReconstructXMLDsigParametersWithVerifyAfterAnalysisParameters(
@@ -534,31 +626,75 @@ public class PdfAsObject implements PdfAs
varxp.setVerifySignatureIndex(verifyAfterAnalysisParameters.getVerifySignatureIndex());
}
- /**
- * @see PdfAs#reconstructXMLDSIG(ReconstructXMLDsigParameters)
- */
public ReconstructXMLDsigResult reconstructXMLDSIG(
+ ReconstructXMLDsigParameters reconstructXMLDsigParameters)
+ throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(reconstructXMLDsigParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performReconstructXMLDSIG(reconstructXMLDsigParameters);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ // only log in case of error
+ if (sd.isError()) {
+ statLog.log(sd);
+ }
+ }
+ }
+
+ private ReconstructXMLDsigResult performReconstructXMLDSIG(
ReconstructXMLDsigParameters reconstructXMLDsigParameters)
throws PdfAsException {
-
+
AnalyzeParameters analyzeParameters = new AnalyzeParameters();
fillAnalyzeParametersWithReconstructXMLDsigParameters(analyzeParameters, reconstructXMLDsigParameters);
- AnalyzeResult ar = analyze(analyzeParameters);
-
+ AnalyzeResult ar = performAnalyze(analyzeParameters);
+
ReconstructXMLDsigAfterAnalysisParameters rxaap = new ReconstructXMLDsigAfterAnalysisParameters();
rxaap.setSignatureDevice(reconstructXMLDsigParameters.getSignatureDevice());
rxaap.setAnalyzeResult(ar);
-
- return reconstructXMLDSIG(rxaap);
+
+ return performReconstructXMLDSIG(rxaap);
}
- /**
- * @see PdfAs#reconstructXMLDSIG(ReconstructXMLDsigAfterAnalysisParameters)
- */
public ReconstructXMLDsigResult reconstructXMLDSIG(
+ ReconstructXMLDsigAfterAnalysisParameters reconstructXMLDsigParameters)
+ throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(reconstructXMLDsigParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performReconstructXMLDSIG(reconstructXMLDsigParameters);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ // only log in case of error
+ if (sd.isError()) {
+ statLog.log(sd);
+ }
+ }
+ }
+
+ private ReconstructXMLDsigResult performReconstructXMLDSIG(
ReconstructXMLDsigAfterAnalysisParameters reconstructXMLDsigParameters)
throws PdfAsException {
-
+
AnalyzeResult ar = reconstructXMLDsigParameters.getAnalyzeResult();
List extendedSignatureInfos = new Vector();
for (int i = 0; i < ar.getSignatures().size(); i++)
@@ -572,31 +708,52 @@ public class PdfAsObject implements PdfAs
// don't care for connector exceptions because of mutli signs. they are handled during verify
extendedSignatureInfos.add(new ExtendedSignatureInformation(si, null));
}
-
+
}
return new ReconstructXMLDsigResult(extendedSignatureInfos, reconstructXMLDsigParameters.getSignatureDevice());
}
+ public VerifyResults verify(VerifyAfterReconstructXMLDsigParameters verifyAfterReconstructXMLDsigParameters)
+ throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(verifyAfterReconstructXMLDsigParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performVerify(verifyAfterReconstructXMLDsigParameters);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ statLog.log(sd);
+ }
+ }
+
/**
* @see PdfAs#verify(VerifyAfterReconstructXMLDsigParameters)
*/
- public VerifyResults verify(
+ private VerifyResults performVerify(
VerifyAfterReconstructXMLDsigParameters verifyAfterReconstructXMLDsigParameters)
throws PdfAsException {
-
+
try {
List extSignatures = verifyAfterReconstructXMLDsigParameters.getReconstructXMLDsigResult().getExtendedSignatures();
String signatureDevice = verifyAfterReconstructXMLDsigParameters.getSignatureDevice();
if (signatureDevice == null){
signatureDevice = verifyAfterReconstructXMLDsigParameters.getReconstructXMLDsigResult().getDevice();
}
- List results = PdfAS.verifyExtendedSignatureHolders(extSignatures,
- signatureDevice,
- verifyAfterReconstructXMLDsigParameters.isReturnHashInputData(),
+ List results = PdfAS.verifyExtendedSignatureHolders(extSignatures,
+ signatureDevice,
+ verifyAfterReconstructXMLDsigParameters.isReturnHashInputData(),
verifyAfterReconstructXMLDsigParameters.getVerificationTime(), verifyAfterReconstructXMLDsigParameters.getVerifySignatureIndex());
-
+
List vrs = new ArrayList(results.size());
-
+
int verifySignatureIndex = verifyAfterReconstructXMLDsigParameters.getVerifySignatureIndex();
if (verifySignatureIndex < 0)
{
@@ -605,23 +762,23 @@ public class PdfAsObject implements PdfAs
SignatureResponse response = (SignatureResponse) results.get(i);
ExtendedSignatureInformation extSigInfo = (ExtendedSignatureInformation)extSignatures.get(i);
SignatureHolder holder = (SignatureHolder) extSigInfo.getSignatureInformation().getInternalSignatureInformation();
-
+
VerifyResult vr = new VerifyResultAdapter(response, holder, verifyAfterReconstructXMLDsigParameters.getVerificationTime(), extSigInfo.getXmlDsigData());
vr.setNonTextualObjects( extSigInfo.getSignatureInformation().getNonTextualObjects());
-
+
vrs.add(vr);
}
}else{
SignatureResponse response = (SignatureResponse) results.get(0);
ExtendedSignatureInformation extSigInfo = (ExtendedSignatureInformation)extSignatures.get(verifySignatureIndex);
SignatureHolder holder = (SignatureHolder) extSigInfo.getSignatureInformation().getInternalSignatureInformation();
-
+
VerifyResult vr = new VerifyResultAdapter(response, holder, verifyAfterReconstructXMLDsigParameters.getVerificationTime(), extSigInfo.getXmlDsigData());
vr.setNonTextualObjects( extSigInfo.getSignatureInformation().getNonTextualObjects());
-
+
vrs.add(vr);
}
-
+
VerifyResultsImpl verifyResults = new VerifyResultsImpl(vrs);
return verifyResults;
} catch (java.lang.OutOfMemoryError e) {
@@ -632,7 +789,7 @@ public class PdfAsObject implements PdfAs
public DynamicSignatureProfile createDynamicSignatureProfile(String parentProfile, DynamicSignatureLifetimeEnum mode) {
return DynamicSignatureProfileImpl.createFromParent(null, parentProfile, mode);
}
-
+
public DynamicSignatureProfile createEmptyDynamicSignatureProfile(DynamicSignatureLifetimeEnum mode) {
return DynamicSignatureProfileImpl.createEmptyProfile(null, mode);
}
@@ -648,19 +805,44 @@ public class PdfAsObject implements PdfAs
public DynamicSignatureProfile createEmptyDynamicSignatureProfile(String myUniqueName,
DynamicSignatureLifetimeEnum mode) {
- return DynamicSignatureProfileImpl.createEmptyProfile(myUniqueName, mode);
+ return DynamicSignatureProfileImpl.createEmptyProfile(myUniqueName, mode);
+ }
+
+ public SignatureDetailInformation prepareSign(SignParameters signParameters) throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(signParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performPrepareSign(signParameters);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ // only log in case of error
+ if (sd.isError()) {
+ statLog.log(sd);
+ }
+ }
}
/**
* @see PdfAs#prepareSign(SignParameters)
*/
- public SignatureDetailInformation prepareSign(SignParameters signParameters) throws PdfAsException {
+ private SignatureDetailInformation performPrepareSign(SignParameters signParameters) throws PdfAsException {
CheckHelper.checkSignParameters(signParameters, true);
-
+
if (signParameters.getProfileOverrideProperties() != null) {
OverridePropertyHolder.setOverrideProps(signParameters.getProfileOverrideProperties());
}
+ PDFASUtils.createPdfReaderCheckingPermissions(signParameters.getDocument());
+
signParameters.setDocument(PdfAS.applyStrictMode(signParameters.getDocument()));
SettingsReader settings = SettingsReader.getInstance();
@@ -730,29 +912,29 @@ public class PdfAsObject implements PdfAs
} else if (fromConfig) {
arguments[0] = "width defined by the profile " + signParameters.getSignatureProfileId();
}
- log.warn(MessageFormat.format(msg, arguments));
+ log.warn(MessageFormat.format(msg, (Object[]) arguments));
}
}
-
+
Signator signator = createSignator(signParameters.getSignatureType());
SignatorInformation signatorInfo = signator.prepareSign(
- new PdfDataSourceAdapter(signParameters.getDocument()),
- signParameters.getSignatureProfileId(),
- pos,
+ new PdfDataSourceAdapter(signParameters.getDocument()),
+ signParameters.getSignatureProfileId(),
+ pos,
signParameters.getTimeStamperImpl());
-
+
SignatureDetailInformationImpl ret = new SignatureDetailInformationImpl();
ret.setSignatorInformation(signatorInfo);
return ret;
}
-
+
private SignaturePlaceholderData getSignaturePlaceholder(SignParameters signParameters,
String defaultProfile) throws SettingsException, PDFDocumentException, PlaceholderExtractionException {
SignaturePlaceholderData spd = null;
SignaturePlaceholderContext.setSignaturePlaceholderData(null);
-
+
SettingsReader settings = SettingsReader.getInstance();
// check sig_obj.PROFILEID.enable_placeholder_search
@@ -766,15 +948,15 @@ public class PdfAsObject implements PdfAs
// check global enable_placeholder_search
configFileActivedString = settings.getValueFromKey(ENABLE_PLACEHOLDER_SEARCH_KEY);
}
-
+
Boolean configFileActived = null;
if (configFileActivedString != null)
configFileActived = Boolean.valueOf(configFileActivedString);
Boolean signParamsActivated = signParameters.isCheckForPlaceholder();
-
+
boolean enableSearch;
-
+
if (signParamsActivated != null)
{
enableSearch = signParamsActivated.booleanValue();
@@ -788,8 +970,8 @@ public class PdfAsObject implements PdfAs
if (enableSearch)
{
spd = SignaturePlaceholderExtractor.extract(
- signParameters.getDocument().createInputStream(),
- signParameters.getPlaceholderId(),
+ signParameters.getDocument().createInputStream(),
+ signParameters.getPlaceholderId(),
signParameters.getPlaceholderMatchMode());
}
return spd;
@@ -809,15 +991,36 @@ public class PdfAsObject implements PdfAs
{
signatorId = SignatorFactory.MOST_RECENT_DETACHEDTEXT_SIGNATOR_ID;
}
-
+
return at.gv.egiz.pdfas.framework.SignatorFactory.createSignator(signatorId);
}
- public SignResult sign(SignParameters signParameters, SignatureDetailInformation signatorInfo)
+ public SignResult sign(SignParameters signParameters, SignatureDetailInformation signatorInfo)
+ throws PdfAsException {
+ // prepare log data
+ StatisticData sd = new StatisticData(signParameters);
+ StopWatch sw = new StopWatch();
+ try {
+ sw.start();
+ return performSign(signParameters, signatorInfo);
+ } catch (PdfAsException e) {
+ sd.setException(e);
+ throw e;
+ } catch (RuntimeException e) {
+ sd.setException(e);
+ throw e;
+ } finally {
+ sw.stop();
+ sd.setDuration(sw.getTime());
+ statLog.log(sd);
+ }
+ }
+
+ private SignResult performSign(SignParameters signParameters, SignatureDetailInformation signatorInfo)
throws PdfAsException {
CheckHelper.checkSignParametersForSignAfterPrepare(signParameters, false);
-
+
if (signParameters.getProfileOverrideProperties() != null) {
OverridePropertyHolder.setOverrideProps(signParameters.getProfileOverrideProperties());
}
@@ -832,34 +1035,34 @@ public class PdfAsObject implements PdfAs
SignatureData sd = new SignatureDataImpl(new PdfDataSourceAdapter(signatorInfo.getSignatureData()), signatorInfo.getSignatureData().getMimeType());
SignSignatureObject sso = PdfAS.sign(sd, c, signParameters.getTimeStamperImpl());
((SignatureDetailInformationImpl)signatorInfo).setSignSignatureObject(sso);
-
+
return finishSign(signParameters, signatorInfo);
}
- public SignResult finishSign(SignParameters signParameters, SignatureDetailInformation signatureDetailInformation)
+ public SignResult finishSign(SignParameters signParameters, SignatureDetailInformation signatureDetailInformation)
throws PdfAsException {
try {
CheckHelper.checkSignParametersForSignAfterPrepare(signParameters, true);
CheckHelper.checkSignatureDetailInformation(signatureDetailInformation);
-
+
if (signParameters.getProfileOverrideProperties() != null) {
OverridePropertyHolder.setOverrideProps(signParameters.getProfileOverrideProperties());
}
-
+
Signator signator = createSignator(signParameters.getSignatureType());
SignatorInformation signatorInfo = ((SignatureDetailInformationImpl)signatureDetailInformation).getSignatorInfo();
signator.finishSign(signatorInfo, new DataSinkAdapter(signParameters.getOutput()));
return new SignResultImpl(
- signParameters.getOutput(),
+ signParameters.getOutput(),
signatorInfo.getSignSignatureObject().getX509Certificate(),
- new ActualSignaturePositionAdapter(signatorInfo.getActualTablePos()),
+ new ActualSignaturePositionAdapter(signatorInfo.getActualTablePos()),
signatorInfo.getNonTextualObjects());
} finally {
OverridePropertyHolder.removeProperties();
DynamicSignatureProfileImpl.disposeLocalProfile();
}
}
-
+
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/DataSinkAdapter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/DataSinkAdapter.java
index 2aee44f..b91d5a9 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/DataSinkAdapter.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/DataSinkAdapter.java
@@ -30,7 +30,7 @@ import at.gv.egiz.pdfas.api.io.DataSink;
/**
* Adapter that converts an API DataSink to a framework DataSink.
- *
+ *
* @author wprinz
*/
public class DataSinkAdapter implements at.gv.egiz.pdfas.framework.output.DataSink
@@ -42,7 +42,7 @@ public class DataSinkAdapter implements at.gv.egiz.pdfas.framework.output.DataSi
/**
* Constructor.
- *
+ *
* @param apiDataSink
* The API DataSink to be adapted to a framework DataSink.
*/
@@ -62,7 +62,6 @@ public class DataSinkAdapter implements at.gv.egiz.pdfas.framework.output.DataSi
}
catch (IOException e)
{
- e.printStackTrace();
throw new RuntimeException(e);
}
}
@@ -79,7 +78,6 @@ public class DataSinkAdapter implements at.gv.egiz.pdfas.framework.output.DataSi
}
catch (IOException e)
{
- e.printStackTrace();
throw new RuntimeException(e);
}
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/SignatureProfileImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/SignatureProfileImpl.java
index 35d8c17..1df1a65 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/SignatureProfileImpl.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/api/commons/SignatureProfileImpl.java
@@ -28,6 +28,7 @@ import java.util.Properties;
import org.apache.commons.lang.builder.ToStringBuilder;
import at.gv.egiz.pdfas.api.commons.SignatureProfile;
+import at.knowcenter.wag.egov.egiz.sig.SignatureTypes.State;
/**
* Holds the data of a signature profile.
@@ -61,6 +62,13 @@ public class SignatureProfileImpl implements SignatureProfile {
* true if this is the default profile, false otherwise.
*/
protected boolean defaultProfile = false;
+
+ /**
+ * The state of the signature profile. Signature profiles may be disabled (OFF), allowed for signature only
+ * (SIGN_ONLY), allowed for verification only (VERIFY_ONLY) or just enabled (ON).
+ * Default value here of ON in order to assure backward compatibility.
+ */
+ private State state = State.ON;
/**
* Constructor.
@@ -88,14 +96,26 @@ public class SignatureProfileImpl implements SignatureProfile {
* @param isDefault
*/
public SignatureProfileImpl(String profileId, String profileDescription, String moaKeyIdentifier, boolean isDefault) {
- this.profileId = profileId;
- this.moaKeyIdentifier = moaKeyIdentifier;
- this.profileDescription = profileDescription;
- this.signatureBlockEntries = new Properties();
- this.defaultProfile = isDefault;
+ this(profileId, moaKeyIdentifier);
+ this.profileDescription = profileDescription;
+ this.defaultProfile = isDefault;
}
/**
+ * Creates a new signature profile instance.
+ * @param profileId The profile identifier.
+ * @param state The profile's state.
+ * @param profileDescription The profile description.
+ * @param moaKeyIdentifier The MOA-SS key identifier.
+ * @param isDefault {@code true} if this is a default profile, {@code false} if not.
+ */
+ public SignatureProfileImpl(String profileId, State state, String profileDescription, String moaKeyIdentifier, boolean isDefault) {
+ this(profileId, profileDescription, moaKeyIdentifier, isDefault);
+ this.state = state;
+ }
+
+
+ /**
* @see at.gv.egiz.pdfas.api.commons.SignatureProfile#getProfileId()
*/
public String getProfileId() {
@@ -140,19 +160,22 @@ public class SignatureProfileImpl implements SignatureProfile {
return this.profileDescription;
}
- public String toString() {
- return new ToStringBuilder(this)
- .append("profileId", this.profileId)
- .append("profileDescription", this.profileDescription)
- .append("moaKeyIdentifier", this.moaKeyIdentifier)
- .toString();
- }
+ @Override
+ public String toString() {
+ return "SignatureProfileImpl [profileId=" + profileId + ", state=" + state + ", profileDescription="
+ + profileDescription + ", moaKeyIdentifier=" + moaKeyIdentifier + ", defaultProfile=" + defaultProfile
+ + "]";
+ }
- /**
+/**
*
*/
public boolean isDefault() {
return this.defaultProfile;
}
+ public State getState() {
+ return state;
+ }
+
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/input/correction/InternalCorrector.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/input/correction/InternalCorrector.java
index eaa6b7f..b193936 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/input/correction/InternalCorrector.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/input/correction/InternalCorrector.java
@@ -26,6 +26,7 @@ package at.gv.egiz.pdfas.impl.input.correction;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import at.gv.egiz.pdfas.api.io.DataSource;
import at.gv.egiz.pdfas.exceptions.ErrorCode;
import at.gv.egiz.pdfas.exceptions.framework.CorrectorException;
import at.gv.egiz.pdfas.framework.input.PdfDataSource;
@@ -40,7 +41,7 @@ import com.lowagie.text.pdf.PdfStamper;
/**
* Corrects a document using iText.
- *
+ *
* @author wprinz
*/
public class InternalCorrector implements Corrector
@@ -53,11 +54,9 @@ public class InternalCorrector implements Corrector
{
try
{
- byte[] pdf = document.getAsByteArray();
- PdfReader reader = new PdfReader(pdf);
- PDFASUtils.checkReaderPermissions(reader);
+ PdfReader reader = PDFASUtils.createPdfReaderCheckingPermissions(document);
- ByteArrayOutputStream baos = new ByteArrayOutputStream(pdf.length);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(document.getLength());
PdfStamper stamper = new PdfStamper(reader, baos, '\0', false);
stamper.close();
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java
index 0af6538..a3ff856 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/binary/BinarySignator_1_0_0.java
@@ -83,7 +83,7 @@ import com.lowagie.text.pdf.PdfPTable;
/**
* Signs the document binary.
- *
+ *
* <p>
* In prepareSign, an Incremental Update is created that contains the Signature block and the egiz dictionary. For
* formatting the layout, variable values are filled with placeholders. After the layout has been fixed, all variable
@@ -92,7 +92,7 @@ import com.lowagie.text.pdf.PdfPTable;
* <p>
* In finishSign, the variable fields (values, /Cert) are replaced with the values according to the encoding.
* </p>
- *
+ *
* @author wprinz
*/
public class BinarySignator_1_0_0 implements Signator {
@@ -204,13 +204,19 @@ public class BinarySignator_1_0_0 implements Signator {
// on a new page, prevent pdf-as to do that, because why should make
// a new page just for an invisible block
// added by rpiazzi
+
+ // disabled by dti: code fixes certain cases with invisible signatures but prevents usage of minimal
+ // signature profiles; the actual invisible signature issue has fixed in method
+ // adjustSignatureTableandCalculatePosition(...) in class at.knowcenter.wag.egov.egiz.PdfAS
+ /*
if (signature_object.getSignatureTypeDefinition().getInvisibleFieldDefinitions().size() == SignatureTypes.REQUIRED_SIG_KEYS.length) {
if (pi.isMakeNewPage()) {
int pageNumber = pi.getPage();
pi = new PositioningInstruction(false, pageNumber - 1, 0, 0);
}
}
- // end added
+ */
+ // end added (rpiazzi)
IncrementalUpdateInformation iui = IncrementalUpdateHelper.writeIncrementalUpdate(pdfDataSource, pdf_table,
profile, pi, variable_field_definitions, all_field_definitions, invisible_field_definitions,
@@ -318,7 +324,7 @@ public class BinarySignator_1_0_0 implements Signator {
/**
* Reads the signature values from the signed signature object and fills the corresponding value in the Replaces
* array.
- *
+ *
* @param iui
* The IncrementalUpdateInformation.
*/
@@ -394,7 +400,7 @@ public class BinarySignator_1_0_0 implements Signator {
/**
* Forms the SignatureData to be used for signing.
- *
+ *
* @param iui
* The IncrementalUpdateInformation.
* @return Returns the SignatureData to be used for signing.
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/detached/DetachedTextualSignator_1_0_0.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/detached/DetachedTextualSignator_1_0_0.java
index 7fcdb2a..16e2718 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/detached/DetachedTextualSignator_1_0_0.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/signator/detached/DetachedTextualSignator_1_0_0.java
@@ -41,7 +41,7 @@ import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUPostConnection;
/**
* Signs a document textually.
- *
+ *
* <p>
* In prepareSign, the document text is extracted and normalized.
* </p>
@@ -49,7 +49,7 @@ import at.knowcenter.wag.egov.egiz.sig.connectors.bku.BKUPostConnection;
* In finishSign, the signed SignatureObject is transformed into a Signature
* block, which is then written as an Incremental Update.
* </p>
- *
+ *
* @author wprinz
*/
public class DetachedTextualSignator_1_0_0 extends TextualSignator_1_0_0
@@ -93,7 +93,7 @@ public class DetachedTextualSignator_1_0_0 extends TextualSignator_1_0_0
// String document_text =
// PdfAS.extractNormalizedTextTextual(pdf.createInputStream());
// // logger_.debug("signed_text = " + document_text);
- //
+ //
// DataSource ds = new TextDataSourceImpl(document_text);
// iui.signature_data = new SignatureDataImpl(ds, MIME_TYPE, "UTF-8");
// //$NON-NLS-1$ //$NON-NLS-2$
@@ -119,7 +119,6 @@ public class DetachedTextualSignator_1_0_0 extends TextualSignator_1_0_0
// }
// catch (UnsupportedEncodingException e)
// {
- // e.printStackTrace();
// throw new PDFDocumentException(300, e);
// }
// }
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java
index 3f0f482..0e0da78 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/VerificationFilterImpl.java
@@ -80,7 +80,7 @@ public class VerificationFilterImpl implements VerificationFilter
public static final String SUPRESS_EXCEPTION_WHEN_LAST_UIBLOCK_IS_NO_SIGNATURE = "supress_exception_when_last_iublock_is_no_signature";
public static final String BINARY_ONLY = "binary_only";
public static final String ASSUME_ONLY_SIGNATURE_BLOCKS = "assume_only_signature_blocks";
-
+
/**
* @see at.gv.egiz.pdfas.framework.vfilter.VerificationFilter#extractSignatureHolders(at.gv.egiz.pdfas.framework.input.PdfDataSource,
* java.util.List,
@@ -97,7 +97,7 @@ public class VerificationFilterImpl implements VerificationFilter
log.debug("Original IU blocks: " + blocks.size());
debugIUBlocks(blocks);
}
-
+
unrollLinearization(blocks);
if (log.isDebugEnabled())
@@ -106,7 +106,7 @@ public class VerificationFilterImpl implements VerificationFilter
debugIUBlocks(blocks);
}
-
+
SettingsReader settings;
try {
settings = SettingsReader.getInstance();
@@ -115,7 +115,7 @@ public class VerificationFilterImpl implements VerificationFilter
}
String check_doc = settings.getSetting(CHECK_DOCUMENT, "false");
- // check document for textual sigs here here if binary_only is set
+ // check document for textual sigs here here if binary_only is set
if ("true".equalsIgnoreCase(check_doc) &&
parameters.extractBinarySignaturesOnly()) {
@@ -125,7 +125,7 @@ public class VerificationFilterImpl implements VerificationFilter
log.debug("Skipping checkDocument for textual sigs.");
}
// end add
-
+
List signatureHolderChain = null;
if (parameters.extractBinarySignaturesOnly())
@@ -156,11 +156,11 @@ public class VerificationFilterImpl implements VerificationFilter
}
}
-
+
log.trace("extractSignaturHolders finished (" + (signatureHolderChain != null ? signatureHolderChain.size() : 0) + " elements).");
sw.stop();
log.debug("extractSignatureHolders: " + sw.getTime() + "ms.");
-
+
return signatureHolderChain;
}
@@ -194,12 +194,12 @@ public class VerificationFilterImpl implements VerificationFilter
foundSignatures = extractNewSignaturesFromText(normalizedText);
}
-
+
List textOnlySignatures = filterOutBinarySignatures(foundSignatures);
-
+
return textOnlySignatures;
}
-
+
protected String normalizeText(String freetext) throws VerificationFilterException
{
try
@@ -214,7 +214,7 @@ public class VerificationFilterImpl implements VerificationFilter
/**
* Removes the linearization footer from the list of update blocks.
- *
+ *
* @param blocks
* The list of FooterParseResult objects in \prev order.
*/
@@ -263,15 +263,15 @@ public class VerificationFilterImpl implements VerificationFilter
if (sao.oldSignature != null)
{
extractedSignatures.add(0, sao.oldSignature);
- }
+ }
}
else
{
log.debug("extracting signatures from last partition...");
extractedSignatures = extractSignaturesFromPartition(pdf, lastTextPartition);
}
-
-
+
+
List signatureHolderChain = intermingleSignatures(binarySignatures, extractedSignatures);
return signatureHolderChain;
@@ -287,15 +287,15 @@ public class VerificationFilterImpl implements VerificationFilter
Set binarySigValues = new HashSet();
Iterator iterator = binarySignatures.iterator();
while(iterator.hasNext()) {
-
+
SignatureHolder sh = (SignatureHolder)iterator.next();
-
+
String sigVal = sh.getSignatureObject().getSignationValue();
binarySigValues.add(sigVal);
}
-
+
SignatureHolder oldSignature = null;
-
+
//List originalPartitions = partitions;
// This gives every IU block an own text partition
// This allows text signatures to be found correctly if there are
@@ -313,36 +313,36 @@ public class VerificationFilterImpl implements VerificationFilter
}
String check_doc = settings.getSetting(CHECK_DOCUMENT, "false");
boolean supressException = "true".equalsIgnoreCase(settings.getSetting(SUPRESS_EXCEPTION_WHEN_LAST_UIBLOCK_IS_NO_SIGNATURE, "false"));
-
+
// flag indicating that the last IU-block of the document is a non-signature IU-block
boolean lastBlockWasModified = false;
-
+
// counter of all signatures (textual and binary) of this document
int signatureCounter = 0;
-
+
// counter of all textual signatures in this document
int txtSigsSoFar = 0;
-
+
// counter of all textual signatures in the current partition
int txtSigsThisPartition = 0;
-
+
List partitionResults = new ArrayList(partitions.size());
- List nshList = new ArrayList();
-
+ List nshList = new ArrayList();
+
boolean sigFound = false;
-
+
for (int i = 0; i < partitions.size(); i++)
{
Partition p = (Partition) partitions.get(i);
-
+
// updating flag and counter
boolean partitionContainsNewTextSignatures = true;
txtSigsSoFar = txtSigsThisPartition;
-
+
if (p instanceof TextPartition)
{
TextPartition tp = (TextPartition) p;
-
+
List partitionResult = null;
boolean scanThisPartitionForOldSignature = (i == 0) && scanForOldSignatures;
@@ -356,34 +356,34 @@ public class VerificationFilterImpl implements VerificationFilter
{
partitionResult = extractSignaturesFromPartition(pdf, tp);
}
-
- // binary signature blocks that have been detected as well are identified by comparing their signature values
+
+ // binary signature blocks that have been detected as well are identified by comparing their signature values
// with those stored in our Set above and are not considered for our IU-check
List onlyTextSignatures = new ArrayList();
Iterator iter = partitionResult.iterator();
while(iter.hasNext()) {
-
+
SignatureHolder sh = (SignatureHolder)iter.next();
if(!binarySigValues.contains(sh.getSignatureObject().getSignationValue())) {
-
+
onlyTextSignatures.add(sh);
}
}
-
+
// update signature counters
txtSigsThisPartition = onlyTextSignatures.size();
int newTextSignatures = txtSigsThisPartition - txtSigsSoFar;
signatureCounter = signatureCounter + newTextSignatures;
-
+
// update sigFound flag
if(txtSigsThisPartition > 0) {
-
+
sigFound = true;
}
-
+
// TextPartition is only valid, if at least one more text signature has been found than in the previous text partition
if(!(newTextSignatures > 0)) {
-
+
partitionContainsNewTextSignatures = false;
}
@@ -391,39 +391,39 @@ public class VerificationFilterImpl implements VerificationFilter
} else {
// should be binary partition
if(p instanceof BinaryPartition) {
-
+
BinaryPartition binpart = (BinaryPartition)p;
// updating counter and flag
signatureCounter = signatureCounter + binpart.blocks.size();
sigFound = true;
-
+
}
}
-
+
// if document checking is enabled, at least one signature has been found so far, we are dealing with a
// non-signature IU-block
if ((check_doc.equalsIgnoreCase("true"))&& (sigFound && !partitionContainsNewTextSignatures)) {
-
- nshList.add(new NoSignatureHolder(signatureCounter));
+
+ nshList.add(new NoSignatureHolder(signatureCounter));
lastBlockWasModified = true;
-
+
} else {
-
+
lastBlockWasModified = false;
}
-
+
}
// throw an exception if the last update block does not contain a signature and signatures have been found in this document
if (lastBlockWasModified) {
if (!supressException) {
- throw new VerificationFilterException(ErrorCode.MODIFIED_AFTER_SIGNATION, "The document has been modified after being signed.");
+ throw new VerificationFilterException(ErrorCode.MODIFIED_AFTER_SIGNATION, "The document has been modified after being signed.");
} else {
log.debug("The document has been modified after being signed. According to the configuration, no exception is thrown.");
}
}
-
+
List extractedSignatures = new ArrayList();
Iterator it = partitionResults.iterator();
List prevPartitionResult = null;
@@ -451,54 +451,54 @@ public class VerificationFilterImpl implements VerificationFilter
}
List signatureHolderChain = intermingleSignatures(binarySignatures, extractedSignatures);
-
+
if (oldSignature != null)
{
signatureHolderChain.add(0, oldSignature);
}
-
+
// add the created NoSignatureHolders
signatureHolderChain.addAll(nshList);
-
+
return signatureHolderChain;
}
-
+
private void mergeSignatures(List oldList, List newList, List result) {
-
+
for(int i=0; i < newList.size(); i++) {
-
+
SignatureHolder currentNewSh = (SignatureHolder)newList.get(i);
-
+
boolean shAlreadyPresentInOldList = false;
int pos = -1;
-
+
for(int j=0; j<oldList.size(); j++) {
-
+
SignatureHolder currentOldSh = (SignatureHolder)oldList.get(j);
-
+
if(currentNewSh.getSignatureObject().getSignationValue().equals(currentOldSh.getSignatureObject().getSignationValue())) {
-
+
shAlreadyPresentInOldList = true;
pos = j;
}
}
-
+
if(!shAlreadyPresentInOldList) {
-
+
// signature holder has not been found earlier -> add
result.add(currentNewSh);
}
-
+
}
-
-
+
+
return;
}
-
-
+
+
protected List flattenOutTextPartitions (List partitions, List blocks)
{
-
+
List blockPartitions = new ArrayList(blocks.size());
Iterator it = partitions.iterator();
while (it.hasNext())
@@ -523,10 +523,10 @@ public class VerificationFilterImpl implements VerificationFilter
blockPartitions.add(p);
}
}
-
+
// note: successive binary blocks are still combined to one binary partition
assert blockPartitions.size() <= blocks.size();
-
+
return blockPartitions;
}
@@ -536,15 +536,15 @@ public class VerificationFilterImpl implements VerificationFilter
protected String extractText(PdfDataSource pdf, int endOfDocument, String encoding) throws PresentableException
{
-
+
log.debug("EXTRACTING TEXT (" + encoding + ")... end index = " + endOfDocument);
-
+
DelimitedPdfDataSource dds = new DelimitedPdfDataSource(pdf, endOfDocument);
//DelimitedInputStream dis = new DelimitedInputStream(pdf.createInputStream(), endOfDocument);
return PdfAS.extractNormalizedTextTextual(dds, encoding);
}
-
-
+
+
protected List extractNewSignaturesFromText(String text) throws VerificationFilterException
{
try
@@ -556,7 +556,7 @@ public class VerificationFilterImpl implements VerificationFilter
throw new VerificationFilterException(e);
}
}
-
+
protected List extractNewAndOldSignaturesFromText(String text) throws VerificationFilterException
{
SignaturesAndOld sao = extractSignaturesAndOld(text);
@@ -651,11 +651,11 @@ public class VerificationFilterImpl implements VerificationFilter
/**
* Extracts the binary singatures from the given PDF.
- *
+ *
* <p>
* IU blocks without an egiz dict are not considered.
* </p>
- *
+ *
* @param pdf
* @param blocks
* @return Returns the List of signature holders.
@@ -673,7 +673,7 @@ public class VerificationFilterImpl implements VerificationFilter
String binary_only = settings.getSetting(BINARY_ONLY, "false");
String assume_sigs_only = settings.getSetting(ASSUME_ONLY_SIGNATURE_BLOCKS, "false");
boolean supressException = "true".equalsIgnoreCase(settings.getSetting(SUPRESS_EXCEPTION_WHEN_LAST_UIBLOCK_IS_NO_SIGNATURE, "false"));
-
+
try
{
// PERF: extract binary signatures needs byte array
@@ -689,15 +689,15 @@ public class VerificationFilterImpl implements VerificationFilter
FooterParseResult fpr = (FooterParseResult) it.next();
assert fpr.next_index > prev_end;
- if (VerificationFilterBinaryHelper.containsEGIZDict(data, fpr))
+ PdfASID kz = null;
+ if (VerificationFilterBinaryHelper.containsEGIZDict(data, fpr) &&
+ (kz = VerificationFilterBinaryHelper.extractKZFromEGIZBlock(data, fpr)) != null)
{
- PdfASID kz = VerificationFilterBinaryHelper.extractKZFromEGIZBlock(data, fpr);
-
// TODO dferbas hack baik test
//kz = new PdfASID("urn:pdfsigfilter:bka.gv.at:binaer:v1.1.0");
-
+
Verificator verificator = VerificatorFactory.createBinaryVerificator(kz);
- List binary_holders = verificator.parseBlock(pdf, data, fpr, prev_end);
+ List binary_holders = verificator.parseBlock(pdf, data, fpr, prev_end);
binarySignatures.addAll(binary_holders);
if(binary_holders.size() > 0) {
@@ -707,21 +707,21 @@ public class VerificationFilterImpl implements VerificationFilter
// an Exception is thrown here if:
// 1) check_document is activated
// 2) assume_only_signature_blocks is false - otherwise we permit updates
- // 3) binary_only is true - otherwise updates are handled in method performFullConservative().
- // when binary-only is true, we can be sure that a block that contains no egiz-dict is no textual
+ // 3) binary_only is true - otherwise updates are handled in method performFullConservative().
+ // when binary-only is true, we can be sure that a block that contains no egiz-dict is no textual
// signature either but an illegal update, otherwise an Exception (doc contains textual sig) would have been thrown before
// 4) a binary signature has been detected in a previous block
- if(check_doc.equalsIgnoreCase("true") &&
+ if(check_doc.equalsIgnoreCase("true") &&
binary_only.equalsIgnoreCase("true") &&
assume_sigs_only.equalsIgnoreCase("false") &&
- sig_detected) {
-
+ sig_detected) {
+
if (!supressException) {
- throw new VerificationFilterException(ErrorCode.MODIFIED_AFTER_SIGNATION, "The document has been modified after being signed.");
+ throw new VerificationFilterException(ErrorCode.MODIFIED_AFTER_SIGNATION, "The document has been modified after being signed.");
} else {
log.debug("The document has been modified after being signed. According to the configuration, no exception is thrown.");
}
-
+
}
}
@@ -749,7 +749,7 @@ public class VerificationFilterImpl implements VerificationFilter
List extractedSignatures = extractNewSignaturesFromText(extractedText);
log.debug("Extracting signatures finished.");
log.debug("Number of found signatures: " + extractedSignatures.size());
-
+
if (extractedSignatures.size() > 0) {
List cp1252SignaturesPositions = new ArrayList();
//boolean iscp1252Sig = false;
@@ -760,19 +760,19 @@ public class VerificationFilterImpl implements VerificationFilter
log.debug("found cp1252 signature");
cp1252SignaturesPositions.add(new Integer(i));
//iscp1252Sig = true;
- //break;
+ //break;
}
- }
+ }
if (cp1252SignaturesPositions.size() > 0) {
log.debug("redo text and signature extraction with cp1252 encoding");
extractedText = extractText(pdf, endOfDocument, "cp1252");
log.debug("Extracting text finished.");
-
+
log.debug("Extracting signatures:");
List cp1252ExtractedSignatures = extractNewSignaturesFromText(extractedText);
log.debug("Extracting signatures finished.");
log.debug("Number of found signatures: " + extractedSignatures.size());
-
+
if (cp1252ExtractedSignatures.size() != extractedSignatures.size()) {
log.error("Invalid cp1252 signatures found. Skipping cp1252 compatibility.");
}
@@ -780,12 +780,12 @@ public class VerificationFilterImpl implements VerificationFilter
for (int i = 0; i < cp1252SignaturesPositions.size(); i++) {
int replaceIndex = ((Integer)cp1252SignaturesPositions.get(i)).intValue();
extractedSignatures.remove(replaceIndex);
- extractedSignatures.add(replaceIndex, cp1252ExtractedSignatures.get(replaceIndex));
+ extractedSignatures.add(replaceIndex, cp1252ExtractedSignatures.get(replaceIndex));
}
}
-
+
}
-
+
if (log.isDebugEnabled())
{
log.debug("extracted signatures:");
@@ -856,7 +856,7 @@ public class VerificationFilterImpl implements VerificationFilter
}
protected void checkBinaryOnly(PdfDataSource pdf, boolean considerOldSigs) throws VerificationFilterException {
-
+
DelimitedPdfDataSource dds = new DelimitedPdfDataSource(pdf, pdf.getLength());
String text = null;
try {
@@ -864,10 +864,10 @@ public class VerificationFilterImpl implements VerificationFilter
} catch (PresentableException e) {
throw new VerificationFilterException(e);
}
-
+
List sigs = new ArrayList();
-
- if(considerOldSigs) {
+
+ if(considerOldSigs) {
SignaturesAndOld sao = extractSignaturesAndOld(text);
if(sao != null) {
if(sao.newSignatures != null) {
@@ -877,30 +877,30 @@ public class VerificationFilterImpl implements VerificationFilter
sigs.add(sao.oldSignature);
}
}
- } else {
+ } else {
List signatures = extractSignatures(pdf, pdf.getLength());
if(signatures != null) {
sigs.addAll(signatures);
}
}
-
+
Iterator it = sigs.iterator();
while(it.hasNext()) {
SignatureHolder current = (SignatureHolder)it.next();
if((current != null)&&(!current.getSignatureObject().isBinary())) {
throw new VerificationFilterException(ErrorCode.NON_BINARY_SIGNATURES_PRESENT, "The document contains non-binary signatures.");
}
- }
+ }
}
-
-
+
+
protected static class SignaturesAndOld
{
public List newSignatures = null;
public SignatureHolder oldSignature = null;
}
-
+
protected SignaturesAndOld extractSignaturesAndOld(String text) throws VerificationFilterException
{
try
@@ -908,7 +908,7 @@ public class VerificationFilterImpl implements VerificationFilter
log.debug("Extracting signatures:");
List extractedSignatures = extractNewSignaturesFromText(text);
log.debug("Extracting signatures finished.");
-
+
log.debug("Extracting old signatures:");
SignatureHolder oldSignature = extractOldSignature(text, extractedSignatures);
log.debug("Extracting old signatures finished.");
@@ -929,7 +929,7 @@ public class VerificationFilterImpl implements VerificationFilter
/**
* Extracts the old signature from the text, but only if it is older than the
* oldest signature of the new signatueres.
- *
+ *
* @param extractedText
* @param newSignatures
* @return
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java
index 735b874..3093c36 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/impl/vfilter/helper/VerificationFilterBinaryHelper.java
@@ -48,7 +48,7 @@ import at.knowcenter.wag.exactparser.parsing.results.ObjectParseResult;
/**
* Contains helpful methods used by the VerificationFilter to analyze the PDF for binary signatures.
- *
+ *
* @author wprinz
*/
public final class VerificationFilterBinaryHelper
@@ -70,12 +70,12 @@ public final class VerificationFilterBinaryHelper
/**
* Tells, if the given incremental update block contains a binary signature.
- *
+ *
* <p>
* According to definition, if a block is a binary block, it must/cannot
* contain other signatures than this one.
* </p>
- *
+ *
* @param block
* The incremental update block.
* @return Returns true, if this block is a binary signature block, false
@@ -94,7 +94,7 @@ public final class VerificationFilterBinaryHelper
/**
* Extracts the PDF AS ID of the egiz block.
- *
+ *
* @param pdf
* The pdf.
* @param block
@@ -120,6 +120,13 @@ public final class VerificationFilterBinaryHelper
IndirectObjectReference ior = egiz_dict_iorpr.ior;
final int egiz_dict_offset = PDFUtils.getObjectOffsetFromXRefByIndirectObjectReference(block.xpr, ior);
+
+ // fix dti:
+ if (egiz_dict_offset < 0) {
+ log.debug("Current ui block contains a /EGIZSigDict trailer entry but no respective xref table entry. This indicates that this ui block does not contain binary signatures.");
+ return null;
+ }
+
// logger_.debug("egiz_dict_offset = " + egiz_dict_offset);
ObjectParseResult obj = PDFUtils.parseObject(pdf, egiz_dict_offset);
@@ -140,7 +147,7 @@ public final class VerificationFilterBinaryHelper
/**
* Restores the Kennzeichnung String from an Array.
- *
+ *
* @param pdf
* The PDF.
* @param kz_apr
@@ -174,7 +181,7 @@ public final class VerificationFilterBinaryHelper
si.pdf = pdf;
log.trace("Adding KZ: " + si.toString());
-
+
partition.add(si);
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/FileBasedTextBasedDataSource.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/FileBasedTextBasedDataSource.java
index aaf99ea..918b13d 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/FileBasedTextBasedDataSource.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/FileBasedTextBasedDataSource.java
@@ -33,7 +33,7 @@ import at.gv.egiz.pdfas.api.io.TextBased;
/**
* FileBased DataSource that is TextBased.
- *
+ *
* @author wprinz
*/
public class FileBasedTextBasedDataSource extends FileBasedDataSource implements TextBased
@@ -113,7 +113,6 @@ public class FileBasedTextBasedDataSource extends FileBasedDataSource implements
}
catch (UnsupportedEncodingException e)
{
- e.printStackTrace();
throw new RuntimeException(e);
}
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/StringTextBasedDataSource.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/StringTextBasedDataSource.java
index 8fe0dd6..8234b2a 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/StringTextBasedDataSource.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/io/StringTextBasedDataSource.java
@@ -32,9 +32,9 @@ import at.gv.egiz.pdfas.api.io.TextBased;
/**
* A String TextBased DataSource.
- *
+ *
* @author wprinz
- *
+ *
*/
public class StringTextBasedDataSource implements DataSource, TextBased
{
@@ -74,7 +74,6 @@ public class StringTextBasedDataSource implements DataSource, TextBased
}
catch (UnsupportedEncodingException e)
{
- e.printStackTrace();
throw new RuntimeException(e);
}
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/placeholder/SignaturePlaceholderExtractor.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/placeholder/SignaturePlaceholderExtractor.java
index 8b8c22e..453b620 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/placeholder/SignaturePlaceholderExtractor.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/placeholder/SignaturePlaceholderExtractor.java
@@ -71,7 +71,7 @@ import com.google.zxing.common.HybridBinarizer;
/**
* Extract all relevant information from a placeholder image.
- *
+ *
* @author exthex
*
*/
@@ -80,10 +80,10 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
* The log.
*/
private static Log log = LogFactory.getLog(SignaturePlaceholderExtractor.class);
-
+
private List placeholders = new Vector();
private int currentPage = 0;
-
+
private SignaturePlaceholderExtractor(String placeholderId, int placeholderMatchMode) throws IOException {
super(ResourceLoader.loadProperties("at/gv/egiz/pdfas/placeholder/pdfbox-reader.properties",
true));
@@ -93,7 +93,7 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
* Search the document for placeholder images and possibly included
* additional info.<br/>
* Searches only for the first placeholder page after page from top.
- *
+ *
* @param inputStream
* @return all available info from the first found placeholder.
* @throws PDFDocumentException if the document could not be read.
@@ -103,14 +103,13 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
throws PDFDocumentException, PlaceholderExtractionException {
SignaturePlaceholderContext.setSignaturePlaceholderData(null);
PDDocument doc = null;
- try
+ try
{
try {
doc = PDDocument.load(inputStream);
} catch (IOException e) {
throw new PDFDocumentException(ErrorCode.DOCUMENT_CANNOT_BE_READ, e);
}
- PDFASUtils.checkDocumentPermissions(doc);
SignaturePlaceholderExtractor extractor;
try
{
@@ -135,7 +134,7 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
} catch (IOException e1) {
throw new PDFDocumentException(ErrorCode.DOCUMENT_CANNOT_BE_READ, e1);
}
-
+
}
if (extractor.placeholders.size() > 0){
SignaturePlaceholderData ret = matchPlaceholderDocument(extractor.placeholders, placeholderId, matchMode);
@@ -146,7 +145,7 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
if (matchMode == Constants.PLACEHOLDER_MATCH_MODE_STRICT) {
throw new PlaceholderExtractionException(ErrorCode.SIGNATURE_PLACEHOLDER_EXTRACTION_FAILED, "no suitable placeholder found and STRICT matching mode requested.");
}
-
+
return null;
} finally {
if (doc != null)
@@ -158,23 +157,23 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
}
}
-
+
private static SignaturePlaceholderData matchPlaceholderDocument(
List placeholders, String placeholderId, int matchMode) throws PlaceholderExtractionException {
-
+
if (matchMode == Constants.PLACEHOLDER_MATCH_MODE_STRICT)
throw new PlaceholderExtractionException(ErrorCode.SIGNATURE_PLACEHOLDER_EXTRACTION_FAILED, "no suitable placeholder found and STRICT matching mode requested.");
-
+
if (placeholders.size() == 0)
return null;
-
+
for (int i = 0; i < placeholders.size(); i++)
{
SignaturePlaceholderData spd = (SignaturePlaceholderData)placeholders.get(i);
if (spd.getId() == null)
return spd;
}
-
+
if (matchMode == Constants.PLACEHOLDER_MATCH_MODE_LENIENT)
return (SignaturePlaceholderData)placeholders.get(0);
@@ -219,7 +218,7 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
PDPage page = getCurrentPage();
Matrix ctm = getGraphicsState().getCurrentTransformationMatrix();
double rotationInRadians = (page.findRotation() * Math.PI)/180;
-
+
AffineTransform rotation = new AffineTransform();
rotation.setToRotation( rotationInRadians );
AffineTransform rotationInverse = rotation.createInverse();
@@ -227,13 +226,13 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
rotationInverseMatrix.setFromAffineTransform( rotationInverse );
Matrix rotationMatrix = new Matrix();
rotationMatrix.setFromAffineTransform( rotation );
-
+
Matrix unrotatedCTM = ctm.multiply( rotationInverseMatrix );
-
+
float x = unrotatedCTM.getXPosition();
float y = unrotatedCTM.getYPosition() + unrotatedCTM.getYScale();
float w = unrotatedCTM.getXScale();
-
+
String posString = "p:" + currentPage + ";x:" + x + ";y:" + y + ";w:" + w;
try
{
@@ -259,7 +258,7 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
/**
* Checks an image if it is a placeholder for a signature.
- *
+ *
* @param image
* @return
* @throws IOException
@@ -291,7 +290,7 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine {
formats.add(BarcodeFormat.QR_CODE);
hints.put(DecodeHintType.POSSIBLE_FORMATS, formats);
result = new MultiFormatReader().decode(bitmap, hints);
-
+
String text = result.getText();
String profile = null;
String type = null;
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/CsvUtils.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/CsvUtils.java
new file mode 100644
index 0000000..a78da93
--- /dev/null
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/CsvUtils.java
@@ -0,0 +1,82 @@
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egiz.pdfas.utils;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Methods in order to create valid delimiter separated data, where the semicolon as used as delimiter, also known as
+ * the German version of CSV.
+ *
+ * @author Datentechnik Innovation GmbH
+ * @see <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>
+ */
+public class CsvUtils {
+
+ /**
+ * The delimiter char used instead of COMMA.
+ */
+ public static final char DEFAULT_DELIMITER = ';';
+
+ private static final char QUOTE_CHAR = '"';
+ private static final char LF_CHAR = '\n';
+ private static final char CR_CHAR = '\r';
+
+ private static final char[] SHOULD_BE_QUOTED = { LF_CHAR, CR_CHAR, DEFAULT_DELIMITER, QUOTE_CHAR };
+ private static final String CSV_QUOTE = String.valueOf(QUOTE_CHAR);
+
+ /**
+ * Returns an DSV escapted representation of the given object using the default delimiter character (
+ * {@link #DEFAULT_DELIMITER}).
+ *
+ * @param obj
+ * The object.
+ * @return An escapted representation of the given object.
+ */
+ public static String escapeCsvValue(Object obj) {
+ // null value should be printed as empty column
+ if (obj == null) {
+ return "";
+ }
+ // get String representation of object
+ String asString = String.valueOf(obj);
+ // do we need to escape anything?
+ if (StringUtils.containsNone(asString, SHOULD_BE_QUOTED)) {
+ return asString;
+ }
+
+ // RFC 4180 (7): If double-quotes are used to enclose fields, then a double-quote
+ // appearing inside a field must be escaped by preceding it with
+ // another double quote.
+ asString = StringUtils.replace(asString, CSV_QUOTE, CSV_QUOTE + CSV_QUOTE);
+
+ // RFC 4180 (6): Fields containing line breaks (CRLF), double quotes, and commas
+ // should be enclosed in double-quotes.
+ if (StringUtils.containsAny(asString, SHOULD_BE_QUOTED)) {
+ return QUOTE_CHAR + asString + QUOTE_CHAR;
+ }
+ return asString;
+ }
+
+}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/PDFASUtils.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/PDFASUtils.java
index 7f09dfc..a2332dd 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/PDFASUtils.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/utils/PDFASUtils.java
@@ -30,63 +30,233 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.pdfbox.pdmodel.PDDocument;
+import at.gv.egiz.pdfas.api.io.DataSource;
import at.gv.egiz.pdfas.exceptions.ErrorCode;
+import at.knowcenter.wag.egov.egiz.cfg.SettingsReader;
import at.knowcenter.wag.egov.egiz.exceptions.PDFDocumentException;
+import com.lowagie.text.Document;
+import com.lowagie.text.pdf.BadPasswordException;
import com.lowagie.text.pdf.PdfReader;
/**
- * @author tknall
+ * Collection of useful utilities.
*/
public class PDFASUtils {
-//23.11.2010 changed by exthex - added checkDocumentPermissions(PDDocument doc)
-
- private PDFASUtils() {
- }
-
- /**
- * Verifies that a document could be opened with full permissions.
- * @param pdfReader The PdfReader
- * @throws PDFDocumentException Thrown if document has not been opened with full permissions.
- */
- public static void checkReaderPermissions(PdfReader pdfReader) throws PDFDocumentException {
- if (pdfReader.isEncrypted()) {
- throw new PDFDocumentException(ErrorCode.DOCUMENT_IS_PROTECTED, "Document is encrypted.");
- }
- if (!pdfReader.isOpenedWithFullPermissions()) {
- throw new PDFDocumentException(ErrorCode.DOCUMENT_IS_PROTECTED, "Document is protected.");
- }
- }
-
- public static boolean toFile(byte[] data, File file) throws IOException {
- return PDFASUtils.toFile(new ByteArrayInputStream(data), file);
- }
-
- public static boolean toFile(InputStream inputStream, File file) throws IOException {
- boolean result = false;
- BufferedOutputStream bufferedOutputStream = null;
- try {
- bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
- ConfigUtils.writeInputStreamToOutputStream(inputStream, bufferedOutputStream);
- } finally {
- if (bufferedOutputStream != null) {
- try {
- bufferedOutputStream.close();
- result = true;
- } catch (IOException e) {
- result = false;
- }
- }
- }
- return result;
- }
-
- public static void checkDocumentPermissions(PDDocument doc) throws PDFDocumentException {
- if (doc.isEncrypted()) {
- throw new PDFDocumentException(ErrorCode.DOCUMENT_IS_PROTECTED, "Document is encrypted.");
- }
- }
-
+
+ private static Log log = LogFactory.getLog(PDFASUtils.class);
+
+ /**
+ * The configuration key for PDF/A support.
+ */
+ public static final String CFG_KEY_PDFA = "SIG_PDFA1B_VALID";
+
+ private PDFASUtils() {
+ }
+
+ /**
+ * Verifies that a document could be opened with full permissions.
+ *
+ * @param pdfReader
+ * The PdfReader.
+ * @throws PDFDocumentException
+ * Thrown if document has not been opened with full permissions.
+ */
+ private static void checkReaderPermissions(PdfReader pdfReader) throws PDFDocumentException {
+ if (pdfReader.isEncrypted()) {
+ throw new PDFDocumentException(ErrorCode.DOCUMENT_IS_PROTECTED, "Document is encrypted.");
+ }
+ if (!pdfReader.isOpenedWithFullPermissions()) {
+ throw new PDFDocumentException(ErrorCode.DOCUMENT_IS_PROTECTED, "Document is protected.");
+ }
+ }
+
+ /**
+ * Verifies that the document is not encrypted and/or protected. In case no restrictions have been applied to the
+ * document a pdf reader is returned.
+ *
+ * @param dataSource
+ * The document data source.
+ * @throws PDFDocumentException
+ * Thrown if the document could not be opened with full permissions.
+ */
+ public static PdfReader createPdfReaderCheckingPermissions(DataSource dataSource) throws PDFDocumentException {
+ return createPdfReaderCheckingPermissions(dataSource.createInputStream());
+ }
+
+ /**
+ * Verifies that the document is not encrypted and/or protected. In case no restrictions have been applied to the
+ * document a pdf reader is returned.
+ *
+ * @param dataSource
+ * The document data source.
+ * @throws PDFDocumentException
+ * Thrown if the document could not be opened with full permissions.
+ */
+ public static PdfReader createPdfReaderCheckingPermissions(at.gv.egiz.pdfas.framework.input.DataSource dataSource)
+ throws PDFDocumentException {
+ return createPdfReaderCheckingPermissions(dataSource.createInputStream());
+ }
+
+ /**
+ * Verifies that the document is not encrypted and/or protected. In case no restrictions have been applied to the
+ * document a pdf reader is returned.
+ *
+ * @param inputStream
+ * The document data input stream.
+ * @throws PDFDocumentException
+ * Thrown if the document could not be opened with full permissions.
+ */
+ public static PdfReader createPdfReaderCheckingPermissions(InputStream inputStream) throws PDFDocumentException {
+ PdfReader reader = null;
+ try {
+ // try to parse document
+ // If fully encrypted, PdfReader will fail;
+ // It should throw a BadPasswordException, but unfortunately does not (throws an IOException instead,
+ // internally catching BadPAsswordException; see comments below).
+ reader = new PdfReader(inputStream);
+ checkReaderPermissions(reader);
+ return reader;
+ } catch (BadPasswordException e) {
+ // will never be reached with itext-2.1.5-rev3628-pdfas:v1.1
+ // just added for later versions... (see comments below)
+ // itext-2.1.5-rev3628-pdfas:v1.2 correctly throws BadPasswordException
+ throw new PDFDocumentException(ErrorCode.DOCUMENT_IS_PROTECTED, "Document is protected.");
+ } catch (PDFDocumentException e) {
+ throw e;
+ } catch (Exception e) {
+ final String EX_MSG_FOR_ENCRYPTED_DOCUMENT = "Bad user Password";
+ // Inspecting the exception message seems to be the only way when using itext-2.1.5-rev3628-pdfas:v1.1:
+ // itext neither externally throws a BadPasswordException nor passed the cause...,
+ // later versions do!
+ // String "Bad user Password" is set in com.lowagie.text.pdf.BadPasswordException so this approach will
+ // work as long as the underlying itext library is not beeing updated.
+ if (StringUtils.containsIgnoreCase(e.getMessage(), EX_MSG_FOR_ENCRYPTED_DOCUMENT)) {
+ throw new PDFDocumentException(ErrorCode.DOCUMENT_IS_PROTECTED, "Document is protected.");
+ }
+ throw new PDFDocumentException(ErrorCode.DOCUMENT_CANNOT_BE_READ, "Unable to parse document.");
+ } finally {
+ IOUtils.closeQuietly(inputStream);
+ closeQuietly(reader);
+ }
+ }
+
+ /**
+ * Quietly closes a pdf reader.
+ *
+ * @param reader
+ * The reader.
+ */
+ public static void closeQuietly(PdfReader reader) {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (Throwable e) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Quietly closes a pdf document.
+ *
+ * @param pdDocument
+ * The pdf document.
+ */
+ public static void closeQuietly(PDDocument pdDocument) {
+ if (pdDocument != null) {
+ try {
+ pdDocument.close();
+ } catch (Throwable e) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Quietly closes a pdf document.
+ *
+ * @param pdDocument
+ * The pdf document.
+ */
+ public static void closeQuietly(org.pdfbox.pdmodel.PDDocument pdDocument) {
+ if (pdDocument != null) {
+ try {
+ pdDocument.close();
+ } catch (Throwable e) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Quietly closes a pdf document.
+ *
+ * @param pdDocument
+ * The pdf document.
+ */
+ public static void closeQuietly(Document doc) {
+ if (doc != null) {
+ try {
+ doc.close();
+ } catch (Throwable e) {
+ // ignore
+ }
+ }
+ }
+
+ public static boolean toFile(byte[] data, File file) throws IOException {
+ return PDFASUtils.toFile(new ByteArrayInputStream(data), file);
+ }
+
+ public static boolean toFile(InputStream inputStream, File file) throws IOException {
+ boolean result = false;
+ BufferedOutputStream bufferedOutputStream = null;
+ try {
+ bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
+ ConfigUtils.writeInputStreamToOutputStream(inputStream, bufferedOutputStream);
+ } finally {
+ if (bufferedOutputStream != null) {
+ try {
+ bufferedOutputStream.close();
+ result = true;
+ } catch (IOException e) {
+ result = false;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns {@code true} if the given {@code profileId} is PDF/A-1b enabled, {@code false} if not.
+ *
+ * @param profileId
+ * The signature profile.
+ * @return {@code true} if the given {@code profileId} is PDF/A-1b enabled, {@code false} if not.
+ */
+ public static boolean isPdfAEnabled(String profileId) {
+ if (profileId == null) {
+ throw new NullPointerException("Profile identifier must not be null.");
+ }
+ if (StringUtils.isEmpty(profileId)) {
+ throw new IllegalArgumentException("Profile identifier must not be empty.");
+ }
+ try {
+ String pdfa = SettingsReader.getInstance().getSetting("sig_obj." + profileId + ".key." + CFG_KEY_PDFA,
+ "default." + CFG_KEY_PDFA, "false");
+ return BooleanUtils.toBoolean(pdfa);
+ } catch (Exception e) {
+ log.error("Unable to read settings for PDF/A functionality.", e);
+ return false;
+ }
+ }
+
}