Switch jgit library to the EDL (3-clause BSD)
[egit/zawir.git] / org.spearce.jgit / src / org / spearce / jgit / lib / Tag.java
blobb3039f25802abdb24fd15dc7ea5e529782273b9c
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.io.BufferedReader;
42 import java.io.ByteArrayInputStream;
43 import java.io.IOException;
44 import java.io.InputStreamReader;
46 import org.spearce.jgit.errors.CorruptObjectException;
47 import org.spearce.jgit.errors.ObjectWritingException;
49 /**
50 * Represents a named reference to another Git object of any type.
52 public class Tag {
53 private final Repository objdb;
55 private ObjectId tagId;
57 private PersonIdent tagger;
59 private String message;
61 private byte[] raw;
63 private String type;
65 private String tag;
67 private ObjectId objId;
69 /**
70 * Construct a new, yet unnamed Tag.
72 * @param db
74 public Tag(final Repository db) {
75 objdb = db;
78 /**
79 * Construct a Tag representing an existing with a known name referencing an known object.
80 * This could be either a simple or annotated tag.
82 * @param db {@link Repository}
83 * @param id target id.
84 * @param refName tag name or null
85 * @param raw data of an annotated tag.
87 public Tag(final Repository db, final ObjectId id, String refName, final byte[] raw) {
88 objdb = db;
89 if (raw != null) {
90 tagId = id;
91 objId = ObjectId.fromString(raw, 7);
92 } else
93 objId = id;
94 if (refName != null && refName.startsWith("refs/tags/"))
95 refName = refName.substring(10);
96 tag = refName;
97 this.raw = raw;
101 * @return tagger of a annotated tag or null
103 public PersonIdent getAuthor() {
104 decode();
105 return tagger;
109 * Set author of an annotated tag.
110 * @param a author identifier as a {@link PersonIdent}
112 public void setAuthor(final PersonIdent a) {
113 tagger = a;
117 * @return comment of an annotated tag, or null
119 public String getMessage() {
120 decode();
121 return message;
124 private void decode() {
125 // FIXME: handle I/O errors
126 if (raw != null) {
127 try {
128 BufferedReader br = new BufferedReader(new InputStreamReader(
129 new ByteArrayInputStream(raw)));
130 String n = br.readLine();
131 if (n == null || !n.startsWith("object ")) {
132 throw new CorruptObjectException(tagId, "no object");
134 objId = ObjectId.fromString(n.substring(7));
135 n = br.readLine();
136 if (n == null || !n.startsWith("type ")) {
137 throw new CorruptObjectException(tagId, "no type");
139 type = n.substring("type ".length());
140 n = br.readLine();
142 if (n == null || !n.startsWith("tag ")) {
143 throw new CorruptObjectException(tagId, "no tag name");
145 tag = n.substring("tag ".length());
146 n = br.readLine();
148 // We should see a "tagger" header here, but some repos have tags
149 // without it.
150 if (n == null)
151 throw new CorruptObjectException(tagId, "no tagger header");
153 if (n.length()>0)
154 if (n.startsWith("tagger "))
155 tagger = new PersonIdent(n.substring("tagger ".length()));
156 else
157 throw new CorruptObjectException(tagId, "no tagger/bad header");
159 // Message should start with an empty line, but
160 StringBuffer tempMessage = new StringBuffer();
161 char[] readBuf = new char[2048];
162 int readLen;
163 while ((readLen = br.read(readBuf)) > 0) {
164 tempMessage.append(readBuf, 0, readLen);
166 message = tempMessage.toString();
167 if (message.startsWith("\n"))
168 message = message.substring(1);
169 } catch (IOException e) {
170 e.printStackTrace();
171 } finally {
172 raw = null;
178 * Set the message of an annotated tag
179 * @param m
181 public void setMessage(final String m) {
182 message = m;
186 * Store a tag.
187 * If author, message or type is set make the tag an annotated tag.
189 * @throws IOException
191 public void tag() throws IOException {
192 if (getTagId() != null)
193 throw new IllegalStateException("exists " + getTagId());
194 final ObjectId id;
195 final RefUpdate ru;
197 if (tagger!=null || message!=null || type!=null) {
198 ObjectId tagid = new ObjectWriter(objdb).writeTag(this);
199 setTagId(tagid);
200 id = tagid;
201 } else {
202 id = objId;
205 ru = objdb.updateRef(Constants.TAGS_PREFIX + "/" + getTag());
206 ru.setNewObjectId(id);
207 ru.setRefLogMessage("tagged " + getTag(), false);
208 if (ru.forceUpdate() == RefUpdate.Result.LOCK_FAILURE)
209 throw new ObjectWritingException("Unable to lock tag " + getTag());
212 public String toString() {
213 return "tag[" + getTag() + getType() + getObjId() + " " + getAuthor() + "]";
217 * @return SHA-1 of this tag (if annotated and stored).
219 public ObjectId getTagId() {
220 return tagId;
224 * Set SHA-1 of this tag. Used by writer.
226 * @param tagId
228 public void setTagId(ObjectId tagId) {
229 this.tagId = tagId;
233 * @return creator of this tag.
235 public PersonIdent getTagger() {
236 decode();
237 return tagger;
241 * Set the creator of this tag
243 * @param tagger
245 public void setTagger(PersonIdent tagger) {
246 this.tagger = tagger;
250 * @return tag target type
252 public String getType() {
253 decode();
254 return type;
258 * Set tag target type
259 * @param type
261 public void setType(String type) {
262 this.type = type;
266 * @return name of the tag.
268 public String getTag() {
269 return tag;
273 * Set the name of this tag.
275 * @param tag
277 public void setTag(String tag) {
278 this.tag = tag;
282 * @return the SHA'1 of the object this tag refers to.
284 public ObjectId getObjId() {
285 return objId;
289 * Set the id of the object this tag refers to.
291 * @param objId
293 public void setObjId(ObjectId objId) {
294 this.objId = objId;