diff options
Diffstat (limited to 'pdf-as-lib')
16 files changed, 699 insertions, 14 deletions
| diff --git a/pdf-as-lib/build.gradle b/pdf-as-lib/build.gradle index 9e440fb8..81c53dce 100644 --- a/pdf-as-lib/build.gradle +++ b/pdf-as-lib/build.gradle @@ -41,7 +41,7 @@ dependencies {  	compile project (':pdf-as-common')  	compile group: 'org.apache.httpcomponents', name: 'httpmime', version: '4.3.1'  	compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3.1' -	compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '1.8.2' +	compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '1.8.4'  	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' 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 index a2ad3575..3fdfb576 100644 --- 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 @@ -530,7 +530,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {  			return;  		} -		if (requestedSignature.isVisual()) { +		if (requestedSignature.isVisual() && false) {  			logger.info("Creating visual siganture block");  			// ================================================================  			// SignBlockCreationStage (visual) -> create visual signature diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java index d93ff5e1..93c19fe5 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java @@ -36,6 +36,7 @@ import org.apache.pdfbox.exceptions.COSVisitorException;  import org.apache.pdfbox.exceptions.SignatureException;  import org.apache.pdfbox.pdmodel.PDDocument;  import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureOptions;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory; @@ -48,6 +49,7 @@ import at.gv.egiz.pdfas.lib.impl.signing.IPdfSigner;  import at.gv.egiz.pdfas.lib.impl.signing.sig_interface.PDFASSignatureInterface;  import at.gv.egiz.pdfas.lib.impl.stamping.TableFactory;  import at.gv.egiz.pdfas.lib.impl.stamping.ValueResolver; +import at.gv.egiz.pdfas.lib.impl.stamping.pdfbox.PDFAsVisualSignatureProperties;  import at.gv.egiz.pdfas.lib.impl.status.PDFObject;  import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature; @@ -103,8 +105,15 @@ public class PADESPDFBOXSigner implements IPdfSigner {              //signature.setSignDate(signer.getSigningDate());              signer.setPDSignature(signature); +            SignatureOptions options = new SignatureOptions(); -            doc.addSignature(signature, signer); +            // FOR DEVELOPING: Call custom visual signature creation +            PDFAsVisualSignatureProperties properties = new PDFAsVisualSignatureProperties( +            		pdfObject.getStatus().getSettings(), pdfObject); +            properties.buildSignature(); +            options.setVisualSignature(properties.getVisibleSignature()); +             +            doc.addSignature(signature, signer, options);              // pdfbox patched (FIS -> IS)              doc.saveIncremental(fis, fos); diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/CertificateResolver.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/CertificateResolver.java index 0aacb1b0..42f81f42 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/CertificateResolver.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/CertificateResolver.java @@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory;  import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings;  import at.gv.egiz.pdfas.common.utils.DNUtils;  import at.gv.egiz.pdfas.common.utils.OgnlUtils; +import at.gv.egiz.pdfas.lib.impl.status.ICertificateProvider;  import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;  public class CertificateResolver implements IResolver { @@ -69,7 +70,7 @@ public class CertificateResolver implements IResolver {      }      public String resolve(String key, String value, SignatureProfileSettings settings, -    		RequestedSignature signature) { +    		ICertificateProvider signature) {          return OgnlUtils.resolvsOgnlExpression(value, this.ctx);      } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IResolver.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IResolver.java index 4ba365fa..8c38039f 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IResolver.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/IResolver.java @@ -24,6 +24,7 @@  package at.gv.egiz.pdfas.lib.impl.stamping;  import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings; +import at.gv.egiz.pdfas.lib.impl.status.ICertificateProvider;  import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;  /** @@ -35,5 +36,5 @@ import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;   */  public interface IResolver {      public String resolve(String key, String value, SignatureProfileSettings settings, -    		RequestedSignature signature); +    		ICertificateProvider signature);  } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/TableFactory.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/TableFactory.java index cbda8e95..038e9a88 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/TableFactory.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/TableFactory.java @@ -26,6 +26,7 @@ package at.gv.egiz.pdfas.lib.impl.stamping;  import at.gv.egiz.pdfas.common.settings.IProfileConstants;  import at.gv.egiz.pdfas.common.settings.ISettings;  import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings; +import at.gv.egiz.pdfas.lib.impl.status.ICertificateProvider;  import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;  import at.knowcenter.wag.egov.egiz.pdf.sig.SignatureEntry;  import at.knowcenter.wag.egov.egiz.table.Entry; @@ -96,7 +97,7 @@ public class TableFactory implements IProfileConstants {       * @see at.knowcenter.wag.egov.egiz.table.Entry       */      public static Table createSigTable(SignatureProfileSettings profile, String tableID, ISettings configuration, -    		RequestedSignature requestedSignature) +    		ICertificateProvider certProvider)      {          String table_key_prefix = SIG_OBJ + profile.getProfileID() + "." + TABLE;          String table_key = table_key_prefix + tableID; @@ -160,7 +161,7 @@ public class TableFactory implements IProfileConstants {                      if (TYPE_TABLE.equals(key))                      {                          // add a table entry -                        Table table = createSigTable(profile, type, configuration, requestedSignature); +                        Table table = createSigTable(profile, type, configuration, certProvider);                          if (table != null)                          {                              Entry entry = new Entry(Entry.TYPE_TABLE, table, key); @@ -188,7 +189,7 @@ public class TableFactory implements IProfileConstants {                      	 ValueResolver resolver = new ValueResolver();                          String value = profile.getValue(key);                          Entry entry = new Entry(Entry.TYPE_VALUE,  -                        		resolver.resolve(key, value, profile, requestedSignature), key); +                        		resolver.resolve(key, value, profile, certProvider), key);                          if (entry != null)                          {                              entry.setColSpan(2); @@ -210,7 +211,7 @@ public class TableFactory implements IProfileConstants {                              c_entry.setStyle(defaultCaptionStyle_);                              ValueResolver resolver = new ValueResolver();                              Entry v_entry = new Entry(Entry.TYPE_VALUE,  -                            		resolver.resolve(key, value, profile, requestedSignature), key); +                            		resolver.resolve(key, value, profile, certProvider), key);                              v_entry.setStyle(defaultValueStyle_);                              if (c_entry != null && v_entry != null)                              { @@ -226,7 +227,7 @@ public class TableFactory implements IProfileConstants {                              ValueResolver resolver = new ValueResolver();                              Entry v_entry = new Entry(Entry.TYPE_VALUE, -                                    resolver.resolve(key, value, profile, requestedSignature), key); +                                    resolver.resolve(key, value, profile, certProvider), key);                              v_entry.setStyle(defaultValueStyle_);                              if (c_entry != null && v_entry != null)                              { diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/ValueResolver.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/ValueResolver.java index dc24f40f..ebd5c962 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/ValueResolver.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/ValueResolver.java @@ -33,6 +33,7 @@ import org.slf4j.LoggerFactory;  import at.gv.egiz.pdfas.common.settings.IProfileConstants;  import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings; +import at.gv.egiz.pdfas.lib.impl.status.ICertificateProvider;  import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;  /** @@ -52,7 +53,7 @@ public class ValueResolver implements IProfileConstants, IResolver {  	public static final String EXP_END = "}";  	public String resolve(String key, String value, -			SignatureProfileSettings settings, RequestedSignature signature) { +			SignatureProfileSettings settings, ICertificateProvider certProvider) {  		logger.debug("Resolving value for key: " + key);  		logger.debug("Resolving value with value: " + value); @@ -72,7 +73,7 @@ public class ValueResolver implements IProfileConstants, IResolver {  			Pattern pattern = Pattern.compile(PatternRegex);  			Matcher matcher = pattern.matcher(value);  			CertificateResolver certificateResolver = new CertificateResolver( -					signature.getCertificate()); +					certProvider.getCertificate());  			String result = "";  			int curidx = 0;  			if (matcher.find()) { @@ -82,7 +83,7 @@ public class ValueResolver implements IProfileConstants, IResolver {  					result += value.substring(curidx, idx);  					curidx = idxe;  					result += certificateResolver.resolve(key, -							matcher.group(1), settings, signature); +							matcher.group(1), settings, certProvider);  				} while (matcher.find());  			} else {  				result = value; diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java new file mode 100644 index 00000000..496bc0d8 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java @@ -0,0 +1,173 @@ +package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; + +import java.io.IOException; +import java.util.ArrayList; + +import org.apache.pdfbox.cos.COSName; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.common.PDStream; +import org.apache.pdfbox.pdmodel.edit.PDPageContentStream; +import org.apache.pdfbox.pdmodel.font.PDType1Font; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSigBuilder; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSignDesigner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.pdfas.lib.test.mains.TestPDFBoxTable; +import at.knowcenter.wag.egov.egiz.table.Entry; +import at.knowcenter.wag.egov.egiz.table.Table; + +public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder { + +	private static final Logger logger = LoggerFactory +			.getLogger(TestPDFBoxTable.class); + +	private static void drawTable(PDPage page, +			PDPageContentStream contentStream, float x, float y, +			Table abstractTable) throws IOException { + +		final int rows = abstractTable.getRows().size(); +		final int cols = abstractTable.getMaxCols(); +		float[] colsSizes = abstractTable.getColsRelativeWith(); +		int max_cols = abstractTable.getMaxCols(); +		if (colsSizes == null) { +			colsSizes = new float[max_cols]; +			// set the column ratio for all columns to 1 +			for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) { +				colsSizes[cols_idx] = 1; +			} +		} + +		logger.info("TOTAL Col: " + abstractTable.getWidth()); + +		float total = 0; + +		for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) { +			total += colsSizes[cols_idx]; +		} + +		for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) { +			colsSizes[cols_idx] = (colsSizes[cols_idx] / total) +					* abstractTable.getWidth(); +		} + +		for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) { +			logger.info("Col: " + cols_idx + " : " + colsSizes[cols_idx]); +		} + +		final float cellMargin = 5f; +		final float rowHeight = 12f + 2 * cellMargin; +		final float tableWidth = abstractTable.getWidth(); +		final float tableHeight = rowHeight * rows; +		final float colWidth = tableWidth / (float) cols; + +		// draw the rows +		float nexty = y; +		for (int i = 0; i <= rows; i++) { +			contentStream.drawLine(x, nexty, x + tableWidth, nexty); +			nexty -= rowHeight; +		} + +		// draw the columns +		float nextx = x; +		for (int i = 0; i <= cols; i++) { +			contentStream.drawLine(nextx, y, nextx, y - tableHeight); +			if (i < colsSizes.length) { +				nextx += (colsSizes != null) ? colsSizes[i] : colWidth; +			} +		} + +		float textx = x + cellMargin; +		float texty = y - 15; +		for (int i = 0; i < abstractTable.getRows().size(); i++) { +			ArrayList row = (ArrayList) abstractTable.getRows().get(i); +			for (int j = 0; j < row.size(); j++) { +				Entry cell = (Entry) row.get(j); +				String text = cell.toString(); +				text = "Hallo"; +				COSName name = COSName.getPDFName("ANDI_TAG!"); +				contentStream.beginMarkedContentSequence(COSName.ALT, name); +				contentStream.beginText(); +				logger.info("Writing: " + textx + " : " + texty + " = " + text); +				contentStream.moveTextPositionByAmount(textx, texty); + +				if (text.contains("\n")) { +					String[] lines = text.split("\n"); +					contentStream.appendRawCommands(10 + " TL\n"); +					for (int k = 0; k < lines.length; k++) { +						contentStream.drawString(lines[k]); +						if (k < lines.length - 1) { +							contentStream.appendRawCommands("T*\n"); +						} +					} +				} else { +					contentStream.drawString(text); +				} +				contentStream.endText(); +				contentStream.endMarkedContentSequence(); +				textx += (colsSizes != null) ? colsSizes[j] : colWidth; +			} +			texty -= rowHeight; +			textx = x + cellMargin; +		} +	} + +	private PDFAsVisualSignatureProperties properties; + +	public PDFAsVisualSignatureBuilder(PDFAsVisualSignatureProperties properties) { +		this.properties = properties; +	} + +	@Override +	public void createTemplate(PDPage page) throws IOException { +		PDDocument template = new PDDocument(); + +		template.addPage(page); +		getStructure().setTemplate(template); +	} + +	@Override +	public void createInnerFormStream(PDDocument template) { +		try { +			PDPageContentStream stream = new PDPageContentStream(template, +					getStructure().getPage()); +			stream.setFont(PDType1Font.HELVETICA_BOLD, 12); +			drawTable(getStructure().getPage(), stream, 0, 0, +					properties.getMainTable()); +			stream.close(); +			PDStream innterFormStream = getStructure().getPage().getContents(); +			getStructure().setInnterFormStream(innterFormStream); +			logger.info("Strean of another form (inner form - it would be inside holder form) has been created"); + +		} catch (Throwable e) { +			e.printStackTrace(); +		} +	} +	 +	   @Override +	    public void injectAppearanceStreams(PDStream holderFormStream, PDStream innterFormStream, PDStream imageFormStream, +	            String imageObjectName, String imageName, String innerFormName, PDVisibleSignDesigner properties) +	            throws IOException +	    { + +	        // 100 means that document width is 100% via the rectangle. if rectangle +	        // is 500px, images 100% is 500px. +	        // String imgFormComment = "q "+imageWidthSize+ " 0 0 50 0 0 cm /" + +	        // imageName + " Do Q\n" + builder.toString(); +	        String imgFormComment = "q " + 100 + " 0 0 50 0 0 cm /" + imageName + " Do Q\n"; +	        String holderFormComment = "q 1 0 0 1 0 0 cm /" + innerFormName + " Do Q \n"; +	        String innerFormComment = "q 1 0 0 1 0 0 cm /" + imageObjectName + " Do Q\n"; + +	        logger.info("Holder Stream: " + getStructure().getInnterFormStream().getInputStreamAsString()); +	         +	        //appendRawCommands(getStructure().getInnterFormStream().createOutputStream(),  +	        //		getStructure().getInnterFormStream().getInputStreamAsString()); +	         +	        appendRawCommands(getStructure().getHolderFormStream().createOutputStream(), holderFormComment); +	        appendRawCommands(getStructure().getInnterFormStream().createOutputStream(), getStructure().getInnterFormStream().getInputStreamAsString()); +	        appendRawCommands(getStructure().getImageFormStream().createOutputStream(), imgFormComment); +	        logger.info("Injected apereance stream to pdf"); + +	    } +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java new file mode 100644 index 00000000..a3d02db2 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java @@ -0,0 +1,70 @@ +package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; + +import iaik.x509.X509Certificate; + +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.IOException; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDFTemplateBuilder; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDFTemplateCreator; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSigProperties; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSignDesigner; + +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings; +import at.gv.egiz.pdfas.lib.impl.stamping.TableFactory; +import at.gv.egiz.pdfas.lib.impl.status.PDFObject; +import at.gv.egiz.pdfas.lib.test.mains.CertificateHolderRequest; +import at.knowcenter.wag.egov.egiz.table.Table; + +public class PDFAsVisualSignatureProperties extends PDVisibleSigProperties { + +	private ISettings settings; + +	private Table main; + +	public PDFAsVisualSignatureProperties(ISettings settings, PDFObject object) { +		this.settings = settings; +		try { +			SignatureProfileSettings profileSettings = TableFactory +					.createProfile("SIGNATURBLOCK_DE", settings); + +			X509Certificate cert = new X509Certificate(new FileInputStream( +					"/home/afitzek/qualified.cer")); + +			CertificateHolderRequest request = new CertificateHolderRequest( +					cert); + +			main = TableFactory.createSigTable(profileSettings, "main", +					settings, request); + +			main.setWidth(400); +		} catch (Throwable e) { +			e.printStackTrace(); +		} +		try { +			PDDocument origDoc = PDDocument.load(new ByteArrayInputStream( +					object.getStampedDocument())); +			PDVisibleSignDesigner designer = new PDVisibleSignDesigner(origDoc, +					new FileInputStream("/home/afitzek/.pdfas/images/signatur-logo_de.png"), 1); + +			this.setPdVisibleSignature(designer); +		} catch (Throwable e) { +			e.printStackTrace(); +		} +	} + +	@Override +	public void buildSignature() throws IOException { +		PDFTemplateBuilder builder = new PDFAsVisualSignatureBuilder(this); +		PDFTemplateCreator creator = new PDFTemplateCreator(builder); +		setVisibleSignature(creator.buildPDF(getPdVisibleSignature())); +	} + +	public Table getMainTable() { +		return main; +	} + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxStamper.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxStamper.java new file mode 100644 index 00000000..559c8c9b --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxStamper.java @@ -0,0 +1,143 @@ +package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; + +import java.io.InputStream; + +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDFTemplateBuilder; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDFTemplateStructure; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSigBuilder; +import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSignDesigner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +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.Table; + +public class PdfBoxStamper implements IPDFStamper { + +	private static final Logger logger = LoggerFactory.getLogger(PdfBoxStamper.class); +	 +	private PDFTemplateBuilder pdfBuilder; +	 +	public PdfBoxStamper() { +		this.pdfBuilder = new PDVisibleSigBuilder(); +	} +	 +	/* +	private InputStream renderTable(Table abstractTable) throws PdfAsException +    { +		logger.info("pdf building has been started"); +        PDFTemplateStructure pdfStructure = pdfBuilder.getStructure(); +        //pdfStructure.setIm +        // we create array of [Text, ImageB, ImageC, ImageI] +        this.pdfBuilder.createProcSetArray(); +          +        //create page +        this.pdfBuilder.createPage(properties); +        PDPage page = pdfStructure.getPage(); + +        //create template +        this.pdfBuilder.createTemplate(page); +        PDDocument template = pdfStructure.getTemplate(); +         +        //create /AcroForm +        this.pdfBuilder.createAcroForm(template); +        PDAcroForm acroForm = pdfStructure.getAcroForm(); + +        // AcroForm contains singature fields +        this.pdfBuilder.createSignatureField(acroForm); +        PDSignatureField pdSignatureField = pdfStructure.getSignatureField(); +         +        // create signature +        this.pdfBuilder.createSignature(pdSignatureField, page, properties.getSignatureFieldName()); +        +        // that is /AcroForm/DR entry +        this.pdfBuilder.createAcroFormDictionary(acroForm, pdSignatureField); +         +        // create AffineTransform +        this.pdfBuilder.createAffineTransform(properties.getAffineTransformParams()); +        AffineTransform transform = pdfStructure.getAffineTransform(); +        +        // rectangle, formatter, image. /AcroForm/DR/XObject contains that form +        this.pdfBuilder.createSignatureRectangle(pdSignatureField, properties); +        this.pdfBuilder.createFormaterRectangle(properties.getFormaterRectangleParams()); +        PDRectangle formater = pdfStructure.getFormaterRectangle(); +        this.pdfBuilder.createSignatureImage(template, properties.getImage()); + +        // create form stream, form and  resource.  +        this.pdfBuilder.createHolderFormStream(template); +        PDStream holderFormStream = pdfStructure.getHolderFormStream(); +        this.pdfBuilder.createHolderFormResources(); +        PDResources holderFormResources = pdfStructure.getHolderFormResources(); +        this.pdfBuilder.createHolderForm(holderFormResources, holderFormStream, formater); +         +        // that is /AP entry the appearance dictionary. +        this.pdfBuilder.createAppearanceDictionary(pdfStructure.getHolderForm(), pdSignatureField); +         +        // inner formstream, form and resource (hlder form containts inner form) +        this.pdfBuilder.createInnerFormStream(template); +        this.pdfBuilder.createInnerFormResource(); +        PDResources innerFormResource = pdfStructure.getInnerFormResources(); +        this.pdfBuilder.createInnerForm(innerFormResource, pdfStructure.getInnterFormStream(), formater); +        PDFormXObject innerForm = pdfStructure.getInnerForm(); +        +        // inner form must be in the holder form as we wrote +        this.pdfBuilder.insertInnerFormToHolerResources(innerForm, holderFormResources); +         +        //  Image form is in this structure: /AcroForm/DR/FRM0/Resources/XObject/n0 +        this.pdfBuilder.createImageFormStream(template); +        PDStream imageFormStream = pdfStructure.getImageFormStream(); +        this.pdfBuilder.createImageFormResources(); +        PDResources imageFormResources = pdfStructure.getImageFormResources(); +        this.pdfBuilder.createImageForm(imageFormResources, innerFormResource, imageFormStream, formater, transform, +                pdfStructure.getImage()); +        +        // now inject procSetArray +        this.pdfBuilder.injectProcSetArray(innerForm, page, innerFormResource, imageFormResources, holderFormResources, +                pdfStructure.getProcSet()); + +        String imgFormName = pdfStructure.getImageFormName(); +        String imgName = pdfStructure.getImageName(); +        String innerFormName = pdfStructure.getInnerFormName(); + +        // now create Streams of AP +        this.pdfBuilder.injectAppearanceStreams(holderFormStream, imageFormStream, imageFormStream, imgFormName, +                imgName, innerFormName, properties); +        this.pdfBuilder.createVisualSignature(template); +        this.pdfBuilder.createWidgetDictionary(pdSignatureField, holderFormResources); +         +        ByteArrayInputStream in = pdfStructure.getTemplateAppearanceStream(); +        logger.info("stream returning started, size= " + in.available()); +         +        // we must close the document +        template.close(); +         +        // return result of the stream  +        return in; +    } +	*/ +	 +	public IPDFVisualObject createVisualPDFObject(PDFObject pdf, Table table) { +		 +		return null; +	} + +	public byte[] writeVisualObject(IPDFVisualObject visualObject, +			PositioningInstruction positioningInstruction, byte[] pdfData, +			String placeholderName) throws PdfAsException { +		// TODO Auto-generated method stub +		return null; +	} + +	public void setSettings(ISettings settings) { +		// TODO Auto-generated method stub +		 +	} + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxVisualObject.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxVisualObject.java new file mode 100644 index 00000000..25028073 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxVisualObject.java @@ -0,0 +1,46 @@ +package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox; + +import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject; + +public class PdfBoxVisualObject implements IPDFVisualObject { + +	public void setWidth(float width) { + +	} + +	public void fixWidth() { +		// TODO Auto-generated method stub +		 +	} + +	public float getHeight() { +		// TODO Auto-generated method stub +		return 0; +	} + +	public float getWidth() { +		// TODO Auto-generated method stub +		return 0; +	} + +	public void setXPos(float x) { +		// TODO Auto-generated method stub +		 +	} + +	public void setYPos(float x) { +		// TODO Auto-generated method stub +		 +	} + +	public int getPage() { +		// TODO Auto-generated method stub +		return 0; +	} + +	public void setPage(int page) { +		// TODO Auto-generated method stub +		 +	} + +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/ICertificateProvider.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/ICertificateProvider.java new file mode 100644 index 00000000..2ae94d2d --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/status/ICertificateProvider.java @@ -0,0 +1,7 @@ +package at.gv.egiz.pdfas.lib.impl.status; + +import iaik.x509.X509Certificate; + +public interface ICertificateProvider { +	public X509Certificate getCertificate(); +} 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 index 63f6a0d7..c9cab906 100644 --- 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 @@ -30,7 +30,7 @@ import at.gv.egiz.pdfas.lib.api.SignaturePosition;  import at.knowcenter.wag.egov.egiz.pdf.TablePos; -public class RequestedSignature { +public class RequestedSignature implements ICertificateProvider {      private String signatureProfile;      private TablePos tablePosition;      private OperationStatus status; diff --git a/pdf-as-lib/src/test/java/at/gv/egiz/pdfas/lib/test/mains/CertificateHolderRequest.java b/pdf-as-lib/src/test/java/at/gv/egiz/pdfas/lib/test/mains/CertificateHolderRequest.java new file mode 100644 index 00000000..6d853f6e --- /dev/null +++ b/pdf-as-lib/src/test/java/at/gv/egiz/pdfas/lib/test/mains/CertificateHolderRequest.java @@ -0,0 +1,18 @@ +package at.gv.egiz.pdfas.lib.test.mains; +import iaik.x509.X509Certificate; +import at.gv.egiz.pdfas.lib.impl.status.ICertificateProvider; + + +public class CertificateHolderRequest implements ICertificateProvider { + +	private X509Certificate cert; +	 +	public CertificateHolderRequest(X509Certificate cert) { +		this.cert = cert; +	} + +	public X509Certificate getCertificate() { +		return cert; +	} + +} diff --git a/pdf-as-lib/src/test/java/at/gv/egiz/pdfas/lib/test/mains/TestPDFBoxTable.java b/pdf-as-lib/src/test/java/at/gv/egiz/pdfas/lib/test/mains/TestPDFBoxTable.java new file mode 100644 index 00000000..cba9b927 --- /dev/null +++ b/pdf-as-lib/src/test/java/at/gv/egiz/pdfas/lib/test/mains/TestPDFBoxTable.java @@ -0,0 +1,207 @@ +package at.gv.egiz.pdfas.lib.test.mains; +import iaik.x509.X509Certificate; + +import java.awt.Graphics; +import java.awt.geom.AffineTransform; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; + +import org.apache.pdfbox.cos.COSName; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.apache.pdfbox.pdmodel.common.PDStream; +import org.apache.pdfbox.pdmodel.edit.PDPageContentStream; +import org.apache.pdfbox.pdmodel.font.PDFont; +import org.apache.pdfbox.pdmodel.font.PDType1Font; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings; +import at.gv.egiz.pdfas.lib.api.PdfAs; +import at.gv.egiz.pdfas.lib.api.PdfAsFactory; +import at.gv.egiz.pdfas.lib.impl.stamping.TableFactory; +import at.knowcenter.wag.egov.egiz.table.Entry; +import at.knowcenter.wag.egov.egiz.table.Style; +import at.knowcenter.wag.egov.egiz.table.Table; + +public class TestPDFBoxTable { + +	private static final Logger logger = LoggerFactory +			.getLogger(TestPDFBoxTable.class); +	 +	private static void drawTable(PDPage page, PDPageContentStream contentStream,  +			float x, float y, Table abstractTable) throws IOException { + +        final int rows = abstractTable.getRows().size(); +        final int cols = abstractTable.getMaxCols(); +        float[] colsSizes = abstractTable.getColsRelativeWith(); +        int max_cols = abstractTable.getMaxCols(); +        if (colsSizes == null) +        { +        	colsSizes = new float[max_cols]; +            // set the column ratio for all columns to 1 +            for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) +            { +            	colsSizes[cols_idx] = 1; +            } +        } +         +        logger.info("TOTAL Col: " + abstractTable.getWidth()); +         +        float total = 0; +         +        for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) +        { +        	total += colsSizes[cols_idx]; +        } +         +        for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) +        { +        	colsSizes[cols_idx] = (colsSizes[cols_idx]/total) * abstractTable.getWidth(); +        } +         +        for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) +        { +        	logger.info("Col: " + cols_idx + " : " + colsSizes[cols_idx]); +        } +         +        final float cellMargin=5f; +        final float rowHeight = 12f + 2 * cellMargin; +        final float tableWidth = abstractTable.getWidth(); +        final float tableHeight = rowHeight * rows; +        final float colWidth = tableWidth/(float)cols; + +        //draw the rows +        float nexty = y ; +        for (int i = 0; i <= rows; i++) { +            contentStream.drawLine(x, nexty, x+tableWidth, nexty); +            nexty-= rowHeight; +        } + +        //draw the columns +        float nextx = x; +        for (int i = 0; i <= cols; i++) { +            contentStream.drawLine(nextx, y, nextx, y-tableHeight); +            if(i < colsSizes.length) { +            	nextx += (colsSizes != null) ? colsSizes[i] : colWidth; +            } +        } +         +        float textx = x+cellMargin; +        float texty = y-15; +        for(int i = 0; i < abstractTable.getRows().size(); i++){ +        	ArrayList row = (ArrayList) abstractTable.getRows().get(i); +            for(int j = 0 ; j < row.size(); j++) { +            	Entry cell = (Entry) row.get(j); +                String text = cell.toString(); +                text = "Hallo"; +                COSName name = COSName.getPDFName("ANDI_TAG!"); +                contentStream.beginMarkedContentSequence(COSName.ALT, name); +                contentStream.beginText(); +                logger.info("Writing: " + textx + " : " + texty + " = " + text); +                contentStream.moveTextPositionByAmount(textx,texty); +                 +                if (text.contains("\n")) { +                    String[] lines = text.split("\n"); +                    contentStream.appendRawCommands(10 + " TL\n"); +                    for (int k = 0; k < lines.length; k++) { +                        contentStream.drawString(lines[k]); +                        if (k < lines.length - 1) { +                            contentStream.appendRawCommands("T*\n"); +                        } +                    } +                } else { +                    contentStream.drawString(text); +                } +                contentStream.endText(); +                contentStream.endMarkedContentSequence(); +                textx += (colsSizes != null) ? colsSizes[j] : colWidth; +            } +            texty-= rowHeight; +            textx = x+cellMargin; +        } +    } +	 +	 +	private static void renderTable(Table abstractTable) { +		 +		ArrayList rows = abstractTable.getRows(); +		Style table_style = abstractTable.getStyle(); +        for (int row_idx = 0; row_idx < rows.size(); row_idx++) +        { +            @SuppressWarnings("rawtypes") +			ArrayList row = (ArrayList) rows.get(row_idx); +            logger.info("## 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.info(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.info("render table:" + abstractTable.getName()); +	} +	 +	public static void main(String[] args) { +		try { +			PdfAs pdfAs = PdfAsFactory.createPdfAs(new File("/home/afitzek/.pdfas/")); +			ISettings settings  =  (ISettings) pdfAs.getConfiguration(); +			SignatureProfileSettings profileSettings =  +					TableFactory.createProfile("SIGNATURBLOCK_DE", settings); +			 +			X509Certificate cert = new X509Certificate(new FileInputStream("/home/afitzek/qualified.cer")); +			 +			CertificateHolderRequest request = new CertificateHolderRequest(cert); +			 +			Table main = TableFactory.createSigTable(profileSettings, "main", settings, request); +		 +			main.setWidth(400); +			 +			renderTable(main); +			 +			PDStream stream1; +			 +			PDDocument document = new PDDocument(); +			PDPage page = new PDPage(); +			page.setMediaBox(new PDRectangle()); +			PDPageContentStream stream = new PDPageContentStream(document, page); +			stream.setFont(PDType1Font.HELVETICA_BOLD , 12); +			drawTable(page, stream, 100, 300, main); +			stream.close(); +			 +			document.addPage(page); +			 +			document.save("/tmp/test.pdf"); +			 +			/* +			FileOutputStream fos = new FileOutputStream("/tmp/buffer.bin"); +			fos.write(page.getContents().getByteArray()); +			fos.close(); +			*/ + +		} catch(Throwable e) { +			e.printStackTrace(); +		} +	} +} diff --git a/pdf-as-lib/src/test/java/at/gv/egiz/pdfas/lib/test/mains/package-info.java b/pdf-as-lib/src/test/java/at/gv/egiz/pdfas/lib/test/mains/package-info.java new file mode 100644 index 00000000..60f666c8 --- /dev/null +++ b/pdf-as-lib/src/test/java/at/gv/egiz/pdfas/lib/test/mains/package-info.java @@ -0,0 +1,8 @@ +/** + *  + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.lib.test.mains;
\ No newline at end of file | 
