/* * Copyright (C) 2018, 2022 Google LLC. 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.transport; import static java.util.Objects.requireNonNull; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.lib.ObjectId; /** * Fetch request from git protocol v2. * *

* This is used as an input to {@link ProtocolV2Hook}. * * @since 5.1 */ public final class FetchV2Request extends FetchRequest { private final List peerHas; private final List wantedRefs; private final boolean doneReceived; private final boolean waitForDone; @NonNull private final List serverOptions; private final boolean sidebandAll; @NonNull private final List packfileUriProtocols; FetchV2Request(@NonNull List peerHas, @NonNull List wantedRefs, @NonNull Set wantIds, @NonNull Set clientShallowCommits, int deepenSince, @NonNull List deepenNots, int depth, @NonNull FilterSpec filterSpec, boolean doneReceived, boolean waitForDone, @NonNull Set clientCapabilities, @Nullable String agent, @NonNull List serverOptions, boolean sidebandAll, @NonNull List packfileUriProtocols, @Nullable String clientSID) { super(wantIds, depth, clientShallowCommits, filterSpec, clientCapabilities, deepenSince, deepenNots, agent, clientSID); this.peerHas = requireNonNull(peerHas); this.wantedRefs = requireNonNull(wantedRefs); this.doneReceived = doneReceived; this.waitForDone = waitForDone; this.serverOptions = requireNonNull(serverOptions); this.sidebandAll = sidebandAll; this.packfileUriProtocols = packfileUriProtocols; } /** * Get object ids received in the "have" lines * * @return object ids received in the "have" lines */ @NonNull List getPeerHas() { return peerHas; } /** * Get list of references received in "want-ref" lines * * @return list of references received in "want-ref" lines * * @since 5.4 */ @NonNull public List getWantedRefs() { return wantedRefs; } /** * Whether the request had a "done" line * * @return true if the request had a "done" line */ boolean wasDoneReceived() { return doneReceived; } /** * Whether the request had a "wait-for-done" line * * @return true if the request had a "wait-for-done" line */ boolean wasWaitForDoneReceived() { return waitForDone; } /** * Options received in server-option lines. The caller can choose to act on * these in an application-specific way * * @return Immutable list of server options received in the request * * @since 5.2 */ @NonNull public List getServerOptions() { return serverOptions; } /** * Whether "sideband-all" was received * * @return true if "sideband-all" was received */ boolean getSidebandAll() { return sidebandAll; } @NonNull List getPackfileUriProtocols() { return packfileUriProtocols; } /** * Get builder * * @return A builder of {@link FetchV2Request}. */ static Builder builder() { return new Builder(); } /** A builder for {@link FetchV2Request}. */ static final class Builder { final List peerHas = new ArrayList<>(); final List wantedRefs = new ArrayList<>(); final Set wantIds = new HashSet<>(); final Set clientShallowCommits = new HashSet<>(); final List deepenNots = new ArrayList<>(); final Set clientCapabilities = new HashSet<>(); int depth; int deepenSince; FilterSpec filterSpec = FilterSpec.NO_FILTER; boolean doneReceived; boolean waitForDone; @Nullable String agent; @Nullable String clientSID; final List serverOptions = new ArrayList<>(); boolean sidebandAll; final List packfileUriProtocols = new ArrayList<>(); private Builder() { } /** * Add object the peer has * * @param objectId * object id received in a "have" line * @return this builder */ Builder addPeerHas(ObjectId objectId) { peerHas.add(objectId); return this; } /** * Add Ref received in "want-ref" line and the object-id it refers to * * @param refName * reference name * @return this builder */ Builder addWantedRef(String refName) { wantedRefs.add(refName); return this; } /** * Add client capability * * @param clientCapability * capability line sent by the client * @return this builder */ Builder addClientCapability(String clientCapability) { clientCapabilities.add(clientCapability); return this; } /** * Add object received in "want" line * * @param wantId * object id received in a "want" line * @return this builder */ Builder addWantId(ObjectId wantId) { wantIds.add(wantId); return this; } /** * Add Object received in a "shallow" line * * @param shallowOid * object id received in a "shallow" line * @return this builder */ Builder addClientShallowCommit(ObjectId shallowOid) { clientShallowCommits.add(shallowOid); return this; } /** * Set depth received in "deepen" line * * @param d * Depth received in a "deepen" line * @return this builder */ Builder setDepth(int d) { depth = d; return this; } /** * Get depth set in request * * @return depth set in the request (via a "deepen" line). Defaulting to * 0 if not set. */ int getDepth() { return depth; } /** * Whether there has been at least one ""deepen not" line * * @return true if there has been at least one "deepen not" line in the * request so far */ boolean hasDeepenNots() { return !deepenNots.isEmpty(); } /** * Add reference received in a "deepen not" line * * @param deepenNot * reference received in a "deepen not" line * @return this builder */ Builder addDeepenNot(String deepenNot) { deepenNots.add(deepenNot); return this; } /** * Set Unix timestamp received in a "deepen since" line * * @param value * Unix timestamp received in a "deepen since" line * @return this builder */ Builder setDeepenSince(int value) { deepenSince = value; return this; } /** * Get shallow since value * * @return shallow since value, sent before in a "deepen since" line. 0 * by default. */ int getDeepenSince() { return deepenSince; } /** * Set filter spec * * @param filter * spec set in a "filter" line * @return this builder */ Builder setFilterSpec(@NonNull FilterSpec filter) { filterSpec = requireNonNull(filter); return this; } /** * Mark that the "done" line has been received. * * @return this builder */ Builder setDoneReceived() { doneReceived = true; return this; } /** * Mark that the "wait-for-done" line has been received. * * @return this builder */ Builder setWaitForDone() { waitForDone = true; return this; } /** * Value of an agent line received after the command and before the * arguments. E.g. "agent=a.b.c/1.0" should set "a.b.c/1.0". * * @param agentValue * the client-supplied agent capability, without the leading * "agent=" * @return this builder */ Builder setAgent(@Nullable String agentValue) { agent = agentValue; return this; } /** * Set value of client-supplied session capability * * @param clientSIDValue * the client-supplied session capability, without the * leading "session-id=" * @return this builder */ Builder setClientSID(@Nullable String clientSIDValue) { clientSID = clientSIDValue; return this; } /** * Records an application-specific option supplied in a server-option * line, for later retrieval with * {@link FetchV2Request#getServerOptions}. * * @param value * the client-supplied server-option capability, without * leading "server-option=". * @return this builder */ Builder addServerOption(@NonNull String value) { serverOptions.add(value); return this; } /** * Set whether client sent "sideband-all * * @param value * true if client sent "sideband-all" * @return this builder */ Builder setSidebandAll(boolean value) { sidebandAll = value; return this; } Builder addPackfileUriProtocol(@NonNull String value) { packfileUriProtocols.add(value); return this; } /** * Build initialized fetch request * * @return Initialized fetch request */ FetchV2Request build() { return new FetchV2Request(peerHas, wantedRefs, wantIds, clientShallowCommits, deepenSince, deepenNots, depth, filterSpec, doneReceived, waitForDone, clientCapabilities, agent, Collections.unmodifiableList(serverOptions), sidebandAll, Collections.unmodifiableList(packfileUriProtocols), clientSID); } } }