All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.europa.esig.dss.diagnostic.PDFRevisionWrapper Maven / Gradle / Ivy

/**
 * DSS - Digital Signature Services
 * Copyright (C) 2015 European Commission, provided under the CEF programme
 * 
 * This file is part of the "DSS - Digital Signature Services" project.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package eu.europa.esig.dss.diagnostic;

import eu.europa.esig.dss.diagnostic.jaxb.XmlByteRange;
import eu.europa.esig.dss.diagnostic.jaxb.XmlDocMDP;
import eu.europa.esig.dss.diagnostic.jaxb.XmlModification;
import eu.europa.esig.dss.diagnostic.jaxb.XmlModificationDetection;
import eu.europa.esig.dss.diagnostic.jaxb.XmlObjectModification;
import eu.europa.esig.dss.diagnostic.jaxb.XmlObjectModifications;
import eu.europa.esig.dss.diagnostic.jaxb.XmlPDFLockDictionary;
import eu.europa.esig.dss.diagnostic.jaxb.XmlPDFRevision;
import eu.europa.esig.dss.diagnostic.jaxb.XmlPDFSignatureField;
import eu.europa.esig.dss.enumerations.CertificationPermission;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * Contains user-friendly methods to extract information from an {@code eu.europa.esig.dss.diagnostic.jaxb.XmlPDFRevision}
 *
 */
public class PDFRevisionWrapper {

    /** Wrapped {@code XmlPDFRevision} */
    private final XmlPDFRevision pdfRevision;

    /**
     * Default constructor
     *
     * @param pdfRevision {@link XmlPDFRevision}
     */
    public PDFRevisionWrapper(XmlPDFRevision pdfRevision) {
        Objects.requireNonNull(pdfRevision, "XmlPDFRevision cannot be null!");
        this.pdfRevision = pdfRevision;
    }

    /**
     * Checks if any visual modifications detected in the PDF
     *
     * @return TRUE if modifications detected in a PDF, FALSE otherwise
     */
    public boolean arePdfModificationsDetected() {
        XmlModificationDetection modificationDetection = pdfRevision.getModificationDetection();
        if (modificationDetection != null) {
            return !modificationDetection.getAnnotationOverlap().isEmpty() ||
                    !modificationDetection.getVisualDifference().isEmpty() ||
                    !modificationDetection.getPageDifference().isEmpty();
        }
        return false;
    }

    /**
     * Returns a list of PDF annotation overlap concerned pages
     *
     * @return a list of page numbers
     */
    public List getPdfAnnotationsOverlapConcernedPages() {
        XmlModificationDetection modificationDetection = pdfRevision.getModificationDetection();
        if (modificationDetection != null) {
            List annotationOverlap = modificationDetection.getAnnotationOverlap();
            return getConcernedPages(annotationOverlap);
        }
        return Collections.emptyList();
    }

    /**
     * Returns a list of PDF visual difference concerned pages
     *
     * @return a list of page numbers
     */
    public List getPdfVisualDifferenceConcernedPages() {
        XmlModificationDetection modificationDetection = pdfRevision.getModificationDetection();
        if (modificationDetection != null) {
            List visualDifference = modificationDetection.getVisualDifference();
            return getConcernedPages(visualDifference);
        }
        return Collections.emptyList();
    }

    /**
     * Returns a list of pages missing/added to the final revision in a comparison with a signed one
     *
     * @return a list of page numbers
     */
    public List getPdfPageDifferenceConcernedPages() {
        XmlModificationDetection modificationDetection = pdfRevision.getModificationDetection();
        if (modificationDetection != null) {
            List pageDifference = modificationDetection.getPageDifference();
            return getConcernedPages(pageDifference);
        }
        return Collections.emptyList();
    }

    /**
     * This method checks whether object modifications are present after the current PDF revisions
     *
     * @return TRUE if PDF has been modified, FALSE otherwise
     */
    public boolean arePdfObjectModificationsDetected() {
        return getPdfObjectModifications() != null;
    }

