001// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
002//
003// SPDX-License-Identifier: Apache-2.0
004
005package org.pgpainless.util;
006
007import java.io.OutputStream;
008
009import org.bouncycastle.bcpg.ArmoredOutputStream;
010
011/**
012 * Factory to create configured {@link ArmoredOutputStream ArmoredOutputStreams}.
013 * The configuration entails setting custom version and comment headers.
014 */
015public final class ArmoredOutputStreamFactory {
016
017    public static final String PGPAINLESS = "PGPainless";
018    private static String version = PGPAINLESS;
019    private static String[] comment = new String[0];
020
021    private ArmoredOutputStreamFactory() {
022
023    }
024
025    /**
026     * Wrap an {@link OutputStream} inside a preconfigured {@link ArmoredOutputStream}.
027     *
028     * @param outputStream inner stream
029     * @return armored output stream
030     */
031    public static ArmoredOutputStream get(OutputStream outputStream) {
032        ArmoredOutputStream armoredOutputStream = new ArmoredOutputStream(outputStream);
033        armoredOutputStream.setHeader(ArmorUtils.HEADER_VERSION, version);
034        for (String comment : comment) {
035            ArmorUtils.addCommentHeader(armoredOutputStream, comment);
036        }
037        return armoredOutputStream;
038    }
039
040    /**
041     * Overwrite the version header of ASCII armors with a custom value.
042     * Newlines in the version info string result in multiple version header entries.
043     *
044     * @param versionString version string
045     */
046    public static void setVersionInfo(String versionString) {
047        if (versionString == null || versionString.trim().isEmpty()) {
048            throw new IllegalArgumentException("Version Info MUST NOT be null NOR empty.");
049        }
050        version = versionString;
051    }
052
053    /**
054     * Reset the version header to its default value of {@link #PGPAINLESS}.
055     */
056    public static void resetVersionInfo() {
057        version = PGPAINLESS;
058    }
059
060    /**
061     * Set a comment header value in the ASCII armor header.
062     * If the comment contains newlines, it will be split into multiple header entries.
063     *
064     * @param commentString comment
065     */
066    public static void setComment(String commentString) {
067        if (commentString == null) {
068            throw new IllegalArgumentException("Comment cannot be null.");
069        }
070        String trimmed = commentString.trim();
071        if (trimmed.isEmpty()) {
072            throw new IllegalArgumentException("Comment cannot be empty.");
073        }
074
075        String[] lines = commentString.split("\n");
076        comment = lines;
077    }
078
079    /**
080     * Reset to the default of no comment headers.
081     */
082    public static void resetComment() {
083        comment = new String[0];
084    }
085}