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 --- pdf-as-cli/.gitignore | 1 + pdf-as-cli/build.gradle | 31 + .../java/at/gv/egiz/pdfas/cli/DeveloperMain.java | 41 ++ .../java/at/gv/egiz/pdfas/cli/package-info.java | 8 + pdf-as-common/.gitignore | 1 + pdf-as-common/build.gradle | 32 ++ .../pdfas/common/exceptions/PDFIOException.java | 20 + .../pdfas/common/exceptions/PdfAsException.java | 31 + .../common/exceptions/PdfAsSettingsException.java | 20 + .../egiz/pdfas/common/exceptions/package-info.java | 8 + .../pdfas/common/messages/MessageResolver.java | 42 ++ .../egiz/pdfas/common/messages/package-info.java | 8 + .../java/at/gv/egiz/pdfas/common/package-info.java | 8 + .../pdfas/common/settings/IProfileConstants.java | 65 +++ .../gv/egiz/pdfas/common/settings/ISettings.java | 13 + .../at/gv/egiz/pdfas/common/settings/Settings.java | 124 ++++ .../common/settings/SignatureProfileEntry.java | 39 ++ .../common/settings/SignatureProfileSettings.java | 121 ++++ .../egiz/pdfas/common/settings/package-info.java | 8 + .../at/gv/egiz/pdfas/common/utils/DNUtils.java | 34 ++ .../at/gv/egiz/pdfas/common/utils/OgnlUtils.java | 22 + .../at/gv/egiz/pdfas/common/utils/PDFUtils.java | 94 +++ .../at/gv/egiz/pdfas/common/utils/StreamUtils.java | 28 + .../at/gv/egiz/pdfas/common/utils/StringUtils.java | 33 ++ .../gv/egiz/pdfas/common/utils/package-info.java | 8 + .../src/main/resources/resources/log4j.properties | 15 + .../resources/resources/messages/common.properties | 8 + pdf-as-lib/build.gradle | 4 + .../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 + .../at/knowcenter/wag/egov/egiz/pdf/PDFPage.java | 502 ++++++++++++++++ .../knowcenter/wag/egov/egiz/pdf/PDFUtilities.java | 72 +++ .../java/at/knowcenter/wag/egov/egiz/pdf/Pos.java | 70 +++ .../wag/egov/egiz/pdf/PositioningInstruction.java | 182 ++++++ .../at/knowcenter/wag/egov/egiz/pdf/TablePos.java | 261 +++++++++ .../path/PathConstructionOperatorProcessor.java | 61 ++ .../path/PathPaintingOperatorProcessor.java | 42 ++ .../pdf/operator/path/construction/ClosePath.java | 67 +++ .../pdf/operator/path/construction/CurveTo.java | 84 +++ .../construction/CurveToReplicateFinalPoint.java | 81 +++ .../construction/CurveToReplicateInitialPoint.java | 83 +++ .../pdf/operator/path/construction/LineTo.java | 70 +++ .../pdf/operator/path/construction/MoveTo.java | 72 +++ .../operator/path/painting/CloseAndStrokePath.java | 58 ++ .../painting/CloseFillEvenOddAndStrokePath.java | 59 ++ .../painting/CloseFillNonZeroAndStrokePath.java | 59 ++ .../egiz/pdf/operator/path/painting/EndPath.java | 67 +++ .../path/painting/FillEvenOddAndStrokePath.java | 71 +++ .../path/painting/FillNonZeroAndStrokePath.java | 71 +++ .../path/painting/FillPathEvenOddRule.java | 70 +++ .../painting/FillPathNonZeroWindingNumberRule.java | 71 +++ .../pdf/operator/path/painting/StrokePath.java | 69 +++ .../wag/egov/egiz/pdf/sig/SignatureEntry.java | 163 ++++++ .../at/knowcenter/wag/egov/egiz/table/Entry.java | 235 ++++++++ .../at/knowcenter/wag/egov/egiz/table/Style.java | 630 +++++++++++++++++++++ .../at/knowcenter/wag/egov/egiz/table/Table.java | 223 ++++++++ settings.gradle | 2 +- signature-standards/sigs-pades/build.gradle | 1 + stamper/stmp-itext/.gitignore | 1 + stamper/stmp-itext/build.gradle | 32 ++ .../at/gv/egiz/pdfas/stmp/itext/ITextStamper.java | 506 +++++++++++++++++ .../egiz/pdfas/stmp/itext/ITextVisualObject.java | 61 ++ .../at/gv/egiz/pdfas/stmp/itext/package-info.java | 2 + 94 files changed, 5970 insertions(+), 1 deletion(-) create mode 100644 pdf-as-cli/.gitignore create mode 100644 pdf-as-cli/build.gradle create mode 100644 pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java create mode 100644 pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/package-info.java create mode 100644 pdf-as-common/.gitignore create mode 100644 pdf-as-common/build.gradle create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PDFIOException.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsException.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSettingsException.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/package-info.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/MessageResolver.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/package-info.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/package-info.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/IProfileConstants.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/ISettings.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/Settings.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileEntry.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileSettings.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/package-info.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/DNUtils.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/OgnlUtils.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/PDFUtils.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StreamUtils.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StringUtils.java create mode 100644 pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/package-info.java create mode 100644 pdf-as-common/src/main/resources/resources/log4j.properties create mode 100644 pdf-as-common/src/main/resources/resources/messages/common.properties 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 create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/Pos.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathConstructionOperatorProcessor.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/sig/SignatureEntry.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Entry.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Style.java create mode 100644 pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Table.java create mode 100644 stamper/stmp-itext/.gitignore create mode 100644 stamper/stmp-itext/build.gradle create mode 100644 stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextStamper.java create mode 100644 stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextVisualObject.java create mode 100644 stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/package-info.java diff --git a/pdf-as-cli/.gitignore b/pdf-as-cli/.gitignore new file mode 100644 index 00000000..5e56e040 --- /dev/null +++ b/pdf-as-cli/.gitignore @@ -0,0 +1 @@ +/bin diff --git a/pdf-as-cli/build.gradle b/pdf-as-cli/build.gradle new file mode 100644 index 00000000..48a9b659 --- /dev/null +++ b/pdf-as-cli/build.gradle @@ -0,0 +1,31 @@ +apply plugin: 'java' +apply plugin: 'eclipse' + +jar { + manifest { + attributes 'Implementation-Title': 'PDF-AS CLI', 'Implementation-Version': version + } +} + +repositories { + mavenCentral() +} + +dependencies { + compile project (':pdf-as-lib') + compile project (':stamper:stmp-itext') + compile group: 'commons-collections', name: 'commons-collections', version: '3.2' + testCompile group: 'junit', name: 'junit', version: '4.+' +} + +test { + systemProperties 'property': 'value' +} + +uploadArchives { + repositories { + flatDir { + dirs 'repos' + } + } +} diff --git a/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java new file mode 100644 index 00000000..6e0118e4 --- /dev/null +++ b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/DeveloperMain.java @@ -0,0 +1,41 @@ +package at.gv.egiz.pdfas.cli; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.common.utils.StreamUtils; +import at.gv.egiz.pdfas.lib.api.ByteArrayDataSource; +import at.gv.egiz.pdfas.lib.api.Configuration; +import at.gv.egiz.pdfas.lib.api.PdfAs; +import at.gv.egiz.pdfas.lib.api.PdfAsFactory; +import at.gv.egiz.pdfas.lib.api.sign.SignParameter; + +public class DeveloperMain { + + public static void main(String[] args) { + String user_home = System.getProperty("user.home"); + String pdfas_dir = user_home + File.separator + "PDF-AS"; + PdfAs pdfas = PdfAsFactory.createPdfAs(new File(pdfas_dir)); + Configuration config = pdfas.getConfiguration(); + + byte[] data; + try { + data = StreamUtils.inputStreamToByteArray(new FileInputStream("/home/afitzek/devel/pdfas_neu/simple.pdf")); + SignParameter parameter = new SignParameter(config, new ByteArrayDataSource(data)); + pdfas.sign(parameter); + } catch (FileNotFoundException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + }catch (PdfAsException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/package-info.java b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/package-info.java new file mode 100644 index 00000000..6dbf3f3e --- /dev/null +++ b/pdf-as-cli/src/main/java/at/gv/egiz/pdfas/cli/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.cli; \ No newline at end of file diff --git a/pdf-as-common/.gitignore b/pdf-as-common/.gitignore new file mode 100644 index 00000000..5e56e040 --- /dev/null +++ b/pdf-as-common/.gitignore @@ -0,0 +1 @@ +/bin diff --git a/pdf-as-common/build.gradle b/pdf-as-common/build.gradle new file mode 100644 index 00000000..19d3dc90 --- /dev/null +++ b/pdf-as-common/build.gradle @@ -0,0 +1,32 @@ +apply plugin: 'java' +apply plugin: 'eclipse' + +jar { + manifest { + attributes 'Implementation-Title': 'PDF-AS-4 Commons', 'Implementation-Version': version + } +} + +repositories { + mavenCentral() +} + +dependencies { + compile group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.5' + compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '1.8.2' + compile group: 'commons-collections', name: 'commons-collections', version: '3.2' + compile group: 'ognl', name: 'ognl', version: '3.0.6' + testCompile group: 'junit', name: 'junit', version: '4.+' +} + +test { + systemProperties 'property': 'value' +} + +uploadArchives { + repositories { + flatDir { + dirs 'repos' + } + } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PDFIOException.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PDFIOException.java new file mode 100644 index 00000000..57c1e7ab --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PDFIOException.java @@ -0,0 +1,20 @@ +package at.gv.egiz.pdfas.common.exceptions; + +/** + * Created with IntelliJ IDEA. + * User: afitzek + * Date: 8/28/13 + * Time: 12:04 PM + * To change this template use File | Settings | File Templates. + */ +public class PDFIOException extends PdfAsException { + + public PDFIOException(String msgId) { + super(msgId); + } + + + public PDFIOException(String msgId, Throwable e) { + super(msgId, e); + } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsException.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsException.java new file mode 100644 index 00000000..e36aa082 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsException.java @@ -0,0 +1,31 @@ +package at.gv.egiz.pdfas.common.exceptions; + +import at.gv.egiz.pdfas.common.messages.MessageResolver; + +public class PdfAsException extends Exception { + public PdfAsException() { + super(); + } + + public PdfAsException(String msgId) { + super(msgId); + } + + public PdfAsException(String msgId, Throwable e) { + super(msgId, e); + } + + @Override + public String getMessage() { + return localizeMessage(super.getMessage()); + } + + @Override + public String getLocalizedMessage() { + return localizeMessage(super.getMessage()); + } + + protected String localizeMessage(String msgId) { + return MessageResolver.resolveMessage(msgId); + } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSettingsException.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSettingsException.java new file mode 100644 index 00000000..431ffa5d --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSettingsException.java @@ -0,0 +1,20 @@ +package at.gv.egiz.pdfas.common.exceptions; + +/** + * Created with IntelliJ IDEA. + * User: afitzek + * Date: 9/10/13 + * Time: 10:54 AM + * To change this template use File | Settings | File Templates. + */ +public class PdfAsSettingsException extends PdfAsException { + + public PdfAsSettingsException(String msgId) { + super(msgId); + } + + + public PdfAsSettingsException(String msgId, Throwable e) { + super(msgId, e); + } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/package-info.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/package-info.java new file mode 100644 index 00000000..cfd6a993 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.common.exceptions; \ No newline at end of file diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/MessageResolver.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/MessageResolver.java new file mode 100644 index 00000000..0bc1bab7 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/MessageResolver.java @@ -0,0 +1,42 @@ +package at.gv.egiz.pdfas.common.messages; + +import java.util.Locale; +import java.util.ResourceBundle; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MessageResolver { + private static final String messageResource = "resources.messages.common"; + private static final String missingMsg = "Please add message "; + + private static final Logger logger = LoggerFactory.getLogger(MessageResolver.class); + + private static ResourceBundle bundle; + + static { + ResourceBundle bundle = ResourceBundle.getBundle(messageResource); + if(bundle == null) { + logger.error("Failed to load resource bundle!!"); + Runtime.getRuntime().exit(-1); + } + } + + public static void forceLocale(Locale locale) { + bundle = ResourceBundle.getBundle(messageResource, locale); + } + + public static String resolveMessage(String msgId) { + if(bundle == null) { + return missingMsg + msgId; + } + if(bundle.containsKey(msgId)) { + String value = bundle.getString(msgId); + if(value == null) { + return missingMsg + msgId; + } + return value; + } + return missingMsg + msgId; + } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/package-info.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/package-info.java new file mode 100644 index 00000000..0ac78c22 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/messages/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.common.messages; \ No newline at end of file diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/package-info.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/package-info.java new file mode 100644 index 00000000..58c99dad --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.common; \ No newline at end of file diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/IProfileConstants.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/IProfileConstants.java new file mode 100644 index 00000000..2e2ee024 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/IProfileConstants.java @@ -0,0 +1,65 @@ +package at.gv.egiz.pdfas.common.settings; + +/** + * Created with IntelliJ IDEA. + * User: afitzek + * Date: 9/10/13 + * Time: 12:58 PM + * To change this template use File | Settings | File Templates. + */ +public interface IProfileConstants { + /** + * The settings key prefix for signature definitions. "sig_obj." + */ + public static final String SIG_OBJ = "sig_obj."; + + public static final String SIG_DATE = "SIG_DATE"; + + /** + * The settings key prefix for the signature table object definition + */ + public static final String TABLE = "table."; + + /** + * The settings value refering to a table + */ + public final static String TYPE_TABLE = "TABLE"; + + /** + * The settings value refering to an image + */ + public final static String TYPE_IMAGE = "i"; + + /** + * The settings value refering to a text caption + */ + public final static String TYPE_CAPTION = "c"; + + /** + * The settings value refering to a text value + */ + public final static String TYPE_VALUE = "v"; + + /** + * The settings key sub prefix getting the width of columns for a table + * definition + */ + public final static String COLS_WITH = "ColsWidth"; + + /** + * The settings key sub prefix getting the style definition + */ + public final static String STYLE = "Style"; + + public final static String PROFILE_VALUE = "value"; + + public final static String PROFILE_KEY = "key"; + + public final static String KEY_SEPARATOR = "."; + + public final static String INCLUDE = "include"; + + public final static String CFG_DIR = "cfg"; + public final static String CFG_FILE = "config.properties"; + +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/ISettings.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/ISettings.java new file mode 100644 index 00000000..9e3291d2 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/ISettings.java @@ -0,0 +1,13 @@ +package at.gv.egiz.pdfas.common.settings; + +import java.util.Map; +import java.util.Vector; + +public interface ISettings { + public String getValue(String key); + public boolean hasValue(String key); + public boolean hasPrefix(String prefix); + public Map getValuesPrefix(String prefix); + public Vector getFirstLevelKeys(String prefix); + public String getWorkingDirectory(); +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/Settings.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/Settings.java new file mode 100644 index 00000000..da946215 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/Settings.java @@ -0,0 +1,124 @@ +package at.gv.egiz.pdfas.common.settings; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsSettingsException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.*; + +public class Settings implements ISettings, IProfileConstants{ + + private static final Logger logger = LoggerFactory.getLogger(Settings.class); + + protected Properties properties = new Properties(); + + protected File workDirectory; + + public Settings(File workDirectory) { + try { + this.workDirectory = workDirectory; + loadSettings(workDirectory); + } catch (PdfAsSettingsException e) { + logger.error(e.getMessage(), e); + } + } + + public void loadSettings(File workDirectory) throws PdfAsSettingsException { + try { + + String configDir = workDirectory.getAbsolutePath() + File.separator + CFG_DIR; + String configFile = configDir + File.separator + CFG_FILE; + logger.debug("Loading cfg file: " + configFile); + properties.load(new FileInputStream(configFile)); + + Map includes = this.getValuesPrefix(INCLUDE); + + if(includes != null) { + Iterator includeIterator = includes.values().iterator(); + while(includeIterator.hasNext()) { + String includeFile = configDir + File.separator + includeIterator.next(); + logger.debug("Loading included cfg file: " + includeFile); + properties.load(new FileInputStream(includeFile)); + } + } + + logger.debug("Configured Properties:"); + if(logger.isDebugEnabled()) { + properties.list(System.out); + } + + } catch (IOException e) { + throw new PdfAsSettingsException("Failed to read settings!", e); + } + } + + public String getValue(String key) { + return properties.getProperty(key); + } + + public boolean hasValue(String key) { + return properties.containsKey(key); + } + + public Map getValuesPrefix(String prefix) { + Iterator keyIterator = properties.keySet().iterator(); + Map valueMap = new HashMap(); + while(keyIterator.hasNext()) { + String key = keyIterator.next().toString(); + + if(key.startsWith(prefix)) { + valueMap.put(key, properties.getProperty(key)); + } + } + + if(valueMap.isEmpty()) { + return null; + } + + return valueMap; + } + + public Vector getFirstLevelKeys(String prefix) { + String mPrefix = prefix.endsWith(".")?prefix:prefix+"."; + Iterator keyIterator = properties.keySet().iterator(); + Vector valueMap = new Vector(); + 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) { + Iterator keyIterator = properties.keySet().iterator(); + while(keyIterator.hasNext()) { + String key = keyIterator.next().toString(); + + if(key.startsWith(prefix)) { + return true; + } + } + return false; + } + + public String getWorkingDirectory() { + return this.workDirectory.getAbsolutePath(); + } + +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileEntry.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileEntry.java new file mode 100644 index 00000000..3df929b1 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileEntry.java @@ -0,0 +1,39 @@ +package at.gv.egiz.pdfas.common.settings; + +public class SignatureProfileEntry { + private String key = null; + private String caption = null; + private String value = null; + + public SignatureProfileEntry() { + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getCaption() { + return caption; + } + + public void setCaption(String caption) { + this.caption = caption; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public String toString() { + return getKey() + "[ " + getCaption() + " : " + getValue() + " ]"; + } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileSettings.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileSettings.java new file mode 100644 index 00000000..46f2ed09 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileSettings.java @@ -0,0 +1,121 @@ +package at.gv.egiz.pdfas.common.settings; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; + +public class SignatureProfileSettings implements IProfileConstants { + + private static final Logger logger = LoggerFactory.getLogger(SignatureProfileSettings.class); + + private Map profileInformations = new HashMap(); + + private Map profileSettings = new HashMap(); + + private String profileID; + + public SignatureProfileSettings(String profileID, ISettings configuration) { + this.profileID = profileID; + String profilePrefix = SIG_OBJ + profileID + KEY_SEPARATOR; + String keysPrefix = profilePrefix + PROFILE_KEY; + String valuesPrefix = profilePrefix + PROFILE_VALUE; + String tablePrefix = profilePrefix + TABLE; + + logger.debug("Reading Profile: " + profileID); + logger.debug("Keys Prefix: " + keysPrefix); + logger.debug("Values Prefix: " + valuesPrefix); + logger.debug("Table Prefix: " + tablePrefix); + + Map keys = configuration.getValuesPrefix(keysPrefix); + Map values = configuration.getValuesPrefix(valuesPrefix); + + Iterator keyIterator = keys.keySet().iterator(); + + while(keyIterator.hasNext()) { + String key = keyIterator.next(); + key = key.substring(key.lastIndexOf('.') + 1); + String valueKey = keys.get(keysPrefix + KEY_SEPARATOR + key); + + String valueValue = values.get(valuesPrefix + KEY_SEPARATOR + key); + + + SignatureProfileEntry entry = new SignatureProfileEntry(); + entry.setKey(key); + entry.setCaption(valueKey); + entry.setValue(valueValue); + profileInformations.put(key, entry); + logger.debug(" " + entry.toString()); + } + + // Find entries where only values exists + Iterator valuesIterator = values.keySet().iterator(); + + while(valuesIterator.hasNext()) { + String key = valuesIterator.next(); + key = key.substring(key.lastIndexOf('.') + 1); + + String valueValue = values.get(valuesPrefix + KEY_SEPARATOR + key); + + SignatureProfileEntry entry = profileInformations.get(key); + if(entry == null) { + entry = new SignatureProfileEntry(); + entry.setKey(key); + entry.setCaption(null); + entry.setValue(valueValue); + profileInformations.put(key, entry); + } + + logger.debug(" " + entry.toString()); + } + + Map others = configuration.getValuesPrefix(profilePrefix); + + Iterator otherIterator = others.keySet().iterator(); + + while(otherIterator.hasNext()) { + String key = otherIterator.next(); + + logger.trace("Checking key " + key); + if( key.startsWith(keysPrefix) || + key.startsWith(valuesPrefix) || + key.startsWith(tablePrefix)) { + continue; + } + + String value = others.get(key); + key = key.substring(key.lastIndexOf('.') + 1); + + profileSettings.put(key, others.get(value)); + + logger.debug(" Settings: " + key + " : " + value); + } + } + + public String getCaption(String key) { + SignatureProfileEntry entry = profileInformations.get(key); + if(entry != null) { + return entry.getCaption(); + } + return null; + } + + public String getValue(String key) { + SignatureProfileEntry entry = profileInformations.get(key); + if(entry != null) { + String value = entry.getValue(); + + if(value == null) { + // TODO: try to find default value for key! + } + + return value; + } + // TODO: try to find default value for key! + return null; + } + + public String getProfileID() { + return profileID; + } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/package-info.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/package-info.java new file mode 100644 index 00000000..c2b123e2 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.common.settings; \ No newline at end of file diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/DNUtils.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/DNUtils.java new file mode 100644 index 00000000..429151ee --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/DNUtils.java @@ -0,0 +1,34 @@ +package at.gv.egiz.pdfas.common.utils; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DNUtils { + private static final Logger logger = LoggerFactory.getLogger(DNUtils.class); + + + public static Map dnToMap(String dn) throws InvalidNameException { + Map map = new HashMap(); + + LdapName ldapName = new LdapName(dn); + + Iterator rdnIterator = ldapName.getRdns().iterator(); + + while(rdnIterator.hasNext()) { + Rdn rdn = rdnIterator.next(); + + logger.debug(rdn.getType() + " = " + rdn.getValue().toString()); + map.put(rdn.getType(), rdn.getValue().toString()); + } + + return map; + } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/OgnlUtils.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/OgnlUtils.java new file mode 100644 index 00000000..e98cb124 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/OgnlUtils.java @@ -0,0 +1,22 @@ +package at.gv.egiz.pdfas.common.utils; + +import ognl.OgnlContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created with IntelliJ IDEA. + * User: afitzek + * Date: 9/11/13 + * Time: 1:05 PM + * To change this template use File | Settings | File Templates. + */ +public class OgnlUtils { + + private static final Logger logger = LoggerFactory.getLogger(OgnlUtils.class); + + public static String resolvsOgnlExpression(String expression, OgnlContext ctx) { + // TODO! + return expression; + } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/PDFUtils.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/PDFUtils.java new file mode 100644 index 00000000..155f9cfb --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/PDFUtils.java @@ -0,0 +1,94 @@ +package at.gv.egiz.pdfas.common.utils; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + + +public class PDFUtils { + + private static final Logger logger = LoggerFactory.getLogger(PDFUtils.class); + + + private static final byte[] signature_pattern = new byte[] { + (byte) 0x0A, (byte) 0x2F, (byte) 0x43, (byte) 0x6F, // ./Co + (byte) 0x6E, (byte) 0x74, (byte) 0x65, (byte) 0x6E, // nten + (byte) 0x74, (byte) 0x73, (byte) 0x20, (byte) 0x0A, // ts . + (byte) 0x2F, (byte) 0x42, (byte) 0x79, (byte) 0x74, // /Byt + (byte) 0x65, (byte) 0x52, (byte) 0x61, (byte) 0x6E, // eRan + (byte) 0x67, (byte) 0x65, (byte) 0x20, (byte) 0x5B, // ge [ + + }; + + private static final byte range_seperation = (byte) 0x20; + private static final byte range_end = (byte) 0x5D; + + private static int extractASCIIInteger(byte[] data, int offset) { + int nextsepp = nextSeperator(data, offset); + + if(nextsepp < offset) { + return -1; + } + + String asciiString = new String(data, offset, nextsepp - offset); + + logger.debug("Extracted " + asciiString); + + return Integer.parseInt(asciiString); + } + + private static int nextSeperator(byte[] data, int offset) { + for(int i = offset; i < data.length; i++) { + if(data[i] == range_seperation) { + return i; + } else if(data[i] == range_end) { + return i; + } + } + return -2; + } + + public static int[] extractSignatureByteRange(byte[] rawPdfData) { + int i = 0; + for(i = rawPdfData.length - 1; i >= 0; i--) { + if(rawPdfData[i] == signature_pattern[0] && + i+signature_pattern.length < rawPdfData.length) { + boolean match = true; + for(int j = 0; j < signature_pattern.length; j++) { + + if(rawPdfData[i+j] != signature_pattern[j]) { + match = false; + break; + } + } + + if(match) { + + int offset = i + signature_pattern.length; + List byteRange = new ArrayList(); + while(offset > 0) { + byteRange.add(extractASCIIInteger(rawPdfData, offset)); + offset = nextSeperator(rawPdfData, offset); + if(rawPdfData[offset] == range_end) { + break; + } + offset++; + } + int[] range = new int[byteRange.size()]; + for(int j = 0; j < byteRange.size(); j++) { + range[j] = byteRange.get(j); + } + return range; + } + } + } + return null; + } + + public static void checkPDFPermissions(PDDocument doc) { + // TODO: Check permission for document + } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StreamUtils.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StreamUtils.java new file mode 100644 index 00000000..0b15d700 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StreamUtils.java @@ -0,0 +1,28 @@ +package at.gv.egiz.pdfas.common.utils; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * Created with IntelliJ IDEA. + * User: afitzek + * Date: 8/29/13 + * Time: 9:54 AM + * To change this template use File | Settings | File Templates. + */ +public class StreamUtils { + + public static byte[] inputStreamToByteArray(InputStream stream) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + byte[] buffer = new byte[4096]; + int readBytes = 0; + + while((readBytes = stream.read(buffer)) != -1) { + bos.write(buffer, 0, readBytes); + } + stream.close(); + bos.close(); + return bos.toByteArray(); + } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StringUtils.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StringUtils.java new file mode 100644 index 00000000..63aae211 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/StringUtils.java @@ -0,0 +1,33 @@ +package at.gv.egiz.pdfas.common.utils; + +import java.util.Formatter; + +/** + * Created with IntelliJ IDEA. + * User: afitzek + * Date: 8/28/13 + * Time: 12:42 PM + * To change this template use File | Settings | File Templates. + */ +public class StringUtils { + + public static String bytesToHexString(byte[] bytes) { + StringBuilder sb = new StringBuilder(bytes.length * 2); + + Formatter formatter = new Formatter(sb); + for (byte b : bytes) { + formatter.format("%02x", b); + } + + return sb.toString(); + } + + public static String extractLastID(String id) { + int lastIDX = id.lastIndexOf('.'); + String result = id; + if(lastIDX > 0) { + result = id.substring(lastIDX+1); + } + return result; + } +} diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/package-info.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/package-info.java new file mode 100644 index 00000000..91b05145 --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/utils/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.common.utils; \ No newline at end of file diff --git a/pdf-as-common/src/main/resources/resources/log4j.properties b/pdf-as-common/src/main/resources/resources/log4j.properties new file mode 100644 index 00000000..696db3ef --- /dev/null +++ b/pdf-as-common/src/main/resources/resources/log4j.properties @@ -0,0 +1,15 @@ +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=INFO, A1 + +log4j.logger.at.gv.egiz=DEBUG +#log4j.A1.at.gv.egiz=true + +log4j.logger.developer=DEBUG +#log4j.A1.developer=true + +# A1 is set to be a ConsoleAppender. +log4j.appender.A1=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n \ No newline at end of file diff --git a/pdf-as-common/src/main/resources/resources/messages/common.properties b/pdf-as-common/src/main/resources/resources/messages/common.properties new file mode 100644 index 00000000..a2729e21 --- /dev/null +++ b/pdf-as-common/src/main/resources/resources/messages/common.properties @@ -0,0 +1,8 @@ +# PDF Permission Errors +error.pdf.perm.01=You do not have permission to extract images. + +#PDF IO Errors +error.pdf.io.01=Failed to read original PDF Document into PDDocument. + +#Signature errors +error.pdf.sig.01=Failed to create signature! \ No newline at end of file diff --git a/pdf-as-lib/build.gradle b/pdf-as-lib/build.gradle index 41c9a3ba..b5601f3a 100644 --- a/pdf-as-lib/build.gradle +++ b/pdf-as-lib/build.gradle @@ -12,6 +12,10 @@ repositories { } dependencies { + compile project (':pdf-as-common') + compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '1.8.2' + compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.1' + compile group: 'org.apache.commons', name: 'commons-io', version: '1.3.2' compile group: 'commons-collections', name: 'commons-collections', version: '3.2' testCompile group: 'junit', name: 'junit', version: '4.+' } 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 diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java new file mode 100644 index 00000000..b5928406 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java @@ -0,0 +1,502 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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. + * + * $Id: PDFPage.java,v 1.5 2006/10/31 08:09:33 wprinz Exp $ + */ +package at.knowcenter.wag.egov.egiz.pdf; + +import at.knowcenter.wag.egov.egiz.pdf.operator.path.construction.*; +import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.*; + +import org.apache.commons.lang3.math.NumberUtils; +import org.apache.pdfbox.cos.COSName; +import org.apache.pdfbox.cos.COSStream; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDResources; +import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.apache.pdfbox.pdmodel.common.PDStream; +import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObject; +import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectForm; +import org.apache.pdfbox.util.Matrix; +import org.apache.pdfbox.util.PDFOperator; +import org.apache.pdfbox.util.PDFTextStripper; +import org.apache.pdfbox.util.TextPosition; +import org.apache.pdfbox.util.operator.OperatorProcessor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.awt.*; +import java.awt.geom.GeneralPath; +import java.io.IOException; +import java.io.Writer; +import java.util.List; +import java.util.Map; + +/** + * PDFPage is an inner class that is used to calculate the page length of a PDF + * Document page. It extends the PDFTextStripper class and implement one + * interested method: {@link at.knowcenter.wag.egov.egiz.pdf.PDFPage#showCharacter(TextPosition)}
+ * This method is called when processing the FileStream. By calling the method + * {@link org.apache.pdfbox.util.PDFStreamEngine#processStream(org.apache.pdfbox.pdmodel.PDPage, org.apache.pdfbox.pdmodel.PDResources, org.pdfbox.cos.COSStream)} + * the implemented method showCharacter is called. + * + * @author wlackner + * @see PDFTextStripper + */ +public class PDFPage extends PDFTextStripper { + /** + * The logger definition. + */ + private static final Logger logger = LoggerFactory.getLogger(PDFPage.class); + + /** + * The maximum (lowest) y position of a character. + */ + protected float max_character_ypos = Float.NEGATIVE_INFINITY; + + /** + * The maximum (lowest y position of an image. + */ + protected float max_image_ypos = Float.NEGATIVE_INFINITY; + + /** + * The effective page height. + */ + protected float effectivePageHeight; + + /** + * The path currently being constructed. + */ + private GeneralPath currentPath = new GeneralPath(); + + /** + * The lowest position of a drawn path (originating from top). + */ + private float maxPathRelatedYPositionFromTop = Float.NEGATIVE_INFINITY; + + /** + * Constructor. + * + * @param effectivePageHeight + * The height of the page to be evaluated. PDF elements outside + * this height will not be considered. + * + * @throws java.io.IOException + */ + public PDFPage(float effectivePageHeight, boolean legacy32) throws IOException { + super(); + + this.effectivePageHeight = effectivePageHeight; + + OperatorProcessor newInvoke = new MyInvoke(this); + newInvoke.setContext(this); + this.registerOperatorProcessor("Do", newInvoke); + + if (!legacy32) { + registerCustomPathOperators(); + } + } + + /** + * Registers operators responsible for path construction and painting in + * order to fix auto positioning on pages with path elements. + * + * @author Datentechnik Innovation GmbH + */ + @SuppressWarnings("unchecked") + private void registerCustomPathOperators() { + + // *** path construction + + this.registerOperatorProcessor("m", new MoveTo(this)); + this.registerOperatorProcessor("l", new LineTo(this)); + this.registerOperatorProcessor("c", new CurveTo(this)); + this.registerOperatorProcessor("y", new CurveToReplicateFinalPoint(this)); + this.registerOperatorProcessor("v", new CurveToReplicateInitialPoint(this)); + this.registerOperatorProcessor("h", new ClosePath(this)); + + // *** path painting + + // "S": stroke path + this.registerOperatorProcessor("S", new StrokePath(this)); + this.registerOperatorProcessor("s", new CloseAndStrokePath(this)); + this.registerOperatorProcessor("f", new FillPathNonZeroWindingNumberRule(this)); + this.registerOperatorProcessor("F", new FillPathNonZeroWindingNumberRule(this)); + this.registerOperatorProcessor("f*", new FillPathEvenOddRule(this)); + this.registerOperatorProcessor("b", new CloseFillNonZeroAndStrokePath(this)); + this.registerOperatorProcessor("B", new FillNonZeroAndStrokePath(this)); + this.registerOperatorProcessor("b*", new CloseFillEvenOddAndStrokePath(this)); + this.registerOperatorProcessor("B*", new FillEvenOddAndStrokePath(this)); + this.registerOperatorProcessor("n", new EndPath(this)); + + // Note: The graphic context + // (org.pdfbox.pdmodel.graphics.PDGraphicsState) of the underlying + // pdfbox library does + // not yet support clipping. This prevents feasible usage of clipping + // operators (W, W*). + // operators.put("W", new ...(this)); + // operators.put("W*", new ...(this)); + + } + + /** + * Returns the path currently being constructed. + * + * @return The path currently being constructed. + */ + public GeneralPath getCurrentPath() { + return currentPath; + } + + /** + * Sets the current path. + * + * @param currentPath + * The new current path. + */ + public void setCurrentPath(GeneralPath currentPath) { + this.currentPath = currentPath; + } + + /** + * Registers a rectangle that bounds the path currently being drawn. + * + * @param bounds + * A rectangle depicting the bounds (coordinates originating from + * bottom left). + * @author Datentechnik Innovation GmbH + */ + public void registerPathBounds(Rectangle bounds) { + if (!bounds.isEmpty()) { + logger.debug("Registering path bounds: " + bounds); + + // vertical start of rectangle (counting from top of page) + float upperBoundYPositionFromTop; + + // vertical end of rectangle (counting from top of page) + // this depicts the current end of path-related page content + float lowerBoundYPositionFromTop; + + PDRectangle boundaryBox = this.getCurrentPage().findMediaBox(); + float pageHeight; + + switch (this.getCurrentPage().findRotation()) { + case 90: // CW + pageHeight = boundaryBox.getWidth(); + upperBoundYPositionFromTop = (float) bounds.getMinX(); + lowerBoundYPositionFromTop = (float) bounds.getMaxX(); + break; + case 180: + pageHeight = boundaryBox.getHeight(); + upperBoundYPositionFromTop = (float) bounds.getMinY(); + lowerBoundYPositionFromTop = (float) bounds.getMaxY(); + break; + case 270: // CCW + pageHeight = boundaryBox.getWidth(); + upperBoundYPositionFromTop = pageHeight + - (float) bounds.getMaxX(); + lowerBoundYPositionFromTop = pageHeight + - (float) bounds.getMinX(); + break; + default: + pageHeight = boundaryBox.getHeight(); + upperBoundYPositionFromTop = pageHeight + - (float) bounds.getMaxY(); + lowerBoundYPositionFromTop = pageHeight + - (float) bounds.getMinY(); + break; + } + + // new maximum ? + if (lowerBoundYPositionFromTop > maxPathRelatedYPositionFromTop) { + // Is the rectangle (at least partly) located above the footer + // line? + // (effective page height := page height - footer line) + if (upperBoundYPositionFromTop <= effectivePageHeight) { + // yes: update current end of path-related page content + maxPathRelatedYPositionFromTop = lowerBoundYPositionFromTop; + logger.trace("New max path related y position (from top): " + + maxPathRelatedYPositionFromTop); + } else { + // no: rectangle is fully located below the footer line -> + // ignore + logger.trace("Ignoring path bound below the footer line."); + } + } + } + } + + protected void processOperator(PDFOperator operator, List arguments) + throws IOException { + logger.trace("operator = " + operator); + super.processOperator(operator, arguments); + } + + @Override + protected void processTextPosition(TextPosition text) { + showCharacter(text); + } + + // exthex + /** + * A method provided as an event interface to allow a subclass to perform + * some specific functionality when a character needs to be displayed. This + * method is used to calculate the latest position of a text in the page. + * Sorry for this missinterpretation of the method, but it is the only way + * to do this (provided by PDFBox)!!! + * + * @param text + * the character to be displayed -> calculate there y position. + */ + protected void showCharacter(TextPosition text) { + float current_y = text.getY(); + final String character = text.getCharacter(); + + int pageRotation = this.getCurrentPage().findRotation(); + // logger_.debug("PageRotation = " + pageRotation); + if (pageRotation == 0) { + current_y = text.getY(); + } + if (pageRotation == 90) { + current_y = text.getX(); + } + if (pageRotation == 180) { + float page_height = this.getCurrentPage().findMediaBox().getHeight(); + current_y = page_height - text.getY(); + } + if (pageRotation == 270) { + float page_height = this.getCurrentPage().findMediaBox().getHeight(); + current_y = page_height - text.getX(); + } + + if (current_y > this.effectivePageHeight) { + // logger_.debug("character is below footer_line. footer_line = " + + // this.footer_line + ", text.character=" + character + ", y=" + + // current_y); + return; + } + + // store ypos of the char if it is not empty + if (!character.equals(" ") && current_y > this.max_character_ypos) { + this.max_character_ypos = current_y; + } + + } + + // use this funtion getting an unsorted text output + // public void showString(byte[] string) { + // logger_.debug(new String(string)); + // } + + /** + * Returns the calculated page length. + * + * @return the max page length value + */ + public float getMaxPageLength() { + if (logger.isDebugEnabled()) { + logger.debug("Determining page content length: text=" + + max_character_ypos + ", image=" + max_image_ypos + + ", path=" + maxPathRelatedYPositionFromTop); + } + return NumberUtils.max(max_character_ypos, max_image_ypos, + maxPathRelatedYPositionFromTop); + } + + public class MyInvoke extends OperatorProcessor { + + private PDFPage mypage; + + public MyInvoke(PDFPage page) { + this.mypage = page; + } + + public void process(PDFOperator operator, List arguments) + throws IOException { + COSName name = (COSName) arguments.get(0); + + // PDResources res = context.getResources(); + + Map xobjects = context.getXObjects(); + PDXObject xobject = (PDXObject) xobjects.get(name.getName()); + + PDStream stream = xobject.getPDStream(); + COSStream cos_stream = stream.getStream(); + + COSName subtype = (COSName) cos_stream + .getDictionaryObject(COSName.SUBTYPE); + if (subtype.equals(COSName.IMAGE)) { + logger.debug("XObject Image"); + + Matrix ctm = context.getGraphicsState() + .getCurrentTransformationMatrix(); + logger.debug("ctm = " + ctm); + + Pos[] coordinates = new Pos[] { new Pos(0, 0, 1), + new Pos(1, 0, 1), new Pos(0, 1, 1), new Pos(1, 1, 1) }; + + Pos[] transformed_coordinates = transtormCoordinates( + coordinates, ctm); + + /********************************************************** + * pdf-as fix: calculating min and max point of an image to look + * where the signature should be placed fix solves problems with + * footer and images and placement of the signature in an image + * only pdf document + **********************************************************/ + + float actual_lowest_point = Float.NaN; + float actual_starting_point = Float.NaN; + + int pageRotation = this.mypage.getCurrentPage().findRotation(); + logger.debug("PageRotation = " + pageRotation); + if (pageRotation == 0) { + float min_y = findMinY(transformed_coordinates); + logger.debug("min_y = " + min_y); + float page_height = this.mypage.getCurrentPage().findMediaBox().getHeight(); + logger.debug("page_height = " + page_height); + + actual_lowest_point = page_height - min_y; + actual_starting_point = page_height + - findMaxY(transformed_coordinates); + } + if (pageRotation == 90) { + float max_x = findMaxX(transformed_coordinates); + logger.debug("max_x = " + max_x); + float page_width = this.mypage.getCurrentPage().findMediaBox().getWidth(); + logger.debug("page_width = " + page_width); + + actual_lowest_point = max_x; + actual_starting_point = findMinX(transformed_coordinates); + } + if (pageRotation == 180) { + float min_y = findMinY(transformed_coordinates); + logger.debug("min_y = " + min_y); + float page_height = this.mypage.getCurrentPage().findMediaBox().getHeight(); + actual_lowest_point = page_height + - findMaxY(transformed_coordinates); + actual_starting_point = page_height - min_y; + } + if (pageRotation == 270) { + float min_x = findMinX(transformed_coordinates); + logger.debug("min_x = " + min_x); + + float page_width = this.mypage.getCurrentPage().findMediaBox().getWidth(); + logger.debug("page_width = " + page_width); + + actual_lowest_point = page_width - min_x; + actual_starting_point = page_width + - findMaxX(transformed_coordinates); + } + + logger.debug("actual_lowest_point = " + actual_lowest_point); + + if (actual_lowest_point > PDFPage.this.effectivePageHeight + && actual_starting_point > PDFPage.this.effectivePageHeight) { + logger.debug("image is below footer_line"); + return; + } + + if (actual_lowest_point > PDFPage.this.max_image_ypos) { + PDFPage.this.max_image_ypos = actual_lowest_point; + } + + return; + } + + if (xobject instanceof PDXObjectForm) { + PDXObjectForm form = (PDXObjectForm) xobject; + COSStream invoke = (COSStream) form.getCOSObject(); + PDResources pdResources = form.getResources(); + PDPage page = context.getCurrentPage(); + if (pdResources == null) { + pdResources = page.findResources(); + } + + getContext().processSubStream(page, pdResources, invoke); + } + } + } + + public static Pos[] transtormCoordinates(Pos[] coordinates, Matrix m) { + Pos[] transformed = new Pos[coordinates.length]; + for (int i = 0; i < coordinates.length; i++) { + transformed[i] = transtormCoordinate(coordinates[i], m); + } + return transformed; + } + + public static Pos transtormCoordinate(Pos pos, Matrix m) { + Pos transformed = new Pos(); + transformed.x = pos.x * m.getValue(0, 0) + pos.y * m.getValue(1, 0) + + pos.z * m.getValue(2, 0); + transformed.y = pos.x * m.getValue(0, 1) + pos.y * m.getValue(1, 1) + + pos.z * m.getValue(2, 1); + transformed.z = pos.x * m.getValue(0, 2) + pos.y * m.getValue(1, 2) + + pos.z * m.getValue(2, 2); + + logger.debug(" transformed " + pos + " --> " + transformed); + return transformed; + } + + public static float findMinY(Pos[] coordinates) { + float min = Float.POSITIVE_INFINITY; + for (int i = 0; i < coordinates.length; i++) { + if (coordinates[i].y < min) { + min = coordinates[i].y; + } + } + return min; + } + + public static float findMaxY(Pos[] coordinates) { + float max = 0; + for (int i = 0; i < coordinates.length; i++) { + if (coordinates[i].y > max) { + max = coordinates[i].y; + } + } + return max; + } + + public static float findMaxX(Pos[] coordinates) { + float max = Float.NEGATIVE_INFINITY; + for (int i = 0; i < coordinates.length; i++) { + if (coordinates[i].x > max) { + max = coordinates[i].x; + } + } + return max; + } + + public static float findMinX(Pos[] coordinates) { + float min = Float.POSITIVE_INFINITY; + for (int i = 0; i < coordinates.length; i++) { + if (coordinates[i].x < min) { + min = coordinates[i].x; + } + } + return min; + } + +} \ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java new file mode 100644 index 00000000..7f223b40 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java @@ -0,0 +1,72 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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. + * + * $Id: PDFUtilities.java,v 1.3 2006/10/31 08:09:33 wprinz Exp $ + */ +package at.knowcenter.wag.egov.egiz.pdf; + +import java.io.IOException; +import java.util.List; + +import at.gv.egiz.pdfas.common.exceptions.PDFIOException; +import org.apache.pdfbox.cos.COSStream; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDResources; +import org.apache.pdfbox.pdmodel.interactive.pagenavigation.PDThreadBead; + + +/** + * Contains useful helpers for accessing PDF documents. + * + * @author wprinz + * @author mruhmer + */ +public abstract class PDFUtilities +{ + public static float calculatePageLength(PDDocument document, int page, float effectivePageHeight, /*int pagerotation,*/ boolean legacy32) throws PDFIOException { + //int last_page_id = document.getNumberOfPages(); + List allPages = document.getDocumentCatalog().getAllPages(); + PDPage pdpage = (PDPage) allPages.get(page); + //pdpage.setRotation(pagerotation); + return calculatePageLength(pdpage, effectivePageHeight, legacy32); + } + + public static float calculatePageLength(PDPage page, float effectivePageHeight, boolean legacy32) throws PDFIOException + { + try{ + PDFPage my_page = new PDFPage(effectivePageHeight, legacy32); + PDResources resources = page.findResources(); + COSStream stream = page.getContents().getStream(); + //List articles = page.getThreadBeads(); + //my_page.processMyPage(page); + my_page.processStream(page, resources, stream); + return my_page.getMaxPageLength(); + } + catch (IOException e) + { + throw new PDFIOException("calculatePageLength", e); + } + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/Pos.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/Pos.java new file mode 100644 index 00000000..6f03fed4 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/Pos.java @@ -0,0 +1,70 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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. + * + * $Id: Pos.java,v 1.1 2006/08/25 17:10:08 wprinz Exp $ + */ +package at.knowcenter.wag.egov.egiz.pdf; + +/** + * Encapsulation of a position on a PDF page. + * + * @author wprinz + */ +public class Pos +{ + + public float x; + + public float y; + + public float z; + + /** + * Default constructor. + */ + public Pos() + { + } + + /** + * Constructor that sets the coordinates. + * @param xx + * @param yy + * @param zz + */ + public Pos(float xx, float yy, float zz) + { + this.x = xx; + this.y = yy; + this.z = zz; + } + + /** + * @see Object#toString() + */ + public String toString() + { + return "(" + this.x + "," + this.y + "," + this.z + ")"; + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java new file mode 100644 index 00000000..0fe399c4 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PositioningInstruction.java @@ -0,0 +1,182 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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. + * + * $Id: $ + */ +package at.knowcenter.wag.egov.egiz.pdf; + +/** + * The positioning instruction holds information of where to place the signature + * block. + * + *

+ * This instruction is given to the PDF writer in order to place the signature. + *

+ * + * @author wprinz + */ +public class PositioningInstruction +{ + + /** + * Tells, if a new plain page should be appended. + * + *

+ * This command is executed before the signature block is positioned according + * to page, x and y. + *

+ */ + protected boolean make_new_page = false; + + /** + * The number of the page on which the signature block is to be placed. If + * specified to make a new page, the number of this newly created page can be + * used here as well. + */ + protected int page = 0; + + /** + * The x coordinate where the upper left corner of the signature block should + * be placed. + */ + protected float x = 0.0f; + + /** + * The y coordinate where the upper left corner of the signature block should + * be placed. + */ + protected float y = 0.0f; + + /** + * + * @param make_new_page + * Tells, if a new plain page should be appended. This command is + * executed before the signature block is positioned according to + * page, x and y. + * @param page + * The number of the page on which the signature block is to be + * placed. If specified to make a new page, the number of this newly + * created page can be used here as well. + * @param x + * The x coordinate where the upper left corner of the signature + * block should be placed. + * @param y + * The y coordinate where the upper left corner of the signature + * block should be placed. + */ + public PositioningInstruction(boolean make_new_page, int page, float x, float y) + { + this.make_new_page = make_new_page; + this.page = page; + this.x = x; + this.y = y; + } + + /** + * Tells, if a new plain page should be appended to the document. + * + * @return Returns true, if a new plain page should be appended. + */ + public boolean isMakeNewPage() + { + return this.make_new_page; + } + + /** + * Returns the page on which the signature is to be printed. + * + * @return Returns the page on which the signature is to be printed. + */ + public int getPage() + { + return this.page; + } + + /** + * Returns the x coordinate where the upper left corner of the signature block + * should be placed. + * + * @return Returns the x coordinate where the upper left corner of the + * signature block should be placed. + */ + public float getX() + { + return this.x; + } + + /** + * Returns the y coordinate where the upper left corner of the signature block + * should be placed. + * + * @return Returns the y coordinate where the upper left corner of the + * signature block should be placed. + */ + public float getY() + { + return this.y; + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (make_new_page ? 1231 : 1237); + result = prime * result + page; + result = prime * result + Float.floatToIntBits(x); + result = prime * result + Float.floatToIntBits(y); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof PositioningInstruction)) + return false; + PositioningInstruction other = (PositioningInstruction) obj; + if (make_new_page != other.make_new_page) + return false; + if (page != other.page) + return false; + if (Float.floatToIntBits(x) != Float.floatToIntBits(other.x)) + return false; + if (Float.floatToIntBits(y) != Float.floatToIntBits(other.y)) + return false; + return true; + } + + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append("PositioningInstruction [page="); + buffer.append(page); + buffer.append(", make_new_page="); + buffer.append(make_new_page); + buffer.append(", x="); + buffer.append(x); + buffer.append(", y="); + buffer.append(y); + buffer.append("]"); + return buffer.toString(); + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java new file mode 100644 index 00000000..92afaf98 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/TablePos.java @@ -0,0 +1,261 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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. + * + * $Id: TablePos.java,v 1.1 2006/08/25 17:10:08 wprinz Exp $ + */ +package at.knowcenter.wag.egov.egiz.pdf; + +import java.io.Serializable; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; + +/** + * Class that holds the exact position where the table should be written to the + * document. + * + * @author wprinz + * @author mruhmer + */ +public class TablePos implements Serializable +{ + + /** + * SVUID. + */ + private static final long serialVersionUID = -5299027706623518059L; + + /** + * The page on which the block should be displayed. + * + */ + private int page = 0; + + /** + * The x position. + */ + private float pos_x = 0.0f; + + /** + * The y position. + */ + private float pos_y = 0.0f; + + /** + * The width of the block. + */ + private float width = 0.0f; + /** + * The top y position of the footer line. + */ + public float footer_line = 0.0f; + + /** + * The y position. + */ + public String myposstring = ""; + + private boolean newpage = false; + private boolean autoX = true; + private boolean autoY = true; + private boolean autoW = true; + private boolean autoP = true; + + public boolean isXauto() + { + return this.autoX; + } + public boolean isYauto() + { + return this.autoY; + } + public boolean isWauto() + { + return this.autoW; + } + public boolean isPauto() + { + return this.autoP; + } + public boolean isNewPage() + { + return this.newpage; + } + public int getPage() + { + return this.page; + } + public float getFooterLine() + { + //ignore if newpage and y is not auto + if (!this.autoY || this.newpage) + { + return 0.0f; + } + return this.footer_line; + } + public float getPosX() + { + return this.pos_x; + } + public float getPosY() + { + return this.pos_y; + } + public float getWidth() + { + return this.width; + } + public TablePos() + { + //nothing to do --> default + } + + /** + * Constructor. + * + * @param pos_string The pos instruction. + * format : [x:x_algo];[y:y_algo];[w:w_algo][p:p_algo];[f:f_algo] + * x_algo:='auto' ... automatic positioning x + * floatvalue ... absolute x + * y_algo:='auto' ... automatic positioning y + * floatvalue ... absolute y + * w_algo:='auto' ... automatic width + * floatvalue ... absolute width + * p_algo:='auto' ... automatic last page + * 'new' ... new page + * intvalue ... pagenumber + * f_algo floatvalue ... consider footerline (only if y_algo is auto and p_algo is not 'new') + * @throws PdfAsException + */ + public TablePos(String pos_string) throws PdfAsException + { + //parse posstring and throw exception + //[x:x_algo];[y:y_algo];[w:w_algo][p:p_algo];[f:f_algo] + + String[] strs = pos_string.split(";"); + try + { + for (int cmds = 0;cmds Copyright 2006 by Know-Center, Graz, Austria + * 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.knowcenter.wag.egov.egiz.pdf.operator.path; + +import at.knowcenter.wag.egov.egiz.pdf.PDFPage; +import org.apache.pdfbox.util.operator.OperatorProcessor; + +import java.awt.geom.Point2D; + +/** + * Provides functions for path construction operators. + * + * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'" + * @author Datentechnik Innovation GmbH + * + */ +public abstract class PathConstructionOperatorProcessor extends OperatorProcessor { + + public PathConstructionOperatorProcessor(PDFPage context) { + setContext(context); + } + + /** + * Transforms the given point from user space coordinates to device space coordinates based on the current + * transition matrix. + * + * @param x + * The x axis value of the user space coordinates. + * @param y + * The y axis value of the user space coordinates. + * @return The transformed point. + */ + public Point2D transform(double x, double y) { + double[] position = { x, y }; + context.getGraphicsState().getCurrentTransformationMatrix().createAffineTransform() + .transform(position, 0, position, 0, 1); + return new Point2D.Double(position[0], position[1]); + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java new file mode 100644 index 00000000..a0b73015 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java @@ -0,0 +1,42 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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.knowcenter.wag.egov.egiz.pdf.operator.path; + +import at.knowcenter.wag.egov.egiz.pdf.PDFPage; +import org.apache.pdfbox.util.operator.OperatorProcessor; + +/** + * Provides functions for path painting operators. + * + * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'" + * @author Datentechnik Innovation GmbH + * + */ +public abstract class PathPaintingOperatorProcessor extends OperatorProcessor { + + public PathPaintingOperatorProcessor(PDFPage context) { + setContext(context); + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java new file mode 100644 index 00000000..c663fb5d --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java @@ -0,0 +1,67 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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.knowcenter.wag.egov.egiz.pdf.operator.path.construction; + +import at.knowcenter.wag.egov.egiz.pdf.PDFPage; +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.pdfbox.util.PDFOperator; + +import java.io.IOException; +import java.util.List; + +/** + * Close the current subpath by appending a straight line segment from the current point to the starting point of the + * subpath. If the current subpath is already closed, h shall donothing. This operator terminates the current subpath. + * Appending another segment to the current path shall begin a new subpath, even if the new segment begins at the + * endpoint reached by the h operation. + * + * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'" + * @author PdfBox, modified by Datentechnik Innovation GmbH + */ +public class ClosePath extends PathConstructionOperatorProcessor { + + private Log log = LogFactory.getLog(getClass()); + + public ClosePath(PDFPage context) { + super(context); + } + + @Override + public void process(PDFOperator operator, List operands) throws IOException { + try { + PDFPage pdfPage = (PDFPage) context; + + pdfPage.getCurrentPath().closePath(); + + if (log.isTraceEnabled()) { + log.trace("Closing current path."); + } + } catch (Exception e) { + log.warn("Error processing operator 'h'.", e); + } + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java new file mode 100644 index 00000000..70f5ab20 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java @@ -0,0 +1,84 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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.knowcenter.wag.egov.egiz.pdf.operator.path.construction; + +import at.knowcenter.wag.egov.egiz.pdf.PDFPage; +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.pdfbox.cos.COSNumber; +import org.apache.pdfbox.util.PDFOperator; + +import java.awt.geom.Point2D; +import java.io.IOException; +import java.util.List; + +/** + * Append a cubic Bezier curve to the current path. The curve shall extend from the current point to the point (x3, y3), + * using (x1, y1) and (x2, y2) as the Bezier control points (see 8.5.2.2, "Cubic Bezier Curves"). The new current point + * shall be (x3, y3). + * + * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'" + * @author PdfBox, modified by Datentechnik Innovation GmbH + */ +public class CurveTo extends PathConstructionOperatorProcessor { + + private Log log = LogFactory.getLog(getClass()); + + public CurveTo(PDFPage context) { + super(context); + } + + @Override + public void process(PDFOperator operator, List operands) throws IOException { + try { + PDFPage pdfPage = (PDFPage) context; + + COSNumber x1 = (COSNumber) operands.get(0); + COSNumber y1 = (COSNumber) operands.get(1); + COSNumber x2 = (COSNumber) operands.get(2); + COSNumber y2 = (COSNumber) operands.get(3); + COSNumber x3 = (COSNumber) operands.get(4); + COSNumber y3 = (COSNumber) operands.get(5); + + Point2D p1 = transform(x1.doubleValue(), y1.doubleValue()); + Point2D p2 = transform(x2.doubleValue(), y2.doubleValue()); + Point2D p3 = transform(x3.doubleValue(), y3.doubleValue()); + + pdfPage.getCurrentPath().curveTo( + (float) p1.getX(), (float) p1.getY(), + (float) p2.getX(), (float) p2.getY(), + (float) p3.getX(), (float) p3.getY() + ); + + if (log.isTraceEnabled()) { + log.trace("Appending cubic Bezier curve with x1:" + p1.getX() + ",y1:" + p1.getY() + ", x2:" + + p2.getX() + ",y2:" + p2.getY() + ", x3:" + p3.getX() + ",y3:" + p3.getY()); + } + } catch (Exception e) { + log.warn("Error processing operator 'c'.", e); + } + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java new file mode 100644 index 00000000..c6125751 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java @@ -0,0 +1,81 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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.knowcenter.wag.egov.egiz.pdf.operator.path.construction; + +import at.knowcenter.wag.egov.egiz.pdf.PDFPage; +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.pdfbox.cos.COSNumber; +import org.apache.pdfbox.util.PDFOperator; + +import java.awt.geom.Point2D; +import java.io.IOException; +import java.util.List; + +/** + * Append a cubic Bezier curve to the current path. The curve shall extend from the current point to the point (x3, y3), + * using (x1, y1) and (x3, y3) as the Bezier control points (see 8.5.2.2, "Cubic Bezier Curves"). The new current point + * shall be (x3, y3). + * + * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'" + * @author PdfBox, modified by Datentechnik Innovation GmbH + */ +public class CurveToReplicateFinalPoint extends PathConstructionOperatorProcessor { + + private Log log = LogFactory.getLog(getClass()); + + public CurveToReplicateFinalPoint(PDFPage context) { + super(context); + } + + @Override + public void process(PDFOperator operator, List operands) throws IOException { + try { + PDFPage pdfPage = (PDFPage) context; + + COSNumber x1 = (COSNumber) operands.get(0); + COSNumber y1 = (COSNumber) operands.get(1); + COSNumber x3 = (COSNumber) operands.get(2); + COSNumber y3 = (COSNumber) operands.get(3); + + Point2D p1 = transform(x1.doubleValue(), y1.doubleValue()); + Point2D p3 = transform(x3.doubleValue(), y3.doubleValue()); + + pdfPage.getCurrentPath().curveTo( + (float) p1.getX(), (float) p1.getY(), + (float) p3.getX(), (float) p3.getY(), + (float) p3.getX(), (float) p3.getY() + ); + + if (log.isTraceEnabled()) { + log.trace("Appending cubic Bezier curve with x1:" + p1.getX() + ",y1:" + p1.getY() + ", x3:" + + p3.getX() + ",y3:" + p3.getY()); + } + } catch (Exception e) { + log.warn("Error processing operator 'y'.", e); + } + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java new file mode 100644 index 00000000..1479bc7d --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java @@ -0,0 +1,83 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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.knowcenter.wag.egov.egiz.pdf.operator.path.construction; + +import at.knowcenter.wag.egov.egiz.pdf.PDFPage; +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.pdfbox.cos.COSNumber; +import org.apache.pdfbox.util.PDFOperator; + +import java.awt.geom.Point2D; +import java.io.IOException; +import java.util.List; + +/** + * Append a cubic Bezier curve to the current path. The curve shall extend from the current point to the point (x3, y3), + * using the current point and (x2, y2) as the Bezier control points (see 8.5.2.2, "Cubic Bezier Curves"). The new + * current point shall be (x3, y3). + * + * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'" + * @author PdfBox, modified by Datentechnik Innovation GmbH + */ +public class CurveToReplicateInitialPoint extends PathConstructionOperatorProcessor { + + private Log log = LogFactory.getLog(getClass()); + + public CurveToReplicateInitialPoint(PDFPage context) { + super(context); + } + + @Override + public void process(PDFOperator operator, List operands) throws IOException { + try { + PDFPage pdfPage = (PDFPage) context; + + COSNumber x2 = (COSNumber) operands.get(0); + COSNumber y2 = (COSNumber) operands.get(1); + COSNumber x3 = (COSNumber) operands.get(2); + COSNumber y3 = (COSNumber) operands.get(3); + + Point2D currentPoint = pdfPage.getCurrentPath().getCurrentPoint(); + Point2D p2 = transform(x2.doubleValue(), y2.doubleValue()); + Point2D p3 = transform(x3.doubleValue(), y3.doubleValue()); + + pdfPage.getCurrentPath().curveTo( + (float)currentPoint.getX(), (float)currentPoint.getY(), + (float) p2.getX(), (float) p2.getY(), + (float) p3.getX(), (float) p3.getY() + ); + + if (log.isTraceEnabled()) { + log.trace("Appending cubic Bezier curve with x2:" + p2.getX() + ",y2:" + p2.getY() + ", x3:" + + p3.getX() + ",y3:" + p3.getY() + ", using current point x:" + currentPoint.getX() + ",y:" + + currentPoint.getY()); + } + } catch (Exception e) { + log.warn("Error processing operator 'v'.", e); + } + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java new file mode 100644 index 00000000..94f16b7f --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java @@ -0,0 +1,70 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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.knowcenter.wag.egov.egiz.pdf.operator.path.construction; + +import at.knowcenter.wag.egov.egiz.pdf.PDFPage; +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.pdfbox.cos.COSNumber; +import org.apache.pdfbox.util.PDFOperator; + +import java.awt.geom.Point2D; +import java.io.IOException; +import java.util.List; + +/** + * Append a straight line segment from the current point to the point (x, y). The new current point shall be (x, y). + * + * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'" + * @author PdfBox, modified by Datentechnik Innovation GmbH + */ +public class LineTo extends PathConstructionOperatorProcessor { + + private Log log = LogFactory.getLog(getClass()); + + public LineTo(PDFPage context) { + super(context); + } + + @Override + public void process(PDFOperator operator, List operands) throws IOException { + try { + PDFPage pdfPage = (PDFPage) context; + + COSNumber x = (COSNumber) operands.get(0); + COSNumber y = (COSNumber) operands.get(1); + Point2D p = transform(x.doubleValue(), y.doubleValue()); + + pdfPage.getCurrentPath().lineTo((float) p.getX(), (float) p.getY()); + + if (log.isTraceEnabled()) { + log.trace("Adding line to x:" + p.getX() + ",y:" + p.getY()); + } + } catch (Exception e) { + log.warn("Error processing operator 'l'.", e); + } + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java new file mode 100644 index 00000000..97424e93 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java @@ -0,0 +1,72 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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.knowcenter.wag.egov.egiz.pdf.operator.path.construction; + +import at.knowcenter.wag.egov.egiz.pdf.PDFPage; +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.pdfbox.cos.COSNumber; +import org.apache.pdfbox.util.PDFOperator; + +import java.awt.geom.Point2D; +import java.io.IOException; +import java.util.List; + +/** + * Begin a new subpath by moving the current point to coordinates (x, y), omitting any connecting line segment. If the + * previous path construction operator in the current path was also m, the new m overrides it; no vestige of the + * previous m operation remains in the path. + * + * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'" + * @author PdfBox, modified by Datentechnik Innovation GmbH + */ +public class MoveTo extends PathConstructionOperatorProcessor { + + private Log log = LogFactory.getLog(getClass()); + + public MoveTo(PDFPage context) { + super(context); + } + + @Override + public void process(PDFOperator operator, List operands) throws IOException { + try { + PDFPage pdfPage = (PDFPage) context; + + COSNumber x = (COSNumber) operands.get(0); + COSNumber y = (COSNumber) operands.get(1); + Point2D p = transform(x.doubleValue(), y.doubleValue()); + + pdfPage.getCurrentPath().moveTo((float) p.getX(), (float) p.getY()); + + if (log.isTraceEnabled()) { + log.trace("Moving current path to x:" + p.getX() + ",y:" + p.getY()); + } + } catch (Exception e) { + log.warn("Error processing operator 'm'.", e); + } + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java new file mode 100644 index 00000000..5a8de9d0 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java @@ -0,0 +1,58 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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.knowcenter.wag.egov.egiz.pdf.operator.path.painting; + +import at.knowcenter.wag.egov.egiz.pdf.PDFPage; +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.pdfbox.util.PDFOperator; + +import java.io.IOException; +import java.util.List; + +/** + * Close and stroke the path. This operator shall have the same effect as the sequence h S. + * + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'" + * @author PdfBox, modified by Datentechnik Innovation GmbH + */ +public class CloseAndStrokePath extends PathPaintingOperatorProcessor { + + private Log log = LogFactory.getLog(getClass()); + + public CloseAndStrokePath(PDFPage context) { + super(context); + } + + @Override + public void process(PDFOperator operator, List operands) throws IOException { + if (log.isTraceEnabled()) { + log.trace("Closing and stroking path."); + } + context.processOperator("h", operands); + context.processOperator("S", operands); + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java new file mode 100644 index 00000000..bdaaaa4a --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java @@ -0,0 +1,59 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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.knowcenter.wag.egov.egiz.pdf.operator.path.painting; + +import at.knowcenter.wag.egov.egiz.pdf.PDFPage; +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.pdfbox.util.PDFOperator; + +import java.io.IOException; +import java.util.List; + +/** + * Close, fill, and then stroke the path, using the even-odd rule to determine the region to fill. This operator shall + * have the same effect as the sequence h B*. + * + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'" + * @author PdfBox, modified by Datentechnik Innovation GmbH + */ +public class CloseFillEvenOddAndStrokePath extends PathPaintingOperatorProcessor { + + private Log log = LogFactory.getLog(getClass()); + + public CloseFillEvenOddAndStrokePath(PDFPage context) { + super(context); + } + + @Override + public void process(PDFOperator operator, List operands) throws IOException { + if (log.isTraceEnabled()) { + log.trace("Closing, filling (even odd rule) and stroking path."); + } + context.processOperator("h", operands); + context.processOperator("B*", operands); + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java new file mode 100644 index 00000000..4d4f3b68 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java @@ -0,0 +1,59 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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.knowcenter.wag.egov.egiz.pdf.operator.path.painting; + +import at.knowcenter.wag.egov.egiz.pdf.PDFPage; +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.pdfbox.util.PDFOperator; + +import java.io.IOException; +import java.util.List; + +/** + * Close, fill, and then stroke the path, using the nonzero winding number rule to determine the region to fill. This + * operator shall have the same effect as the sequence h B. + * + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'" + * @author PdfBox, modified by Datentechnik Innovation GmbH + */ +public class CloseFillNonZeroAndStrokePath extends PathPaintingOperatorProcessor { + + private Log log = LogFactory.getLog(getClass()); + + public CloseFillNonZeroAndStrokePath(PDFPage context) { + super(context); + } + + @Override + public void process(PDFOperator operator, List operands) throws IOException { + if (log.isTraceEnabled()) { + log.trace("Closing, filling (non zero rule) and stroking path."); + } + context.processOperator("h", operands); + context.processOperator("B", operands); + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java new file mode 100644 index 00000000..291175aa --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java @@ -0,0 +1,67 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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.knowcenter.wag.egov.egiz.pdf.operator.path.painting; + +import at.knowcenter.wag.egov.egiz.pdf.PDFPage; +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.pdfbox.util.PDFOperator; + +import java.io.IOException; +import java.util.List; + +/** + * End the path object without filling or stroking it. This operator shall be a path-painting no-op, used primarily for + * the side effect of changing the current clipping path. + * + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'" + * @author PdfBox, modified by Datentechnik Innovation GmbH + */ +public class EndPath extends PathPaintingOperatorProcessor { + + private Log log = LogFactory.getLog(getClass()); + + public EndPath(PDFPage context) { + super(context); + } + + @Override + public void process(PDFOperator operator, List operands) throws IOException { + try { + PDFPage pdfPage = (PDFPage) context; + + log.debug("Ending path " + pdfPage.getCurrentPath()); + pdfPage.getCurrentPath().reset(); + + if (log.isTraceEnabled()) { + log.trace("End path without filling or stroking."); + } + + } catch (Exception e) { + log.warn("Error processing operator 'n'.", e); + } + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java new file mode 100644 index 00000000..b1e836d5 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java @@ -0,0 +1,71 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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.knowcenter.wag.egov.egiz.pdf.operator.path.painting; + +import at.knowcenter.wag.egov.egiz.pdf.PDFPage; +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.pdfbox.util.PDFOperator; + +import java.awt.geom.GeneralPath; +import java.io.IOException; +import java.util.List; + +/** + * Fill and then stroke the path, using the even-odd rule to determine the region to fill. This operator shall produce + * the same result as B, except that the path is filled as if with f* instead of + * f. + * + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'" + * @author PdfBox, modified by Datentechnik Innovation GmbH + */ +public class FillEvenOddAndStrokePath extends PathPaintingOperatorProcessor { + + private Log log = LogFactory.getLog(getClass()); + + public FillEvenOddAndStrokePath(PDFPage context) { + super(context); + } + + @Override + public void process(PDFOperator operator, List operands) throws IOException { + try { + PDFPage pdfPage = (PDFPage) context; + + if (log.isTraceEnabled()) { + log.trace("Filling (even odd rule) and stroking path."); + } + + GeneralPath currentPath = (GeneralPath) pdfPage.getCurrentPath().clone(); + context.processOperator("f*", operands); + pdfPage.setCurrentPath(currentPath); + context.processOperator("S", operands); + + } catch (Exception e) { + log.warn("Error processing operator 'B*'.", e); + } + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java new file mode 100644 index 00000000..72719ec3 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java @@ -0,0 +1,71 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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.knowcenter.wag.egov.egiz.pdf.operator.path.painting; + +import at.knowcenter.wag.egov.egiz.pdf.PDFPage; +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.pdfbox.util.PDFOperator; + +import java.awt.geom.GeneralPath; +import java.io.IOException; +import java.util.List; + +/** + * Fill and then stroke the path, using the nonzero winding number rule to determine the region to fill. This operator + * shall produce the same result as constructing two identical path objects, painting the first with f and + * the second with S. + * + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'" + * @author PdfBox, modified by Datentechnik Innovation GmbH + */ +public class FillNonZeroAndStrokePath extends PathPaintingOperatorProcessor { + + private Log log = LogFactory.getLog(getClass()); + + public FillNonZeroAndStrokePath(PDFPage context) { + super(context); + } + + @Override + public void process(PDFOperator operator, List operands) throws IOException { + try { + PDFPage pdfPage = (PDFPage) context; + + if (log.isTraceEnabled()) { + log.trace("Filling (non zero rule) and stroking path."); + } + + GeneralPath currentPath = (GeneralPath) pdfPage.getCurrentPath().clone(); + context.processOperator("f", operands); + pdfPage.setCurrentPath(currentPath); + context.processOperator("S", operands); + + } catch (Exception e) { + log.warn("Error processing operator 'B'.", e); + } + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java new file mode 100644 index 00000000..28343c5a --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java @@ -0,0 +1,70 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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.knowcenter.wag.egov.egiz.pdf.operator.path.painting; + +import at.knowcenter.wag.egov.egiz.pdf.PDFPage; +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.pdfbox.util.PDFOperator; + +import java.awt.*; +import java.io.IOException; +import java.util.List; + +/** + * Fill the path, using the even-odd rule to determine the region to fill. + * + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'" + * @author PdfBox, modified by Datentechnik Innovation GmbH + */ +public class FillPathEvenOddRule extends PathPaintingOperatorProcessor { + + private Log log = LogFactory.getLog(getClass()); + + public FillPathEvenOddRule(PDFPage context) { + super(context); + } + + @Override + public void process(PDFOperator operator, List operands) throws IOException { + try { + PDFPage pdfPage = (PDFPage) context; + + pdfPage.getCurrentPath().setWindingRule(java.awt.geom.GeneralPath.WIND_EVEN_ODD); + Rectangle bounds = pdfPage.getCurrentPath().getBounds(); + pdfPage.getCurrentPath().reset(); + + if (log.isTraceEnabled()) { + log.trace("Filling path, using even-odd rule."); + } + + pdfPage.registerPathBounds(bounds); + + } catch (Exception e) { + log.warn("Error processing operator 'f*'.", e); + } + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java new file mode 100644 index 00000000..28e5c373 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java @@ -0,0 +1,71 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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.knowcenter.wag.egov.egiz.pdf.operator.path.painting; + +import at.knowcenter.wag.egov.egiz.pdf.PDFPage; +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.pdfbox.util.PDFOperator; + +import java.awt.*; +import java.io.IOException; +import java.util.List; + +/** + * Fill the path, using the nonzero winding number rule to determine the region to fill. Any subpaths that are open + * shall be implicitly closed before being filled. + * + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'" + * @author PdfBox, modified by Datentechnik Innovation GmbH + */ +public class FillPathNonZeroWindingNumberRule extends PathPaintingOperatorProcessor { + + private Log log = LogFactory.getLog(getClass()); + + public FillPathNonZeroWindingNumberRule(PDFPage context) { + super(context); + } + + @Override + public void process(PDFOperator operator, List operands) throws IOException { + try { + PDFPage pdfPage = (PDFPage) context; + + pdfPage.getCurrentPath().setWindingRule(java.awt.geom.GeneralPath.WIND_NON_ZERO); + Rectangle bounds = pdfPage.getCurrentPath().getBounds(); + pdfPage.getCurrentPath().reset(); + + if (log.isTraceEnabled()) { + log.trace("Filling path, using nonzero winding number rule."); + } + + pdfPage.registerPathBounds(bounds); + + } catch (Exception e) { + log.warn("Error processing operator 'f/F'.", e); + } + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java new file mode 100644 index 00000000..0530a925 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java @@ -0,0 +1,69 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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.knowcenter.wag.egov.egiz.pdf.operator.path.painting; + +import at.knowcenter.wag.egov.egiz.pdf.PDFPage; +import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.pdfbox.util.PDFOperator; + +import java.awt.*; +import java.io.IOException; +import java.util.List; + +/** + * Strokes the path. + * + * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'" + * @author PdfBox, modified by Datentechnik Innovation GmbH + */ +public class StrokePath extends PathPaintingOperatorProcessor { + + private Log log = LogFactory.getLog(getClass()); + + public StrokePath(PDFPage context) { + super(context); + } + + @Override + public void process(PDFOperator operator, List operands) throws IOException { + try { + PDFPage pdfPage = (PDFPage) context; + + Rectangle bounds = pdfPage.getCurrentPath().getBounds(); + pdfPage.getCurrentPath().reset(); + + if (log.isTraceEnabled()) { + log.trace("Stroking path."); + } + + pdfPage.registerPathBounds(bounds); + + } catch (Exception e) { + log.warn("Error processing operator 'S'.", e); + } + } + +} diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/sig/SignatureEntry.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/sig/SignatureEntry.java new file mode 100644 index 00000000..957e947f --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/sig/SignatureEntry.java @@ -0,0 +1,163 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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. + * + * $Id: SignatureEntry.java,v 1.3 2006/08/25 17:09:41 wprinz Exp $ + */ +package at.knowcenter.wag.egov.egiz.pdf.sig; + +import java.io.Serializable; + +/** + * This class is to store a signature entry. The signature entry is 3-tupel. A key that is defined + * or declarated in the settings file, an optional caption or a value.
+ * An additional helper value is a marker for the start index of the key, if the key is found in an + * analysing process extracting captions and values from a raw signature text. + * + * @author wlackner + * @see at.knowcenter.wag.egov.egiz.sig.SignatureObject + */ +public class SignatureEntry implements Serializable { + + /** + * SVUID. + */ + private static final long serialVersionUID = 4640380069301731879L; + + /** + * The signature key. + */ + private String key_ = null; + /** + * The signature caption for the key found or set in the signature text. + */ + private String caption_ = null; + /** + * The signature value for the key found or set in the signature text. + */ + private String value_ = null; + /** + * The starting index position of the key if it is found in the signature text. + */ + private int startIndex_ = -1; + + public boolean isPlaceholder = false; + + /** + * The empty constructor. + */ + public SignatureEntry() { + } + + /** + * A new SignatureEntry init with the key. + * + * @param key + */ + public SignatureEntry(String key) { + key_ = key; + } + + /** + * Returns the caption off the current key. + * + * @return Returns the caption. + */ + public String getCaption() { + return caption_; + } + + /** + * Set the caption of the current key. + * + * @param caption The caption to set. + */ + public void setCaption(String caption) { + caption_ = caption; + } + + /** + * Return the current key. + * + * @return Returns the key. + */ + public String getKey() { + return key_; + } + + /** + * Set the current key. + * + * @param key The key to set. + */ + public void setKey(String key) { + key_ = key; + } + + /** + * Return the start position of the key that caption is found in the signature text. + * + * @return Returns the startIndex. + */ + public int getStartIndex() { + return startIndex_; + } + + /** + * Set the start position of the current key. + * + * @param startIndex The startIndex to set. + */ + public void setStartIndex(int startIndex) { + startIndex_ = startIndex; + } + + /** + * Return the value of the current key. + * + * @return Returns the value. + */ + public String getValue() { + return value_; + } + + /** + * Set the value of the current key. + * + * @param value The value to set. + */ + public void setValue(String value) { + value_ = value; + } + + /** + * The toString method, used for tests or debugging. + */ + public String toString() { + String the_string = ""; + the_string += "\n Key:" + key_; + the_string += "\nCaption:" + caption_; + the_string += "\n Value:" + value_; +// the_string += "\nStart I:" + startIndex_; + return the_string; + } +} \ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Entry.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Entry.java new file mode 100644 index 00000000..289a7f6f --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Entry.java @@ -0,0 +1,235 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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. + * + * $Id: Entry.java,v 1.3 2006/08/25 17:08:19 wprinz Exp $ + */ +package at.knowcenter.wag.egov.egiz.table; + +import java.io.Serializable; + +/** + * This class implements a table entry for different types. A table entry can be + * styled and setting there column dimensions. The default value for the column + * dimension is 1. To declare the type of the entry use the public + * TYPE_ definitions. + * + * @author wlackner + */ +public class Entry implements Serializable +{ + + /** + * SVUID. + */ + private static final long serialVersionUID = -7952755200668528348L; + + /** + * Type for a text entry. + */ + public final static int TYPE_CAPTION = 0; + + /** + * Type for a text entry. + */ + public final static int TYPE_VALUE = 1; + + /** + * Type for an image entry. + */ + public final static int TYPE_IMAGE = 2; + + /** + * Type for a table entry. + */ + public final static int TYPE_TABLE = 3; + + /** + * The type info holder, default value is 0! + */ + private int type_ = 0; + + /** + * The entry value. + */ + private Object value_ = null; + + /** + * The key value + */ + private String key_ = null; + + /** + * The entry style information. + */ + private Style style_ = null; + + /** + * The column dimension. + */ + private int colSpan_ = 1; + + /** + * Text wrap indicator, default is false. + */ + private boolean noWrap_ = false; + + /** + * The empty constructor. + */ + public Entry() + { + } + + /** + * A constructor setting the type and the value. + * + * @param type + * the entry type to set + * @param value + * the entry value to set + */ + public Entry(int type, Object value, String key) + { + type_ = type; + value_ = value; + key_ = key; + } + + /** + * @return Returns the entry style. + */ + public Style getStyle() + { + return style_; + } + + /** + * @param style + * The style to set. + */ + public void setStyle(Style style) + { + style_ = style; + } + + /** + * @return Returns the entry type. + */ + public int getType() + { + return type_; + } + + /** + * @param type + * The type to set. + */ + public void setType(int type) + { + type_ = type; + } + + /** + * @return Returns the entry value. + */ + public Object getValue() + { + return value_; + } + + /** + * @param value + * The value to set. + */ + public void setValue(Object value) + { + value_ = value; + } + + /** + * @return Returns the key. + */ + + public String getKey() + { + return key_; + } + + /** + * @param key + * The key to set. + */ + public void setKey(String key) + { + key_ = key; + } + + /** + * @return Returns the colSpan. + */ + public int getColSpan() + { + return colSpan_; + } + + /** + * @param colSpan + * The colSpan to set. + */ + public void setColSpan(int colSpan) + { + colSpan_ = colSpan; + } + + /** + * @return Returns the wrap indicator. + */ + public boolean isNoWrap() + { + return noWrap_; + } + + /** + * @param noWrap + * The wrap indicator to set. + */ + public void setNoWrap(boolean noWrap) + { + noWrap_ = noWrap; + } + + /** + * The toString method, used for tests or debugging. + */ + public String toString() + { + Object obj = getValue(); + String value = null; + if (obj != null) + { + value = obj.toString(); + } + return "Type:" + getType() + " Value:" + value + " ColSpan:" + getColSpan(); + } + +} \ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Style.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Style.java new file mode 100644 index 00000000..489c9419 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Style.java @@ -0,0 +1,630 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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. + * + * $Id: Style.java,v 1.3 2006/08/25 17:08:19 wprinz Exp $ + */ +package at.knowcenter.wag.egov.egiz.table; + +import java.awt.Color; +import java.io.Serializable; + +/** + * This class implements an abstract style definiton used in tables or table entrys. Predefined + * values exists for valign and halign. Color definitions uses the native awt color declarations. + *
+ * The predefined keys are used in the setting definition file to style tables and table entries. + *
+ * It provides an static method to inherit style informations from a given style object. + * {@link Style#doInherit} + * + * + * @author wlackner + * @see java.awt.Color + */ +public class Style implements Serializable { + +// 03.11.2010 changed by exthex - added valuevalign and valuehalign to allow separate layout for value and non-value cells. +// Also the hardcoded default values for halign and valign were removed to allow proper inheritment. +// 04.11.2010 changed by exthex - added imagevalign and imagehalign analog to valuevalign/valuehalign + + /** + * SVUID. + */ + private static final long serialVersionUID = 5855722896712428387L; + + /** + * valign statement key top + */ + public final static String TOP = "top"; + /** + * valign statement key middle + */ + public final static String MIDDLE = "middle"; + /** + * valign statement key bottom + */ + public final static String BOTTOM = "bottom"; + /** + * halign statement key left + */ + public final static String LEFT = "left"; + /** + * halign statement key center + */ + public final static String CENTER = "center"; + /** + * halign statement key right + */ + public final static String RIGHT = "right"; + + /** + * bgcolor key + */ + public final static String BGCOLOR = "bgcolor"; + /** + * halign key + */ + public final static String HALIGN = "halign"; + /** + * valign key + */ + public final static String VALIGN = "valign"; + + /** + * value halign key + */ + public final static String VALUEHALIGN = "valuehalign"; + /** + * value valign key + */ + public final static String VALUEVALIGN = "valuevalign"; + + /** + * image halign key + */ + public final static String IMAGEHALIGN = "imagehalign"; + /** + * image valign key + */ + public final static String IMAGEVALIGN = "imagevalign"; + /** + * padding key, default padding = 1 + */ + public final static String PADDING = "padding"; + /** + * border key, default border = 1;
+ * The border value is one value for all border lines of an entry or table!
+ * No separte definitions for top, right, bottom or left are possible. + */ + public final static String BORDER = "border"; + + /** + * Font key + */ + public final static String FONT = "font"; + + /** + * The value font key. + */ + public final static String VALUEFONT = "valuefont"; + + /** + * The imageScaleToFit key. + */ + public final static String IMAGE_SCALE_TO_FIT = "imagescaletofit"; + + /** + * Font name HELVETICA + */ + public final static String HELVETICA = "HELVETICA"; + /** + * Font name TIMES_ROMAN + */ + public final static String TIMES_ROMAN = "TIMES_ROMAN"; + /** + * Font name COURIER + */ + public final static String COURIER = "COURIER"; + /** + * Font type NORMAL + */ + public final static String NORMAL = "NORMAL"; + /** + * Font type BOLD + */ + public final static String BOLD = "BOLD"; + /** + * Font type ITALIC + */ + public final static String ITALIC = "ITALIC"; + /** + * Font type BOLDITALIC + */ + public final static String BOLDITALIC = "BOLDITALIC"; + /** + * Font type UNDERLINE + */ + public final static String UNDERLINE = "UNDERLINE"; + /** + * Font type STRIKETHRU + */ + public final static String STRIKETHRU = "STRIKETHRU"; + + + /** + * all paddings initialized with the default padding value (1) + */ + private static final float DEFAULT_PADDING = 1; + /** + * all borders initialized with the default border value (1) + */ + private static final float DEFAULT_BORDER = 1; + /** + * The background color definition. + */ + private Color bgColor_ = null; + /** + * The current padding value -> initialized with the default padding value + */ + private float padding_ = DEFAULT_PADDING; + /** + * The current halign value + */ + private String hAlign_ = null; + /** + * The current valign value + */ + private String vAlign_ = null; + /** + * The current valuehalign value + */ + private String valueHAlign_ = null; + /** + * The current valuevalign value + */ + private String valueVAlign_ = null; + /** + * The current imagehalign value + */ + private String imageHAlign_ = null; + /** + * The current imagevalign value + */ + private String imageVAlign_ = null; + /** + * The current border value -> initialized with the default border value + */ + private float border_ = DEFAULT_BORDER; + /** + * The font string of the style definition + */ + private String font_ = null; + /** + * The font string of the value font. + */ + private String valuefont_ = null; + /** + * The scaleToFit dimensions to be applied for image-cells. + */ + private ImageScaleToFit imageScaleToFit_ = null; + + /** + * The empty constructor. + */ + public Style() { + } + + /** + * Set a style attribute. The style attribute must be one of the public definitions + * + * @param id the style attribute to set + * @param value the style value to set for the given attribute + */ + public void setStyle(String id, String value) { + if (BGCOLOR.equals(id)) { + String[] col_strg = value.split(" "); + if (col_strg.length == 3) { + int r = Integer.parseInt(col_strg[0]); + int g = Integer.parseInt(col_strg[1]); + int b = Integer.parseInt(col_strg[2]); + if (r < 256 && g < 256 && b < 256 && r >= 0 && g >= 0 && b >= 0) { + bgColor_ = new Color(r, g, b); + } + } + } + if (HALIGN.equals(id)) { + if (LEFT.equals(value) || CENTER.equals(value) || RIGHT.equals(value)) { + hAlign_ = value; + } + } + if (VALIGN.equals(id)) { + if (TOP.equals(value) || MIDDLE.equals(value) || BOTTOM.equals(value)) { + vAlign_ = value; + } + } + if (VALUEHALIGN.equals(id)) { + if (LEFT.equals(value) || CENTER.equals(value) || RIGHT.equals(value)) { + valueHAlign_ = value; + } + } + if (VALUEVALIGN.equals(id)) { + if (TOP.equals(value) || MIDDLE.equals(value) || BOTTOM.equals(value)) { + valueVAlign_ = value; + } + } + if (IMAGEHALIGN.equals(id)) { + if (LEFT.equals(value) || CENTER.equals(value) || RIGHT.equals(value)) { + imageHAlign_ = value; + } + } + if (IMAGEVALIGN.equals(id)) { + if (TOP.equals(value) || MIDDLE.equals(value) || BOTTOM.equals(value)) { + imageVAlign_ = value; + } + } + if (PADDING.equals(id)) { + padding_ = Float.parseFloat(value); + } + if (BORDER.equals(id)) { + border_ = Float.parseFloat(value); + } + if (FONT.equals(id)) { + font_ = value; + } + if (VALUEFONT.equals(id)) { + valuefont_ = value; + } + if (IMAGE_SCALE_TO_FIT.equals(id)) + { + imageScaleToFit_ = parseImageScaleToFit(value); + } + } + + /** + * @return Returns the bgColor. + */ + public Color getBgColor() { + return bgColor_; + } + + /** + * @param bgColor The bgColor to set. + */ + public void setBgColor(Color bgColor) { + bgColor_ = bgColor; + } + + /** + * @return Returns the hAlign. + */ + public String getHAlign() { + return hAlign_; + } + + /** + * @param align The hAlign to set. + */ + public void setHAlign(String align) { + hAlign_ = align; + } + + /** + * @return Returns the padding. + */ + public float getPadding() { + return padding_; + } + + /** + * @param padding The padding to set. + */ + public void setPadding(float padding) { + padding_ = padding; + } + + /** + * @return Returns the vAlign. + */ + public String getVAlign() { + return vAlign_; + } + + /** + * @param align The vAlign to set. + */ + public void setVAlign(String align) { + vAlign_ = align; + } + + /** + * @return Returns the border. + */ + public float getBorder() { + return border_; + } + + /** + * @param border The border to set. + */ + public void setBorder(float border) { + border_ = border; + } + + + /** + * @return Returns the font. + */ + public String getFont() { + return font_; + } + + /** + * @param font The font to set. + */ + public void setFont(String font) { + font_ = font; + } + + + /** + * Returns the value font. + * @return Returns the value font. + */ + public String getValueFont() + { + return valuefont_; + } + + /** + * Sets the value font. + * @param valuefont The value font to be set. + */ + public void setValueFont(String valuefont) + { + this.valuefont_ = valuefont; + } + + /** + * @param align The valueHAlign to set. + */ + public void setValueHAlign(String align) { + valueHAlign_ = align; + } + + /** + * Returns the value halign + * @return Returns the value halign + */ + public String getValueHAlign() { + return valueHAlign_; + } + + /** + * @param align The valueVAlign to set. + */ + public void setValueVAlign(String align) { + valueVAlign_ = align; + } + + /** + * Returns the value valign + * @return Returns the value valign + */ + public String getValueVAlign() { + return valueVAlign_; + } + + /** + * @param align The imageHAlign to set. + */ + public void setImageHAlign(String align) { + imageHAlign_ = align; + } + + /** + * Returns the image halign + * @return Returns the image halign + */ + public String getImageHAlign() { + return imageHAlign_; + } + + /** + * @param align The imageVAlign to set. + */ + public void setImageVAlign(String align) { + imageVAlign_ = align; + } + + /** + * Returns the image valign + * @return Returns the image valign + */ + public String getImageVAlign() { + return imageVAlign_; + } + + /** + * Returns the scaleToFit dimensions to be applied for image-cells. + * @return Returns the scaleToFit dimensions to be applied for image-cells. + */ + public ImageScaleToFit getImageScaleToFit() + { + return this.imageScaleToFit_; + } + + /** + * Sets the scaleToFit dimensions to be applied for image-cells. + * @param imageScaleToFit_ The scaleToFit dimensions to be applied for image-cells. + */ + public void setImageScaleToFit(ImageScaleToFit imageScaleToFit) + { + this.imageScaleToFit_ = imageScaleToFit; + } + + /** + * The toString method, used for tests or debugging. + */ + public String toString() { + return "bgcolor:" + getBgColor() + " halign:" + getHAlign() + " valign:" + getVAlign() + " padding:" + getPadding() + " border:" + getBorder() + " font:" + getFont() + " valuefont:" + getValueFont() + " imageScaleToFit:" + getImageScaleToFit(); + } + + /** + * This method inherits all style attributes (values) from a given style object. + * + *

+ * A new style object is created that receives the properly inherited styles. + *

+ *

+ * If a value is not defined in the baseStyle object it would be inhert from the inheritStyle object. + *

+ * + * @param baseStyle the style object that serves as a primary style source. + * @param inheritStyle the style object that serves as a secondary style source in case a style attribute is not defined on the primary style source. + * @param isValue + * @return Returns a new Style object being fully equipped with styles. + */ + public static Style doInherit(Style baseStyle, Style inheritStyle) { + Style newStyle = new Style(); + + if (baseStyle != null) + { + newStyle.setBgColor(baseStyle.getBgColor()); + newStyle.setBorder(baseStyle.getBorder()); + newStyle.setFont(baseStyle.getFont()); + newStyle.setHAlign(baseStyle.getHAlign()); + newStyle.setImageHAlign(baseStyle.getImageHAlign()); + newStyle.setImageVAlign(baseStyle.getImageVAlign()); + newStyle.setPadding(baseStyle.getPadding()); + newStyle.setVAlign(baseStyle.getVAlign()); + newStyle.setValueFont(baseStyle.getValueFont()); + newStyle.setValueHAlign(baseStyle.getValueHAlign()); + newStyle.setValueVAlign(baseStyle.getValueVAlign()); + newStyle.setImageScaleToFit(baseStyle.getImageScaleToFit()); + } + + if (inheritStyle != null) + { + if (newStyle.getBgColor() == null) { newStyle.setBgColor(inheritStyle.getBgColor()); } + if (newStyle.getBorder() == DEFAULT_BORDER) { newStyle.setBorder(inheritStyle.getBorder()); } + if (newStyle.getFont() == null) { newStyle.setFont(inheritStyle.getFont()); } + if (newStyle.getHAlign() == null) { newStyle.setHAlign(inheritStyle.getHAlign()); } + if (newStyle.getImageHAlign() == null) { newStyle.setImageHAlign(inheritStyle.getImageHAlign()); } + if (newStyle.getImageVAlign() == null) { newStyle.setImageVAlign(inheritStyle.getImageVAlign()); } + if (newStyle.getPadding() == DEFAULT_PADDING) { newStyle.setPadding(inheritStyle.getPadding()); } + if (newStyle.getVAlign() == null) { newStyle.setVAlign(inheritStyle.getVAlign()); } + if (newStyle.getValueFont() == null) { newStyle.setValueFont(inheritStyle.getValueFont()); } + if (newStyle.getValueHAlign() == null) { newStyle.setValueHAlign(inheritStyle.getValueHAlign()); } + if (newStyle.getValueVAlign() == null) { newStyle.setValueVAlign(inheritStyle.getValueVAlign()); } + if (newStyle.getImageScaleToFit() == null) { newStyle.setImageScaleToFit(inheritStyle.getImageScaleToFit()); } + } + + return newStyle; + } + + protected static ImageScaleToFit parseImageScaleToFit (String imageScaleToFit) + { + if (imageScaleToFit == null || imageScaleToFit.length() == 0 || imageScaleToFit.trim().length() == 0) + { + return null; + } + + String [] dimensions = imageScaleToFit.split(";"); + if (dimensions.length != 2) + { + return null; + } + + float width = Float.parseFloat(dimensions[0]); + float height = Float.parseFloat(dimensions[0]); + + return new ImageScaleToFit(width, height); + } + + /** + * Holds the width and the height an image can be scaled to fit. + * + * @author wprinz + */ + public static class ImageScaleToFit + { + /** + * The width. + */ + protected float width; + + /** + * The height. + */ + protected float height; + + /** + * Constructor. + * + * @param width The width. + * @param height The height. + */ + public ImageScaleToFit(float width, float height) + { + this.width = width; + this.height = height; + } + + /** + * Returns the width. + * @return Returns the width. + */ + public float getWidth() + { + return this.width; + } + + /** + * Sets the width. + * @param width The width to set. + */ + public void setWidth(float width) + { + this.width = width; + } + + /** + * Returns the height. + * @return Returns the height. + */ + public float getHeight() + { + return this.height; + } + + /** + * Sets the height. + * @param height The height to set. + */ + public void setHeight(float height) + { + this.height = height; + } + + } +} \ No newline at end of file diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Table.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Table.java new file mode 100644 index 00000000..c5a0c58f --- /dev/null +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/table/Table.java @@ -0,0 +1,223 @@ +/** + * Copyright 2006 by Know-Center, Graz, Austria + * 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. + * + * $Id: Table.java,v 1.2 2006/08/25 17:08:19 wprinz Exp $ + */ +package at.knowcenter.wag.egov.egiz.table; + +import java.io.Serializable; +import java.util.Map; +import java.util.HashMap; +import java.util.ArrayList; + +/** + * This class implements an abstract table definition. The table contains table + * rows and the table rows contains the table entries. A table can be styled and + * a relative column width can be set. + * + * @author wlackner + * @see Style + * @see at.knowcenter.wag.egov.egiz.table.Entry + */ +public class Table implements Serializable +{ + + /** + * SVUID. + */ + private static final long serialVersionUID = 8488947943674086618L; + + /** + * The table column settings. + */ + private float[] colsRelativeWith_ = null; + + /** + * The row definitions. + */ + private Map rows_ = new HashMap(); + + /** + * The table width. + */ + private float width_ = 100; + + /** + * The table style. + */ + private Style style_ = null; + + /** + * Number of columns that are defined for the current table. + */ + private int maxCols_ = 0; + + /** + * A table name. + */ + private String name_ = null; + + /** + * The table constructor init by a table name. + * + * @param name + * the name for the table. + */ + public Table(String name) + { + name_ = name; + } + + /** + * The width of the columns are relative to each other. This means the values + * are summarized and divided into portions of columns used.
+ * Example: [1,4] means the second column is four times wider + * than the first column. + * + * @return Returns the relative width of the columns + */ + public float[] getColsRelativeWith() + { + return colsRelativeWith_; + } + + /** + * The width of the columns are relative to each other. This means the values + * are summarized and divided into portions of columns used.
+ * Example: [10,90] means the first colum consumes 10% and the + * second column consumes 90% of the table width.
+ * The relative width of the columns to set. + */ + public void setColsRelativeWith(float[] cols) + { + colsRelativeWith_ = cols; + } + + /** + * @return Returns the style. + */ + public Style getStyle() + { + return style_; + } + + /** + * @param style + * The style to set. + */ + public void setStyle(Style style) + { + style_ = style; + } + + /** + * @return Returns the width. + */ + public float getWidth() + { + return width_; + } + + /** + * @param width + * The width to set. + */ + public void setWidth(float width) + { + width_ = width; + } + + /** + * @return Returns the maxCols. + */ + public int getMaxCols() + { + return maxCols_; + } + + /** + * @return Returns the name. + */ + public String getName() + { + return name_; + } + + /** + * This method returns a sorted row list beginning with the row number 1. The + * entrys in a row also stored in a {@link java.util.ArrayList}. + * + * @return Returns the sorted (by row number) table rows. + */ + public ArrayList getRows() + { + ArrayList rows = new ArrayList(); + for (int row_idx = 1; row_idx <= rows_.size(); row_idx++) + { + ArrayList row = (ArrayList) rows_.get("" + row_idx); + rows.add(row); + } + return rows; + } + + /** + * Add a comlete table row to the current table. Be carefull usding the + * correct row number because no check is done if a row with the given row + * number does exist! In that case the stored row would be replaced! + * + * @param rowNumber + * the row number to store the row entries + * @param row + * the entry list to store + */ + public void addRow(String rowNumber, ArrayList row) + { + rows_.put(rowNumber, row); + if (row.size() > maxCols_) + { + maxCols_ = row.size(); + } + } + + /** + * The toString method, used for tests or debugging. + */ + public String toString() + { + String the_string = "\n#### TABLE " + name_ + " BEGIN #####"; + the_string += " Width:" + width_ + " max cols:" + maxCols_ + " cols:" + colsRelativeWith_; + the_string += "\nStyle:" + style_; + ArrayList rows = getRows(); + for (int row_idx = 0; row_idx < rows.size(); row_idx++) + { + ArrayList row = (ArrayList) rows.get(row_idx); + String row_prefix = "\n ++ ROW " + row_idx + " ++ "; + for (int entry_idx = 0; entry_idx < row.size(); entry_idx++) + { + the_string += row_prefix + ((Entry) row.get(entry_idx)).toString(); + } + } + the_string += "\n#### TABLE " + name_ + " END #####"; + return the_string; + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index e9bc3cf7..f439cf3c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ -include "signature-standards:sigs-pades", "pdf-as-lib" +include "pdf-as-common", "stamper:stmp-itext", "signature-standards:sigs-pades", "pdf-as-lib", "pdf-as-cli" diff --git a/signature-standards/sigs-pades/build.gradle b/signature-standards/sigs-pades/build.gradle index 4aee14ee..58151a7e 100644 --- a/signature-standards/sigs-pades/build.gradle +++ b/signature-standards/sigs-pades/build.gradle @@ -13,6 +13,7 @@ repositories { dependencies { compile project (':pdf-as-lib') + compile project (':pdf-as-common') compile group: 'commons-collections', name: 'commons-collections', version: '3.2' testCompile group: 'junit', name: 'junit', version: '4.+' } diff --git a/stamper/stmp-itext/.gitignore b/stamper/stmp-itext/.gitignore new file mode 100644 index 00000000..5e56e040 --- /dev/null +++ b/stamper/stmp-itext/.gitignore @@ -0,0 +1 @@ +/bin diff --git a/stamper/stmp-itext/build.gradle b/stamper/stmp-itext/build.gradle new file mode 100644 index 00000000..1495d8af --- /dev/null +++ b/stamper/stmp-itext/build.gradle @@ -0,0 +1,32 @@ +apply plugin: 'java' +apply plugin: 'eclipse' + +jar { + manifest { + attributes 'Implementation-Title': 'PDF-AS Stamper with itext', 'Implementation-Version': version + } +} + +repositories { + mavenCentral() +} + +dependencies { + compile project (':pdf-as-lib') + compile project (':pdf-as-common') + compile group: 'commons-collections', name: 'commons-collections', version: '3.2' + compile group: 'com.lowagie', name: 'itext', version: '4.2.0' + testCompile group: 'junit', name: 'junit', version: '4.+' +} + +test { + systemProperties 'property': 'value' +} + +uploadArchives { + repositories { + flatDir { + dirs 'repos' + } + } +} diff --git a/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextStamper.java b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextStamper.java new file mode 100644 index 00000000..5c0fb7df --- /dev/null +++ b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextStamper.java @@ -0,0 +1,506 @@ +package at.gv.egiz.pdfas.stmp.itext; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.lib.impl.stamping.IPDFStamper; +import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject; +import at.gv.egiz.pdfas.lib.impl.status.PDFObject; +import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; +import at.knowcenter.wag.egov.egiz.table.Entry; +import at.knowcenter.wag.egov.egiz.table.Style; +import at.knowcenter.wag.egov.egiz.table.Table; + +import com.lowagie.text.*; +import com.lowagie.text.pdf.*; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.ArrayList; +import java.util.HashMap; + +public class ITextStamper implements IPDFStamper { + + private static final Logger logger = LoggerFactory.getLogger(ITextStamper.class); + + /** + * The default font definition + */ + private static Font DEFAULT_FONT = new Font(Font.HELVETICA, 8, Font.NORMAL); + + private ISettings settings; + + /** + * This method visualize an abstract table into a corresponding pdf table. The + * new pdf table is redered and get the style information from the abstract + * cell. + * + * @param abstractTable + * the abstract table definition + * @return the new redererd pdf table cell + * @throws PdfAsException + * ErrorCode:220, 221, 222, 223 + * @see com.lowagie.text.pdf.PdfPTable + * @see at.knowcenter.wag.egov.egiz.table.Table + */ + private PdfPTable renderTable(Table abstractTable) throws PdfAsException + { + if (abstractTable == null) + { + PdfAsException pde = new PdfAsException("Table is not defined."); + throw pde; + } + PdfPTable pdf_table = null; + float[] cols = abstractTable.getColsRelativeWith(); + int max_cols = abstractTable.getMaxCols(); + if (cols == null) + { + cols = new float[max_cols]; + // set the column ratio for all columns to 1 + for (int cols_idx = 0; cols_idx < cols.length; cols_idx++) + { + cols[cols_idx] = 1; + } + } + pdf_table = new PdfPTable(cols); + pdf_table.setWidthPercentage(abstractTable.getWidth()); + Style table_style = abstractTable.getStyle(); + setCellStyle(pdf_table.getDefaultCell(), table_style, Entry.TYPE_TABLE); + + ArrayList rows = abstractTable.getRows(); + for (int row_idx = 0; row_idx < rows.size(); row_idx++) + { + ArrayList row = (ArrayList) rows.get(row_idx); + logger.debug("## Row:" + row_idx + " ## of table:" + abstractTable.getName()); + for (int entry_idx = 0; entry_idx < row.size(); entry_idx++) + { + Entry cell = (Entry) row.get(entry_idx); + // 03.11.2010 changed by exthex - swapped the two params, was probably a bug + Style inherit_style = Style.doInherit(table_style, cell.getStyle()); + cell.setStyle(inherit_style); + logger.debug(cell.toString()); + PdfPCell pdf_cell = renderCell(cell); + if (cell.getColSpan() > 1) + { + pdf_cell.setColspan(cell.getColSpan()); + } + if (cell.isNoWrap()) + { + pdf_cell.setNoWrap(true); + } + // System.err.println("valign:" + pdf_cell.getVerticalAlignment() + " + // halign:" + + // pdf_cell.getHorizontalAlignment()); + pdf_table.addCell(pdf_cell); + } + pdf_table.completeRow(); + } + logger.debug("render table:" + abstractTable.getName()); + return pdf_table; + } + + /** + * Map the style align definitions to IText's align statements + */ + private static HashMap alignMap_ = new HashMap(); + + /** + * Map the font definitions to IText's font statements + */ + private static HashMap fontMap_ = new HashMap(); + + static { + initStyleMaps(); + } + + /** + * This method initialize the style maps. It maps the style style definitions + * to IText styles. + */ + private static void initStyleMaps() + { + alignMap_.put(Style.TOP, new Integer(Element.ALIGN_TOP)); + alignMap_.put(Style.MIDDLE, new Integer(Element.ALIGN_MIDDLE)); + alignMap_.put(Style.BOTTOM, new Integer(Element.ALIGN_BOTTOM)); + alignMap_.put(Style.LEFT, new Integer(Element.ALIGN_LEFT)); + alignMap_.put(Style.CENTER, new Integer(Element.ALIGN_CENTER)); + alignMap_.put(Style.RIGHT, new Integer(Element.ALIGN_RIGHT)); + + fontMap_.put(Style.HELVETICA, new Integer(Font.HELVETICA)); + fontMap_.put(Style.TIMES_ROMAN, new Integer(Font.TIMES_ROMAN)); + fontMap_.put(Style.COURIER, new Integer(Font.COURIER)); + fontMap_.put(Style.NORMAL, new Integer(Font.NORMAL)); + fontMap_.put(Style.BOLD, new Integer(Font.BOLD)); + fontMap_.put(Style.ITALIC, new Integer(Font.ITALIC)); + fontMap_.put(Style.BOLDITALIC, new Integer(Font.BOLDITALIC)); + fontMap_.put(Style.UNDERLINE, new Integer(Font.UNDERLINE)); + fontMap_.put(Style.STRIKETHRU, new Integer(Font.STRIKETHRU)); + } + + /** + * This method maps the table cell definitions to the pdfCell element. + * + * @param pdfCell + * the pdf cell to be styled + * @param cellStyle + * the abstract style definition + * @param type + * type of the cell to render - the appropriate style will be set + * @see com.lowagie.text.pdf.PdfPCell + * @see at.knowcenter.wag.egov.egiz.table.Style + */ + private void setCellStyle(PdfPCell pdfCell, Style cellStyle, int type) + { + if (cellStyle != null) + { + if (cellStyle.getBgColor() != null) + { + pdfCell.setBackgroundColor(cellStyle.getBgColor()); + } + pdfCell.setPadding(cellStyle.getPadding()); + //exthex - fix for not exactly vertically centered text + pdfCell.setUseAscender(true); + + if (cellStyle.getBorder() > 0) + { + pdfCell.setBorderWidth(cellStyle.getBorder()); + } + else + { + pdfCell.setBorder(0); + } + int align = -1; + if (type == Entry.TYPE_VALUE && cellStyle.getValueVAlign() != null) + align = ((Integer) alignMap_.get(cellStyle.getValueVAlign())).intValue(); + //Note: to change the default valign of images to those of values, change the if construct below + else if (type == Entry.TYPE_IMAGE && cellStyle.getImageVAlign() != null) + align = ((Integer) alignMap_.get(cellStyle.getImageVAlign())).intValue(); + else if (cellStyle.getVAlign() != null) + + if(alignMap_.get(cellStyle.getVAlign()) == null) { + align = -1; + } else { + align = alignMap_.get(cellStyle.getVAlign()).intValue(); + } + if (align != -1) + pdfCell.setVerticalAlignment(align); + + align = -1; + if (type == Entry.TYPE_VALUE && cellStyle.getValueHAlign() != null) + align = ((Integer) alignMap_.get(cellStyle.getValueHAlign())).intValue(); + //Note: to change the default halign of images to those of values, change the if construct below + else if (type == Entry.TYPE_IMAGE && cellStyle.getImageHAlign() != null) + align = ((Integer) alignMap_.get(cellStyle.getImageHAlign())).intValue(); + else if (cellStyle.getHAlign() != null) + align = ((Integer) alignMap_.get(cellStyle.getHAlign())).intValue(); + if (align != -1) + pdfCell.setHorizontalAlignment(align); + } + } + + /** + * Creates a custom + * @param fontString + * @return + * @throws PdfAsException + */ + private Font getCellTrueTypeFont(String fontString) throws PdfAsException { + float fontSize=8; + String fontName = fontString.replaceFirst("TTF:", ""); + String[] split = fontName.split(","); + if(split.length>1) + { + fontName = split[0].trim(); + try + { + fontSize = Float.parseFloat(split[1].trim()); + }catch (NumberFormatException e) + { + logger.error("Unable to parse fontsize:"+fontString); + } + } + logger.debug("TrueType Font detected:"+fontName +" ("+fontSize+")"); + + //try { + + Font font = new Font(fontMap_.get(fontString)); + //Font font = (Font) fontMap_.get(fontString); + + // TODO: implement FONT resources via settings path! + /*if (font == null) { + logger.debug("Font \"" + fontString + "\" not in cache. Instantiating font."); + String fontPath = SettingsReader.RESOURCES_PATH + "fonts" + File.separator + fontName; + logger.debug("Instantiating \"" + fontPath + "\"."); + + font = new Font(BaseFont.createFont(fontPath, BaseFont.WINANSI, true), fontSize); + fontMap_.put(fontString, font); + } */ + return font; + // } catch (DocumentException e) { + // throw new PdfAsException(e.getMessage()); + //} catch (IOException e) { + // throw new PdfAsException(e.getMessage()); + //} + } + + + /** + * This method maps the cell font definition to the iText Font Object + * + * @param fontString + * @return the corresponding iText Font Object + * @see com.lowagie.text.Font + */ + private Font getCellFont(String fontString) + { + Font font = DEFAULT_FONT; + if (fontString == null) + { + return font; + } + Object cache_font = fontMap_.get(fontString); + if (cache_font != null) + { + return (Font) cache_font; + } + String[] font_arr = fontString.split(","); + if (font_arr.length != 3) + { + return font; + } + Object font_face = fontMap_.get(font_arr[0]); + if (font_face == null) + { + return font; + } + Object font_weight = fontMap_.get(font_arr[2]); + if (font_weight == null) + { + return font; + } + int face = ((Integer) font_face).intValue(); + float height = Float.parseFloat(font_arr[1]); + int weight = ((Integer) font_weight).intValue(); + + font = new Font(face, height, weight); + //fontMap_.put(fontString, font); + return font; + } + + /** + * This method visualize an abstract table cell into a corresponding pdf table + * cell. The new pdf table cell is redered and get the style information from + * the abstract cell. Following types can be rendered: + *
    + *
  • text statements
  • + *
  • images
  • + *
  • tables
  • + *
+ * + * @param abstractCell + * the abstract cell definition + * @return the new redererd pdf table cell + * @throws PdfAsException + * ErrorCode:220, 221, 222 + * @see com.lowagie.text.pdf.PdfPCell + * @see at.knowcenter.wag.egov.egiz.table.Entry + */ + private PdfPCell renderCell(Entry abstractCell) throws PdfAsException + { + // TODO: read if signature should be PDF/A compatible!! + boolean pdfaValid = false;//PDFASUtils.isPdfAEnabled(sigObject_.getSignatureTypeDefinition().getType()); + + PdfPCell pdf_cell = null; + Style cell_style = abstractCell.getStyle(); + boolean isValue = true; + switch (abstractCell.getType()) + { + case Entry.TYPE_CAPTION: + isValue = false; + case Entry.TYPE_VALUE: + String text = (String) abstractCell.getValue(); + if (text == null) + { + text = ""; + } + String font_string = cell_style.getFont(); + if (abstractCell.getType() == Entry.TYPE_VALUE && cell_style.getValueFont() != null) + { + font_string = cell_style.getValueFont(); + } + + logger.trace("using cell font: "+font_string); + + Font cell_font; + if(font_string.startsWith("TTF:")) + { + cell_font = getCellTrueTypeFont(font_string); + } + else + { + if (pdfaValid) { + throw new PdfAsException("PDF/A modus requires an embedable true type font"); + } + cell_font = getCellFont(font_string); + + } + //TODO: check and maybe remove ... + // exthex + //if (pdfaValid && abstractCell.getType() == Entry.TYPE_VALUE) { + // SubsetLocal.addNonSubsetFont(cell_font.getBaseFont()); + //} + Phrase text_phrase = new Phrase(text, cell_font); + pdf_cell = new PdfPCell(text_phrase); + setCellStyle(pdf_cell, cell_style, (isValue?Entry.TYPE_VALUE:Entry.TYPE_CAPTION)); + break; + case Entry.TYPE_IMAGE: + try + { + String img_ref = (String) abstractCell.getValue(); + // fixed by tknall start + File img_file = new File(img_ref); + if (!img_file.isAbsolute()) { + logger.debug("Image file declaration is relative. Prepending path of resources directory."); + //TODO: implement settings .... + img_file = new File(settings.getWorkingDirectory() + File.separator + img_ref); + } else { + logger.debug("Image file declaration is absolute. Skipping file relocation."); + } +// String img_location = SettingsReader.relocateFile(img_ref); +// File img_file = new File (img_location); + if (!img_file.exists()) + { + logger.debug("Image file \"" + img_file.getCanonicalPath() + "\" doesn't exist."); + throw new PdfAsException("Image file \"" + img_file.getCanonicalPath() + "\" doesn't exist."); + } + Image image = Image.getInstance(img_file.getCanonicalPath()); + logger.debug("Using image file \"" + img_file.getCanonicalPath() + "\"."); + + image.scaleToFit(80.0f, 80.0f); + boolean fit = true; + Style.ImageScaleToFit istf = cell_style.getImageScaleToFit(); + if (istf != null) + { + image.scaleToFit(istf.getWidth(), istf.getHeight()); + fit = false; + } + pdf_cell = new PdfPCell(image, fit); + setCellStyle(pdf_cell, cell_style, Entry.TYPE_IMAGE); + } + catch (BadElementException e) + { + logger.error("BadElementException:" + e.getMessage()); + PdfAsException pde = new PdfAsException("Unable to create PDF table."); + throw pde; + } + catch (MalformedURLException e) + { + logger.error("MalformedURLException:" + e.getMessage()); + PdfAsException pde = new PdfAsException("Unable to create PDF table."); + throw pde; + } + catch (IOException e) + { + logger.error("Error Code: 222, IOException:" + e.getMessage()); + PdfAsException pde = new PdfAsException("Unable to create PDF table, unable to load image."); + throw pde; + } + break; + case Entry.TYPE_TABLE: + Table table = (Table) abstractCell.getValue(); + // inherit the style from the parent table + Style inherit_style = Style.doInherit(table.getStyle(), cell_style); + table.setStyle(inherit_style); + PdfPTable pdf_table = renderTable(table); + pdf_cell = new PdfPCell(pdf_table); + // The default new PdfPCell has a default border of 15. + // For blocks without border and subtables this results + // in a border to be drawn around the cell. + // ==> no border on default + pdf_cell.setBorder(0); + break; + } + return pdf_cell; + } + + public IPDFVisualObject createVisualPDFObject(PDFObject pdf, Table table) { + + // TODO: Adapt PDFSignatureObjectIText to render PDFPTable to iTextVisualObject from table + try { + PdfPTable pdfPTable = renderTable(table); + + ITextVisualObject iTextVisualObject = new ITextVisualObject(pdfPTable); + + return iTextVisualObject; + } catch (PdfAsException e) { + e.printStackTrace(); + return null; + } + } + + public byte[] writeVisualObject(IPDFVisualObject visualObject, PositioningInstruction positioningInstruction, + byte[] pdfData) throws PdfAsException { + try { + + ITextVisualObject object = null; + if(visualObject instanceof ITextVisualObject) { + object = (ITextVisualObject)visualObject; + } + + if(object == null) { + //TODO: exception! + return null; + } + + PdfReader reader = new PdfReader(pdfData); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + PdfStamper stamper = new PdfStamper(reader, baos, reader.getPdfVersion(), true); + + int pages = reader.getNumberOfPages(); + int targetPage = positioningInstruction.getPage(); + + // TODO: maybe add new page ... + if(positioningInstruction.isMakeNewPage()) { + Rectangle rect = reader.getPageSize(pages); + stamper.insertPage(pages + 1, new Rectangle(rect)); + targetPage = pages + 1; + } + + if (positioningInstruction.getPage() < 1 || + positioningInstruction.getPage() > stamper.getReader().getNumberOfPages()) + { + throw new PdfAsException("The provided page (=" + + positioningInstruction.getPage() + ") is out of range."); + } + + PdfContentByte content = stamper.getOverContent(targetPage); + + PdfPTable table = object.getTable(); + + table.writeSelectedRows(0, -1, positioningInstruction.getX(), + positioningInstruction.getY(), content); + + stamper.close(); + + baos.close(); + + return baos.toByteArray(); + + } catch (IOException e) { + logger.error(e.getMessage(), e); + } catch (DocumentException e) { + logger.error(e.getMessage(), e); + } + return null; + } + + public void setSettings(ISettings settings) { + this.settings = settings; + } +} \ No newline at end of file diff --git a/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextVisualObject.java b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextVisualObject.java new file mode 100644 index 00000000..76b8b0fc --- /dev/null +++ b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/ITextVisualObject.java @@ -0,0 +1,61 @@ +package at.gv.egiz.pdfas.stmp.itext; + +import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject; +import at.knowcenter.wag.egov.egiz.pdf.Pos; +import com.lowagie.text.pdf.PdfPTable; + +public class ITextVisualObject implements IPDFVisualObject { + + private PdfPTable table; + private float x; + private float y; + private int page; + + public ITextVisualObject(PdfPTable table) { + this.table = table; + } + + public void setWidth(float width) { + table.setTotalWidth(width); + } + + public void fixWidth() { + table.setLockedWidth(true); + } + + public float getHeight() { + return this.table.getTotalHeight(); + } + + public float getWidth() { + return this.table.getTotalWidth(); + } + + public void setXPos(float x) { + this.x = x; + } + + public void setYPos(float y) { + this.y = y; + } + + public float getX() { + return x; + } + + public float getY() { + return y; + } + + public int getPage() { + return page; + } + + public void setPage(int page) { + this.page = page; + } + + public PdfPTable getTable() { + return table; + } +} diff --git a/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/package-info.java b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/package-info.java new file mode 100644 index 00000000..53f799b4 --- /dev/null +++ b/stamper/stmp-itext/src/main/java/at/gv/egiz/pdfas/stmp/itext/package-info.java @@ -0,0 +1,2 @@ + +package at.gv.egiz.pdfas.stmp.itext; \ No newline at end of file -- cgit v1.2.3