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 static java.nio.charset.StandardCharsets.UTF_8;
49  
50  import java.io.ByteArrayOutputStream;
51  import java.io.IOException;
52  import java.io.OutputStreamWriter;
53  
54  import org.eclipse.jgit.revwalk.RevObject;
55  
56  /**
57   * Mutable builder to construct an annotated tag recording a project state.
58   *
59   * Applications should use this object when they need to manually construct a
60   * tag and want precise control over its fields.
61   *
62   * To read a tag object, construct a {@link org.eclipse.jgit.revwalk.RevWalk}
63   * and obtain a {@link org.eclipse.jgit.revwalk.RevTag} instance by calling
64   * {@link org.eclipse.jgit.revwalk.RevWalk#parseTag(AnyObjectId)}.
65   */
66  public class TagBuilder {
67  	private ObjectId object;
68  
69  	private int type = Constants.OBJ_BAD;
70  
71  	private String tag;
72  
73  	private PersonIdent tagger;
74  
75  	private String message;
76  
77  	/**
78  	 * Get the type of object this tag refers to.
79  	 *
80  	 * @return the type of object this tag refers to.
81  	 */
82  	public int getObjectType() {
83  		return type;
84  	}
85  
86  	/**
87  	 * Get the object this tag refers to.
88  	 *
89  	 * @return the object this tag refers to.
90  	 */
91  	public ObjectId getObjectId() {
92  		return object;
93  	}
94  
95  	/**
96  	 * Set the object this tag refers to, and its type.
97  	 *
98  	 * @param obj
99  	 *            the object.
100 	 * @param objType
101 	 *            the type of {@code obj}. Must be a valid type code.
102 	 */
103 	public void setObjectId(AnyObjectId obj, int objType) {
104 		object = obj.copy();
105 		type = objType;
106 	}
107 
108 	/**
109 	 * Set the object this tag refers to, and infer its type.
110 	 *
111 	 * @param obj
112 	 *            the object the tag will refer to.
113 	 */
114 	public void setObjectId(RevObject obj) {
115 		setObjectId(obj, obj.getType());
116 	}
117 
118 	/**
119 	 * Get short name of the tag (no {@code refs/tags/} prefix).
120 	 *
121 	 * @return short name of the tag (no {@code refs/tags/} prefix).
122 	 */
123 	public String getTag() {
124 		return tag;
125 	}
126 
127 	/**
128 	 * Set the name of this tag.
129 	 *
130 	 * @param shortName
131 	 *            new short name of the tag. This short name should not start
132 	 *            with {@code refs/} as typically a tag is stored under the
133 	 *            reference derived from {@code "refs/tags/" + getTag()}.
134 	 */
135 	public void setTag(String shortName) {
136 		this.tag = shortName;
137 	}
138 
139 	/**
140 	 * Get creator of this tag.
141 	 *
142 	 * @return creator of this tag. May be null.
143 	 */
144 	public PersonIdent getTagger() {
145 		return tagger;
146 	}
147 
148 	/**
149 	 * Set the creator of this tag.
150 	 *
151 	 * @param taggerIdent
152 	 *            the creator. May be null.
153 	 */
154 	public void setTagger(PersonIdent taggerIdent) {
155 		tagger = taggerIdent;
156 	}
157 
158 	/**
159 	 * Get the complete commit message.
160 	 *
161 	 * @return the complete commit message.
162 	 */
163 	public String getMessage() {
164 		return message;
165 	}
166 
167 	/**
168 	 * Set the tag's message.
169 	 *
170 	 * @param newMessage
171 	 *            the tag's message.
172 	 */
173 	public void setMessage(String newMessage) {
174 		message = newMessage;
175 	}
176 
177 	/**
178 	 * Format this builder's state as an annotated tag object.
179 	 *
180 	 * @return this object in the canonical annotated tag format, suitable for
181 	 *         storage in a repository.
182 	 */
183 	public byte[] build() {
184 		ByteArrayOutputStream os = new ByteArrayOutputStream();
185 		try (OutputStreamWriter w = new OutputStreamWriter(os,
186 				UTF_8)) {
187 			w.write("object "); //$NON-NLS-1$
188 			getObjectId().copyTo(w);
189 			w.write('\n');
190 
191 			w.write("type "); //$NON-NLS-1$
192 			w.write(Constants.typeString(getObjectType()));
193 			w.write("\n"); //$NON-NLS-1$
194 
195 			w.write("tag "); //$NON-NLS-1$
196 			w.write(getTag());
197 			w.write("\n"); //$NON-NLS-1$
198 
199 			if (getTagger() != null) {
200 				w.write("tagger "); //$NON-NLS-1$
201 				w.write(getTagger().toExternalString());
202 				w.write('\n');
203 			}
204 
205 			w.write('\n');
206 			if (getMessage() != null)
207 				w.write(getMessage());
208 		} catch (IOException err) {
209 			// This should never occur, the only way to get it above is
210 			// for the ByteArrayOutputStream to throw, but it doesn't.
211 			//
212 			throw new RuntimeException(err);
213 		}
214 		return os.toByteArray();
215 	}
216 
217 	/**
218 	 * Format this builder's state as an annotated tag object.
219 	 *
220 	 * @return this object in the canonical annotated tag format, suitable for
221 	 *         storage in a repository.
222 	 */
223 	public byte[] toByteArray() {
224 		return build();
225 	}
226 
227 	/** {@inheritDoc} */
228 	@SuppressWarnings("nls")
229 	@Override
230 	public String toString() {
231 		StringBuilder r = new StringBuilder();
232 		r.append("Tag");
233 		r.append("={\n");
234 
235 		r.append("object ");
236 		r.append(object != null ? object.name() : "NOT_SET");
237 		r.append("\n");
238 
239 		r.append("type ");
240 		r.append(object != null ? Constants.typeString(type) : "NOT_SET");
241 		r.append("\n");
242 
243 		r.append("tag ");
244 		r.append(tag != null ? tag : "NOT_SET");
245 		r.append("\n");
246 
247 		if (tagger != null) {
248 			r.append("tagger ");
249 			r.append(tagger);
250 			r.append("\n");
251 		}
252 
253 		r.append("\n");
254 		r.append(message != null ? message : "");
255 		r.append("}");
256 		return r.toString();
257 	}
258 }