    /**
     * Returns a list of changes occurred in a PDF after the current signature's revision associated
     * with a signature/document extension
     *
     * @return a list of {@link XmlObjectModification}s
     */
    public List getPdfExtensionChanges() {
        XmlObjectModifications pdfObjectModifications = getPdfObjectModifications();
        if (pdfObjectModifications != null) {
            return pdfObjectModifications.getExtensionChanges();
        }
        return Collections.emptyList();
    }

    /**
     * Returns a list of changes occurred in a PDF after the current signature's revision associated
     * with a signature creation, form filling
     *
     * @return a list of {@link XmlObjectModification}s
     */
    public List getPdfSignatureOrFormFillChanges() {
        XmlObjectModifications pdfObjectModifications = getPdfObjectModifications();
        if (pdfObjectModifications != null) {
            return pdfObjectModifications.getSignatureOrFormFill();
        }
        return Collections.emptyList();
    }

    /**
     * Returns a list of changes occurred in a PDF after the current signature's revision associated
     * with annotation(s) modification
     *
     * @return a list of {@link XmlObjectModification}s
     */
    public List getPdfAnnotationChanges() {
        XmlObjectModifications pdfObjectModifications = getPdfObjectModifications();
        if (pdfObjectModifications != null) {
            return pdfObjectModifications.getAnnotationChanges();
        }
        return Collections.emptyList();
    }

    /**
     * Returns a list of undefined changes occurred in a PDF after the current signature's revision
     *
     * @return a list of {@link XmlObjectModification}s
     */
    public List getPdfUndefinedChanges() {
        XmlObjectModifications pdfObjectModifications = getPdfObjectModifications();
        if (pdfObjectModifications != null) {
            return pdfObjectModifications.getUndefined();
        }
        return Collections.emptyList();
    }

    /**
     * This method returns a list of field names modified after the current signature's revision
     *
     * @return a list of {@link String}s
     */
    public List getModifiedFieldNames() {
        List names = new ArrayList<>();
        XmlObjectModifications pdfObjectModifications = getPdfObjectModifications();
        if (pdfObjectModifications != null) {
            names.addAll(getModifiedFieldNames(pdfObjectModifications.getExtensionChanges()));
            names.addAll(getModifiedFieldNames(pdfObjectModifications.getSignatureOrFormFill()));
            names.addAll(getModifiedFieldNames(pdfObjectModifications.getAnnotationChanges()));
            names.addAll(getModifiedFieldNames(pdfObjectModifications.getUndefined()));
        }
        return names;
    }

    /**
     * Returns the first signature field name
     *
     * @return {@link String} field name
     */
    public String getFirstFieldName() {
        List fields = pdfRevision.getFields();
        if (fields != null && !fields.isEmpty()) {
            return fields.iterator().next().getName();
        }
        return null;
    }

    /**
     * Returns a list of signature field names, where the signature is referenced from
     *
     * @return a list of {@link String} signature field names
     */
    public List getSignatureFieldNames() {
        List names = new ArrayList<>();
        List fields = pdfRevision.getFields();
        if (fields != null && !fields.isEmpty()) {
            for (XmlPDFSignatureField signatureField : fields) {
                names.add(signatureField.getName());
            }
        }
        return names;
    }

    /**
     * Returns the signer's name
     *
     * @return {@link String}
     */
    public String getSignerName() {
        return pdfRevision.getPDFSignatureDictionary().getSignerName();
    }

    /**
     * Returns the PDF signature dictionary /Type value
     *
     * @return {@link String}
     */
    public String getSignatureDictionaryType() {
        return pdfRevision.getPDFSignatureDictionary().getType();
    }

    /**
     * Returns the PDF signature dictionary /Filter value
     *
     * @return {@link String}
     */
    public String getFilter() {
        return pdfRevision.getPDFSignatureDictionary().getFilter();
    }

