485981: retrieve patchset and project details via REST

Bug fixes for ECLIPSE-279 and ECLIPSE-280, implementation for group
rights.

Change-Id: I35a17c8d0a7c6c700f177b438f26194857d1a54e
Signed-off-by: Natasha Carson <natasha.carson@tasktop.com>
diff --git a/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/client/GerritClient212.java b/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/client/GerritClient212.java
index 6fc8b05..88385a8 100644
--- a/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/client/GerritClient212.java
+++ b/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/client/GerritClient212.java
@@ -33,6 +33,7 @@
 import org.eclipse.mylyn.internal.gerrit.core.client.compat.PatchScriptX;
 import org.eclipse.mylyn.internal.gerrit.core.client.compat.ProjectDetailX;
 import org.eclipse.mylyn.internal.gerrit.core.client.compat.SchemeInfo;
+import org.eclipse.mylyn.internal.gerrit.core.client.rest.AccessSectionInfo;
 import org.eclipse.mylyn.internal.gerrit.core.client.rest.AccountInfo;
 import org.eclipse.mylyn.internal.gerrit.core.client.rest.ChangeInfo;
 import org.eclipse.mylyn.internal.gerrit.core.client.rest.CommentInfo;
@@ -45,6 +46,8 @@
 import org.eclipse.mylyn.internal.gerrit.core.client.rest.FileInfo;
 import org.eclipse.mylyn.internal.gerrit.core.client.rest.GitPersonalInfo;
 import org.eclipse.mylyn.internal.gerrit.core.client.rest.GroupInfo;
+import org.eclipse.mylyn.internal.gerrit.core.client.rest.PermissionInfo;
+import org.eclipse.mylyn.internal.gerrit.core.client.rest.PermissionRuleInfo;
 import org.eclipse.mylyn.internal.gerrit.core.client.rest.ProjectAccessInfo;
 import org.eclipse.mylyn.internal.gerrit.core.client.rest.ProjectInfo;
 import org.eclipse.mylyn.internal.gerrit.core.client.rest.ServerInfo;
@@ -54,12 +57,14 @@
 import com.google.gerrit.common.data.AccountInfoCache;
 import com.google.gerrit.common.data.CommentDetail;
 import com.google.gerrit.common.data.GerritConfig;
+import com.google.gerrit.common.data.InheritedRefRight;
 import com.google.gerrit.common.data.PatchScript.DisplayMethod;
 import com.google.gerrit.common.data.PatchSetDetail;
 import com.google.gerrit.prettify.common.SparseFileContent;
 import com.google.gerrit.reviewdb.Account;
 import com.google.gerrit.reviewdb.AccountDiffPreference;
 import com.google.gerrit.reviewdb.AccountGroup;
+import com.google.gerrit.reviewdb.ApprovalCategory;
 import com.google.gerrit.reviewdb.Change;
 import com.google.gerrit.reviewdb.Patch;
 import com.google.gerrit.reviewdb.Patch.ChangeType;
@@ -70,6 +75,8 @@
 import com.google.gerrit.reviewdb.PatchSetInfo;
 import com.google.gerrit.reviewdb.Project;
 import com.google.gerrit.reviewdb.Project.NameKey;
+import com.google.gerrit.reviewdb.RefRight;
+import com.google.gerrit.reviewdb.RefRight.RefPattern;
 import com.google.gerrit.reviewdb.RevId;
 import com.google.gerrit.reviewdb.UserIdentity;
 
@@ -151,12 +158,15 @@
 			diffInfo = retrieveDiffInfoNotBase(rightId, leftId, fileName, monitor);
 		}
 
