Switch jgit library to the EDL (3-clause BSD)
[jgit.git] / org.spearce.jgit / src / org / spearce / jgit / lib / Constants.java
blobd1e8a410af7e7b2c8a952f65a9257492e9d37a98
1 /*
2 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
3 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or
8 * without modification, are permitted provided that the following
9 * conditions are met:
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * - Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer in the documentation and/or other materials provided
17 * with the distribution.
19 * - Neither the name of the Git Development Community nor the
20 * names of its contributors may be used to endorse or promote
21 * products derived from this software without specific prior
22 * written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
25 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
26 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 package org.spearce.jgit.lib;
41 import java.nio.charset.Charset;
42 import java.security.MessageDigest;
43 import java.security.NoSuchAlgorithmException;
45 import org.spearce.jgit.errors.CorruptObjectException;
46 import org.spearce.jgit.util.MutableInteger;
48 /** Misc. constants used throughout JGit. */
49 public final class Constants {
50 /** Hash function used natively by Git for all objects. */
51 private static final String HASH_FUNCTION = "SHA-1";
53 /** Length of an object hash. */
54 public static final int OBJECT_ID_LENGTH = 20;
56 /** Special name for the "HEAD" symbolic-ref. */
57 public static final String HEAD = "HEAD";
59 /**
60 * Text string that identifies an object as a commit.
61 * <p>
62 * Commits connect trees into a string of project histories, where each
63 * commit is an assertion that the best way to continue is to use this other
64 * tree (set of files).
66 public static final String TYPE_COMMIT = "commit";
68 /**
69 * Text string that identifies an object as a blob.
70 * <p>
71 * Blobs store whole file revisions. They are used for any user file, as
72 * well as for symlinks. Blobs form the bulk of any project's storage space.
74 public static final String TYPE_BLOB = "blob";
76 /**
77 * Text string that identifies an object as a tree.
78 * <p>
79 * Trees attach object ids (hashes) to names and file modes. The normal use
80 * for a tree is to store a version of a directory and its contents.
82 public static final String TYPE_TREE = "tree";
84 /**
85 * Text string that identifies an object as an annotated tag.
86 * <p>
87 * Annotated tags store a pointer to any other object, and an additional
88 * message. It is most commonly used to record a stable release of the
89 * project.
91 public static final String TYPE_TAG = "tag";
93 private static final byte[] ENCODED_TYPE_COMMIT = encodeASCII(TYPE_COMMIT);
95 private static final byte[] ENCODED_TYPE_BLOB = encodeASCII(TYPE_BLOB);
97 private static final byte[] ENCODED_TYPE_TREE = encodeASCII(TYPE_TREE);
99 private static final byte[] ENCODED_TYPE_TAG = encodeASCII(TYPE_TAG);
101 /** An unknown or invalid object type code. */
102 public static final int OBJ_BAD = -1;
105 * In-pack object type: extended types.
106 * <p>
107 * This header code is reserved for future expansion. It is currently
108 * undefined/unsupported.
110 public static final int OBJ_EXT = 0;
113 * In-pack object type: commit.
114 * <p>
115 * Indicates the associated object is a commit.
116 * <p>
117 * <b>This constant is fixed and is defined by the Git packfile format.</b>
119 * @see #TYPE_COMMIT
121 public static final int OBJ_COMMIT = 1;
124 * In-pack object type: tree.
125 * <p>
126 * Indicates the associated object is a tree.
127 * <p>
128 * <b>This constant is fixed and is defined by the Git packfile format.</b>
130 * @see #TYPE_BLOB
132 public static final int OBJ_TREE = 2;
135 * In-pack object type: blob.
136 * <p>
137 * Indicates the associated object is a blob.
138 * <p>
139 * <b>This constant is fixed and is defined by the Git packfile format.</b>
141 * @see #TYPE_BLOB
143 public static final int OBJ_BLOB = 3;
146 * In-pack object type: annotated tag.
147 * <p>
148 * Indicates the associated object is an annotated tag.
149 * <p>
150 * <b>This constant is fixed and is defined by the Git packfile format.</b>
152 * @see #TYPE_TAG
154 public static final int OBJ_TAG = 4;
156 /** In-pack object type: reserved for future use. */
157 public static final int OBJ_TYPE_5 = 5;
160 * In-pack object type: offset delta
161 * <p>
162 * Objects stored with this type actually have a different type which must
163 * be obtained from their delta base object. Delta objects store only the
164 * changes needed to apply to the base object in order to recover the
165 * original object.
166 * <p>
167 * An offset delta uses a negative offset from the start of this object to
168 * refer to its delta base. The base object must exist in this packfile
169 * (even in the case of a thin pack).
170 * <p>
171 * <b>This constant is fixed and is defined by the Git packfile format.</b>
173 public static final int OBJ_OFS_DELTA = 6;
176 * In-pack object type: reference delta
177 * <p>
178 * Objects stored with this type actually have a different type which must
179 * be obtained from their delta base object. Delta objects store only the
180 * changes needed to apply to the base object in order to recover the
181 * original object.
182 * <p>
183 * A reference delta uses a full object id (hash) to reference the delta
184 * base. The base object is allowed to be omitted from the packfile, but
185 * only in the case of a thin pack being transferred over the network.
186 * <p>
187 * <b>This constant is fixed and is defined by the Git packfile format.</b>
189 public static final int OBJ_REF_DELTA = 7;
191 /** Native character encoding for commit messages, file names... */
192 public static final String CHARACTER_ENCODING = "UTF-8";
194 /** Native character encoding for commit messages, file names... */
195 public static final Charset CHARSET;
197 /** Default main branch name */
198 public static final String MASTER = "master";
200 /** Prefix for branch refs */
201 public static final String HEADS_PREFIX = "refs/heads";
203 /** Prefix for remotes refs */
204 public static final String REMOTES_PREFIX = "refs/remotes";
206 /** Prefix for tag refs */
207 public static final String TAGS_PREFIX = "refs/tags";
210 * Create a new digest function for objects.
212 * @return a new digest object.
213 * @throws RuntimeException
214 * this Java virtual machine does not support the required hash
215 * function. Very unlikely given that JGit uses a hash function
216 * that is in the Java reference specification.
218 public static MessageDigest newMessageDigest() {
219 try {
220 return MessageDigest.getInstance(HASH_FUNCTION);
221 } catch (NoSuchAlgorithmException nsae) {
222 throw new RuntimeException("Required hash function "
223 + HASH_FUNCTION + " not available.", nsae);
228 * Convert an OBJ_* type constant to a TYPE_* type constant.
230 * @param typeCode the type code, from a pack representation.
231 * @return the canonical string name of this type.
233 public static String typeString(final int typeCode) {
234 switch (typeCode) {
235 case OBJ_COMMIT:
236 return TYPE_COMMIT;
237 case OBJ_TREE:
238 return TYPE_TREE;
239 case OBJ_BLOB:
240 return TYPE_BLOB;
241 case OBJ_TAG:
242 return TYPE_TAG;
243 default:
244 throw new IllegalArgumentException("Bad object type: " + typeCode);
249 * Convert an OBJ_* type constant to an ASCII encoded string constant.
250 * <p>
251 * The ASCII encoded string is often the canonical representation of
252 * the type within a loose object header, or within a tag header.
254 * @param typeCode the type code, from a pack representation.
255 * @return the canonical ASCII encoded name of this type.
257 public static byte[] encodedTypeString(final int typeCode) {
258 switch (typeCode) {
259 case OBJ_COMMIT:
260 return ENCODED_TYPE_COMMIT;
261 case OBJ_TREE:
262 return ENCODED_TYPE_TREE;
263 case OBJ_BLOB:
264 return ENCODED_TYPE_BLOB;
265 case OBJ_TAG:
266 return ENCODED_TYPE_TAG;
267 default:
268 throw new IllegalArgumentException("Bad object type: " + typeCode);
273 * Parse an encoded type string into a type constant.
275 * @param id
276 * object id this type string came from; may be null if that is
277 * not known at the time the parse is occurring.
278 * @param typeString
279 * string version of the type code.
280 * @param endMark
281 * character immediately following the type string. Usually ' '
282 * (space) or '\n' (line feed).
283 * @param offset
284 * position within <code>typeString</code> where the parse
285 * should start. Updated with the new position (just past
286 * <code>endMark</code> when the parse is successful.
287 * @return a type code constant (one of {@link #OBJ_BLOB},
288 * {@link #OBJ_COMMIT}, {@link #OBJ_TAG}, {@link #OBJ_TREE}.
289 * @throws CorruptObjectException
290 * there is no valid type identified by <code>typeString</code>.
292 public static int decodeTypeString(final ObjectId id,
293 final byte[] typeString, final byte endMark,
294 final MutableInteger offset) throws CorruptObjectException {
295 try {
296 int position = offset.value;
297 switch (typeString[position]) {
298 case 'b':
299 if (typeString[position + 1] != 'l'
300 || typeString[position + 2] != 'o'
301 || typeString[position + 3] != 'b'
302 || typeString[position + 4] != endMark)
303 throw new CorruptObjectException(id, "invalid type");
304 offset.value = position + 5;
305 return Constants.OBJ_BLOB;
307 case 'c':
308 if (typeString[position + 1] != 'o'
309 || typeString[position + 2] != 'm'
310 || typeString[position + 3] != 'm'
311 || typeString[position + 4] != 'i'
312 || typeString[position + 5] != 't'
313 || typeString[position + 6] != endMark)
314 throw new CorruptObjectException(id, "invalid type");
315 offset.value = position + 7;
316 return Constants.OBJ_COMMIT;
318 case 't':
319 switch (typeString[position + 1]) {
320 case 'a':
321 if (typeString[position + 2] != 'g'
322 || typeString[position + 3] != endMark)
323 throw new CorruptObjectException(id, "invalid type");
324 offset.value = position + 4;
325 return Constants.OBJ_TAG;
327 case 'r':
328 if (typeString[position + 2] != 'e'
329 || typeString[position + 3] != 'e'
330 || typeString[position + 4] != endMark)
331 throw new CorruptObjectException(id, "invalid type");
332 offset.value = position + 5;
333 return Constants.OBJ_TREE;
335 default:
336 throw new CorruptObjectException(id, "invalid type");
339 default:
340 throw new CorruptObjectException(id, "invalid type");
342 } catch (ArrayIndexOutOfBoundsException bad) {
343 throw new CorruptObjectException(id, "invalid type");
348 * Convert an integer into its decimal representation.
350 * @param s
351 * the integer to convert.
352 * @return a decimal representation of the input integer. The returned array
353 * is the smallest array that will hold the value.
355 public static byte[] encodeASCII(final long s) {
356 return encodeASCII(Long.toString(s));
360 * Convert a string to US-ASCII encoding.
362 * @param s
363 * the string to convert. Must not contain any characters over
364 * 127 (outside of 7-bit ASCII).
365 * @return a byte array of the same length as the input string, holding the
366 * same characters, in the same order.
367 * @throws IllegalArgumentException
368 * the input string contains one or more characters outside of
369 * the 7-bit ASCII character space.
371 public static byte[] encodeASCII(final String s) {
372 final byte[] r = new byte[s.length()];
373 for (int k = r.length - 1; k >= 0; k--) {
374 final char c = s.charAt(k);
375 if (c > 127)
376 throw new IllegalArgumentException("Not ASCII string: " + s);
377 r[k] = (byte) c;
379 return r;
382 static {
383 if (OBJECT_ID_LENGTH != newMessageDigest().getDigestLength())
384 throw new LinkageError("Incorrect OBJECT_ID_LENGTH.");
385 CHARSET = Charset.forName(CHARACTER_ENCODING);
388 private Constants() {
389 // Hide the default constructor