    /**
     * Returns the PDF signature dictionary /SubFilter value
     *
     * @return {@link String}
     */
    public String getSubFilter() {
        return pdfRevision.getPDFSignatureDictionary().getSubFilter();
    }

    /**
     * Returns the PDF signature dictionary /ContactInfo value
     *
     * @return {@link String}
     */
    public String getContactInfo() {
        return pdfRevision.getPDFSignatureDictionary().getContactInfo();
    }

    /**
     * Returns the PDF signature dictionary /Location value
     *
     * @return {@link String}
     */
    public String getLocation() {
        return pdfRevision.getPDFSignatureDictionary().getLocation();
    }

    /**
     * Returns the PDF signature dictionary /Reason value
     *
     * @return {@link String}
     */
    public String getReason() {
        return pdfRevision.getPDFSignatureDictionary().getReason();
    }

    /**
     * Returns the PDF signature dictionary /ByteRange value
     *
     * @return byte range
     */
    public List getSignatureByteRange() {
        XmlByteRange byteRange = getXmlByteRange();
        if (byteRange != null) {
            return byteRange.getValue();
        }
        return Collections.emptyList();
    }

    /**
     * This method returns whether the PDF signature dictionary /ByteRange is found and valid
     *
     * @return TRUE if the /ByteRange is valid, FALSE otherwise
     */
    public boolean isSignatureByteRangeValid() {
        XmlByteRange byteRange = getXmlByteRange();
        if (byteRange != null) {
            return byteRange.isValid();
        }
        return false;
    }

    private XmlByteRange getXmlByteRange() {
        return pdfRevision.getPDFSignatureDictionary().getSignatureByteRange();
    }

    /**
     * This method returns whether the PDF signature dictionary is consistent across PDF revisions.
     *
     * @return TRUE if the signature dictionary is consistent, FALSE otherwise
     */
    public boolean isPdfSignatureDictionaryConsistent() {
        return pdfRevision.getPDFSignatureDictionary().isConsistent();
    }

    /**
     * Returns a {@code CertificationPermission} value of a /DocMDP dictionary, when present
     *
     * @return {@link CertificationPermission}
     */
    public CertificationPermission getDocMDPPermissions() {
        XmlDocMDP docMDP = pdfRevision.getPDFSignatureDictionary().getDocMDP();
        if (docMDP != null) {
            return docMDP.getPermissions();
        }
        return null;
    }

    /**
     * Returns a /FieldMDP dictionary content, when present
     *
     * @return {@link XmlPDFLockDictionary}
     */
    public XmlPDFLockDictionary getFieldMDP() {
        return pdfRevision.getPDFSignatureDictionary().getFieldMDP();
    }

    /**
     * Returns a /SigFieldLock dictionary, when present
     *
     * @return {@link XmlPDFLockDictionary}
     */
    public XmlPDFLockDictionary getSigFieldLock() {
        List fields = pdfRevision.getFields();
        for (XmlPDFSignatureField field : fields) {
            XmlPDFLockDictionary sigFieldLock = field.getSigFieldLock();
            if (sigFieldLock != null) {
                return sigFieldLock;
            }
        }
        return null;
    }

    private List getConcernedPages(List xmlModifications) {
        List pages = new ArrayList<>();
        for (XmlModification modification : xmlModifications) {
            pages.add(modification.getPage());
        }
        return pages;
    }

    private XmlObjectModifications getPdfObjectModifications() {
        XmlModificationDetection modificationDetection = pdfRevision.getModificationDetection();
        if (modificationDetection != null) {
            return modificationDetection.getObjectModifications();
        }
        return null;
    }

    private List getModifiedFieldNames(List objectModifications) {
        List names = new ArrayList<>();
        for (XmlObjectModification objectModification : objectModifications) {
            String fieldName = objectModification.getFieldName();
            if (fieldName != null) {
                names.add(fieldName);
            }
        }
        return names;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy