001// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
002//
003// SPDX-License-Identifier: Apache-2.0
004
005package org.pgpainless.signature.consumer;
006
007import java.util.Comparator;
008
009import org.bouncycastle.openpgp.PGPSignature;
010import org.pgpainless.signature.SignatureUtils;
011
012/**
013 * Comparator which sorts signatures based on an ordering and on revocation hardness.
014 *
015 * If a list of signatures gets ordered using this comparator, hard revocations will always
016 * come first.
017 * Further, signatures are ordered by date according to the {@link SignatureCreationDateComparator.Order}.
018 */
019public class SignatureValidityComparator implements Comparator<PGPSignature> {
020
021    private final SignatureCreationDateComparator creationDateComparator;
022
023    /**
024     * Create a new {@link SignatureValidityComparator} which orders signatures the oldest first.
025     * Still, hard revocations will come first.
026     */
027    public SignatureValidityComparator() {
028        this(SignatureCreationDateComparator.DEFAULT_ORDER);
029    }
030
031    /**
032     * Create a new {@link SignatureValidityComparator} which orders signatures following the passed ordering.
033     * Still, hard revocations will come first.
034     */
035    public SignatureValidityComparator(SignatureCreationDateComparator.Order order) {
036        this.creationDateComparator = new SignatureCreationDateComparator(order);
037    }
038
039    @Override
040    public int compare(PGPSignature one, PGPSignature two) {
041        boolean oneIsHard = SignatureUtils.isHardRevocation(one);
042        boolean twoIsHard = SignatureUtils.isHardRevocation(two);
043
044        // both have same "hardness", so compare creation time
045        if (oneIsHard == twoIsHard) {
046            return creationDateComparator.compare(one, two);
047        }
048        // favor the "harder" signature
049        return oneIsHard ? -1 : 1;
050    }
051}