diff options
Diffstat (limited to 'pdf-as-lib/src/main/java/at')
11 files changed, 674 insertions, 12 deletions
| 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 index 10391ecc..e26e3fdb 100644 --- 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 @@ -14,8 +14,8 @@ import at.gv.egiz.pdfas.lib.impl.VerifyParameterImpl;  public class PdfAsFactory {  	static { -		//PropertyConfigurator.configure(ClassLoader.getSystemResourceAsStream("resources/log4j.properties")); -		BasicConfigurator.configure(); +		PropertyConfigurator.configure(ClassLoader.getSystemResourceAsStream("resources/log4j.properties")); +		//BasicConfigurator.configure();  	}  	public static PdfAs createPdfAs(File configuration) { 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 4a8e41c3..2f2d47c8 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 @@ -3,6 +3,7 @@ package at.gv.egiz.pdfas.lib.impl;  import java.io.ByteArrayInputStream;  import java.io.ByteArrayOutputStream;  import java.io.File; +import java.io.FileOutputStream;  import java.io.IOException;  import java.io.OutputStream;  import java.util.ArrayList; @@ -35,6 +36,8 @@ 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.configuration.SignatureProfileConfiguration; +import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderData; +import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderExtractor;  import at.gv.egiz.pdfas.lib.impl.positioning.Positioning;  import at.gv.egiz.pdfas.lib.impl.signing.IPdfSigner;  import at.gv.egiz.pdfas.lib.impl.signing.PdfSignerFactory; @@ -105,13 +108,12 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {  			status.getPdfObject().setOriginalDocument(  					parameter.getDataSource().getByteData()); -			// Placeholder search? -			if (placeholderConfiguration.isGlobalPlaceholderEnabled()) { -				// TODO: Do placeholder search -			} -  			this.stampPdf(status); +			FileOutputStream fos = new FileOutputStream("/home/afitzek/qr_2_stamped.pdf"); +			fos.write(status.getPdfObject().getStampedDocument()); +			fos.close(); +			  			/*  			 * if (requestedSignature.isVisual()) {  			 * logger.info("Creating visual siganture block"); // @@ -259,7 +261,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {  					if (verifyFilter != null) {  						List<VerifyResult> results = verifyFilter.verify(  								contentData.toByteArray(), content.getBytes()); -						if(results != null && !results.isEmpty()) { +						if (results != null && !results.isEmpty()) {  							result.addAll(results);  						}  					} @@ -421,6 +423,72 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {  		}  	} +	private boolean checkPlaceholderSignature(OperationStatus status) +			throws PdfAsException, IOException { +		if (status.getPlaceholderConfiguration().isGlobalPlaceholderEnabled()) { +			SignaturePlaceholderData signaturePlaceholderData = SignaturePlaceholderExtractor +					.extract(new ByteArrayInputStream(status.getPdfObject() +							.getOriginalDocument()), null, 1); + +			if (signaturePlaceholderData != null) { +				RequestedSignature requestedSignature = status +						.getRequestedSignature(); + +				if (signaturePlaceholderData.getProfile() != null) { +					requestedSignature +							.setSignatureProfileID(signaturePlaceholderData +									.getProfile()); +				} + +				String signatureProfileID = requestedSignature +						.getSignatureProfileID(); + +				TablePos tablePos = signaturePlaceholderData.getTablePos(); + +				SignatureProfileSettings signatureProfileSettings = TableFactory +						.createProfile(signatureProfileID, settings); + +				Table main = TableFactory.createSigTable( +						signatureProfileSettings, MAIN, settings, +						requestedSignature); + +				IPDFStamper stamper = StamperFactory +						.createDefaultStamper(settings); +				IPDFVisualObject visualObject = stamper.createVisualPDFObject( +						status.getPdfObject(), main); +				 +				PDDocument originalDocument = PDDocument +						.load(new ByteArrayInputStream(status.getPdfObject() +								.getOriginalDocument())); + +				PositioningInstruction positioningInstruction = Positioning +						.determineTablePositioning(tablePos, "", originalDocument, +								visualObject); + +				// ================================================================ +				// StampingStage (visual) -> stamp logical signature block to +				// location (itext) + +				byte[] incrementalUpdate = stamper.writeVisualObject(visualObject, +						positioningInstruction, status.getPdfObject() +								.getOriginalDocument(), signaturePlaceholderData.getPlaceholderName()); + +				SignaturePositionImpl position = new SignaturePositionImpl(); +				position.setX(positioningInstruction.getX()); +				position.setY(positioningInstruction.getY()); +				position.setPage(positioningInstruction.getPage()); +				position.setHeight(visualObject.getHeight()); +				position.setWidth(visualObject.getWidth()); + +				requestedSignature.setSignaturePosition(position); + +				status.getPdfObject().setStampedDocument(incrementalUpdate); +				return true; +			} +		} +		return false; +	} +  	private void stampPdf(OperationStatus status) throws PdfAsException,  			IOException { @@ -429,6 +497,11 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {  		SignatureProfileConfiguration signatureProfileConfiguration = status  				.getSignatureProfileConfiguration(signatureProfileID); +		if (checkPlaceholderSignature(status)) { +			logger.info("Placeholder found for Signature"); +			return; +		} +  		if (requestedSignature.isVisual()) {  			logger.info("Creating visual siganture block");  			// ================================================================ @@ -477,7 +550,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {  			byte[] incrementalUpdate = stamper.writeVisualObject(visualObject,  					positioningInstruction, status.getPdfObject() -							.getOriginalDocument()); +							.getOriginalDocument(), null);  			SignaturePositionImpl position = new SignaturePositionImpl();  			position.setX(positioningInstruction.getX()); diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderContext.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderContext.java new file mode 100644 index 00000000..28a34f6a --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderContext.java @@ -0,0 +1,72 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.gv.egiz.pdfas.lib.impl.placeholder;
 +
 +/**
 + * Store and retrieve {@link SignaturePlaceholderData} in/from a thread local context.
 + * 
 + * @author exthex
 + *
 + */
 +public class SignaturePlaceholderContext {
 +   
 +   private ThreadLocal sigHolder = new ThreadLocal();
 +   
 +   private static SignaturePlaceholderContext instance = new SignaturePlaceholderContext();
 +   
 +   /**
 +    * Constructor. Private because this is a singleton.
 +    */
 +   private SignaturePlaceholderContext() {
 +      
 +   }
 +
 +   /**
 +    * Get the {@link SignaturePlaceholderData} which is currently bound to this thread.
 +    * Might be null.
 +    * 
 +    * @return
 +    */
 +   public static SignaturePlaceholderData getSignaturePlaceholderData(){
 +      return (SignaturePlaceholderData)instance.sigHolder.get();
 +   }
 +
 +   /**
 +    * 
 +    * @return true if there is currently a {@link SignaturePlaceholderData} bound to this thread, false otherwise.
 +    */
 +   public static boolean isSignaturePlaceholderDataSet() {
 +      return instance.sigHolder.get() != null;
 +   }
 +
 +   /**
 +    * Bind a {@link SignaturePlaceholderData} to this thread.
 +    * If the given data is null, the context will be cleared.
 +    * 
 +    * @param data if null, clears the ThreadLocal, else binds the data to the current thread.
 +    */
 +   public static void setSignaturePlaceholderData(SignaturePlaceholderData data) {
 +      instance.sigHolder.set(data);
 +   }
 +}
 diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderData.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderData.java new file mode 100644 index 00000000..d068104a --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderData.java @@ -0,0 +1,152 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.gv.egiz.pdfas.lib.impl.placeholder;
 +
 +import at.knowcenter.wag.egov.egiz.pdf.TablePos;
 +
 +/**
 + * This class represents all the data which can be extracted from a placeholder image.
 + * 
 + * @author exthex
 + *
 + */
 +public class SignaturePlaceholderData {
 +
 +   public static final String ID_KEY = "id";
 +
 +   public static final String PROFILE_KEY = "profile";
 +
 +   public static final String TYPE_KEY = "type";
 +
 +   public static final String SIG_KEY_KEY = "key";
 +
 +   private String profile;
 +
 +   private String type;
 +
 +   private String key;
 +
 +   private String id;
 +
 +   private TablePos tablePos;
 +
 +   private String placeholderName;
 +
 +   /**
 +    * 
 +    * @param profile
 +    * @param type
 +    * @param sigKey
 +    * @param id 
 +    */
 +   public SignaturePlaceholderData(String profile, String type, String sigKey, String id) {
 +      this.profile = profile;
 +      this.type = type;
 +      this.key = sigKey;
 +      this.id = id;
 +   }
 +
 +   /**
 +    * Get the table position for the signature block.<br/>
 +    * The table position is created from the page number, the upper left corner and the width of the placeholder image.
 +    * 
 +    * @return
 +    */
 +   public TablePos getTablePos() {
 +      return tablePos;
 +   }
 +
 +   void setTablePos(TablePos tablePos) {
 +      this.tablePos = tablePos;
 +   }
 +
 +   /**
 +    * The profile name. Might be null if not included in the qr-code.
 +    * 
 +    * @return
 +    */
 +   public String getProfile() {
 +      return profile;
 +   }
 +
 +   void setProfile(String profile) {
 +      this.profile = profile;
 +   }
 +
 +   /**
 +    * The signature type: "textual" or "binary". Might be null if not included in the qr-code.
 +    * @return
 +    */
 +   public String getType() {
 +      return type;
 +   }
 +
 +   void setType(String type) {
 +      this.type = type;
 +   }
 +
 +   /**
 +    * The key identifier for MOA signature. Might be null if not included in the qr-code.
 +    * 
 +    * @return
 +    */
 +   public String getKey() {
 +      return key;
 +   }
 +
 +   void setKey(String key) {
 +      this.key = key;
 +   }
 +
 +   public String toString() {
 +      return getClass().toString() + ": profile=" + profile + "; type=" + type + "; sigKey=" + key + "; table pos=" + tablePos;
 +   }
 +
 +   void setPlaceholderName(String name) {
 +      this.placeholderName = name;
 +   }
 +
 +   /**
 +    * The name of the placeholder image.
 +    * 
 +    * @return
 +    */
 +   public String getPlaceholderName() {
 +      return placeholderName;
 +   }
 +
 +   /**
 +    * The id associated with this placeholder.
 +    * 
 +    * @return
 +    */
 +   public String getId() {
 +      return id;
 +   }
 +
 +   void setId(String id) {
 +      this.id = id;
 +   }
 +
 +}
 diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderExtractor.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderExtractor.java new file mode 100644 index 00000000..eabc27e2 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderExtractor.java @@ -0,0 +1,351 @@ +/**
 + * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
 + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
 + * joint initiative of the Federal Chancellery Austria and Graz University of
 + * Technology.
 + *
 + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 + * the European Commission - subsequent versions of the EUPL (the "Licence");
 + * You may not use this work except in compliance with the Licence.
 + * You may obtain a copy of the Licence at:
 + * http://www.osor.eu/eupl/
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the Licence is distributed on an "AS IS" basis,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the Licence for the specific language governing permissions and
 + * limitations under the Licence.
 + *
 + * This product combines work with different licenses. See the "NOTICE" text
 + * file for details on the various modules and licenses.
 + * The "NOTICE" text file is part of the distribution. Any derivative works
 + * that you distribute must include a readable copy of the "NOTICE" text file.
 + */
 +package at.gv.egiz.pdfas.lib.impl.placeholder;
 +
 +import java.awt.geom.AffineTransform;
 +import java.awt.geom.NoninvertibleTransformException;
 +import java.awt.image.BufferedImage;
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.util.Hashtable;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Vector;
 +
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +import org.apache.pdfbox.cos.COSName;
 +import org.apache.pdfbox.exceptions.WrappedIOException;
 +import org.apache.pdfbox.pdmodel.PDDocument;
 +import org.apache.pdfbox.pdmodel.PDPage;
 +import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObject;
 +import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;
 +import org.apache.pdfbox.util.Matrix;
 +import org.apache.pdfbox.util.PDFOperator;
 +import org.apache.pdfbox.util.PDFStreamEngine;
 +import org.apache.pdfbox.util.ResourceLoader;
 +
 +import at.gv.egiz.pdfas.common.exceptions.PDFIOException;
 +import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
 +import at.gv.egiz.pdfas.common.exceptions.PlaceholderExtractionException;
 +import at.knowcenter.wag.egov.egiz.pdf.TablePos;
 +
 +import com.google.zxing.BarcodeFormat;
 +import com.google.zxing.BinaryBitmap;
 +import com.google.zxing.DecodeHintType;
 +import com.google.zxing.LuminanceSource;
 +import com.google.zxing.MultiFormatReader;
 +import com.google.zxing.NotFoundException;
 +import com.google.zxing.ReaderException;
 +import com.google.zxing.Result;
 +import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
 +import com.google.zxing.common.HybridBinarizer;
 +
 +//////
 +
 +
 +
 +/**
 + * Extract all relevant information from a placeholder image.
 + *
 + * @author exthex
 + *
 + */
 +public class SignaturePlaceholderExtractor extends PDFStreamEngine {
 +   /**
 +    * The log.
 +    */
 +   private static Log log = LogFactory.getLog(SignaturePlaceholderExtractor.class);
 +
 +   public static final String QR_PLACEHOLDER_IDENTIFIER = "PDF-AS-POS";
 +   public static final int PLACEHOLDER_MATCH_MODE_STRICT = 0;
 +   public static final int PLACEHOLDER_MATCH_MODE_MODERATE = 1;
 +   public static final int PLACEHOLDER_MATCH_MODE_LENIENT = 2;
 +   
 +   private List placeholders = new Vector();
 +   private int currentPage = 0;
 +
 +   private SignaturePlaceholderExtractor(String placeholderId, int placeholderMatchMode) throws IOException {
 +      super(ResourceLoader.loadProperties("placeholder/pdfbox-reader.properties",
 +            true));
 +   }
 +
 +   /**
 +    * Search the document for placeholder images and possibly included
 +    * additional info.<br/>
 +    * Searches only for the first placeholder page after page from top.
 +    *
 +    * @param inputStream
 +    * @return all available info from the first found placeholder.
 +    * @throws PDFDocumentException if the document could not be read.
 +    * @throws PlaceholderExtractionException if STRICT matching mode was requested and no suitable placeholder could be found.
 +    */
 +   public static SignaturePlaceholderData extract(InputStream inputStream, String placeholderId, int matchMode)
 +         throws PdfAsException {
 +      SignaturePlaceholderContext.setSignaturePlaceholderData(null);
 +      PDDocument doc = null;
 +      try
 +      {
 +         try {
 +            doc = PDDocument.load(inputStream);
 +         } catch (IOException e) {
 +            throw new PDFIOException("failed to read document", e);
 +         }
 +         SignaturePlaceholderExtractor extractor;
 +         try
 +         {
 +            extractor = new SignaturePlaceholderExtractor(placeholderId, matchMode);
 +         } catch (IOException e2) {
 +            throw new PDFIOException("failed to read document", e2);
 +         }
 +         List pages = doc.getDocumentCatalog().getAllPages();
 +         Iterator iter = pages.iterator();
 +         int pageNr = 0;
 +         while (iter.hasNext()) {
 +            pageNr++;
 +            PDPage page = (PDPage) iter.next();
 +            try {
 +               extractor.setCurrentPage(pageNr);
 +               extractor.processStream( page, page.findResources(), page.getContents().getStream() );
 +               SignaturePlaceholderData ret = matchPlaceholderPage(extractor.placeholders, placeholderId, matchMode);
 +               if (ret != null){
 +            	   SignaturePlaceholderContext.setSignaturePlaceholderData(ret);
 +                  return ret;
 +               }
 +            } catch (IOException e1) {
 +            	throw new PDFIOException("failed to read document", e1);
 +            }
 +
 +         }
 +         if (extractor.placeholders.size() > 0){
 +        	SignaturePlaceholderData ret = matchPlaceholderDocument(extractor.placeholders, placeholderId, matchMode);
 +            SignaturePlaceholderContext.setSignaturePlaceholderData(ret);
 +            return ret;
 +         }
 +         // no placeholders found, apply strict mode if set
 +         if (matchMode == PLACEHOLDER_MATCH_MODE_STRICT) {
 +            throw new PlaceholderExtractionException("no suitable placeholder found and STRICT matching mode requested.");
 +         }
 +
 +         return null;
 +      } finally {
 +         if (doc != null)
 +            try {
 +               doc.close();
 +            } catch (IOException e) {
 +               log.debug("Could not close document.", e);
 +            }
 +      }
 +
 +   }
 +
 +   private static SignaturePlaceholderData matchPlaceholderDocument(
 +         List placeholders, String placeholderId, int matchMode) throws PlaceholderExtractionException {
 +
 +      if (matchMode == PLACEHOLDER_MATCH_MODE_STRICT)
 +         throw new PlaceholderExtractionException("no suitable placeholder found and STRICT matching mode requested.");
 +
 +      if (placeholders.size() == 0)
 +         return null;
 +
 +      for (int i = 0; i < placeholders.size(); i++)
 +      {
 +         SignaturePlaceholderData spd = (SignaturePlaceholderData)placeholders.get(i);
 +         if (spd.getId() == null)
 +            return spd;
 +      }
 +
 +      if (matchMode == PLACEHOLDER_MATCH_MODE_LENIENT)
 +         return (SignaturePlaceholderData)placeholders.get(0);
 +
 +      return null;
 +   }
 +
 +   private static SignaturePlaceholderData matchPlaceholderPage(List placeholders,
 +         String placeholderId, int matchMode) {
 +      if (placeholders.size() == 0)
 +         return null;
 +      for (int i = 0; i < placeholders.size(); i++)
 +      {
 +         SignaturePlaceholderData data = (SignaturePlaceholderData)placeholders.get(i);
 +         if (placeholderId != null && placeholderId.equals(data.getId()))
 +            return data;
 +         if (placeholderId == null && data.getId() == null)
 +            return data;
 +      }
 +      return null;
 +   }
 +
 +   private void setCurrentPage(int pageNr) {
 +      this.currentPage = pageNr;
 +   }
 +
 +   protected void processOperator( PDFOperator operator, List arguments ) throws IOException
 +   {
 +	   String operation = operator.getOperation();
 +	  if( operation.equals( "Do" ) )
 +       {
 +		   COSName objectName = (COSName)arguments.get( 0 );
 +           Map xobjects = getResources().getXObjects();
 +           PDXObject xobject = (PDXObject)xobjects.get( objectName.getName() );
 +           if( xobject instanceof PDXObjectImage )
 +           {
 +        	   try
 +               {
 +                   PDXObjectImage image = (PDXObjectImage)xobject;
 +                   SignaturePlaceholderData data = checkImage(image);
 +                   if (data != null)
 +                   {
 +                      PDPage page = getCurrentPage();
 +                      Matrix ctm = getGraphicsState().getCurrentTransformationMatrix();
 +                      double rotationInRadians = (page.findRotation() * Math.PI)/180;
 +
 +                      AffineTransform rotation = new AffineTransform();
 +                      rotation.setToRotation( rotationInRadians );
 +                      AffineTransform rotationInverse = rotation.createInverse();
 +                      Matrix rotationInverseMatrix = new Matrix();
 +                      rotationInverseMatrix.setFromAffineTransform( rotationInverse );
 +                      Matrix rotationMatrix = new Matrix();
 +                      rotationMatrix.setFromAffineTransform( rotation );
 +
 +                      Matrix unrotatedCTM = ctm.multiply( rotationInverseMatrix );
 +
 +                      float x = unrotatedCTM.getXPosition();
 +                      float y = unrotatedCTM.getYPosition() + unrotatedCTM.getYScale();
 +                      float w = unrotatedCTM.getXScale();
 +
 +                      String posString = "p:" + currentPage + ";x:" + x + ";y:" + y + ";w:" + w;
 +                      try
 +                      {
 +                         data.setTablePos(new TablePos(posString));
 +                         data.setPlaceholderName(objectName.getName());
 +                         placeholders.add(data);
 +                      } catch (PdfAsException e) {
 +                         throw new WrappedIOException(e);
 +                      }
 +                   }
 +               }
 +               catch( NoninvertibleTransformException e )
 +               {
 +                   throw new WrappedIOException( e );
 +               }
 +           }
 +       }
 +       else
 +       {
 +    	   super.processOperator( operator, arguments );
 +       }
 +   }
 +
 +   /**
 +    * Checks an image if it is a placeholder for a signature.
 +    *
 +    * @param image
 +    * @return
 +    * @throws IOException
 +    */
 +   private SignaturePlaceholderData checkImage(PDXObjectImage image) throws IOException {
 +	  BufferedImage bimg = image.getRGBImage();
 +      if (bimg == null) {
 +         String type = image.getSuffix();
 +         if (type != null) {
 +            type = type.toUpperCase() + " images";
 +         } else {
 +            type = "Image type";
 +         }
 +         log.info("Unable to extract image for QRCode analysis. " + type + " not supported. Add additional JAI Image filters to your classpath. Refer to https://jai.dev.java.net. Skipping image.");
 +         return null;
 +      }
 +      if(bimg.getHeight() < 10 || bimg.getWidth() < 10) {
 +         log.debug("Image too small for QRCode. Skipping image.");
 +         return null;
 +      }
 +
 +      LuminanceSource source = new BufferedImageLuminanceSource(bimg);
 +      BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
 +      Result result;
 +      long before = System.currentTimeMillis();
 +      try {
 +    	 Hashtable hints = new Hashtable();
 +         Vector formats = new Vector();
 +         formats.add(BarcodeFormat.QR_CODE);
 +         hints.put(DecodeHintType.POSSIBLE_FORMATS, formats);
 +         result = new MultiFormatReader().decode(bitmap, hints);
 +
 +         String text = result.getText();
 +         String profile = null;
 +         String type = null;
 +         String sigKey = null;
 +         String id = null;
 +         if (text != null) {
 +            if (text.startsWith(QR_PLACEHOLDER_IDENTIFIER)) {
 +               String[] data = text.split(";");
 +               if (data.length > 1) {
 +            	  for (int i = 1; i < data.length; i++) {
 +                     String kvPair = data[i];
 +                     String[] kv = kvPair.split("=");
 +                     if (kv.length != 2) {
 +                        log.debug("Invalid parameter in placeholder data: " + kvPair);
 +                     } else {
 +                        if (kv[0].equalsIgnoreCase(SignaturePlaceholderData.ID_KEY)) {
 +                           id = kv[1];
 +                        } else if (kv[0].equalsIgnoreCase(SignaturePlaceholderData.PROFILE_KEY)) {
 +                           profile = kv[1];
 +                        } else if (kv[0]
 +                              .equalsIgnoreCase(SignaturePlaceholderData.SIG_KEY_KEY)) {
 +                           sigKey = kv[1];
 +                        } else if (kv[0]
 +                              .equalsIgnoreCase(SignaturePlaceholderData.TYPE_KEY)) {
 +                           type = kv[1];
 +                        }
 +                     }
 +                  }
 +               }
 +               return new SignaturePlaceholderData(profile, type, sigKey, id);
 +            } else {
 +               log.warn("QR-Code found but does not start with \"" + QR_PLACEHOLDER_IDENTIFIER + "\". Ignoring QR placeholder.");
 +            }
 +         }
 +      } catch (ReaderException re) {
 +         if (log.isDebugEnabled()) {
 +            log.debug("Could not decode - not a placeholder. needed: "
 +                  + (System.currentTimeMillis() - before));
 +         }
 +         if (!(re instanceof NotFoundException)){
 +            if (log.isInfoEnabled()) {
 +               log.info("Failed to decode image", re);
 +            }
 +         }
 +      } catch(ArrayIndexOutOfBoundsException e){
 +         if (log.isInfoEnabled()) {
 +            log.info("Failed to decode image. Probably a zxing bug", e);
 +         }
 +      }
 +      return null;
 +   }
 +
 +}
 +
 +
 diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/package-info.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/package-info.java new file mode 100644 index 00000000..815565da --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/package-info.java @@ -0,0 +1,8 @@ +/** + *  + */ +/** + * @author afitzek + * + */ +package at.gv.egiz.pdfas.lib.impl.placeholder;
\ 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 index fce18ce7..5c84acfe 100644 --- 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 @@ -9,7 +9,7 @@ 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; +                                    byte[] pdfData, String placeholderName) throws PdfAsException;      public void setSettings(ISettings settings);  } 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 8bf56259..8ae8e377 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 @@ -50,6 +50,10 @@ public class RequestedSignature {      	return this.signatureProfile;      } +    public void setSignatureProfileID(String signatureProfile) { +    	this.signatureProfile = signatureProfile; +    } +          public X509Certificate getCertificate() {      	return this.certificate;      } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifyFilter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifyFilter.java index 7aca582b..53c2e342 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifyFilter.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/IVerifyFilter.java @@ -3,9 +3,11 @@ package at.gv.egiz.pdfas.lib.impl.verify;  import java.util.List;  import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.lib.api.Configuration;  import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;  public interface IVerifyFilter { +	public void setConfiguration(Configuration config);  	public List<VerifyResult> verify(byte[] contentData, byte[] signatureContent) throws PdfAsException;  	public List<FilterEntry> getFiters();  } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BKUSLConnector.java b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BKUSLConnector.java index 3381dca5..deecae21 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BKUSLConnector.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/BKUSLConnector.java @@ -130,7 +130,7 @@ public class BKUSLConnector extends BaseSLConnector {  		try {  			slRequest = SLMarschaller.marshalToString(of  					.createCreateCMSSignatureRequest(request)); -			logger.trace(slRequest); +			logger.debug(slRequest);  			String slResponse = performHttpRequestToBKU(slRequest); diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java index 491c465a..8a7950a4 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/sl/util/ISignatureConnectorSLWrapper.java @@ -47,7 +47,7 @@ public class ISignatureConnectorSLWrapper implements ISignatureConnector {  	}  	public byte[] sign(byte[] input, int[] byteRange) throws PdfAsException { -		CreateCMSSignatureRequestType request = connector.createCMSRequest(input, byteRange); +		CreateCMSSignatureRequestType request = connector.createCMSRequest(input, byteRange);		  		CreateCMSSignatureResponseType response = connector.sendCMSRequest(request);  		return response.getCMSSignature(); | 
