Fix Repository isValidRefName() for empty names
[egit/zawir.git] / org.spearce.jgit / src / org / spearce / jgit / lib / PersonIdent.java
blob5e524d3b2734461170e086ab9c72c1ad701a428c
1 /*
2 * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
3 * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
4 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or
9 * without modification, are permitted provided that the following
10 * conditions are met:
12 * - Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
20 * - Neither the name of the Git Development Community nor the
21 * names of its contributors may be used to endorse or promote
22 * products derived from this software without specific prior
23 * written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
26 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
27 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
30 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
32 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
34 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
37 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 package org.spearce.jgit.lib;
42 import java.util.Date;
43 import java.util.TimeZone;
45 /**
46 * A combination of a person identity and time in Git.
48 * Git combines Name + email + time + time zone to specify who wrote or
49 * committed something.
51 public class PersonIdent {
52 private final String name;
54 private final String emailAddress;
56 private final long when;
58 private final int tzOffset;
60 private static String getHostName() {
61 try {
62 java.net.InetAddress addr = java.net.InetAddress.getLocalHost();
63 String hostname = addr.getCanonicalHostName();
64 return hostname;
65 } catch (java.net.UnknownHostException e) {
66 return "localhost";
70 /**
71 * Creates new PersonIdent from config info in repository, with current time
73 * @param repo
75 public PersonIdent(final Repository repo) {
76 RepositoryConfig config = repo.getConfig();
77 String username = config.getString("user", null, "name");
78 if (username == null)
79 username = System.getProperty("user.name");
81 String email = config.getString("user", null, "email");
82 if (email == null)
83 email = System.getProperty("user.name") + "@" + getHostName();
85 name = username;
86 emailAddress = email;
87 when = System.currentTimeMillis();
88 tzOffset = TimeZone.getDefault().getOffset(when) / (60 * 1000);
91 /**
92 * Copy a {@link PersonIdent}.
94 * @param pi
95 * Original {@link PersonIdent}
97 public PersonIdent(final PersonIdent pi) {
98 this(pi.getName(), pi.getEmailAddress());
102 * Construct a new {@link PersonIdent} with current time.
104 * @param aName
105 * @param aEmailAddress
107 public PersonIdent(final String aName, final String aEmailAddress) {
108 this(aName, aEmailAddress, new Date(), TimeZone.getDefault());
112 * Copy a PersonIdent, but alter the clone's time stamp
114 * @param pi
115 * original {@link PersonIdent}
116 * @param when
117 * local time
118 * @param tz
119 * time zone
121 public PersonIdent(final PersonIdent pi, final Date when, final TimeZone tz) {
122 this(pi.getName(), pi.getEmailAddress(), when, tz);
126 * Copy a {@link PersonIdent}, but alter the clone's time stamp
128 * @param pi
129 * original {@link PersonIdent}
130 * @param aWhen
131 * local time
133 public PersonIdent(final PersonIdent pi, final Date aWhen) {
134 name = pi.getName();
135 emailAddress = pi.getEmailAddress();
136 when = aWhen.getTime();
137 tzOffset = pi.tzOffset;
141 * Construct a PersonIdent from simple data
143 * @param aName
144 * @param aEmailAddress
145 * @param aWhen
146 * local time stamp
147 * @param aTZ
148 * time zone
150 public PersonIdent(final String aName, final String aEmailAddress,
151 final Date aWhen, final TimeZone aTZ) {
152 name = aName;
153 emailAddress = aEmailAddress;
154 when = aWhen.getTime();
155 tzOffset = aTZ.getOffset(when) / (60 * 1000);
159 * Construct a {@link PersonIdent}
161 * @param aName
162 * @param aEmailAddress
163 * @param aWhen
164 * local time stamp
165 * @param aTZ
166 * time zone
168 public PersonIdent(final String aName, final String aEmailAddress,
169 final long aWhen, final int aTZ) {
170 name = aName;
171 emailAddress = aEmailAddress;
172 when = aWhen;
173 tzOffset = aTZ;
177 * Copy a PersonIdent, but alter the clone's time stamp
179 * @param pi
180 * original {@link PersonIdent}
181 * @param aWhen
182 * local time stamp
183 * @param aTZ
184 * time zone
186 public PersonIdent(final PersonIdent pi, final long aWhen, final int aTZ) {
187 name = pi.getName();
188 emailAddress = pi.getEmailAddress();
189 when = aWhen;
190 tzOffset = aTZ;
194 * Construct a PersonIdent from a string with full name, email, time time
195 * zone string. The input string must be valid.
197 * @param in
198 * a Git internal format author/committer string.
200 public PersonIdent(final String in) {
201 final int lt = in.indexOf('<');
202 if (lt == -1) {
203 throw new IllegalArgumentException("Malformed PersonIdent string"
204 + " (no < was found): " + in);
206 final int gt = in.indexOf('>', lt);
207 if (gt == -1) {
208 throw new IllegalArgumentException("Malformed PersonIdent string"
209 + " (no > was found): " + in);
211 final int sp = in.indexOf(' ', gt + 2);
212 if (sp == -1) {
213 when = 0;
214 tzOffset = -1;
215 } else {
216 final String tzHoursStr = in.substring(sp + 1, sp + 4).trim();
217 final int tzHours;
218 if (tzHoursStr.charAt(0) == '+') {
219 tzHours = Integer.parseInt(tzHoursStr.substring(1));
220 } else {
221 tzHours = Integer.parseInt(tzHoursStr);
223 final int tzMins = Integer.parseInt(in.substring(sp + 4).trim());
224 when = Long.parseLong(in.substring(gt + 1, sp).trim()) * 1000;
225 tzOffset = tzHours * 60 + tzMins;
228 name = in.substring(0, lt).trim();
229 emailAddress = in.substring(lt + 1, gt).trim();
233 * @return Name of person
235 public String getName() {
236 return name;
240 * @return email address of person
242 public String getEmailAddress() {
243 return emailAddress;
247 * @return timestamp
249 public Date getWhen() {
250 return new Date(when);
254 * @return this person's preferred time zone; null if time zone is unknown.
256 public TimeZone getTimeZone() {
257 final String[] ids = TimeZone.getAvailableIDs(tzOffset * 60 * 1000);
258 if (ids.length == 0)
259 return null;
260 return TimeZone.getTimeZone(ids[0]);
263 public int hashCode() {
264 return getEmailAddress().hashCode() ^ (int) when;
267 public boolean equals(final Object o) {
268 if (o instanceof PersonIdent) {
269 final PersonIdent p = (PersonIdent) o;
270 return getName().equals(p.getName())
271 && getEmailAddress().equals(p.getEmailAddress())
272 && when == p.when;
274 return false;
278 * Format for Git storage.
280 * @return a string in the git author format
282 public String toExternalString() {
283 final StringBuffer r = new StringBuffer();
284 int offset = tzOffset;
285 final char sign;
286 final int offsetHours;
287 final int offsetMins;
289 if (offset < 0) {
290 sign = '-';
291 offset = -offset;
292 } else {
293 sign = '+';
296 offsetHours = offset / 60;
297 offsetMins = offset % 60;
299 r.append(getName());
300 r.append(" <");
301 r.append(getEmailAddress());
302 r.append("> ");
303 r.append(when / 1000);
304 r.append(' ');
305 r.append(sign);
306 if (offsetHours < 10) {
307 r.append('0');
309 r.append(offsetHours);
310 if (offsetMins < 10) {
311 r.append('0');
313 r.append(offsetMins);
314 return r.toString();
317 public String toString() {
318 final StringBuffer r = new StringBuffer();
319 int minutes;
321 minutes = tzOffset < 0 ? -tzOffset : tzOffset;
322 minutes = (minutes / 100) * 60 + (minutes % 100);
323 minutes = tzOffset < 0 ? -minutes : minutes;
325 r.append("PersonIdent[");
326 r.append(getName());
327 r.append(", ");
328 r.append(getEmailAddress());
329 r.append(", ");
330 r.append(new Date(when + minutes * 60));
331 r.append("]");
333 return r.toString();