-		CommentDetail commentDetail;
-		if (diffInfo.getContent().get(0).getA() != null || diffInfo.getContent().get(0).getAb() != null
-				|| diffInfo.getContent().get(0).getB() != null) {
-			commentDetail = setCommentDetails(leftId, rightId, fileName, monitor);
-		} else {
-			commentDetail = new CommentDetail(leftId, rightId);
+		CommentDetail commentDetail = new CommentDetail(leftId, rightId);
+		if (diffInfo != null) {
+			if (diffInfo.getContent().size() > 0) {
+				if (diffInfo.getContent().get(0).getA() != null || diffInfo.getContent().get(0).getAb() != null
+						|| diffInfo.getContent().get(0).getB() != null) {
+					commentDetail = setCommentDetails(leftId, rightId, fileName, commentDetail, monitor);
+				}
+			}
+
 		}
 
 		PatchScriptX patchScriptX = new PatchScriptX();
@@ -267,8 +277,7 @@
 	}
 
 	private CommentDetail setCommentDetails(PatchSet.Id leftId, PatchSet.Id rightId, String fileName,
-			IProgressMonitor monitor) throws GerritException {
-		CommentDetail commentDetail = new CommentDetail(leftId, rightId);
+			CommentDetail commentDetail, IProgressMonitor monitor) throws GerritException {
 		if (leftId != null) {
 			Map<String, List<CommentInfo>> commentInfo_A = retrieveRevisionComments(leftId, monitor);
 			adaptCommentDetails(commentInfo_A, leftId, commentDetail.getCommentsA(), fileName, commentDetail);
@@ -288,7 +297,6 @@
 	}
 
 	private com.google.gerrit.common.data.AccountInfo setAccountFromChangeInfo(ChangeInfo changeInfo) {
-		com.google.gerrit.common.data.AccountInfo accountInfo;
 		Account account = new Account(new Account.Id(changeInfo.getOwner().getId()));
 		account.setFullName(changeInfo.getOwner().getName());
 		account.setUserName(changeInfo.getOwner().getUsername());
@@ -336,8 +344,19 @@
 		Map<String, ProjectInfo> listedProjects = listProjects(monitor);
 		for (String projectName : listedProjects.keySet()) {
 			ProjectDetailX projectDetail = new ProjectDetailX();
+			ProjectAccessInfo accessRights = listAccessRights(projectName, monitor);
 			projectDetail.setProject(adaptProject(configInfo, projectName, monitor));
-			projectDetail.setGroups(adaptGroups(projectName, monitor));
+			if (accessRights.getGroups() != null) {
+				projectDetail.setGroups(adaptGroups(projectName, accessRights, monitor));
+				projectDetail.setRights(adaptRights(projectName, accessRights, monitor));
+			}
+			if (accessRights.is_owner()) {
+				projectDetail.setCanModifyDescription(true);
+				projectDetail.setCanModifyMergeType(true);
+				projectDetail.setCanModifyAgreements(true);
+				projectDetail.setCanModifyAccess(true);
+			}
+
 			projectDetails.add(projectDetail);
 		}
 		return projectDetails;
@@ -354,45 +373,78 @@
 
 	}
 
-	private Map<AccountGroup.Id, AccountGroup> adaptGroups(String projectName, IProgressMonitor monitor)
-			throws GerritException {
+	private Map<AccountGroup.Id, AccountGroup> adaptGroups(String projectName, ProjectAccessInfo accessRights,
+			IProgressMonitor monitor) throws GerritException {
 		Map<AccountGroup.Id, AccountGroup> groups = new HashMap<>();
-		ProjectAccessInfo accessRights = listAccessRights(projectName, monitor);
 		Map<String, GroupInfo> groupInfos = accessRights.getGroups();
 		if (groupInfos != null) {
 			for (String groupUuid : groupInfos.keySet()) {
 				GroupInfo groupInfo = groupInfos.get(groupUuid);
-				AccountGroup.Id groupId = AccountGroup.Id.parse(groupUuid);
+				AccountGroup.Id groupId = new AccountGroup.Id(groupInfo.getGroup_id());
 				String groupName = groupInfo.getName();
 				if (groupInfo.getName() == null) {
 					groupName = groupUuid;
 				}
-				groups.put(groupId, setAccountGroup(groupInfo, groupName, groupId));
+				groups.put(groupId, setAccountGroup(groupInfo, groupName, groupId, groupUuid));
 			}
 		}
 		return groups;
 	}
 
-	private AccountGroup setAccountGroup(GroupInfo groupInfo, String groupName, AccountGroup.Id groupId) {
+	private List<InheritedRefRight> adaptRights(String projectName, ProjectAccessInfo accessRights,
+			IProgressMonitor monitor) throws GerritException {
+		List<InheritedRefRight> inheritedRights = new ArrayList<>();
+		Map<String, AccessSectionInfo> localAccessRights = accessRights.getLocal();
+		for (String refName : localAccessRights.keySet()) {
+			RefPattern refPattern = new RefPattern(refName);
+			Map<String, PermissionInfo> accessSectionInfo = localAccessRights.get(refName).getPermissions();
+			for (String permissionName : accessSectionInfo.keySet()) {
+				ApprovalCategory.Id categoryId = new ApprovalCategory.Id(permissionName);
+				Map<String, PermissionRuleInfo> rules = accessSectionInfo.get(permissionName).getRules();
+				for (String groupUuid : rules.keySet()) {
+					if (getGroupType(groupUuid).equals(AccountGroup.Type.INTERNAL)
+							&& accessRights.getGroups().containsKey(groupUuid)) {
+						AccountGroup.Id groupId = new AccountGroup.Id(
+								accessRights.getGroups().get(groupUuid).getGroup_id());
+						RefRight refRight = new RefRight(
+								new RefRight.Key(new Project.NameKey(projectName), refPattern, categoryId, groupId)); // non internal groups dont have a group id
+						boolean inherited = true;
+						if (accessRights.getInherits_from() == null) {
+							inherited = false;
+						}
+						InheritedRefRight inheritedrefRight = new InheritedRefRight(refRight, inherited,
+								accessRights.is_owner());
+						inheritedRights.add(inheritedrefRight);
+					}
+				}
+			}
+		}
+		return inheritedRights;
+	}
+
+	private AccountGroup setAccountGroup(GroupInfo groupInfo, String groupName, AccountGroup.Id groupId,
+			String groupUuid) {
 		AccountGroup.NameKey nameKey = new AccountGroup.NameKey(groupName);
 		AccountGroup accGroup = new AccountGroup(nameKey, groupId);
 		accGroup.setDescription(groupInfo.getDescription());
 		accGroup.setExternalNameKey(new AccountGroup.ExternalNameKey(groupName));
 		accGroup.setNameKey(nameKey);
 		accGroup.setOwnerGroupId(groupId);
-		accGroup.setType(getGroupType(groupInfo.getId()));
+		if (groupUuid != null) {
+			accGroup.setType(getGroupType(groupUuid));
+		}
 		return accGroup;
 	}
 
 	private AccountGroup.Type getGroupType(String groupUuid) {
 		if (groupUuid.matches("^[0-9a-f]{40}$")) { //$NON-NLS-1$
 			return AccountGroup.Type.INTERNAL;
-		} else if (groupUuid.startsWith("global:")) { //$NON-NLS-1$
+		} else if (groupUuid.startsWith("global")) { //$NON-NLS-1$
 			return AccountGroup.Type.SYSTEM;
-		} else if (groupUuid.startsWith("ldap:")) { //$NON-NLS-1$
+		} else if (groupUuid.startsWith("ldap")) { //$NON-NLS-1$
 			return AccountGroup.Type.LDAP;
 		} else {
-			return null;
+			return AccountGroup.Type.INTERNAL;
 		}
 	}
 
diff --git a/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/client/rest/ProjectAccessInfo.java b/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/client/rest/ProjectAccessInfo.java
index 80d3425..742c20f 100644
--- a/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/client/rest/ProjectAccessInfo.java
+++ b/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/client/rest/ProjectAccessInfo.java
@@ -62,7 +62,7 @@
 		this.local = local;
 	}
 
-	public boolean isIs_owner() {
+	public boolean is_owner() {
 		return is_owner;
 	}