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