aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src/org/eclipse/jgit/lib/BlobBasedConfig.java
blob: 15341587dddff5e1e3e1b35229daee20cc0724e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
 * Copyright (C) 2009, Constantine Plotnikov <constantine.plotnikov@gmail.com>
 * Copyright (C) 2009, Google Inc.
 * Copyright (C) 2009, JetBrains s.r.o. 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.FileNotFoundException;
import java.io.IOException;
import java.text.MessageFormat;

import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.util.RawParseUtils;

/**
 * Configuration file based on the blobs stored in the repository.
 *
 * This implementation currently only provides reading support, and is primarily
 * useful for supporting the {@code .gitmodules} file.
 */
public class BlobBasedConfig extends Config {
	/**
	 * Parse a configuration from a byte array.
	 *
	 * @param base
	 *            the base configuration file
	 * @param blob
	 *            the byte array, should be UTF-8 encoded text.
	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
	 *             the byte array is not a valid configuration format.
	 */
	public BlobBasedConfig(Config base, byte[] blob)
			throws ConfigInvalidException {
		super(base);
		final String decoded;
		if (isUtf8(blob)) {
			decoded = RawParseUtils.decode(UTF_8, blob, 3, blob.length);
		} else {
			decoded = RawParseUtils.decode(blob);
		}
		fromText(decoded);
	}

	/**
	 * Load a configuration file from a blob.
	 *
	 * @param base
	 *            the base configuration file
	 * @param db
	 *            the repository
	 * @param objectId
	 *            the object identifier
	 * @throws java.io.IOException
	 *             the blob cannot be read from the repository.
	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
	 *             the blob is not a valid configuration format.
	 */
	public BlobBasedConfig(Config base, Repository db, AnyObjectId objectId)
			throws IOException, ConfigInvalidException {
		this(base, read(db, objectId));
	}

	private static byte[] read(Repository db, AnyObjectId blobId)
			throws MissingObjectException, IncorrectObjectTypeException,
			IOException {
		try (ObjectReader or = db.newObjectReader()) {
			return read(or, blobId);
		}
	}

	private static byte[] read(ObjectReader or, AnyObjectId blobId)
			throws MissingObjectException, IncorrectObjectTypeException,
			IOException {
		ObjectLoader loader = or.open(blobId, Constants.OBJ_BLOB);
		return loader.getCachedBytes(Integer.MAX_VALUE);
	}

	/**
	 * Load a configuration file from a blob stored in a specific commit.
	 *
	 * @param base
	 *            the base configuration file
	 * @param db
	 *            the repository containing the objects.
	 * @param treeish
	 *            the tree (or commit) that contains the object
	 * @param path
	 *            the path within the tree
	 * @throws java.io.FileNotFoundException
	 *             the path does not exist in the commit's tree.
	 * @throws java.io.IOException
	 *             the tree and/or blob cannot be accessed.
	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
	 *             the blob is not a valid configuration format.
	 */
	public BlobBasedConfig(Config base, Repository db, AnyObjectId treeish,
			String path) throws FileNotFoundException, IOException,
			ConfigInvalidException {
		this(base, read(db, treeish, path));
	}

	private static byte[] read(Repository db, AnyObjectId treeish, String path)
			throws MissingObjectException, IncorrectObjectTypeException,
			IOException {
		try (ObjectReader or = db.newObjectReader()) {
			TreeWalk tree = TreeWalk.forPath(or, path, asTree(or, treeish));
			if (tree == null)
				throw new FileNotFoundException(MessageFormat.format(JGitText
						.get().entryNotFoundByPath, path));
			return read(or, tree.getObjectId(0));
		}
	}

	private static AnyObjectId asTree(ObjectReader or, AnyObjectId treeish)
			throws MissingObjectException, IncorrectObjectTypeException,
			IOException {
		if (treeish instanceof RevTree)
			return treeish;

		if (treeish instanceof RevCommit
				&& ((RevCommit) treeish).getTree() != null)
			return ((RevCommit) treeish).getTree();

		try (RevWalk rw = new RevWalk(or)) {
			return rw.parseTree(treeish).getId();
		}
	}
}