2 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
3 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
7 * Redistribution and use in source and binary forms, with or
8 * without modification, are permitted provided that the following
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
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
;
50 * Represents a named reference to another Git object of any type.
53 private final Repository objdb
;
55 private ObjectId tagId
;
57 private PersonIdent tagger
;
59 private String message
;
67 private ObjectId objId
;
70 * Construct a new, yet unnamed Tag.
74 public Tag(final Repository db
) {
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
) {
91 objId
= ObjectId
.fromString(raw
, 7);
94 if (refName
!= null && refName
.startsWith("refs/tags/"))
95 refName
= refName
.substring(10);
101 * @return tagger of a annotated tag or null
103 public PersonIdent
getAuthor() {
109 * Set author of an annotated tag.
110 * @param a author identifier as a {@link PersonIdent}
112 public void setAuthor(final PersonIdent a
) {
117 * @return comment of an annotated tag, or null
119 public String
getMessage() {
124 private void decode() {
125 // FIXME: handle I/O errors
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));
136 if (n
== null || !n
.startsWith("type ")) {
137 throw new CorruptObjectException(tagId
, "no type");
139 type
= n
.substring("type ".length());
142 if (n
== null || !n
.startsWith("tag ")) {
143 throw new CorruptObjectException(tagId
, "no tag name");
145 tag
= n
.substring("tag ".length());
148 // We should see a "tagger" header here, but some repos have tags
151 throw new CorruptObjectException(tagId
, "no tagger header");
154 if (n
.startsWith("tagger "))
155 tagger
= new PersonIdent(n
.substring("tagger ".length()));
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];
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
) {
178 * Set the message of an annotated tag
181 public void setMessage(final String m
) {
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());
197 if (tagger
!=null || message
!=null || type
!=null) {
198 ObjectId tagid
= new ObjectWriter(objdb
).writeTag(this);
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() {
224 * Set SHA-1 of this tag. Used by writer.
228 public void setTagId(ObjectId tagId
) {
233 * @return creator of this tag.
235 public PersonIdent
getTagger() {
241 * Set the creator of this tag
245 public void setTagger(PersonIdent tagger
) {
246 this.tagger
= tagger
;
250 * @return tag target type
252 public String
getType() {
258 * Set tag target type
261 public void setType(String type
) {
266 * @return name of the tag.
268 public String
getTag() {
273 * Set the name of this tag.
277 public void setTag(String tag
) {
282 * @return the SHA'1 of the object this tag refers to.
284 public ObjectId
getObjId() {
289 * Set the id of the object this tag refers to.
293 public void setObjId(ObjectId objId
) {