Remove old changeDetail RPC
Convert the new RPC data into the old data, just enough to keep the old UI alive against a newer server. This will allow us to build a final version of the old UI code and run it for quite some time against a modern REST API. Users who refuse to upgrade to ChangeScreen2 can run this frozen old UI build until it no longer works. Change-Id: Ieef15c39e97673f6bcdeb03567fc48ddbd289a6e
This commit is contained in:
@@ -52,6 +52,10 @@ public class AccountInfo {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setFullName(String n) {
|
||||
fullName = n;
|
||||
}
|
||||
|
||||
/** @return the full name of the account holder; null if not supplied */
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
|
@@ -17,7 +17,6 @@ package com.google.gerrit.common.data;
|
||||
import com.google.gerrit.common.audit.Audit;
|
||||
import com.google.gerrit.common.auth.SignInRequired;
|
||||
import com.google.gerrit.reviewdb.client.AccountDiffPreference;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
||||
import com.google.gwtjsonrpc.common.RemoteJsonService;
|
||||
@@ -26,12 +25,6 @@ import com.google.gwtjsonrpc.common.RpcImpl.Version;
|
||||
|
||||
@RpcImpl(version = Version.V2_0)
|
||||
public interface ChangeDetailService extends RemoteJsonService {
|
||||
@Audit
|
||||
void changeDetail(Change.Id id, AsyncCallback<ChangeDetail> callback);
|
||||
|
||||
@Audit
|
||||
void includedInDetail(Change.Id id, AsyncCallback<IncludedInDetail> callback);
|
||||
|
||||
@Audit
|
||||
void patchSetDetail(PatchSet.Id key, AsyncCallback<PatchSetDetail> callback);
|
||||
|
||||
|
@@ -35,10 +35,14 @@ public class ChangeInfo {
|
||||
protected PatchSet.Id patchSetId;
|
||||
protected boolean latest;
|
||||
|
||||
protected ChangeInfo() {
|
||||
public ChangeInfo() {
|
||||
}
|
||||
|
||||
public ChangeInfo(final Change c, final PatchSet.Id patchId) {
|
||||
set(c, patchId);
|
||||
}
|
||||
|
||||
public void set(final Change c, final PatchSet.Id patchId) {
|
||||
id = c.getId();
|
||||
key = c.getKey();
|
||||
owner = c.getOwner();
|
||||
|
@@ -39,7 +39,7 @@ import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
class RelatedChanges extends TabPanel {
|
||||
public class RelatedChanges extends TabPanel {
|
||||
private enum Tab {
|
||||
RELATED_CHANGES(Resources.C.relatedChanges(),
|
||||
Resources.C.relatedChangesTooltip()) {
|
||||
@@ -284,19 +284,19 @@ class RelatedChanges extends TabPanel {
|
||||
}
|
||||
}
|
||||
|
||||
private static class RelatedInfo extends JavaScriptObject {
|
||||
final native JsArray<ChangeAndCommit> changes() /*-{ return this.changes }-*/;
|
||||
public static class RelatedInfo extends JavaScriptObject {
|
||||
public final native JsArray<ChangeAndCommit> changes() /*-{ return this.changes }-*/;
|
||||
protected RelatedInfo() {
|
||||
}
|
||||
}
|
||||
|
||||
static class ChangeAndCommit extends JavaScriptObject {
|
||||
public static class ChangeAndCommit extends JavaScriptObject {
|
||||
static ChangeAndCommit create() {
|
||||
return (ChangeAndCommit) createObject();
|
||||
}
|
||||
|
||||
final native String id() /*-{ return this.change_id }-*/;
|
||||
final native CommitInfo commit() /*-{ return this.commit }-*/;
|
||||
public final native String id() /*-{ return this.change_id }-*/;
|
||||
public final native CommitInfo commit() /*-{ return this.commit }-*/;
|
||||
final native String branch() /*-{ return this.branch }-*/;
|
||||
|
||||
final native void set_id(String i)
|
||||
@@ -308,11 +308,11 @@ class RelatedChanges extends TabPanel {
|
||||
final native void set_branch(String b)
|
||||
/*-{ if(b)this.branch=b; }-*/;
|
||||
|
||||
final Change.Id legacy_id() {
|
||||
public final Change.Id legacy_id() {
|
||||
return has_change_number() ? new Change.Id(_change_number()) : null;
|
||||
}
|
||||
|
||||
final PatchSet.Id patch_set_id() {
|
||||
public final PatchSet.Id patch_set_id() {
|
||||
return has_change_number() && has_revision_number()
|
||||
? new PatchSet.Id(legacy_id(), _revision_number())
|
||||
: null;
|
||||
|
@@ -14,15 +14,54 @@
|
||||
|
||||
package com.google.gerrit.client.changes;
|
||||
|
||||
import com.google.gerrit.client.actions.ActionInfo;
|
||||
import com.google.gerrit.client.changes.ChangeInfo.CommitInfo;
|
||||
import com.google.gerrit.client.changes.ChangeInfo.GitPerson;
|
||||
import com.google.gerrit.client.changes.ChangeInfo.MessageInfo;
|
||||
import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo;
|
||||
import com.google.gerrit.client.rpc.NativeMap;
|
||||
import com.google.gerrit.client.rpc.Natives;
|
||||
import com.google.gerrit.client.rpc.RestApi;
|
||||
import com.google.gerrit.client.ui.ListenableValue;
|
||||
import com.google.gerrit.common.changes.ListChangesOption;
|
||||
import com.google.gerrit.common.data.AccountInfo;
|
||||
import com.google.gerrit.common.data.AccountInfoCache;
|
||||
import com.google.gerrit.common.data.ChangeDetail;
|
||||
import com.google.gerrit.common.data.PatchSetDetail;
|
||||
import com.google.gerrit.common.data.SubmitRecord;
|
||||
import com.google.gerrit.common.data.SubmitTypeRecord;
|
||||
import com.google.gerrit.common.data.UiCommandDetail;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
|
||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
||||
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||
import com.google.gerrit.reviewdb.client.Patch;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gerrit.reviewdb.client.PatchSetInfo;
|
||||
import com.google.gerrit.reviewdb.client.PatchSetInfo.ParentInfo;
|
||||
import com.google.gerrit.reviewdb.client.RevId;
|
||||
import com.google.gerrit.reviewdb.client.UserIdentity;
|
||||
import com.google.gwt.core.client.JsArray;
|
||||
import com.google.gwt.user.client.ui.FocusWidget;
|
||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ChangeDetailCache extends ListenableValue<ChangeDetail> {
|
||||
public static class GerritCallback extends
|
||||
public static class NewGerritCallback extends
|
||||
com.google.gerrit.client.rpc.GerritCallback<ChangeInfo> {
|
||||
@Override
|
||||
public void onSuccess(ChangeInfo detail) {
|
||||
setChangeDetail(reverse(detail));
|
||||
}
|
||||
}
|
||||
|
||||
public static class OldGerritCallback extends
|
||||
com.google.gerrit.client.rpc.GerritCallback<ChangeDetail> {
|
||||
@Override
|
||||
public void onSuccess(ChangeDetail detail) {
|
||||
@@ -37,7 +76,7 @@ public class ChangeDetailCache extends ListenableValue<ChangeDetail> {
|
||||
*
|
||||
* It is up to the caller to handle the original disabling of the Widget.
|
||||
*/
|
||||
public static class GerritWidgetCallback extends GerritCallback {
|
||||
public static class GerritWidgetCallback extends OldGerritCallback {
|
||||
private FocusWidget widget;
|
||||
|
||||
public GerritWidgetCallback(FocusWidget widget) {
|
||||
@@ -53,8 +92,8 @@ public class ChangeDetailCache extends ListenableValue<ChangeDetail> {
|
||||
|
||||
public static class IgnoreErrorCallback implements AsyncCallback<ChangeDetail> {
|
||||
@Override
|
||||
public void onSuccess(ChangeDetail detail) {
|
||||
setChangeDetail(detail);
|
||||
public void onSuccess(ChangeDetail info) {
|
||||
setChangeDetail(info);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,6 +101,173 @@ public class ChangeDetailCache extends ListenableValue<ChangeDetail> {
|
||||
}
|
||||
}
|
||||
|
||||
public static ChangeDetail reverse(ChangeInfo info) {
|
||||
info.revisions().copyKeysIntoChildren("name");
|
||||
RevisionInfo rev = current(info);
|
||||
|
||||
ChangeDetail r = new ChangeDetail();
|
||||
r.setAllowsAnonymous(rev.has_fetch() && rev.fetch().containsKey("http"));
|
||||
r.setCanAbandon(can(info.actions(), "abandon"));
|
||||
r.setCanEditCommitMessage(can(info.actions(), "message"));
|
||||
r.setCanCherryPick(can(rev.actions(), "cherrypick"));
|
||||
r.setCanPublish(can(rev.actions(), "publish"));
|
||||
r.setCanRebase(can(rev.actions(), "rebase"));
|
||||
r.setCanRestore(can(info.actions(), "restore"));
|
||||
r.setCanRevert(can(info.actions(), "revert"));
|
||||
r.setCanDeleteDraft(can(rev.actions(), "/"));
|
||||
r.setCanEditTopicName(can(info.actions(), "topic"));
|
||||
r.setCanSubmit(can(rev.actions(), "submit"));
|
||||
r.setCanEdit(true);
|
||||
r.setChange(toChange(info));
|
||||
r.setStarred(info.starred());
|
||||
r.setPatchSets(toPatchSets(info));
|
||||
r.setMessages(toMessages(info));
|
||||
r.setAccounts(users(info));
|
||||
r.setCurrentPatchSetId(new PatchSet.Id(info.legacy_id(), rev._number()));
|
||||
r.setCurrentPatchSetDetail(toPatchSetDetail(info));
|
||||
r.setSubmitRecords(new ArrayList<SubmitRecord>());
|
||||
|
||||
// Obtained later in ChangeScreen.
|
||||
r.setSubmitTypeRecord(new SubmitTypeRecord());
|
||||
r.getSubmitTypeRecord().status = SubmitTypeRecord.Status.RULE_ERROR;
|
||||
r.setPatchSetsWithDraftComments(new HashSet<PatchSet.Id>());
|
||||
r.setDependsOn(new ArrayList<com.google.gerrit.common.data.ChangeInfo>());
|
||||
r.setNeededBy(new ArrayList<com.google.gerrit.common.data.ChangeInfo>());
|
||||
return r;
|
||||
}
|
||||
|
||||
private static PatchSetDetail toPatchSetDetail(ChangeInfo info) {
|
||||
RevisionInfo rev = current(info);
|
||||
PatchSetDetail p = new PatchSetDetail();
|
||||
p.setPatchSet(toPatchSet(info, rev));
|
||||
p.setProject(info.project_name_key());
|
||||
p.setInfo(new PatchSetInfo(p.getPatchSet().getId()));
|
||||
p.getInfo().setRevId(rev.name());
|
||||
p.getInfo().setParents(new ArrayList<ParentInfo>());
|
||||
p.getInfo().setAuthor(toUser(rev.commit().author()));
|
||||
p.getInfo().setCommitter(toUser(rev.commit().committer()));
|
||||
p.getInfo().setSubject(rev.commit().subject());
|
||||
p.getInfo().setMessage(rev.commit().message());
|
||||
if (rev.commit().parents() != null) {
|
||||
for (CommitInfo c : Natives.asList(rev.commit().parents())) {
|
||||
p.getInfo().getParents().add(new ParentInfo(
|
||||
new RevId(c.commit()),
|
||||
c.subject()));
|
||||
}
|
||||
}
|
||||
p.setPatches(new ArrayList<Patch>());
|
||||
p.setCommands(new ArrayList<UiCommandDetail>());
|
||||
|
||||
rev.files();
|
||||
return p;
|
||||
}
|
||||
|
||||
private static UserIdentity toUser(GitPerson p) {
|
||||
UserIdentity u = new UserIdentity();
|
||||
u.setName(p.name());
|
||||
u.setEmail(p.email());
|
||||
u.setDate(p.date());
|
||||
return u;
|
||||
}
|
||||
|
||||
public static AccountInfoCache users(ChangeInfo info) {
|
||||
Map<Integer, AccountInfo> r = new HashMap<Integer, AccountInfo>();
|
||||
add(r, info.owner());
|
||||
if (info.messages() != null) {
|
||||
for (MessageInfo m : Natives.asList(info.messages())) {
|
||||
add(r, m.author());
|
||||
}
|
||||
}
|
||||
return new AccountInfoCache(r.values());
|
||||
}
|
||||
|
||||
private static void add(Map<Integer, AccountInfo> r,
|
||||
com.google.gerrit.client.account.AccountInfo user) {
|
||||
if (user != null && !r.containsKey(user._account_id())) {
|
||||
AccountInfo a = new AccountInfo(new Account.Id(user._account_id()));
|
||||
a.setPreferredEmail(user.email());
|
||||
a.setFullName(user.name());
|
||||
r.put(user._account_id(), a);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean can(NativeMap<ActionInfo> m, String n) {
|
||||
return m != null && m.containsKey(n) && m.get(n).enabled();
|
||||
}
|
||||
|
||||
private static List<ChangeMessage> toMessages(ChangeInfo info) {
|
||||
List<ChangeMessage> msgs = new ArrayList<ChangeMessage>();
|
||||
for (MessageInfo m : Natives.asList(info.messages())) {
|
||||
ChangeMessage o = new ChangeMessage(
|
||||
new ChangeMessage.Key(
|
||||
info.legacy_id(),
|
||||
m.date().toString()),
|
||||
m.author() != null
|
||||
? new Account.Id(m.author()._account_id())
|
||||
: null,
|
||||
m.date(),
|
||||
m._revisionNumber() > 0
|
||||
? new PatchSet.Id(info.legacy_id(), m._revisionNumber())
|
||||
: null);
|
||||
o.setMessage(m.message());
|
||||
msgs.add(o);
|
||||
}
|
||||
return msgs;
|
||||
}
|
||||
|
||||
private static List<PatchSet> toPatchSets(ChangeInfo info) {
|
||||
JsArray<RevisionInfo> all = info.revisions().values();
|
||||
RevisionInfo.sortRevisionInfoByNumber(all);
|
||||
|
||||
List<PatchSet> r = new ArrayList<PatchSet>(all.length());
|
||||
for (RevisionInfo rev : Natives.asList(all)) {
|
||||
r.add(toPatchSet(info, rev));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
private static PatchSet toPatchSet(ChangeInfo info, RevisionInfo rev) {
|
||||
PatchSet p = new PatchSet(
|
||||
new PatchSet.Id(info.legacy_id(), rev._number()));
|
||||
p.setCreatedOn(rev.commit().committer().date());
|
||||
p.setDraft(rev.draft());
|
||||
p.setRevision(new RevId(rev.name()));
|
||||
return p;
|
||||
}
|
||||
|
||||
public static Change toChange(ChangeInfo info) {
|
||||
RevisionInfo rev = current(info);
|
||||
PatchSetInfo p = new PatchSetInfo(
|
||||
new PatchSet.Id(
|
||||
info.legacy_id(),
|
||||
rev._number()));
|
||||
p.setSubject(info.subject());
|
||||
Change c = new Change(
|
||||
new Change.Key(info.change_id()),
|
||||
info.legacy_id(),
|
||||
new Account.Id(info.owner()._account_id()),
|
||||
new Branch.NameKey(
|
||||
info.project_name_key(),
|
||||
info.branch()),
|
||||
info.created());
|
||||
c.setTopic(info.topic());
|
||||
c.setStatus(info.status());
|
||||
c.setCurrentPatchSet(p);
|
||||
c.setLastUpdatedOn(info.updated());
|
||||
c.setMergeable(info.mergeable());
|
||||
return c;
|
||||
}
|
||||
|
||||
private static RevisionInfo current(ChangeInfo info) {
|
||||
RevisionInfo rev = info.revision(info.current_revision());
|
||||
if (rev == null) {
|
||||
JsArray<RevisionInfo> all = info.revisions().values();
|
||||
RevisionInfo.sortRevisionInfoByNumber(all);
|
||||
rev = all.get(all.length() - 1);
|
||||
}
|
||||
return rev;
|
||||
}
|
||||
|
||||
public static void setChangeDetail(ChangeDetail detail) {
|
||||
Change.Id chgId = detail.getChange().getId();
|
||||
ChangeCache.get(chgId).getChangeDetailCache().set(detail);
|
||||
@@ -75,6 +281,11 @@ public class ChangeDetailCache extends ListenableValue<ChangeDetail> {
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
Util.DETAIL_SVC.changeDetail(changeId, new GerritCallback());
|
||||
RestApi call = ChangeApi.detail(changeId.get());
|
||||
ChangeList.addOptions(call, EnumSet.of(
|
||||
ListChangesOption.CURRENT_ACTIONS,
|
||||
ListChangesOption.ALL_REVISIONS,
|
||||
ListChangesOption.ALL_COMMITS));
|
||||
call.get(new NewGerritCallback());
|
||||
}
|
||||
}
|
||||
|
@@ -18,9 +18,18 @@ import com.google.gerrit.client.Dispatcher;
|
||||
import com.google.gerrit.client.FormatUtil;
|
||||
import com.google.gerrit.client.Gerrit;
|
||||
import com.google.gerrit.client.account.AccountInfo;
|
||||
import com.google.gerrit.client.change.RelatedChanges;
|
||||
import com.google.gerrit.client.change.RelatedChanges.ChangeAndCommit;
|
||||
import com.google.gerrit.client.changes.ChangeInfo.CommitInfo;
|
||||
import com.google.gerrit.client.diff.DiffApi;
|
||||
import com.google.gerrit.client.diff.FileInfo;
|
||||
import com.google.gerrit.client.projects.ConfigInfoCache;
|
||||
import com.google.gerrit.client.rpc.CallbackGroup;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.client.rpc.NativeMap;
|
||||
import com.google.gerrit.client.rpc.NativeString;
|
||||
import com.google.gerrit.client.rpc.Natives;
|
||||
import com.google.gerrit.client.rpc.RestApi;
|
||||
import com.google.gerrit.client.ui.CommentLinkProcessor;
|
||||
import com.google.gerrit.client.ui.CommentPanel;
|
||||
import com.google.gerrit.client.ui.ComplexDisclosurePanel;
|
||||
@@ -28,14 +37,22 @@ import com.google.gerrit.client.ui.ExpandAllCommand;
|
||||
import com.google.gerrit.client.ui.LinkMenuBar;
|
||||
import com.google.gerrit.client.ui.NeedsSignInKeyCommand;
|
||||
import com.google.gerrit.client.ui.Screen;
|
||||
import com.google.gerrit.common.changes.ListChangesOption;
|
||||
import com.google.gerrit.common.data.AccountInfoCache;
|
||||
import com.google.gerrit.common.data.ChangeDetail;
|
||||
import com.google.gerrit.common.data.ChangeInfo;
|
||||
import com.google.gerrit.common.data.SubmitTypeRecord;
|
||||
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.CommentVisibilityStrategy;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.Change.Status;
|
||||
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||
import com.google.gerrit.reviewdb.client.Patch;
|
||||
import com.google.gerrit.reviewdb.client.Patch.ChangeType;
|
||||
import com.google.gerrit.reviewdb.client.Patch.PatchType;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gwt.core.client.JsArray;
|
||||
import com.google.gwt.core.client.JsArrayString;
|
||||
import com.google.gwt.event.dom.client.ChangeEvent;
|
||||
import com.google.gwt.event.dom.client.ChangeHandler;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
@@ -45,6 +62,7 @@ import com.google.gwt.event.logical.shared.ValueChangeEvent;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeHandler;
|
||||
import com.google.gwt.event.shared.HandlerRegistration;
|
||||
import com.google.gwt.i18n.client.LocaleInfo;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.DisclosurePanel;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
@@ -59,7 +77,13 @@ import com.google.gwtexpui.globalkey.client.KeyCommand;
|
||||
import com.google.gwtexpui.globalkey.client.KeyCommandSet;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
public class ChangeScreen extends Screen
|
||||
@@ -273,10 +297,209 @@ public class ChangeScreen extends Screen
|
||||
// happen sequentially after the ChangeDetail lookup, because we can't
|
||||
// start an async get at the source of every call that might trigger a
|
||||
// value change.
|
||||
CallbackGroup cbs = new CallbackGroup();
|
||||
CallbackGroup cbs1 = new CallbackGroup();
|
||||
final CallbackGroup cbs2 = new CallbackGroup();
|
||||
final PatchSet.Id psId = event.getValue().getCurrentPatchSet().getId();
|
||||
final Map<String, Patch> patches = new HashMap<String, Patch>();
|
||||
String revId =
|
||||
event.getValue().getCurrentPatchSetDetail().getInfo().getRevId();
|
||||
|
||||
if (event.getValue().getChange().getStatus().isOpen()) {
|
||||
ChangeApi.revision(changeId.get(), "current")
|
||||
.view("submit_type")
|
||||
.get(cbs1.add(new GerritCallback<NativeString>() {
|
||||
@Override
|
||||
public void onSuccess(NativeString result) {
|
||||
event.getValue().setSubmitTypeRecord(SubmitTypeRecord.OK(
|
||||
Project.SubmitType.valueOf(result.asString())));
|
||||
}
|
||||
public void onFailure(Throwable caught) {}
|
||||
}));
|
||||
}
|
||||
if (Gerrit.isSignedIn()) {
|
||||
ChangeApi.revision(changeId.get(), "" + psId.get())
|
||||
.view("related")
|
||||
.get(cbs1.add(new AsyncCallback<RelatedChanges.RelatedInfo>() {
|
||||
@Override
|
||||
public void onSuccess(RelatedChanges.RelatedInfo info) {
|
||||
if (info.changes() != null) {
|
||||
dependsOn(info);
|
||||
neededBy(info);
|
||||
}
|
||||
}
|
||||
|
||||
private void dependsOn(RelatedChanges.RelatedInfo info) {
|
||||
ChangeAndCommit self = null;
|
||||
Map<String, ChangeAndCommit> m = new HashMap<String, ChangeAndCommit>();
|
||||
for (int i = 0; i < info.changes().length(); i++) {
|
||||
ChangeAndCommit c = info.changes().get(i);
|
||||
if (changeId.equals(c.legacy_id())) {
|
||||
self = c;
|
||||
}
|
||||
if (c.commit() != null && c.commit().commit() != null) {
|
||||
m.put(c.commit().commit(), c);
|
||||
}
|
||||
}
|
||||
if (self != null && self.commit() != null
|
||||
&& self.commit().parents() != null) {
|
||||
List<ChangeInfo> d = new ArrayList<ChangeInfo>();
|
||||
for (CommitInfo p : Natives.asList(self.commit().parents())) {
|
||||
ChangeAndCommit pc = m.get(p.commit());
|
||||
if (pc != null) {
|
||||
ChangeInfo i = new ChangeInfo();
|
||||
load(pc, i);
|
||||
d.add(i);
|
||||
}
|
||||
}
|
||||
event.getValue().setDependsOn(d);
|
||||
}
|
||||
}
|
||||
|
||||
private void neededBy(RelatedChanges.RelatedInfo info) {
|
||||
Set<String> mine = new HashSet<String>();
|
||||
for (PatchSet ps : event.getValue().getPatchSets()) {
|
||||
mine.add(ps.getRevision().get());
|
||||
}
|
||||
|
||||
List<ChangeInfo> n = new ArrayList<ChangeInfo>();
|
||||
for (int i = 0; i < info.changes().length(); i++) {
|
||||
ChangeAndCommit c = info.changes().get(i);
|
||||
if (c.commit() != null && c.commit().parents() != null) {
|
||||
for (int j = 0; j < c.commit().parents().length(); j++) {
|
||||
CommitInfo p = c.commit().parents().get(j);
|
||||
if (mine.contains(p.commit())) {
|
||||
ChangeInfo u = new ChangeInfo();
|
||||
load(c, u);
|
||||
n.add(u);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
event.getValue().setNeededBy(n);
|
||||
}
|
||||
|
||||
private void load(final ChangeAndCommit pc, final ChangeInfo i) {
|
||||
RestApi call = ChangeApi.change(pc.legacy_id().get());
|
||||
ChangeList.addOptions(call, EnumSet.of(
|
||||
ListChangesOption.DETAILED_ACCOUNTS,
|
||||
ListChangesOption.CURRENT_REVISION));
|
||||
call.get(cbs2.add(new AsyncCallback<
|
||||
com.google.gerrit.client.changes.ChangeInfo>() {
|
||||
public void onFailure(Throwable caught) {}
|
||||
public void onSuccess(
|
||||
com.google.gerrit.client.changes.ChangeInfo result) {
|
||||
i.set(ChangeDetailCache.toChange(result),
|
||||
pc.patch_set_id());
|
||||
i.setStarred(result.starred());
|
||||
event.getValue().getAccounts()
|
||||
.merge(ChangeDetailCache.users(result));
|
||||
}}));
|
||||
}
|
||||
public void onFailure(Throwable caught) {}
|
||||
}));
|
||||
ChangeApi.revision(changeId.get(), revId)
|
||||
.view("files")
|
||||
.addParameterTrue("reviewed")
|
||||
.get(cbs1.add(new AsyncCallback<JsArrayString>() {
|
||||
@Override
|
||||
public void onSuccess(JsArrayString result) {
|
||||
for(int i = 0; i < result.length(); i++) {
|
||||
String path = result.get(i);
|
||||
Patch p = patches.get(path);
|
||||
if (p == null) {
|
||||
p = new Patch(new Patch.Key(psId, path));
|
||||
patches.put(path, p);
|
||||
}
|
||||
p.setReviewedByCurrentUser(true);
|
||||
}
|
||||
}
|
||||
public void onFailure(Throwable caught) {}
|
||||
}));
|
||||
final Set<PatchSet.Id> withDrafts = new HashSet<PatchSet.Id>();
|
||||
event.getValue().setPatchSetsWithDraftComments(withDrafts);
|
||||
for (PatchSet ps : event.getValue().getPatchSets()) {
|
||||
if (!ps.getId().equals(psId)) {
|
||||
final PatchSet.Id id = ps.getId();
|
||||
ChangeApi.revision(changeId.get(), "" + id.get())
|
||||
.view("drafts")
|
||||
.get(cbs1.add(new AsyncCallback<NativeMap<JsArray<CommentInfo>>>() {
|
||||
@Override
|
||||
public void onSuccess(NativeMap<JsArray<CommentInfo>> result) {
|
||||
if (!result.isEmpty()) {
|
||||
withDrafts.add(id);
|
||||
}
|
||||
}
|
||||
public void onFailure(Throwable caught) {}
|
||||
}));
|
||||
}
|
||||
}
|
||||
ChangeApi.revision(changeId.get(), "" + psId.get())
|
||||
.view("drafts")
|
||||
.get(cbs1.add(new AsyncCallback<NativeMap<JsArray<CommentInfo>>>() {
|
||||
@Override
|
||||
public void onSuccess(NativeMap<JsArray<CommentInfo>> result) {
|
||||
for (String path : result.keySet()) {
|
||||
Patch p = patches.get(path);
|
||||
if (p == null) {
|
||||
p = new Patch(new Patch.Key(psId, path));
|
||||
patches.put(path, p);
|
||||
}
|
||||
p.setDraftCount(result.get(path).length());
|
||||
}
|
||||
if (!result.isEmpty()) {
|
||||
withDrafts.add(psId);
|
||||
}
|
||||
}
|
||||
public void onFailure(Throwable caught) {}
|
||||
}));
|
||||
}
|
||||
ChangeApi.revision(changeId.get(), revId)
|
||||
.view("comments")
|
||||
.get(cbs1.add(new AsyncCallback<NativeMap<JsArray<CommentInfo>>>() {
|
||||
@Override
|
||||
public void onSuccess(NativeMap<JsArray<CommentInfo>> result) {
|
||||
for (String path : result.keySet()) {
|
||||
Patch p = patches.get(path);
|
||||
if (p == null) {
|
||||
p = new Patch(new Patch.Key(psId, path));
|
||||
patches.put(path, p);
|
||||
}
|
||||
p.setCommentCount(result.get(path).length());
|
||||
}
|
||||
}
|
||||
public void onFailure(Throwable caught) {}
|
||||
}));
|
||||
DiffApi.list(changeId.get(), null, revId,
|
||||
new AsyncCallback<NativeMap<FileInfo>>() {
|
||||
@Override
|
||||
public void onSuccess(NativeMap<FileInfo> result) {
|
||||
JsArray<FileInfo> fileInfos = result.values();
|
||||
FileInfo.sortFileInfoByPath(fileInfos);
|
||||
List<Patch> list = new ArrayList<Patch>(fileInfos.length());
|
||||
for (FileInfo f : Natives.asList(fileInfos)) {
|
||||
Patch p = patches.get(f.path());
|
||||
if (p == null) {
|
||||
p = new Patch(new Patch.Key(psId, f.path()));
|
||||
patches.put(f.path(), p);
|
||||
}
|
||||
p.setInsertions(f.lines_inserted());
|
||||
p.setDeletions(f.lines_deleted());
|
||||
p.setPatchType(f.binary() ? PatchType.BINARY : PatchType.UNIFIED);
|
||||
if (f.status() == null) {
|
||||
p.setChangeType(ChangeType.MODIFIED);
|
||||
} else {
|
||||
p.setChangeType(ChangeType.forCode(f.status().charAt(0)));
|
||||
}
|
||||
list.add(p);
|
||||
}
|
||||
event.getValue().getCurrentPatchSetDetail().setPatches(list);
|
||||
}
|
||||
public void onFailure(Throwable caught) {}
|
||||
});
|
||||
ConfigInfoCache.get(
|
||||
event.getValue().getChange().getProject(),
|
||||
cbs.add(new GerritCallback<ConfigInfoCache.Entry>() {
|
||||
cbs1.add(new GerritCallback<ConfigInfoCache.Entry>() {
|
||||
@Override
|
||||
public void onSuccess(ConfigInfoCache.Entry result) {
|
||||
commentLinkProcessor = result.getCommentLinkProcessor();
|
||||
@@ -288,13 +511,19 @@ public class ChangeScreen extends Screen
|
||||
// Handled by last callback's onFailure.
|
||||
}
|
||||
}));
|
||||
ChangeApi.detail(event.getValue().getChange().getId().get(), cbs.addFinal(
|
||||
ChangeApi.detail(changeId.get(), cbs1.addFinal(
|
||||
new GerritCallback<com.google.gerrit.client.changes.ChangeInfo>() {
|
||||
@Override
|
||||
public void onSuccess(
|
||||
com.google.gerrit.client.changes.ChangeInfo result) {
|
||||
changeInfo = result;
|
||||
display(event.getValue());
|
||||
cbs2.addFinal(new AsyncCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(Void result) {
|
||||
display(event.getValue());
|
||||
}
|
||||
public void onFailure(Throwable caught) {}
|
||||
}).onSuccess(null);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
@@ -15,9 +15,11 @@
|
||||
package com.google.gerrit.client.changes;
|
||||
|
||||
import com.google.gerrit.client.Gerrit;
|
||||
import com.google.gerrit.client.changes.ChangeInfo.IncludedInInfo;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.common.data.IncludedInDetail;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gwt.core.client.JsArrayString;
|
||||
import com.google.gwt.event.logical.shared.OpenEvent;
|
||||
import com.google.gwt.event.logical.shared.OpenHandler;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
@@ -25,6 +27,9 @@ import com.google.gwt.user.client.ui.DisclosurePanel;
|
||||
import com.google.gwt.user.client.ui.Grid;
|
||||
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/** Displays a table of Branches and Tags containing the change record. */
|
||||
public class IncludedInTable extends Composite implements
|
||||
@@ -73,13 +78,26 @@ public class IncludedInTable extends Composite implements
|
||||
@Override
|
||||
public void onOpen(OpenEvent<DisclosurePanel> event) {
|
||||
if (!loaded) {
|
||||
Util.DETAIL_SVC.includedInDetail(changeId,
|
||||
new GerritCallback<IncludedInDetail>() {
|
||||
@Override
|
||||
public void onSuccess(final IncludedInDetail result) {
|
||||
loadTable(result);
|
||||
ChangeApi.includedIn(changeId.get(),
|
||||
new GerritCallback<IncludedInInfo>() {
|
||||
@Override
|
||||
public void onSuccess(IncludedInInfo r) {
|
||||
IncludedInDetail result = new IncludedInDetail();
|
||||
result.setBranches(toList(r.branches()));
|
||||
result.setTags(toList(r.tags()));
|
||||
loadTable(result);
|
||||
}
|
||||
|
||||
private List<String> toList(JsArrayString in) {
|
||||
List<String> r = new ArrayList<String>();
|
||||
if (in != null) {
|
||||
for (int i = 0; i < in.length(); i++) {
|
||||
r.add(in.get(i));
|
||||
}
|
||||
});
|
||||
}
|
||||
return r;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -20,7 +20,6 @@ import com.google.gerrit.client.Gerrit;
|
||||
import com.google.gerrit.client.GitwebLink;
|
||||
import com.google.gerrit.client.change.DraftActions;
|
||||
import com.google.gerrit.client.download.DownloadPanel;
|
||||
import com.google.gerrit.client.patches.PatchUtil;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.client.rpc.NativeString;
|
||||
import com.google.gerrit.client.rpc.RestApi;
|
||||
|
@@ -1,377 +0,0 @@
|
||||
// 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.httpd.rpc.changedetail;
|
||||
|
||||
import com.google.gerrit.common.data.ChangeDetail;
|
||||
import com.google.gerrit.common.data.ChangeInfo;
|
||||
import com.google.gerrit.common.data.SubmitRecord;
|
||||
import com.google.gerrit.common.errors.NoSuchEntityException;
|
||||
import com.google.gerrit.extensions.restapi.AuthException;
|
||||
import com.google.gerrit.extensions.restapi.BadRequestException;
|
||||
import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
||||
import com.google.gerrit.httpd.rpc.Handler;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gerrit.reviewdb.client.PatchSetAncestor;
|
||||
import com.google.gerrit.reviewdb.client.RevId;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.AnonymousUser;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.ProjectUtil;
|
||||
import com.google.gerrit.server.account.AccountInfoCacheFactory;
|
||||
import com.google.gerrit.server.change.ChangeResource;
|
||||
import com.google.gerrit.server.change.Mergeable;
|
||||
import com.google.gerrit.server.change.RevisionResource;
|
||||
import com.google.gerrit.server.changedetail.RebaseChange;
|
||||
import com.google.gerrit.server.config.GerritServerConfig;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
import com.google.gerrit.server.project.NoSuchChangeException;
|
||||
import com.google.gerrit.server.project.NoSuchProjectException;
|
||||
import com.google.gerrit.server.query.change.ChangeData;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.gwtorm.server.ResultSet;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/** Creates a {@link ChangeDetail} from a {@link Change}. */
|
||||
public class ChangeDetailFactory extends Handler<ChangeDetail> {
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(ChangeDetailFactory.class);
|
||||
|
||||
public interface Factory {
|
||||
ChangeDetailFactory create(Change.Id id);
|
||||
}
|
||||
|
||||
private final ChangeControl.Factory changeControlFactory;
|
||||
private final PatchSetDetailFactory.Factory patchSetDetail;
|
||||
private final AccountInfoCacheFactory aic;
|
||||
private final AnonymousUser anonymousUser;
|
||||
private final ReviewDb db;
|
||||
private final GitRepositoryManager repoManager;
|
||||
|
||||
private final Change.Id changeId;
|
||||
|
||||
private ChangeDetail detail;
|
||||
private ChangeControl control;
|
||||
private Map<PatchSet.Id, PatchSet> patchsetsById;
|
||||
|
||||
private final Mergeable mergeable;
|
||||
|
||||
private List<PatchSetAncestor> currentPatchSetAncestors;
|
||||
private List<PatchSet> currentDepPatchSets;
|
||||
private List<Change> currentDepChanges;
|
||||
|
||||
@Inject
|
||||
ChangeDetailFactory(
|
||||
final PatchSetDetailFactory.Factory patchSetDetail, final ReviewDb db,
|
||||
final GitRepositoryManager repoManager,
|
||||
final ChangeControl.Factory changeControlFactory,
|
||||
final AccountInfoCacheFactory.Factory accountInfoCacheFactory,
|
||||
final AnonymousUser anonymousUser,
|
||||
final Mergeable mergeable,
|
||||
@GerritServerConfig final Config cfg,
|
||||
@Assisted final Change.Id id) {
|
||||
this.patchSetDetail = patchSetDetail;
|
||||
this.db = db;
|
||||
this.repoManager = repoManager;
|
||||
this.changeControlFactory = changeControlFactory;
|
||||
this.anonymousUser = anonymousUser;
|
||||
this.aic = accountInfoCacheFactory.create();
|
||||
|
||||
this.mergeable = mergeable;
|
||||
|
||||
this.changeId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChangeDetail call() throws OrmException, NoSuchEntityException,
|
||||
PatchSetInfoNotAvailableException, NoSuchChangeException,
|
||||
RepositoryNotFoundException, IOException, NoSuchProjectException {
|
||||
control = changeControlFactory.validateFor(changeId);
|
||||
final Change change = control.getChange();
|
||||
final PatchSet patch = db.patchSets().get(change.currentPatchSetId());
|
||||
if (patch == null) {
|
||||
throw new NoSuchEntityException();
|
||||
}
|
||||
|
||||
aic.want(change.getOwner());
|
||||
|
||||
detail = new ChangeDetail();
|
||||
detail.setChange(change);
|
||||
detail.setAllowsAnonymous(control.forUser(anonymousUser).isVisible(db));
|
||||
|
||||
detail.setCanAbandon(change.getStatus() != Change.Status.DRAFT && change.getStatus().isOpen() && control.canAbandon());
|
||||
detail.setCanPublish(control.canPublish(db));
|
||||
detail.setCanRestore(change.getStatus() == Change.Status.ABANDONED
|
||||
&& control.canRestore()
|
||||
&& ProjectUtil.branchExists(repoManager, change.getDest()));
|
||||
detail.setCanDeleteDraft(control.canDeleteDraft(db));
|
||||
detail.setStarred(control.getCurrentUser().getStarredChanges().contains(
|
||||
changeId));
|
||||
|
||||
detail.setCanRevert(change.getStatus() == Change.Status.MERGED && control.canAddPatchSet());
|
||||
detail.setCanCherryPick(control.getProjectControl().canUpload());
|
||||
detail.setCanEdit(control.getRefControl().canWrite());
|
||||
detail.setCanEditCommitMessage(change.getStatus().isOpen() && control.canAddPatchSet());
|
||||
detail.setCanEditTopicName(control.canEditTopicName());
|
||||
|
||||
List<SubmitRecord> submitRecords = control.getSubmitRecords(db, patch);
|
||||
for (SubmitRecord rec : submitRecords) {
|
||||
if (rec.labels != null) {
|
||||
for (SubmitRecord.Label lbl : rec.labels) {
|
||||
aic.want(lbl.appliedBy);
|
||||
}
|
||||
}
|
||||
if (detail.getChange().getStatus().isOpen()
|
||||
&& rec.status == SubmitRecord.Status.OK
|
||||
&& control.getRefControl().canSubmit()
|
||||
&& ProjectUtil.branchExists(repoManager, change.getDest())) {
|
||||
detail.setCanSubmit(true);
|
||||
}
|
||||
}
|
||||
detail.setSubmitRecords(submitRecords);
|
||||
|
||||
detail.setSubmitTypeRecord(control.getSubmitTypeRecord(db, patch));
|
||||
|
||||
patchsetsById = new HashMap<PatchSet.Id, PatchSet>();
|
||||
loadPatchSets();
|
||||
loadMessages();
|
||||
if (change.currentPatchSetId() != null) {
|
||||
loadCurrentPatchSet();
|
||||
}
|
||||
load();
|
||||
|
||||
detail.setCanRebase(detail.getChange().getStatus().isOpen() &&
|
||||
control.canRebase() &&
|
||||
RebaseChange.canDoRebase(db, change, repoManager,
|
||||
currentPatchSetAncestors, currentDepPatchSets, currentDepChanges));
|
||||
detail.setAccounts(aic.create());
|
||||
return detail;
|
||||
}
|
||||
|
||||
private void loadPatchSets() throws OrmException {
|
||||
ResultSet<PatchSet> source = db.patchSets().byChange(changeId);
|
||||
List<PatchSet> patches = new ArrayList<PatchSet>();
|
||||
Set<PatchSet.Id> patchesWithDraftComments = new HashSet<PatchSet.Id>();
|
||||
final CurrentUser user = control.getCurrentUser();
|
||||
final Account.Id me =
|
||||
user.isIdentifiedUser() ? ((IdentifiedUser) user).getAccountId()
|
||||
: null;
|
||||
for (PatchSet ps : source) {
|
||||
final PatchSet.Id psId = ps.getId();
|
||||
if (control.isPatchVisible(ps, db)) {
|
||||
patches.add(ps);
|
||||
if (me != null
|
||||
&& db.patchComments().draftByPatchSetAuthor(psId, me)
|
||||
.iterator().hasNext()) {
|
||||
patchesWithDraftComments.add(psId);
|
||||
}
|
||||
}
|
||||
patchsetsById.put(psId, ps);
|
||||
}
|
||||
detail.setPatchSets(patches);
|
||||
detail.setPatchSetsWithDraftComments(patchesWithDraftComments);
|
||||
}
|
||||
|
||||
private void loadMessages() throws OrmException {
|
||||
ResultSet<ChangeMessage> source = db.changeMessages().byChange(changeId);
|
||||
List<ChangeMessage> msgList = new ArrayList<ChangeMessage>();
|
||||
for (ChangeMessage msg : source) {
|
||||
PatchSet.Id id = msg.getPatchSetId();
|
||||
if (id != null) {
|
||||
PatchSet ps = patchsetsById.get(msg.getPatchSetId());
|
||||
if (ps != null && control.isPatchVisible(ps, db)) {
|
||||
msgList.add(msg);
|
||||
}
|
||||
} else {
|
||||
// Not guaranteed to have a non-null patchset id, so just display it.
|
||||
msgList.add(msg);
|
||||
}
|
||||
}
|
||||
detail.setMessages(msgList);
|
||||
for (final ChangeMessage m : detail.getMessages()) {
|
||||
aic.want(m.getAuthor());
|
||||
}
|
||||
}
|
||||
|
||||
private void load() throws OrmException, NoSuchChangeException,
|
||||
NoSuchProjectException {
|
||||
final Change.Status status = detail.getChange().getStatus();
|
||||
if ((status.equals(Change.Status.NEW) || status.equals(Change.Status.DRAFT))) {
|
||||
try {
|
||||
detail.getChange().setMergeable(mergeable.apply(new RevisionResource(
|
||||
new ChangeResource(control),
|
||||
detail.getCurrentPatchSet())).mergeable);
|
||||
} catch (RepositoryNotFoundException e) {
|
||||
log.warn("Cannot check mergeable", e);
|
||||
} catch (ResourceConflictException e) {
|
||||
log.warn("Cannot check mergeable", e);
|
||||
} catch (BadRequestException e) {
|
||||
log.warn("Cannot check mergeable", e);
|
||||
} catch (AuthException e) {
|
||||
log.warn("Cannot check mergeable", e);
|
||||
} catch (IOException e) {
|
||||
log.warn("Cannot check mergeable", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isReviewer(Change change) {
|
||||
// Return true if the currently logged in user is a reviewer of the change.
|
||||
try {
|
||||
return control.isReviewer(db, new ChangeData(change));
|
||||
} catch (OrmException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void loadCurrentPatchSet() throws OrmException,
|
||||
NoSuchEntityException, PatchSetInfoNotAvailableException,
|
||||
NoSuchChangeException {
|
||||
currentDepPatchSets = new ArrayList<PatchSet>();
|
||||
currentDepChanges = new ArrayList<Change>();
|
||||
final PatchSet currentPatch = findCurrentOrLatestPatchSet();
|
||||
final PatchSet.Id psId = currentPatch.getId();
|
||||
final PatchSetDetailFactory loader = patchSetDetail.create(null, psId, null);
|
||||
loader.patchSet = currentPatch;
|
||||
loader.control = control;
|
||||
detail.setCurrentPatchSetDetail(loader.call());
|
||||
detail.setCurrentPatchSetId(psId);
|
||||
|
||||
final HashSet<Change.Id> changesToGet = new HashSet<Change.Id>();
|
||||
final HashMap<Change.Id,PatchSet.Id> ancestorPatchIds =
|
||||
new HashMap<Change.Id,PatchSet.Id>();
|
||||
final List<Change.Id> ancestorOrder = new ArrayList<Change.Id>();
|
||||
currentPatchSetAncestors = db.patchSetAncestors().ancestorsOf(psId).toList();
|
||||
for (PatchSetAncestor a : currentPatchSetAncestors) {
|
||||
for (PatchSet p : db.patchSets().byRevision(a.getAncestorRevision())) {
|
||||
currentDepPatchSets.add(p);
|
||||
final Change.Id ck = p.getId().getParentKey();
|
||||
if (changesToGet.add(ck)) {
|
||||
ancestorPatchIds.put(ck, p.getId());
|
||||
ancestorOrder.add(ck);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Set<PatchSet.Id> descendants = new HashSet<PatchSet.Id>();
|
||||
RevId cprev;
|
||||
for (PatchSet p : detail.getPatchSets()) {
|
||||
cprev = p.getRevision();
|
||||
if (cprev != null) {
|
||||
for (PatchSetAncestor a : db.patchSetAncestors().descendantsOf(cprev)) {
|
||||
if (descendants.add(a.getPatchSet())) {
|
||||
changesToGet.add(a.getPatchSet().getParentKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
final Map<Change.Id, Change> m =
|
||||
db.changes().toMap(db.changes().get(changesToGet));
|
||||
|
||||
final CurrentUser currentUser = control.getCurrentUser();
|
||||
Account.Id currentUserId = null;
|
||||
if (currentUser.isIdentifiedUser()) {
|
||||
currentUserId = ((IdentifiedUser) currentUser).getAccountId();
|
||||
}
|
||||
|
||||
final ArrayList<ChangeInfo> dependsOn = new ArrayList<ChangeInfo>();
|
||||
for (final Change.Id a : ancestorOrder) {
|
||||
final Change ac = m.get(a);
|
||||
if (ac != null && ac.getProject().equals(detail.getChange().getProject())) {
|
||||
currentDepChanges.add(ac);
|
||||
if (ac.getStatus().getCode() != Change.STATUS_DRAFT
|
||||
|| ac.getOwner().equals(currentUserId)
|
||||
|| isReviewer(ac)) {
|
||||
dependsOn.add(newChangeInfo(ac, ancestorPatchIds));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final ArrayList<ChangeInfo> neededBy = new ArrayList<ChangeInfo>();
|
||||
for (final PatchSet.Id a : descendants) {
|
||||
final Change ac = m.get(a.getParentKey());
|
||||
if (ac != null && ac.currentPatchSetId().equals(a)) {
|
||||
if (ac.getStatus().getCode() != Change.STATUS_DRAFT
|
||||
|| ac.getOwner().equals(currentUserId)
|
||||
|| isReviewer(ac)) {
|
||||
neededBy.add(newChangeInfo(ac, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(neededBy, new Comparator<ChangeInfo>() {
|
||||
public int compare(final ChangeInfo o1, final ChangeInfo o2) {
|
||||
return o1.getId().get() - o2.getId().get();
|
||||
}
|
||||
});
|
||||
|
||||
detail.setDependsOn(dependsOn);
|
||||
detail.setNeededBy(neededBy);
|
||||
}
|
||||
|
||||
private PatchSet findCurrentOrLatestPatchSet() {
|
||||
PatchSet currentPatch = detail.getCurrentPatchSet();
|
||||
// If the current patch set is a draft and user can't see it, set the
|
||||
// current patch set to whatever the latest one is
|
||||
if (currentPatch == null) {
|
||||
List<PatchSet> patchSets = detail.getPatchSets();
|
||||
if (!detail.getPatchSets().isEmpty()) {
|
||||
currentPatch = patchSets.get(patchSets.size() - 1);
|
||||
} else {
|
||||
// Shouldn't happen, change shouldn't be visible if all the patchsets
|
||||
// are drafts
|
||||
}
|
||||
}
|
||||
return currentPatch;
|
||||
}
|
||||
|
||||
private ChangeInfo newChangeInfo(final Change ac,
|
||||
Map<Change.Id,PatchSet.Id> ancestorPatchIds) {
|
||||
aic.want(ac.getOwner());
|
||||
ChangeInfo ci;
|
||||
if (ancestorPatchIds == null) {
|
||||
ci = new ChangeInfo(ac);
|
||||
} else {
|
||||
ci = new ChangeInfo(ac, ancestorPatchIds.get(ac.getId()));
|
||||
}
|
||||
ci.setStarred(isStarred(ac));
|
||||
return ci;
|
||||
}
|
||||
|
||||
private boolean isStarred(final Change ac) {
|
||||
return control.getCurrentUser().getStarredChanges().contains(ac.getId());
|
||||
}
|
||||
}
|
@@ -14,44 +14,26 @@
|
||||
|
||||
package com.google.gerrit.httpd.rpc.changedetail;
|
||||
|
||||
import com.google.gerrit.common.data.ChangeDetail;
|
||||
import com.google.gerrit.common.data.ChangeDetailService;
|
||||
import com.google.gerrit.common.data.IncludedInDetail;
|
||||
import com.google.gerrit.common.data.PatchSetDetail;
|
||||
import com.google.gerrit.common.data.PatchSetPublishDetail;
|
||||
import com.google.gerrit.reviewdb.client.AccountDiffPreference;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
class ChangeDetailServiceImpl implements ChangeDetailService {
|
||||
private final ChangeDetailFactory.Factory changeDetail;
|
||||
private final IncludedInDetailFactory.Factory includedInDetail;
|
||||
private final PatchSetDetailFactory.Factory patchSetDetail;
|
||||
private final PatchSetPublishDetailFactory.Factory patchSetPublishDetail;
|
||||
|
||||
@Inject
|
||||
ChangeDetailServiceImpl(final ChangeDetailFactory.Factory changeDetail,
|
||||
final IncludedInDetailFactory.Factory includedInDetail,
|
||||
ChangeDetailServiceImpl(
|
||||
final PatchSetDetailFactory.Factory patchSetDetail,
|
||||
final PatchSetPublishDetailFactory.Factory patchSetPublishDetail) {
|
||||
this.changeDetail = changeDetail;
|
||||
this.includedInDetail = includedInDetail;
|
||||
this.patchSetDetail = patchSetDetail;
|
||||
this.patchSetPublishDetail = patchSetPublishDetail;
|
||||
}
|
||||
|
||||
public void changeDetail(final Change.Id id,
|
||||
final AsyncCallback<ChangeDetail> callback) {
|
||||
changeDetail.create(id).to(callback);
|
||||
}
|
||||
|
||||
public void includedInDetail(final Change.Id id,
|
||||
final AsyncCallback<IncludedInDetail> callback) {
|
||||
includedInDetail.create(id).to(callback);
|
||||
}
|
||||
|
||||
public void patchSetDetail(PatchSet.Id id,
|
||||
AsyncCallback<PatchSetDetail> callback) {
|
||||
patchSetDetail2(null, id, null, callback);
|
||||
|
@@ -28,8 +28,6 @@ public class ChangeModule extends RpcServletModule {
|
||||
install(new FactoryModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
factory(ChangeDetailFactory.Factory.class);
|
||||
factory(IncludedInDetailFactory.Factory.class);
|
||||
factory(PatchSetDetailFactory.Factory.class);
|
||||
factory(PatchSetPublishDetailFactory.Factory.class);
|
||||
}
|
||||
|
@@ -1,95 +0,0 @@
|
||||
// Copyright (C) 2010 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.httpd.rpc.changedetail;
|
||||
|
||||
import com.google.gerrit.common.data.IncludedInDetail;
|
||||
import com.google.gerrit.common.errors.InvalidRevisionException;
|
||||
import com.google.gerrit.httpd.rpc.Handler;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.change.IncludedInResolver;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
import com.google.gerrit.server.project.NoSuchChangeException;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||
import org.eclipse.jgit.errors.MissingObjectException;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/** Creates a {@link IncludedInDetail} of a {@link Change}. */
|
||||
class IncludedInDetailFactory extends Handler<IncludedInDetail> {
|
||||
|
||||
interface Factory {
|
||||
IncludedInDetailFactory create(Change.Id id);
|
||||
}
|
||||
|
||||
private final ReviewDb db;
|
||||
private final ChangeControl.Factory changeControlFactory;
|
||||
private final GitRepositoryManager repoManager;
|
||||
private final Change.Id changeId;
|
||||
|
||||
private ChangeControl control;
|
||||
|
||||
@Inject
|
||||
IncludedInDetailFactory(final ReviewDb db,
|
||||
final ChangeControl.Factory changeControlFactory,
|
||||
final GitRepositoryManager repoManager, @Assisted final Change.Id changeId) {
|
||||
this.changeControlFactory = changeControlFactory;
|
||||
this.repoManager = repoManager;
|
||||
this.changeId = changeId;
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IncludedInDetail call() throws OrmException, NoSuchChangeException,
|
||||
IOException, InvalidRevisionException {
|
||||
control = changeControlFactory.validateFor(changeId);
|
||||
|
||||
final PatchSet patch =
|
||||
db.patchSets().get(control.getChange().currentPatchSetId());
|
||||
final Repository repo =
|
||||
repoManager.openRepository(control.getProject().getNameKey());
|
||||
try {
|
||||
final RevWalk rw = new RevWalk(repo);
|
||||
try {
|
||||
rw.setRetainBody(false);
|
||||
|
||||
final RevCommit rev;
|
||||
try {
|
||||
rev = rw.parseCommit(ObjectId.fromString(patch.getRevision().get()));
|
||||
} catch (IncorrectObjectTypeException err) {
|
||||
throw new InvalidRevisionException();
|
||||
} catch (MissingObjectException err) {
|
||||
throw new InvalidRevisionException();
|
||||
}
|
||||
|
||||
return IncludedInResolver.resolve(repo, rw, rev);
|
||||
} finally {
|
||||
rw.release();
|
||||
}
|
||||
} finally {
|
||||
repo.close();
|
||||
}
|
||||
}
|
||||
}
|
@@ -19,7 +19,6 @@ import com.google.gerrit.common.data.PatchScript;
|
||||
import com.google.gerrit.common.errors.NoSuchEntityException;
|
||||
import com.google.gerrit.httpd.rpc.BaseServiceImplementation;
|
||||
import com.google.gerrit.httpd.rpc.Handler;
|
||||
import com.google.gerrit.httpd.rpc.changedetail.ChangeDetailFactory;
|
||||
import com.google.gerrit.reviewdb.client.AccountDiffPreference;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.Patch;
|
||||
@@ -48,7 +47,6 @@ class PatchDetailServiceImpl extends BaseServiceImplementation implements
|
||||
final Provider<CurrentUser> currentUser,
|
||||
final PatchScriptFactory.Factory patchScriptFactoryFactory,
|
||||
final SaveDraft.Factory saveDraftFactory,
|
||||
final ChangeDetailFactory.Factory changeDetailFactory,
|
||||
final ChangeControl.Factory changeControlFactory) {
|
||||
super(schema, currentUser);
|
||||
|
||||
|
Reference in New Issue
Block a user