ObjectBuilder.java
- /*
- * Copyright (C) 2020, Thomas Wolf <thomas.wolf@paranor.ch> and others
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Distribution License v. 1.0 which is available at
- * https://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- package org.eclipse.jgit.lib;
- import static java.nio.charset.StandardCharsets.UTF_8;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.io.UnsupportedEncodingException;
- import java.nio.charset.Charset;
- import java.nio.charset.StandardCharsets;
- import java.text.MessageFormat;
- import java.util.Objects;
- import org.eclipse.jgit.annotations.NonNull;
- import org.eclipse.jgit.annotations.Nullable;
- import org.eclipse.jgit.internal.JGitText;
- import org.eclipse.jgit.util.References;
- /**
- * Common base class for {@link CommitBuilder} and {@link TagBuilder}.
- *
- * @since 5.11
- */
- public abstract class ObjectBuilder {
- /** Byte representation of "encoding". */
- private static final byte[] hencoding = Constants.encodeASCII("encoding"); //$NON-NLS-1$
- private PersonIdent author;
- private GpgSignature gpgSignature;
- private String message;
- private Charset encoding = StandardCharsets.UTF_8;
- /**
- * Retrieves the author of this object.
- *
- * @return the author of this object, or {@code null} if not set yet
- */
- protected PersonIdent getAuthor() {
- return author;
- }
- /**
- * Sets the author (name, email address, and date) of this object.
- *
- * @param newAuthor
- * the new author, must be non-{@code null}
- */
- protected void setAuthor(PersonIdent newAuthor) {
- author = Objects.requireNonNull(newAuthor);
- }
- /**
- * Sets the GPG signature of this object.
- * <p>
- * Note, the signature set here will change the payload of the object, i.e.
- * the output of {@link #build()} will include the signature. Thus, the
- * typical flow will be:
- * <ol>
- * <li>call {@link #build()} without a signature set to obtain payload</li>
- * <li>create {@link GpgSignature} from payload</li>
- * <li>set {@link GpgSignature}</li>
- * </ol>
- * </p>
- *
- * @param gpgSignature
- * the signature to set or {@code null} to unset
- * @since 5.3
- */
- public void setGpgSignature(@Nullable GpgSignature gpgSignature) {
- this.gpgSignature = gpgSignature;
- }
- /**
- * Retrieves the GPG signature of this object.
- *
- * @return the GPG signature of this object, or {@code null} if the object
- * is not signed
- * @since 5.3
- */
- @Nullable
- public GpgSignature getGpgSignature() {
- return gpgSignature;
- }
- /**
- * Retrieves the complete message of the object.
- *
- * @return the complete message; can be {@code null}.
- */
- @Nullable
- public String getMessage() {
- return message;
- }
- /**
- * Sets the message (commit message, or message of an annotated tag).
- *
- * @param message
- * the message.
- */
- public void setMessage(@Nullable String message) {
- this.message = message;
- }
- /**
- * Retrieves the encoding that should be used for the message text.
- *
- * @return the encoding that should be used for the message text.
- */
- @NonNull
- public Charset getEncoding() {
- return encoding;
- }
- /**
- * Sets the encoding for the object message.
- *
- * @param encoding
- * the encoding to use.
- */
- public void setEncoding(@NonNull Charset encoding) {
- this.encoding = encoding;
- }
- /**
- * Format this builder's state as a git object.
- *
- * @return this object in the canonical git format, suitable for storage in
- * a repository.
- * @throws java.io.UnsupportedEncodingException
- * the encoding specified by {@link #getEncoding()} is not
- * supported by this Java runtime.
- */
- @NonNull
- public abstract byte[] build() throws UnsupportedEncodingException;
- /**
- * Writes signature to output as per <a href=
- * "https://github.com/git/git/blob/master/Documentation/technical/signature-format.txt#L66,L89">gpgsig
- * header</a>.
- * <p>
- * CRLF and CR will be sanitized to LF and signature will have a hanging
- * indent of one space starting with line two. A trailing line break is
- * <em>not</em> written; the caller is supposed to terminate the GPG
- * signature header by writing a single newline.
- * </p>
- *
- * @param in
- * signature string with line breaks
- * @param out
- * output stream
- * @param enforceAscii
- * whether to throw {@link IllegalArgumentException} if non-ASCII
- * characters are encountered
- * @throws IOException
- * thrown by the output stream
- * @throws IllegalArgumentException
- * if the signature string contains non 7-bit ASCII chars and
- * {@code enforceAscii == true}
- */
- static void writeMultiLineHeader(@NonNull String in,
- @NonNull OutputStream out, boolean enforceAscii)
- throws IOException, IllegalArgumentException {
- int length = in.length();
- for (int i = 0; i < length; ++i) {
- char ch = in.charAt(i);
- switch (ch) {
- case '\r':
- if (i + 1 < length && in.charAt(i + 1) == '\n') {
- ++i;
- }
- if (i + 1 < length) {
- out.write('\n');
- out.write(' ');
- }
- break;
- case '\n':
- if (i + 1 < length) {
- out.write('\n');
- out.write(' ');
- }
- break;
- default:
- // sanity check
- if (ch > 127 && enforceAscii)
- throw new IllegalArgumentException(MessageFormat
- .format(JGitText.get().notASCIIString, in));
- out.write(ch);
- break;
- }
- }
- }
- /**
- * Writes an "encoding" header.
- *
- * @param encoding
- * to write
- * @param out
- * to write to
- * @throws IOException
- * if writing fails
- */
- static void writeEncoding(@NonNull Charset encoding,
- @NonNull OutputStream out) throws IOException {
- if (!References.isSameObject(encoding, UTF_8)) {
- out.write(hencoding);
- out.write(' ');
- out.write(Constants.encodeASCII(encoding.name()));
- out.write('\n');
- }
- }
- }