| // Copyright (C) 2012 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.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.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.extensions.common.ListChangesOption; |
| import com.google.gerrit.reviewdb.client.Account; |
| import com.google.gerrit.reviewdb.client.Branch; |
| import com.google.gerrit.reviewdb.client.Change; |
| 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.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 NewGerritCallback extends |
| com.google.gerrit.client.rpc.GerritCallback<ChangeInfo> { |
| @Override |
| public void onSuccess(ChangeInfo detail) { |
| setChangeDetail(reverse(detail)); |
| } |
| } |
| |
| public static class IgnoreErrorCallback implements AsyncCallback<ChangeDetail> { |
| @Override |
| public void onSuccess(ChangeDetail info) { |
| setChangeDetail(info); |
| } |
| |
| @Override |
| public void onFailure(Throwable caught) { |
| } |
| } |
| |
| 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(rev.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(info.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<>(); |
| 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<>(); |
| 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<>(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); |
| StarredChanges.fireChangeStarEvent(chgId, detail.isStarred()); |
| } |
| |
| private final Change.Id changeId; |
| |
| public ChangeDetailCache(final Change.Id chg) { |
| changeId = chg; |
| } |
| |
| public void refresh() { |
| RestApi call = ChangeApi.detail(changeId.get()); |
| ChangeList.addOptions(call, EnumSet.of( |
| ListChangesOption.CURRENT_ACTIONS, |
| ListChangesOption.ALL_REVISIONS, |
| ListChangesOption.ALL_COMMITS)); |
| call.get(new NewGerritCallback()); |
| } |
| } |