From fc44d4bcad00192f0df8f6086737b9b126094dcd Mon Sep 17 00:00:00 2001 From: Andreas Fitzek Date: Thu, 26 Sep 2013 15:48:43 +0200 Subject: initial code commit --- .../at/gv/egiz/pdfas/lib/api/Configuration.java | 7 + .../pdfas/lib/api/IConfigurationConstants.java | 16 ++ .../java/at/gv/egiz/pdfas/lib/api/IDataSource.java | 6 + .../main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java | 40 ++++ .../at/gv/egiz/pdfas/lib/api/PdfAsFactory.java | 9 + .../at/gv/egiz/pdfas/lib/api/PdfAsParameter.java | 32 +++ .../at/gv/egiz/pdfas/lib/api/package-info.java | 8 + .../gv/egiz/pdfas/lib/api/sign/SignParameter.java | 37 +++ .../at/gv/egiz/pdfas/lib/api/sign/SignResult.java | 5 + .../gv/egiz/pdfas/lib/api/sign/package-info.java | 8 + .../egiz/pdfas/lib/api/verify/SignatureCheck.java | 19 ++ .../egiz/pdfas/lib/api/verify/VerifyParameter.java | 14 ++ .../gv/egiz/pdfas/lib/api/verify/VerifyResult.java | 50 ++++ .../gv/egiz/pdfas/lib/api/verify/package-info.java | 8 + .../java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java | 69 ++++++ .../lib/impl/configuration/ConfigurationImpl.java | 110 +++++++++ .../impl/configuration/GlobalConfiguration.java | 21 ++ .../configuration/PlaceholderConfiguration.java | 23 ++ .../SignatureProfileConfiguration.java | 21 ++ .../configuration/SpecificBaseConfiguration.java | 13 ++ .../pdfas/lib/impl/configuration/package-info.java | 8 + .../at/gv/egiz/pdfas/lib/impl/package-info.java | 8 + .../pdfas/lib/impl/positioning/Positioning.java | 251 +++++++++++++++++++++ .../pdfas/lib/impl/positioning/package-info.java | 8 + .../egiz/pdfas/lib/impl/stamping/IPDFStamper.java | 12 + .../pdfas/lib/impl/stamping/IPDFVisualObject.java | 12 + .../pdfas/lib/impl/stamping/StamperFactory.java | 18 ++ .../egiz/pdfas/lib/impl/stamping/package-info.java | 8 + .../pdfas/lib/impl/status/OperationStatus.java | 76 +++++++ .../gv/egiz/pdfas/lib/impl/status/PDFObject.java | 31 +++ .../pdfas/lib/impl/status/RequestedSignature.java | 53 +++++ .../egiz/pdfas/lib/impl/status/package-info.java | 1 + .../java/at/gv/egiz/pdfas/lib/package-info.java | 4 + 33 files changed, 1006 insertions(+) create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/Configuration.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IConfigurationConstants.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IDataSource.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsParameter.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/package-info.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignParameter.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignResult.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/package-info.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/SignatureCheck.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyParameter.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyResult.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/package-info.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigurationImpl.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/GlobalConfiguration.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderConfiguration.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SignatureProfileConfiguration.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SpecificBaseConfiguration.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/package-info.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/package-info.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/Positioning.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/package-info.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFVisualObject.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/StamperFactory.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/package-info.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/PDFObject.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/package-info.java create mode 100644 pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/package-info.java (limited to 'pdf-as-lib/src/main/java/at/gv') diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/Configuration.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/Configuration.java new file mode 100644 index 00000000..89acc747 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/Configuration.java @@ -0,0 +1,7 @@ +package at.gv.egiz.pdfas.lib.api; + +public interface Configuration { + public String getValue(String key); + public boolean hasValue(String key); + public void setValue(String key, String value); +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IConfigurationConstants.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IConfigurationConstants.java new file mode 100644 index 00000000..9a8d773a --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IConfigurationConstants.java @@ -0,0 +1,16 @@ +package at.gv.egiz.pdfas.lib.api; + +public interface IConfigurationConstants { + + public static final String TRUE = "true"; + + public static final String SIG_OBJECT = "sig_obj"; + public static final String TYPE = "type"; + public static final String TABLE = "type"; + public static final String MAIN = "main"; + public static final String DEFAULT = "default"; + public static final String SEPERATOR = "."; + + public static final String PLACEHOLDER_SEARCH_ENABLED = "enable_placeholder_search"; + public static final String DEFAULT_SIGNATURE_PROFILE = SIG_OBJECT + SEPERATOR + TYPE + SEPERATOR + DEFAULT; +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IDataSource.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IDataSource.java new file mode 100644 index 00000000..6fea788c --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IDataSource.java @@ -0,0 +1,6 @@ +package at.gv.egiz.pdfas.lib.api; + +public interface IDataSource { + public String getMIMEType(); + public byte[] getByteData(); +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java new file mode 100644 index 00000000..4b491064 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAs.java @@ -0,0 +1,40 @@ +package at.gv.egiz.pdfas.lib.api; + +import java.util.List; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.lib.api.sign.SignParameter; +import at.gv.egiz.pdfas.lib.api.sign.SignResult; +import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter; +import at.gv.egiz.pdfas.lib.api.verify.VerifyResult; + +public interface PdfAs { + + // Sign + // Verify + // Get Configuration + + /** + * Signs a PDF document using PDF-AS. + * + * @param parameter + * @return + */ + public SignResult sign(SignParameter parameter) throws PdfAsException; + + /** + * Verifies a document with (potentially multiple) PDF-AS signatures. + * + * @param parameter The verification parameter + * @return A list of verification Results + */ + public List verify(VerifyParameter parameter); + + /** + * Gets a copy of the PDF-AS configuration, to allow the application to + * override configuration parameters at runtime. + * + * @return A private copy of the pdf as configuration + */ + public Configuration getConfiguration(); +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java new file mode 100644 index 00000000..ae9388eb --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java @@ -0,0 +1,9 @@ +package at.gv.egiz.pdfas.lib.api; + +import java.io.File; + +public class PdfAsFactory { + public static PdfAs createPdfAs(File configuration) { + return null; + } +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsParameter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsParameter.java new file mode 100644 index 00000000..999c91bc --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsParameter.java @@ -0,0 +1,32 @@ +package at.gv.egiz.pdfas.lib.api; + +public abstract class PdfAsParameter { + + protected Configuration configuration; + + protected IDataSource dataSource; + + public PdfAsParameter(Configuration configuration, + IDataSource dataSource) { + this.configuration = configuration; + this.dataSource = dataSource; + } + + public Configuration getConfiguration() { + return configuration; + } + + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; + } + + public IDataSource getDataSource() { + return dataSource; + } + + public void setDataSource(IDataSource dataSource) { + this.dataSource = dataSource; + } + + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/package-info.java new file mode 100644 index 00000000..debc6d4f --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.lib.api; \ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignParameter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignParameter.java new file mode 100644 index 00000000..1eee841a --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignParameter.java @@ -0,0 +1,37 @@ +package at.gv.egiz.pdfas.lib.api.sign; + +import at.gv.egiz.pdfas.lib.api.Configuration; +import at.gv.egiz.pdfas.lib.api.IDataSource; +import at.gv.egiz.pdfas.lib.api.PdfAsParameter; + +public class SignParameter extends PdfAsParameter { + + protected String signatureProfileId = null; + protected String signaturePosition = null; + + public SignParameter(Configuration configuration, + IDataSource dataSource) { + super(configuration, dataSource); + } + + // ======================================================================== + + public String getSignatureProfileId() { + return signatureProfileId; + } + + public void setSignatureProfileId(String signatureProfileId) { + this.signatureProfileId = signatureProfileId; + } + + public String getSignaturePosition() { + return signaturePosition; + } + + public void setSignaturePosition(String signaturePosition) { + this.signaturePosition = signaturePosition; + } + + + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignResult.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignResult.java new file mode 100644 index 00000000..91da083e --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignResult.java @@ -0,0 +1,5 @@ +package at.gv.egiz.pdfas.lib.api.sign; + +public class SignResult { + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/package-info.java new file mode 100644 index 00000000..2052ad71 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.lib.api.sign; \ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/SignatureCheck.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/SignatureCheck.java new file mode 100644 index 00000000..a021eb2a --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/SignatureCheck.java @@ -0,0 +1,19 @@ +package at.gv.egiz.pdfas.lib.api.verify; + +public interface SignatureCheck { + /** + * Returns the response code of the check. + * + * @return Returns the response code of the check. + */ + public int getCode(); + + /** + * Returns the textual response message of the check (corresponding to the + * code). + * + * @return Returns the textual response message of the check (corresponding + * to the code). + */ + public String getMessage(); +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyParameter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyParameter.java new file mode 100644 index 00000000..8c53ad47 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyParameter.java @@ -0,0 +1,14 @@ +package at.gv.egiz.pdfas.lib.api.verify; + +import at.gv.egiz.pdfas.lib.api.Configuration; +import at.gv.egiz.pdfas.lib.api.IDataSource; +import at.gv.egiz.pdfas.lib.api.PdfAsParameter; + +public class VerifyParameter extends PdfAsParameter { + + public VerifyParameter(Configuration configuration, + IDataSource dataSource) { + super(configuration, dataSource); + } + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyResult.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyResult.java new file mode 100644 index 00000000..339f7b15 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/VerifyResult.java @@ -0,0 +1,50 @@ +package at.gv.egiz.pdfas.lib.api.verify; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; + +public interface VerifyResult { + /** + * Returns if the verification was possible or could not even be startet. + * see {@link #getVerificationException()} for details. + * + * @return + */ + public boolean isVerificationDone(); + + /** + * Returns a verification exception if any. Shows that the verification + * could not be started. See {@link #isVerificationDone()}. + * + * @return + */ + public PdfAsException getVerificationException(); + + /** + * Returns the result of the certificate check. + * + * @return Returns the result of the certificate check. + */ + public SignatureCheck getCertificateCheck(); + + /** + * Returns the result of the value (and hash) check. + * + * @return Returns the result of the value (and hash) check. + */ + public SignatureCheck getValueCheckCode(); + + /** + * Returns the result of the manifest check. + * + * @return Returns the result of the manifest check. + */ + public SignatureCheck getManifestCheckCode(); + + /** + * Returns true, if the signer's certificate is a qualified certificate. + * + * @return Returns true, if the signer's certificate is a qualified + * certificate. + */ + public boolean isQualifiedCertificate(); +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/package-info.java new file mode 100644 index 00000000..68dda721 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/verify/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.lib.api.verify; \ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java new file mode 100644 index 00000000..d7ed5f3a --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java @@ -0,0 +1,69 @@ +package at.gv.egiz.pdfas.lib.impl; + +import java.util.List; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.lib.api.Configuration; +import at.gv.egiz.pdfas.lib.api.IConfigurationConstants; +import at.gv.egiz.pdfas.lib.api.PdfAs; +import at.gv.egiz.pdfas.lib.api.sign.SignParameter; +import at.gv.egiz.pdfas.lib.api.sign.SignResult; +import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter; +import at.gv.egiz.pdfas.lib.api.verify.VerifyResult; +import at.gv.egiz.pdfas.lib.impl.configuration.ConfigurationImpl; +import at.gv.egiz.pdfas.lib.impl.configuration.PlaceholderConfiguration; +import at.gv.egiz.pdfas.lib.impl.status.OperationStatus; +import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature; + +public class PdfAsImpl implements PdfAs, IConfigurationConstants { + + public SignResult sign(SignParameter parameter) throws PdfAsException { + // TODO: verify signParameter + + // Status initialization + if(!(parameter.getConfiguration() instanceof ISettings)) { + + } + ISettings settings = (ISettings) parameter.getConfiguration(); + OperationStatus status = new OperationStatus(settings, parameter); + PlaceholderConfiguration placeholderConfiguration = status.getPlaceholderConfiguration(); + // set Original PDF Document Data + status.getPdfObject().setOriginalDocument(parameter.getDataSource().getByteData()); + + + // Placeholder search? + if(placeholderConfiguration.isGlobalPlaceholderEnabled()) { + // TODO: Do placeholder search + } + + RequestedSignature requestedSignature = new RequestedSignature(status); + + // TODO get Certificate + + if(requestedSignature.isVisual()) { + // TODO: SignBlockCreationStage (visual) -> create visual signature block (logicaly) + + // TODO: PositioningStage (visual) -> find position or use fixed position + + // TODO: StampingStage (visual) -> stamp logical signature block to location (itext) + } else { + // Stamped Object is equal to original + status.getPdfObject().setStampedDocument(status.getPdfObject().getOriginalDocument()); + } + + // TODO: Create signature + + return null; + } + + public List verify(VerifyParameter parameter) { + // TODO Auto-generated method stub + return null; + } + + public Configuration getConfiguration() { + return new ConfigurationImpl(); + } + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigurationImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigurationImpl.java new file mode 100644 index 00000000..b901b597 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigurationImpl.java @@ -0,0 +1,110 @@ +package at.gv.egiz.pdfas.lib.impl.configuration; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; +import java.util.Vector; + +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.common.settings.Settings; +import at.gv.egiz.pdfas.lib.api.Configuration; + +public class ConfigurationImpl implements ISettings, Configuration { + + protected Properties overwrittenProperties = new Properties(); + + public void setValue(String key, String value) { + overwrittenProperties.setProperty(key, value); + } + + public String getValue(String key) { + if(overwrittenProperties.containsKey(key)) { + return overwrittenProperties.getProperty(key); + } else { + return Settings.getInstance().getValue(key); + } + } + + public boolean hasValue(String key) { + if(overwrittenProperties.containsKey(key)) { + return true; + } else { + return Settings.getInstance().hasValue(key); + } + } + + public Map getValuesPrefix(String prefix) { + + Map valueMap = null; + valueMap = Settings.getInstance().getValuesPrefix(prefix); + if(valueMap == null) { + valueMap = new HashMap(); + } + + Iterator keyIterator = overwrittenProperties.keySet().iterator(); + + while(keyIterator.hasNext()) { + String key = keyIterator.next().toString(); + + if(key.startsWith(prefix)) { + valueMap.put(key, overwrittenProperties.getProperty(key)); + } + } + + if(valueMap.isEmpty()) { + return null; + } + + return valueMap; + } + + public Vector getFirstLevelKeys(String prefix) { + + Vector valueMap = Settings.getInstance().getFirstLevelKeys(prefix); + if(valueMap == null) { + valueMap = new Vector(); + } + + + String mPrefix = prefix.endsWith(".")?prefix:prefix+"."; + Iterator keyIterator = overwrittenProperties.keySet().iterator(); + + while(keyIterator.hasNext()) { + String key = keyIterator.next().toString(); + + if(key.startsWith(prefix)) { + int keyIdx = key.indexOf('.', mPrefix.length()) > 0 ? key.indexOf('.', mPrefix.length()) : key.length(); + String firstLevels = key.substring(0, keyIdx); + if(!valueMap.contains(firstLevels)) { + valueMap.add(firstLevels); + } + } + } + + if(valueMap.isEmpty()) { + return null; + } + + return valueMap; + } + + public boolean hasPrefix(String prefix) { + + if(Settings.getInstance().hasPrefix(prefix)) { + return true; + } + + Iterator keyIterator = overwrittenProperties.keySet().iterator(); + while(keyIterator.hasNext()) { + String key = keyIterator.next().toString(); + + if(key.startsWith(prefix)) { + return true; + } + } + return false; + } + + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/GlobalConfiguration.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/GlobalConfiguration.java new file mode 100644 index 00000000..2124f63e --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/GlobalConfiguration.java @@ -0,0 +1,21 @@ +package at.gv.egiz.pdfas.lib.impl.configuration; + +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.lib.api.Configuration; +import at.gv.egiz.pdfas.lib.api.IConfigurationConstants; + +public class GlobalConfiguration extends SpecificBaseConfiguration + implements IConfigurationConstants { + + public GlobalConfiguration(ISettings configuration) { + super(configuration); + } + + public String getDefaultSignatureProfile() { + if(this.configuration.hasValue(DEFAULT_SIGNATURE_PROFILE)) { + return this.configuration.getValue(DEFAULT_SIGNATURE_PROFILE); + } + return null; + } + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderConfiguration.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderConfiguration.java new file mode 100644 index 00000000..7d3beb5c --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderConfiguration.java @@ -0,0 +1,23 @@ +package at.gv.egiz.pdfas.lib.impl.configuration; + +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.lib.api.IConfigurationConstants; + +public class PlaceholderConfiguration extends SpecificBaseConfiguration + implements IConfigurationConstants { + + public PlaceholderConfiguration(ISettings configuration) { + super(configuration); + } + + public boolean isGlobalPlaceholderEnabled() { + if(configuration.hasValue(PLACEHOLDER_SEARCH_ENABLED)) { + String value = configuration.getValue(PLACEHOLDER_SEARCH_ENABLED); + if(value.equalsIgnoreCase(TRUE)) { + return true; + } + } + return false; + } + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SignatureProfileConfiguration.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SignatureProfileConfiguration.java new file mode 100644 index 00000000..d7792dca --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SignatureProfileConfiguration.java @@ -0,0 +1,21 @@ +package at.gv.egiz.pdfas.lib.impl.configuration; + +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.lib.api.IConfigurationConstants; + +public class SignatureProfileConfiguration extends SpecificBaseConfiguration + implements IConfigurationConstants { + + protected String profileID; + + public SignatureProfileConfiguration(ISettings configuration, + String profileID) { + super(configuration); + this.profileID = profileID; + } + + public boolean isVisualSignature() { + String key = SIG_OBJECT + SEPERATOR + profileID + SEPERATOR + TABLE + SEPERATOR + MAIN; + return this.configuration.hasPrefix(key); + } +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SpecificBaseConfiguration.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SpecificBaseConfiguration.java new file mode 100644 index 00000000..88c7b3d7 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/SpecificBaseConfiguration.java @@ -0,0 +1,13 @@ +package at.gv.egiz.pdfas.lib.impl.configuration; + +import at.gv.egiz.pdfas.common.settings.ISettings; + +public abstract class SpecificBaseConfiguration { + + protected ISettings configuration; + + public SpecificBaseConfiguration(ISettings configuration) { + this.configuration = configuration; + } + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/package-info.java new file mode 100644 index 00000000..d766824e --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.lib.impl.configuration; \ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/package-info.java new file mode 100644 index 00000000..aba811aa --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.lib.impl; \ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/Positioning.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/Positioning.java new file mode 100644 index 00000000..340ba0bb --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/Positioning.java @@ -0,0 +1,251 @@ +package at.gv.egiz.pdfas.lib.impl.positioning; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject; +import at.gv.egiz.pdfas.common.utils.PDFUtils; +import at.knowcenter.wag.egov.egiz.pdf.PDFUtilities; +import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; +import at.knowcenter.wag.egov.egiz.pdf.TablePos; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.common.PDRectangle; + +/** + * Created with IntelliJ IDEA. + * User: afitzek + * Date: 8/29/13 + * Time: 4:30 PM + * To change this template use File | Settings | File Templates. + */ +public class Positioning { + + /** + * The left/right margin. + */ + public static final float SIGNATURE_MARGIN_HORIZONTAL = 50f; + + /** + * The top/bottom margin. + */ + public static final float SIGNATURE_MARGIN_VERTICAL = 20f; + + /** + * Evalutates absolute positioning and prepares the PositioningInstruction for + * placing the table. + * + * @param pos + * The absolute positioning parameter. If null it is sought in the + * profile definition. + * @param signature_type + * The profile definition of the table to be written. + * @param pdfDataSource + * The pdf. + * @param pdf_table + * The pdf table to be written. + * @return Returns the PositioningInformation. + * @throws PdfAsException + * F.e. + */ + public static PositioningInstruction determineTablePositioning(TablePos pos, String signature_type, + PDDocument pdfDataSource, IPDFVisualObject pdf_table) throws PdfAsException + { + boolean legacy32 = false; + + //TODO: settings reader ... + + /* + if (pos == null) + { + String pos_string = SettingsReader.getInstance().getSetting(SignatureTypes.SIG_OBJ + signature_type + ".pos", null); + if (pos_string != null) + { + pos = PdfAS.parsePositionFromPosString(pos_string); + } + } + if (pos == null) + { + // The default algorithm. x,y,w =auto ,p=lastpage, f:ignored because + // y:auto + pos = new TablePos(); + } + + // afitzek + // Allow legacy positioning (3.2) for BRZ Templates ... + boolean legacy32 = false; + String leg = SettingsReader.getInstance().getSetting(SignatureTypes.SIG_OBJ + signature_type + ".legacy.pos", "false"); + if (leg != null) { + if ("true".equals(leg.trim())) { + legacy32 = true; + } + } + */ + // System.out.println("Tablepos="+pos); + return adjustSignatureTableandCalculatePosition(pdfDataSource, pdf_table, pos, legacy32); + } + + /** + * Sets the width of the table according to the layout of the document and + * calculates the y position where the PDFPTable should be placed. + * + * @param pdfDataSource + * The PDF document. + * @param pdf_table + * The PDFPTable to be placed. + * @return Returns the position where the PDFPTable should be placed. + * @throws PdfAsException + * F.e. + */ + public static PositioningInstruction adjustSignatureTableandCalculatePosition(final PDDocument pdfDataSource, + IPDFVisualObject pdf_table, TablePos pos, boolean legacy32) throws PdfAsException + { + + try { + PDFUtils.checkPDFPermissions(pdfDataSource); + // get pages of currentdocument + + int doc_pages = pdfDataSource.getNumberOfPages(); + int page = doc_pages; + boolean make_new_page = pos.isNewPage(); + if (!(pos.isNewPage() || pos.isPauto())) + { + // we should posit signaturtable on this page + + page = pos.getPage(); + // System.out.println("XXXXPAGE="+page+" doc_pages="+doc_pages); + if (page > doc_pages) + { + make_new_page = true; + page = doc_pages; + // throw new PDFDocumentException(227, "Page number is to big(=" + page+ + // ") cannot be parsed."); + } + } + + PDPage pdPage = (PDPage)pdfDataSource.getDocumentCatalog().getAllPages().get(page - 1); + PDRectangle cropBox = pdPage.getCropBox(); + + if(cropBox == null) { + cropBox = pdPage.findCropBox(); + } + + + if(cropBox == null) { + cropBox = pdPage.findMediaBox(); + } + + //TODO: fallback to MediaBox if Cropbox not available! + + // getPagedimensions + //Rectangle psize = reader.getPageSizeWithRotation(page); + //int page_rotation = reader.getPageRotation(page); + + //Integer rotation = pdPage.getRotation(); + //int page_rotation = rotation.intValue(); + + float page_width = cropBox.getWidth(); + float page_height = cropBox.getHeight(); + + // now we can calculate x-position + float pre_pos_x = SIGNATURE_MARGIN_HORIZONTAL; + if (!pos.isXauto()) + { + // we do have absolute x + pre_pos_x = pos.getPosX(); + } + // calculate width + // center + float pre_width = page_width - 2*pre_pos_x; + if (!pos.isWauto()) + { + // we do have absolute width + pre_width = pos.getWidth(); + if (pos.isXauto()) + { // center x + pre_pos_x = (page_width - pre_width) / 2; + } + } + final float pos_x = pre_pos_x; + final float width = pre_width; + // Signatur table dimensions are complete + pdf_table.setWidth(width); + pdf_table.fixWidth(); + //pdf_table.setTotalWidth(width); + //pdf_table.setLockedWidth(true); + + final float table_height = pdf_table.getHeight(); + // now check pos_y + float pos_y = pos.getPosY(); + + // in case an absolute y position is already given OR + // if the table is related to an invisible signature + // there is no need for further calculations + // (fixed adding new page in case of invisible signatures) + if (!pos.isYauto() || table_height == 0) + { + // we do have y-position too --> all parameters but page ok + if (make_new_page) + { + page++; + } + return new PositioningInstruction(make_new_page, page, pos_x, pos_y); + } + // pos_y is auto + if (make_new_page) + { + // ignore footer in new page + page++; + pos_y = page_height - SIGNATURE_MARGIN_VERTICAL; + return new PositioningInstruction(make_new_page, page, pos_x, pos_y); + } + // up to here no checks have to be made if Tablesize and Pagesize are fit + // Now we have to getfreespace in page and reguard footerline + float footer_line = pos.getFooterLine(); + float pre_page_length = PDFUtilities.calculatePageLength(pdfDataSource, page - 1, page_height - footer_line, /*page_rotation,*/ legacy32); + if (pre_page_length == Float.NEGATIVE_INFINITY) + { + // we do have an empty page or nothing in area above footerline + pre_page_length = page_height; + // no text --> SIGNATURE_BORDER + pos_y = page_height - SIGNATURE_MARGIN_VERTICAL; + if (pos_y - footer_line <= table_height) + { + make_new_page = true; + if (!pos.isPauto()) + { + // we have to correct pagenumber + page = pdfDataSource.getNumberOfPages(); + } + page++; + // no text --> SIGNATURE_BORDER + pos_y = page_height - SIGNATURE_MARGIN_VERTICAL; + } + return new PositioningInstruction(make_new_page, page, pos_x, pos_y); + } + final float page_length = pre_page_length; + // we do have text take SIGNATURE_MARGIN + pos_y = page_height - page_length - SIGNATURE_MARGIN_VERTICAL; + if (pos_y - footer_line <= table_height) + { + make_new_page = true; + if (!pos.isPauto()) + { + // we have to correct pagenumber in case of absolute page and not enough + // space + page = pdfDataSource.getNumberOfPages(); + } + page++; + // no text --> SIGNATURE_BORDER + pos_y = page_height - SIGNATURE_MARGIN_VERTICAL; + } + return new PositioningInstruction(make_new_page, page, pos_x, pos_y); + } finally { + if (pdfDataSource != null) { + try { + pdfDataSource.close(); + } catch (Exception e) { + } + } + } + } + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/package-info.java new file mode 100644 index 00000000..5b209e06 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.lib.impl.positioning; \ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java new file mode 100644 index 00000000..f1b59ceb --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFStamper.java @@ -0,0 +1,12 @@ +package at.gv.egiz.pdfas.lib.impl.stamping; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.lib.impl.status.PDFObject; +import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; +import at.knowcenter.wag.egov.egiz.table.Table; + +public interface IPDFStamper { + public IPDFVisualObject createVisualPDFObject(PDFObject pdf, Table table); + public byte[] writeVisualObject(IPDFVisualObject visualObject, PositioningInstruction positioningInstruction, + byte[] pdfData) throws PdfAsException; +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFVisualObject.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFVisualObject.java new file mode 100644 index 00000000..fd7cac5c --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IPDFVisualObject.java @@ -0,0 +1,12 @@ +package at.gv.egiz.pdfas.lib.impl.stamping; + +public interface IPDFVisualObject { + public void setWidth(float width); + public void fixWidth(); + public float getHeight(); + public float getWidth(); + public void setXPos(float x); + public void setYPos(float x); + public int getPage(); + public void setPage(int page); +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/StamperFactory.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/StamperFactory.java new file mode 100644 index 00000000..1720057a --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/StamperFactory.java @@ -0,0 +1,18 @@ +package at.gv.egiz.pdfas.lib.impl.stamping; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; + +public class StamperFactory { + + public static final String DEFAULT_STAMPER_CLASS = "at.gv.egiz.pdfas.stmp.itext.ITextStamper"; + + public static IPDFStamper createDefaultStamper() throws PdfAsException { + try { + Class cls = (Class) + Class.forName(DEFAULT_STAMPER_CLASS); + return cls.newInstance(); + } catch (Throwable e) { + throw new PdfAsException("NO STAMPER!", e); + } + } +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/package-info.java new file mode 100644 index 00000000..496f592f --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.lib.impl.stamping; \ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java new file mode 100644 index 00000000..d7b956a7 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/OperationStatus.java @@ -0,0 +1,76 @@ +package at.gv.egiz.pdfas.lib.impl.status; + +import java.util.HashMap; +import java.util.Map; + +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.lib.api.sign.SignParameter; +import at.gv.egiz.pdfas.lib.impl.configuration.GlobalConfiguration; +import at.gv.egiz.pdfas.lib.impl.configuration.PlaceholderConfiguration; +import at.gv.egiz.pdfas.lib.impl.configuration.SignatureProfileConfiguration; + +public class OperationStatus { + + private SignParameter signParamter; + private PDFObject pdfObject = new PDFObject(); + + + private ISettings configuration; + private PlaceholderConfiguration placeholderConfiguration = null; + private GlobalConfiguration gloablConfiguration = null; + private Map signatureProfiles = + new HashMap(); + + public OperationStatus(ISettings configuration, SignParameter signParameter) { + this.configuration = configuration; + this.signParamter = signParameter; + } + + // ======================================================================== + + public PlaceholderConfiguration getPlaceholderConfiguration() { + if(this.placeholderConfiguration == null) { + this.placeholderConfiguration = + new PlaceholderConfiguration(this.configuration); + } + return this.placeholderConfiguration; + } + + public GlobalConfiguration getGlobalConfiguration() { + if(this.gloablConfiguration == null) { + this.gloablConfiguration = + new GlobalConfiguration(this.configuration); + } + return this.gloablConfiguration; + } + + public SignatureProfileConfiguration getSignatureProfileConfiguration(String profileID) { + + SignatureProfileConfiguration signatureProfileConfiguration = signatureProfiles.get(profileID); + if(signatureProfileConfiguration == null) { + signatureProfileConfiguration = new SignatureProfileConfiguration(this.configuration, profileID); + signatureProfiles.put(profileID, signatureProfileConfiguration); + } + + return signatureProfileConfiguration; + } + + // ======================================================================== + + public PDFObject getPdfObject() { + return pdfObject; + } + + public void setPdfObject(PDFObject pdfObject) { + this.pdfObject = pdfObject; + } + + public SignParameter getSignParamter() { + return signParamter; + } + + public void setSignParamter(SignParameter signParamter) { + this.signParamter = signParamter; + } + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/PDFObject.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/PDFObject.java new file mode 100644 index 00000000..1fe64bee --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/PDFObject.java @@ -0,0 +1,31 @@ +package at.gv.egiz.pdfas.lib.impl.status; + +public class PDFObject { + private byte[] originalDocument; + private byte[] stampedDocument; + private byte[] signedDocument; + + public byte[] getOriginalDocument() { + return originalDocument; + } + + public void setOriginalDocument(byte[] originalDocument) { + this.originalDocument = originalDocument; + } + + public byte[] getStampedDocument() { + return stampedDocument; + } + + public void setStampedDocument(byte[] stampedDocument) { + this.stampedDocument = stampedDocument; + } + + public byte[] getSignedDocument() { + return signedDocument; + } + + public void setSignedDocument(byte[] signedDocument) { + this.signedDocument = signedDocument; + } +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java new file mode 100644 index 00000000..a78828f3 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/RequestedSignature.java @@ -0,0 +1,53 @@ +package at.gv.egiz.pdfas.lib.impl.status; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.common.exceptions.PdfAsSettingsException; +import at.knowcenter.wag.egov.egiz.pdf.TablePos; + + +public class RequestedSignature { + private String signatureProfile; + private TablePos signaturePosition; + private OperationStatus status; + //private IPlainSigner signer = null; + + public RequestedSignature(OperationStatus status) throws PdfAsException { + + this.status = status; + + String profileID = status.getSignParamter().getSignatureProfileId(); + + if(profileID == null) { + profileID = status.getGlobalConfiguration().getDefaultSignatureProfile(); + + if(profileID == null) { + throw new PdfAsSettingsException("Failed to determine Signature Profile!"); + } + } + + this.signatureProfile = profileID; + + if(status.getSignParamter().getSignaturePosition() == null) { + this.signaturePosition = new TablePos(); + } else { + this.signaturePosition = new TablePos(status.getSignParamter().getSignaturePosition()); + } + } + + public boolean isVisual() { + return this.status.getSignatureProfileConfiguration(signatureProfile).isVisualSignature(); + } + + public TablePos getTablePos() { + return this.signaturePosition; + } + +/* + public IPlainSigner getSigner() { + return signer; + } + + public void setSigner(IPlainSigner signer) { + this.signer = signer; + }*/ +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/package-info.java new file mode 100644 index 00000000..4321a9b5 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/package-info.java @@ -0,0 +1 @@ +package at.gv.egiz.pdfas.lib.impl.status; \ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/package-info.java new file mode 100644 index 00000000..62eb0d25 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/package-info.java @@ -0,0 +1,4 @@ +/** + * + */ +package at.gv.egiz.pdfas.lib; \ No newline at end of file -- cgit v1.2.3