blob: 684f09236b75b6df07f80a4b7341960a10a676b5 [file] [log] [blame]
// Copyright (C) 2008 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.reviewdb.client;
import com.google.gerrit.common.Nullable;
import com.google.gwtorm.client.IntKey;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/** A single revision of a {@link Change}. */
public final class PatchSet {
/** Is the reference name a change reference? */
public static boolean isChangeRef(String name) {
return Id.fromRef(name) != null;
}
/**
* Is the reference name a change reference?
*
* @deprecated use isChangeRef instead.
*/
@Deprecated
public static boolean isRef(String name) {
return isChangeRef(name);
}
public static String joinGroups(List<String> groups) {
if (groups == null) {
throw new IllegalArgumentException("groups may not be null");
}
StringBuilder sb = new StringBuilder();
boolean first = true;
for (String g : groups) {
if (!first) {
sb.append(',');
} else {
first = false;
}
sb.append(g);
}
return sb.toString();
}
public static List<String> splitGroups(String joinedGroups) {
if (joinedGroups == null) {
throw new IllegalArgumentException("groups may not be null");
}
List<String> groups = new ArrayList<>();
int i = 0;
while (true) {
int idx = joinedGroups.indexOf(',', i);
if (idx < 0) {
groups.add(joinedGroups.substring(i));
break;
}
groups.add(joinedGroups.substring(i, idx));
i = idx + 1;
}
return groups;
}
public static Id id(Change.Id changeId, int id) {
return new Id(changeId, id);
}
public static class Id extends IntKey<Change.Id> {
private static final long serialVersionUID = 1L;
public Change.Id changeId;
public int patchSetId;
public Id() {
changeId = new Change.Id();
}
public Id(Change.Id change, int id) {
this.changeId = change;
this.patchSetId = id;
}
@Override
public Change.Id getParentKey() {
return changeId;
}
public Change.Id changeId() {
return getParentKey();
}
@Override
public int get() {
return patchSetId;
}
@Override
protected void set(int newValue) {
patchSetId = newValue;
}
public String toRefName() {
return changeId.refPrefixBuilder().append(patchSetId).toString();
}
/** Parse a PatchSet.Id out of a string representation. */
public static Id parse(String str) {
final Id r = new Id();
r.fromString(str);
return r;
}
/** Parse a PatchSet.Id from a {@link PatchSet#getRefName()} result. */
public static Id fromRef(String ref) {
int cs = Change.Id.startIndex(ref);
if (cs < 0) {
return null;
}
int ce = Change.Id.nextNonDigit(ref, cs);
int patchSetId = fromRef(ref, ce);
if (patchSetId < 0) {
return null;
}
int changeId = Integer.parseInt(ref.substring(cs, ce));
return new PatchSet.Id(new Change.Id(changeId), patchSetId);
}
static int fromRef(String ref, int changeIdEnd) {
// Patch set ID.
int ps = changeIdEnd + 1;
if (ps >= ref.length() || ref.charAt(ps) == '0') {
return -1;
}
for (int i = ps; i < ref.length(); i++) {
if (ref.charAt(i) < '0' || ref.charAt(i) > '9') {
return -1;
}
}
return Integer.parseInt(ref.substring(ps));
}
public String getId() {
return toId(patchSetId);
}
public static String toId(int number) {
return number == 0 ? "edit" : String.valueOf(number);
}
}
protected Id id;
@Nullable protected RevId revision;
protected Account.Id uploader;
/** When this patch set was first introduced onto the change. */
protected Timestamp createdOn;
/**
* Opaque group identifier, usually assigned during creation.
*
* <p>This field is actually a comma-separated list of values, as in rare cases involving merge
* commits a patch set may belong to multiple groups.
*
* <p>Changes on the same branch having patch sets with intersecting groups are considered
* related, as in the "Related Changes" tab.
*/
@Nullable protected String groups;
// DELETED id = 7 (pushCertficate)
/** Certificate sent with a push that created this patch set. */
@Nullable protected String pushCertificate;
/**
* Optional user-supplied description for this patch set.
*
* <p>When this field is null, the description was never set on the patch set. When this field is
* an empty string, the description was set and later cleared.
*/
@Nullable protected String description;
protected PatchSet() {}
public PatchSet(PatchSet.Id k) {
id = k;
}
public PatchSet(PatchSet src) {
this.id = src.id;
this.revision = src.revision;
this.uploader = src.uploader;
this.createdOn = src.createdOn;
this.groups = src.groups;
this.pushCertificate = src.pushCertificate;
this.description = src.description;
}
public PatchSet.Id getId() {
return id;
}
public int getPatchSetId() {
return id.get();
}
public RevId getRevision() {
return revision;
}
public void setRevision(RevId i) {
revision = i;
}
public Account.Id getUploader() {
return uploader;
}
public void setUploader(Account.Id who) {
uploader = who;
}
public Timestamp getCreatedOn() {
return createdOn;
}
public void setCreatedOn(Timestamp ts) {
createdOn = ts;
}
public List<String> getGroups() {
if (groups == null) {
return Collections.emptyList();
}
return splitGroups(groups);
}
public void setGroups(List<String> groups) {
if (groups == null) {
groups = Collections.emptyList();
}
this.groups = joinGroups(groups);
}
public String getRefName() {
return id.toRefName();
}
public String getPushCertificate() {
return pushCertificate;
}
public void setPushCertificate(String cert) {
pushCertificate = cert;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof PatchSet)) {
return false;
}
PatchSet p = (PatchSet) o;
return Objects.equals(id, p.id)
&& Objects.equals(revision, p.revision)
&& Objects.equals(uploader, p.uploader)
&& Objects.equals(createdOn, p.createdOn)
&& Objects.equals(groups, p.groups)
&& Objects.equals(pushCertificate, p.pushCertificate)
&& Objects.equals(description, p.description);
}
@Override
public int hashCode() {
return Objects.hash(id, revision, uploader, createdOn, groups, pushCertificate, description);
}
@Override
public String toString() {
return "[PatchSet " + getId().toString() + "]";
}
}