View Javadoc
1   /*
2    * Copyright (C) 2006-2008, Robin Rosenberg <robin.rosenberg@dewire.com>
3    * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
4    * Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com>
5    * and other copyright owners as documented in the project's IP log.
6    *
7    * This program and the accompanying materials are made available
8    * under the terms of the Eclipse Distribution License v1.0 which
9    * accompanies this distribution, is reproduced below, and is
10   * available at http://www.eclipse.org/org/documents/edl-v10.php
11   *
12   * All rights reserved.
13   *
14   * Redistribution and use in source and binary forms, with or
15   * without modification, are permitted provided that the following
16   * conditions are met:
17   *
18   * - Redistributions of source code must retain the above copyright
19   *   notice, this list of conditions and the following disclaimer.
20   *
21   * - Redistributions in binary form must reproduce the above
22   *   copyright notice, this list of conditions and the following
23   *   disclaimer in the documentation and/or other materials provided
24   *   with the distribution.
25   *
26   * - Neither the name of the Eclipse Foundation, Inc. nor the
27   *   names of its contributors may be used to endorse or promote
28   *   products derived from this software without specific prior
29   *   written permission.
30   *
31   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
32   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
33   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
34   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
36   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
37   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
38   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
40   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
43   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44   */
45  
46  package org.eclipse.jgit.lib;
47  
48  import java.io.ByteArrayOutputStream;
49  import java.io.IOException;
50  import java.io.OutputStreamWriter;
51  
52  import org.eclipse.jgit.revwalk.RevObject;
53  
54  /**
55   * Mutable builder to construct an annotated tag recording a project state.
56   *
57   * Applications should use this object when they need to manually construct a
58   * tag and want precise control over its fields.
59   *
60   * To read a tag object, construct a {@link org.eclipse.jgit.revwalk.RevWalk}
61   * and obtain a {@link org.eclipse.jgit.revwalk.RevTag} instance by calling
62   * {@link org.eclipse.jgit.revwalk.RevWalk#parseTag(AnyObjectId)}.
63   */
64  public class TagBuilder {
65  	private ObjectId object;
66  
67  	private int type = Constants.OBJ_BAD;
68  
69  	private String tag;
70  
71  	private PersonIdent tagger;
72  
73  	private String message;
74  
75  	/** @return the type of object this tag refers to. */
76  	public int getObjectType() {
77  		return type;
78  	}
79  
80  	/** @return the object this tag refers to. */
81  	public ObjectId getObjectId() {
82  		return object;
83  	}
84  
85  	/**
86  	 * Set the object this tag refers to, and its type.
87  	 *
88  	 * @param obj
89  	 *            the object.
90  	 * @param objType
91  	 *            the type of {@code obj}. Must be a valid type code.
92  	 */
93  	public void setObjectId(AnyObjectId obj, int objType) {
94  		object = obj.copy();
95  		type = objType;
96  	}
97  
98  	/**
99  	 * Set the object this tag refers to, and infer its type.
100 	 *
101 	 * @param obj
102 	 *            the object the tag will refer to.
103 	 */
104 	public void setObjectId(RevObject obj) {
105 		setObjectId(obj, obj.getType());
106 	}
107 
108 	/** @return short name of the tag (no {@code refs/tags/} prefix). */
109 	public String getTag() {
110 		return tag;
111 	}
112 
113 	/**
114 	 * Set the name of this tag.
115 	 *
116 	 * @param shortName
117 	 *            new short name of the tag. This short name should not start
118 	 *            with {@code refs/} as typically a tag is stored under the
119 	 *            reference derived from {@code "refs/tags/" + getTag()}.
120 	 */
121 	public void setTag(String shortName) {
122 		this.tag = shortName;
123 	}
124 
125 	/** @return creator of this tag. May be null. */
126 	public PersonIdent getTagger() {
127 		return tagger;
128 	}
129 
130 	/**
131 	 * Set the creator of this tag.
132 	 *
133 	 * @param taggerIdent
134 	 *            the creator. May be null.
135 	 */
136 	public void setTagger(PersonIdent taggerIdent) {
137 		tagger = taggerIdent;
138 	}
139 
140 	/** @return the complete commit message. */
141 	public String getMessage() {
142 		return message;
143 	}
144 
145 	/**
146 	 * Set the tag's message.
147 	 *
148 	 * @param newMessage
149 	 *            the tag's message.
150 	 */
151 	public void setMessage(final String newMessage) {
152 		message = newMessage;
153 	}
154 
155 	/**
156 	 * Format this builder's state as an annotated tag object.
157 	 *
158 	 * @return this object in the canonical annotated tag format, suitable for
159 	 *         storage in a repository.
160 	 */
161 	public byte[] build() {
162 		ByteArrayOutputStream os = new ByteArrayOutputStream();
163 		OutputStreamWriter w = new OutputStreamWriter(os, Constants.CHARSET);
164 		try {
165 			w.write("object "); //$NON-NLS-1$
166 			getObjectId().copyTo(w);
167 			w.write('\n');
168 
169 			w.write("type "); //$NON-NLS-1$
170 			w.write(Constants.typeString(getObjectType()));
171 			w.write("\n"); //$NON-NLS-1$
172 
173 			w.write("tag "); //$NON-NLS-1$
174 			w.write(getTag());
175 			w.write("\n"); //$NON-NLS-1$
176 
177 			if (getTagger() != null) {
178 				w.write("tagger "); //$NON-NLS-1$
179 				w.write(getTagger().toExternalString());
180 				w.write('\n');
181 			}
182 
183 			w.write('\n');
184 			if (getMessage() != null)
185 				w.write(getMessage());
186 			w.close();
187 		} catch (IOException err) {
188 			// This should never occur, the only way to get it above is
189 			// for the ByteArrayOutputStream to throw, but it doesn't.
190 			//
191 			throw new RuntimeException(err);
192 		}
193 		return os.toByteArray();
194 	}
195 
196 	/**
197 	 * Format this builder's state as an annotated tag object.
198 	 *
199 	 * @return this object in the canonical annotated tag format, suitable for
200 	 *         storage in a repository.
201 	 */
202 	public byte[] toByteArray() {
203 		return build();
204 	}
205 
206 	@SuppressWarnings("nls")
207 	@Override
208 	public String toString() {
209 		StringBuilder r = new StringBuilder();
210 		r.append("Tag");
211 		r.append("={\n");
212 
213 		r.append("object ");
214 		r.append(object != null ? object.name() : "NOT_SET");
215 		r.append("\n");
216 
217 		r.append("type ");
218 		r.append(object != null ? Constants.typeString(type) : "NOT_SET");
219 		r.append("\n");
220 
221 		r.append("tag ");
222 		r.append(tag != null ? tag : "NOT_SET");
223 		r.append("\n");
224 
225 		if (tagger != null) {
226 			r.append("tagger ");
227 			r.append(tagger);
228 			r.append("\n");
229 		}
230 
231 		r.append("\n");
232 		r.append(message != null ? message : "");
233 		r.append("}");
234 		return r.toString();
235 	}
236 }