diff options
Diffstat (limited to 'pdf-as-lib/src')
7 files changed, 518 insertions, 513 deletions
| 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 7946f966..25e57188 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 @@ -95,22 +95,23 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {  			}  		} -		if(parameter.getDataSource() == null || parameter.getDataSource().getByteData() == null) { +		if (parameter.getDataSource() == null +				|| parameter.getDataSource().getByteData() == null) {  			throw new PdfAsValidationException("error.pdf.sig.10", null);  		} -		 -		if(parameter.getOutput() == null) { + +		if (parameter.getOutput() == null) {  			throw new PdfAsValidationException("error.pdf.sig.11", null);  		} -		 -		try { -			PDDocument doc = PDDocument.load(new ByteArrayInputStream(parameter.getDataSource().getByteData())); -			PDFUtils.checkPDFPermissions(doc); -			doc.close(); -		} catch(IOException e) { -			throw new PdfAsValidationException("error.pdf.sig.12", null, e); -		} -		 + +		/* +		 * try { PDDocument doc = PDDocument.load(new +		 * ByteArrayInputStream(parameter.getDataSource().getByteData())); +		 * PDFUtils.checkPDFPermissions(doc); doc.close(); } catch(IOException +		 * e) { throw new PdfAsValidationException("error.pdf.sig.12", null, e); +		 * } +		 */ +  		// TODO: verify Sign Parameter  	} @@ -120,8 +121,9 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {  		if (!(parameter.getConfiguration() instanceof ISettings)) {  			throw new PdfAsSettingsException("Invalid settings object!");  		} -		 -		if(parameter.getDataSource() == null || parameter.getDataSource().getByteData() == null) { + +		if (parameter.getDataSource() == null +				|| parameter.getDataSource().getByteData() == null) {  			throw new PdfAsValidationException("error.pdf.verify.01", null);  		} @@ -142,8 +144,16 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {  			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()); + +			PDDocument doc = status.getPdfObject().getDocument(); +			PDFUtils.checkPDFPermissions(doc); + +			// PlaceholderConfiguration placeholderConfiguration = status +			// .getPlaceholderConfiguration();  			RequestedSignature requestedSignature = new RequestedSignature(  					status); @@ -164,11 +174,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {  			// status  			// .getSignatureProfileConfiguration(signatureProfileID); -			// set Original PDF Document Data -			status.getPdfObject().setOriginalDocument( -					parameter.getDataSource().getByteData()); - -			//this.stampPdf(status); +			// this.stampPdf(status);  			// Create signature  			IPdfSigner signer = PdfSignerFactory.createPdfSigner(); @@ -272,7 +278,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {  						if (verifyFilter != null) {  							List<VerifyResult> results = verifyFilter.verify(  									contentData.toByteArray(), -									content.getBytes(),  +									content.getBytes(),  									parameter.getVerificationTime(), bytes);  							if (results != null && !results.isEmpty()) {  								result.addAll(results); @@ -308,7 +314,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {  			throws PdfAsException {  		verifySignParameter(parameter); -		 +  		StatusRequestImpl request = new StatusRequestImpl();  		try { @@ -355,7 +361,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants {  						status.getSignParamter().getDataSource().getByteData());  				// STAMPER! -				//stampPdf(status); +				// stampPdf(status);  				request.setNeedCertificate(false);  				status.setSigningDate(Calendar.getInstance()); diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderFilter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderFilter.java index a4d2c7aa..8e0171fb 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderFilter.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderFilter.java @@ -1,6 +1,5 @@  package at.gv.egiz.pdfas.lib.impl.placeholder; -import java.io.ByteArrayInputStream;  import java.io.IOException;  import at.gv.egiz.pdfas.common.exceptions.PdfAsException; @@ -16,8 +15,7 @@ public class PlaceholderFilter implements IConfigurationConstants {  		if (status.getPlaceholderConfiguration().isGlobalPlaceholderEnabled()) {  			SignaturePlaceholderData signaturePlaceholderData = SignaturePlaceholderExtractor -					.extract(new ByteArrayInputStream(status.getPdfObject() -							.getOriginalDocument()), null, 1); +					.extract(status.getPdfObject().getDocument(), null, 1);  			return signaturePlaceholderData;  			/* 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 index 816ca04f..93162bd3 100644 --- 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 @@ -89,8 +89,6 @@ import com.google.zxing.common.HybridBinarizer;  ////// - -  /**   * Extract all relevant information from a placeholder image.   * @@ -98,279 +96,276 @@ import com.google.zxing.common.HybridBinarizer;   *   */  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<SignaturePlaceholderData> placeholders = new Vector<SignaturePlaceholderData>(); -   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("error.pdf.io.04", e); -         } -         SignaturePlaceholderExtractor extractor; -         try -         { -            extractor = new SignaturePlaceholderExtractor(placeholderId, matchMode); -         } catch (IOException e2) { -            throw new PDFIOException("error.pdf.io.04", 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("error.pdf.io.04", 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("error.pdf.stamp.09"); -         } - -         return null; -      } finally { -         if (doc != null) -            try { -               doc.close(); -            } catch (IOException e) { -               log.debug("Could not close document.", e); -            } -      } - -   } - -   private static SignaturePlaceholderData matchPlaceholderDocument( -         List<SignaturePlaceholderData> placeholders, String placeholderId, int matchMode) throws PlaceholderExtractionException { - -      if (matchMode == PLACEHOLDER_MATCH_MODE_STRICT) -         throw new PlaceholderExtractionException("error.pdf.stamp.09"); - -      if (placeholders.size() == 0) -         return null; - -      for (int i = 0; i < placeholders.size(); i++) -      { -         SignaturePlaceholderData spd = placeholders.get(i); -         if (spd.getId() == null) -            return spd; -      } - -      if (matchMode == PLACEHOLDER_MATCH_MODE_LENIENT) -         return placeholders.get(0); - -      return null; -   } - -   private static SignaturePlaceholderData matchPlaceholderPage(List<SignaturePlaceholderData> placeholders, -         String placeholderId, int matchMode) { -      if (placeholders.size() == 0) -         return null; -      for (int i = 0; i < placeholders.size(); i++) -      { -         SignaturePlaceholderData data = 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; -   } - -   @Override -   protected void processOperator(PDFOperator operator, List<COSBase> 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<DecodeHintType, Vector<BarcodeFormat>> hints = new Hashtable<DecodeHintType, Vector<BarcodeFormat>>(); -         Vector<BarcodeFormat> formats = new Vector<BarcodeFormat>(); -         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; -   } +	/** +	 * 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<SignaturePlaceholderData> placeholders = new Vector<SignaturePlaceholderData>(); +	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(PDDocument doc, +			String placeholderId, int matchMode) throws PdfAsException { +		SignaturePlaceholderContext.setSignaturePlaceholderData(null); + +		SignaturePlaceholderExtractor extractor; +		try { +			extractor = new SignaturePlaceholderExtractor(placeholderId, +					matchMode); +		} catch (IOException e2) { +			throw new PDFIOException("error.pdf.io.04", 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("error.pdf.io.04", 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("error.pdf.stamp.09"); +		} + +		return null; +	} + +	private static SignaturePlaceholderData matchPlaceholderDocument( +			List<SignaturePlaceholderData> placeholders, String placeholderId, +			int matchMode) throws PlaceholderExtractionException { + +		if (matchMode == PLACEHOLDER_MATCH_MODE_STRICT) +			throw new PlaceholderExtractionException("error.pdf.stamp.09"); + +		if (placeholders.size() == 0) +			return null; + +		for (int i = 0; i < placeholders.size(); i++) { +			SignaturePlaceholderData spd = placeholders.get(i); +			if (spd.getId() == null) +				return spd; +		} + +		if (matchMode == PLACEHOLDER_MATCH_MODE_LENIENT) +			return placeholders.get(0); + +		return null; +	} + +	private static SignaturePlaceholderData matchPlaceholderPage( +			List<SignaturePlaceholderData> placeholders, String placeholderId, +			int matchMode) { +		if (placeholders.size() == 0) +			return null; +		for (int i = 0; i < placeholders.size(); i++) { +			SignaturePlaceholderData data = 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; +	} + +	@Override +	protected void processOperator(PDFOperator operator, List<COSBase> 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<DecodeHintType, Vector<BarcodeFormat>> hints = new Hashtable<DecodeHintType, Vector<BarcodeFormat>>(); +			Vector<BarcodeFormat> formats = new Vector<BarcodeFormat>(); +			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/positioning/Positioning.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/positioning/Positioning.java index c8c2f99f..b6405c2d 100644 --- 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 @@ -34,210 +34,196 @@ 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. + * 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, boolean legacy32) throws PdfAsException -    { -        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.rotation); -            } -            // 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, pos.rotation); -            } -            // 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, pos.rotation); -            } -            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, pos.rotation); -        } finally { -            if (pdfDataSource != null) { -                try { -                    pdfDataSource.close(); -                } catch (Exception e) { -                } -            } -        } -    } +	/** +	 * 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, boolean legacy32) throws PdfAsException { +		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 { + +		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.rotation); +		} +		// 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, pos.rotation); +		} +		// 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, pos.rotation); +		} +		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, +				pos.rotation); + +	}  } 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 c04dca59..43d501f1 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 @@ -99,8 +99,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  			FileInputStream fis = new FileInputStream(new File(fisTmpFile)); -			PDDocument doc = PDDocument.load(new ByteArrayInputStream(pdfObject -					.getOriginalDocument())); +			PDDocument doc = pdfObject.getDocument();  			PDSignature signature = new PDSignature();  			signature.setFilter(COSName.getPDFName(signer.getPDFFilter())); // default @@ -198,13 +197,13 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {  				IPDFVisualObject visualObject = stamper.createVisualPDFObject(  						pdfObject, main); -				PDDocument originalDocument = PDDocument +				/*PDDocument originalDocument = PDDocument  						.load(new ByteArrayInputStream(pdfObject.getStatus() -								.getPdfObject().getOriginalDocument())); +								.getPdfObject().getOriginalDocument()));*/  				PositioningInstruction positioningInstruction = Positioning  						.determineTablePositioning(tablePos, "", -								originalDocument, visualObject, +								doc, visualObject,  								legacy32Position);  				SignaturePositionImpl position = new SignaturePositionImpl(); 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 index 05cce46d..6b1edf13 100644 --- 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 @@ -32,8 +32,7 @@ public class PDFAsVisualSignatureProperties extends PDVisibleSigProperties {  			e.printStackTrace();  		}  		try { -			PDDocument origDoc = PDDocument.load(new ByteArrayInputStream( -					object.getOriginalDocument())); +			PDDocument origDoc = object.getDocument();  			designer = new PDFAsVisualSignatureDesigner(origDoc, pos.getPage(), this, pos.isMakeNewPage());  			float posy = designer.getPageHeight() - pos.getY(); 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 index b402d0d2..f8ca3567 100644 --- 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 @@ -23,25 +23,47 @@   ******************************************************************************/  package at.gv.egiz.pdfas.lib.impl.status; +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import org.apache.pdfbox.pdmodel.PDDocument; +  public class PDFObject {  	private OperationStatus status; +	private PDDocument doc;  	private byte[] originalDocument;  	private byte[] signedDocument;  	public PDFObject(OperationStatus operationStatus) {  		this.status = operationStatus;  	} +	 +	@Override +	protected void finalize() throws Throwable { +		super.finalize(); +		if(doc != null) { +			doc.close(); +		} +	}  	public byte[] getOriginalDocument() {  		return originalDocument;  	} -	public void setOriginalDocument(byte[] originalDocument) { +	public void setOriginalDocument(byte[] originalDocument) throws IOException {  		this.originalDocument = originalDocument; +		if(doc != null) { +			doc.close(); +		} +		this.doc = PDDocument.load(new ByteArrayInputStream(this.originalDocument));  	} +	public PDDocument getDocument() { +		return this.doc; +	} +	  	public byte[] getSignedDocument() {  		return signedDocument;  	} | 
