View Javadoc
1   /*
2    * Copyright (C) 2018, Google LLC. and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  package org.eclipse.jgit.internal.transport.parser;
11  
12  
13  import java.util.Collections;
14  import java.util.HashMap;
15  import java.util.Map;
16  
17  import org.eclipse.jgit.annotations.NonNull;
18  
19  /**
20   * In a push, the client sends a list of commands. The first command
21   * is special, as it can include a list of capabilities at its end.
22   * <p>
23   * For example:
24   * "oid oid name\0cap1 cap cap3"
25   * <p>
26   * Not to be confused with {@link FirstWant}, nor with the first line
27   * of the reference advertisement parsed by
28   * {@code BasePackConnection.readAdvertisedRefs}.
29   * <p>
30   * This class parses the inputted command line and holds the results:
31   * the actual command line and the capabilities.
32   */
33  public final class FirstCommand {
34  	private final String line;
35  	private final Map<String, String> capabilities;
36  
37  	/**
38  	 * Parse the first line of a receive-pack request.
39  	 *
40  	 * @param line
41  	 *            line from the client.
42  	 * @return an instance of FirstCommand with capabilities parsed out
43  	 */
44  	@NonNull
45  	public static FirstCommand fromLine(String line) {
46  		int nul = line.indexOf('\0');
47  		if (nul < 0) {
48  			return new FirstCommand(line,
49  					Collections.<String, String> emptyMap());
50  		}
51  		String[] splitCapablities = line.substring(nul + 1).split(" "); //$NON-NLS-1$
52  		Map<String, String> options = new HashMap<>();
53  
54  		for (String c : splitCapablities) {
55  			int i = c.indexOf("="); //$NON-NLS-1$
56  			if (i != -1) {
57  				options.put(c.substring(0, i), c.substring(i + 1));
58  			} else {
59  				options.put(c, null);
60  			}
61  		}
62  
63  		return new FirstCommand(line.substring(0, nul),
64  				Collections.<String, String> unmodifiableMap(options));
65  	}
66  
67  	private FirstCommand(String line, Map<String, String> capabilities) {
68  		this.line = line;
69  		this.capabilities = capabilities;
70  	}
71  
72  	/** @return non-capabilities part of the line. */
73  	@NonNull
74  	public String getLine() {
75  		return line;
76  	}
77  
78  	/** @return capabilities parsed from the line, as an immutable map. */
79  	@NonNull
80  	public Map<String, String> getCapabilities() {
81  		return capabilities;
82  	}
83  }