BFO releases Java PDF Library 2.11.24

We've just released our PDF Library version 2.13, the first release in five months. You might be wondering what we've been up to for five months, and based on the changelog the answer is probably "not much". Internally we've restructured a lot of things that needed to be restructured, and there are a lot of relatively small improvements, to the viewer in particular.

One of the bigger changes is the addition of "permissions" to the viewer. Prior to this release, the viewer would limit saving, printing or text-extraction if requested to by the document's encryption, but otherwise you had free reign to edit the document as you wish

Now, with permissions, you can limit this: a permission can be added or removed at any point throughout the life of the document, and the viewer will respect those changes.

Certified documents that limit changes

The most obvious example of this is a digitally signed PDF that prevents further changes, which in PDF are called "certifying" signatures. These can be created in Acrobat or with our own API, and can be set to disallow all changes after signing, to allow only edits to form fields, or to allow form edits and annotations to be made.

To respect these restrictions in our viewer you'll need to set a property - this isn't on by default, to ensure that the behaviour out of the box is backwards-compatible. Here's an example:

  java -Dorg.faceless.pdf2.viewer.respectSignatureCertification org.faceless.pdf2.viewer2.PDFViewer

Setting the org.faceless.pdf2.viewer.respectSignatureCertification System property will ensure that when loading a certified document in the viewer, you won't be able to edit unless the author allowed it.

What this means for extenders

This framework isn't limited to signatures. For example, if you've written a custom feature that runs a background task on the viewer, you can temporarily disable the various features that would allow you to modify the PDF to ensure the document stays unchanged while the task is running. You can lock out the ability to save the file unless some external requirement is met. Or you can use your own custom permissions to selectively disable features in response to actions.

The permissions are implemented with two new methods on DocumentPanel:

As well as a new permissionChanged type of DocumentPanelEvent. There are several types of permission, or you can create your own - the main ones are:
Save The right to save the PDF
Print The right to print the PDF
Extract The right to extract the text from the PDF
Assemble The right to modify the page list or document structure - being able to add pages, reorder them, rotate them or delete them (the name is from the PDF specification, and is a little unintuitive)>
FormFill The right to edit the values of existing form fields - this includes digitally signing the PDF in an existing signature field - and to submit the form electronically
Annotate The right to annotate the PDF with notes, stamps, text edits, highlights and so on.
PageEdit The right to modify the content of the page, perhaps by cropping, redacting, flattening the annotations or so on. This is our general catch all for any edits not covered by Assemble, FormFill or Annotate>

So if you've added a custom feature to the PDF API and you want it to respect the permissions, it's pretty easy. Listen for any permissionChanged or activate DocumentPanelEvents, and when you hear them check the appropriate permission on the document panel, and update your enabled status accordingly. For example, if you had a feature that saves the PDF to your own custom store, you might have a DocumentPanelListener like the following:

public void documentUpated(DocumentPanelEvent event) {
    if (event.getType().equals("activate') || event.getType().equals("permissionChanged")) {
         DocumentPanel docpanel = event.getDocumentPanel();
         boolean allowed = docpanel.hasPermission("Save");

The only other thing to add is how the default values of these permissions is determined. By default permissions are always allowed, unless they are restricted by the document's EncryptionHandler, or by a signature. The last piece of this puzzle is the signature restrictions, and that is set on the DocumentPanel via the setSignaturePermissionRestrictions method. If the respectSignatureCertification property is set as described above, when the PDF is set on the document panel, the most restrictive signature on the document will be passed into this method. If later you remove this signature, just pass in null to remove the signatures restrictions.