Support to list child projects recursively via REST
Change-Id: I046e4d546ca1f0a971382816de4ea76aef035f3f Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
This commit is contained in:

committed by
Gerrit Code Review

parent
5b6c406e38
commit
f95bd17c34
@@ -535,6 +535,63 @@ returned that describe the child projects.
|
||||
]
|
||||
----
|
||||
|
||||
To resolve the child projects of a project recursively the parameter
|
||||
`recursive` can be set.
|
||||
|
||||
Child projects that are not visible to the calling user are ignored and
|
||||
are not resolved further.
|
||||
|
||||
.Request
|
||||
----
|
||||
GET /projects/Public-Projects/children/?recursive HTTP/1.0
|
||||
----
|
||||
|
||||
.Response
|
||||
----
|
||||
HTTP/1.1 200 OK
|
||||
Content-Disposition: attachment
|
||||
Content-Type: application/json;charset=UTF-8
|
||||
|
||||
)]}'
|
||||
[
|
||||
{
|
||||
"kind": "gerritcodereview#project",
|
||||
"id": "gerrit",
|
||||
"name": "gerrit",
|
||||
"parent": "Public-Projects",
|
||||
"description": "Gerrit Code Review"
|
||||
},
|
||||
{
|
||||
"kind": "gerritcodereview#project",
|
||||
"id": "plugins%2Freplication",
|
||||
"name": "plugins/replication",
|
||||
"parent": "Public-Plugins",
|
||||
"description": "Copies to other servers using the Git protocol"
|
||||
},
|
||||
{
|
||||
"kind": "gerritcodereview#project",
|
||||
"id": "plugins%2Freviewnotes",
|
||||
"name": "plugins/reviewnotes",
|
||||
"parent": "Public-Plugins",
|
||||
"description": "Annotates merged commits using notes on refs/notes/review."
|
||||
},
|
||||
{
|
||||
"kind": "gerritcodereview#project",
|
||||
"id": "plugins%2Fsingleusergroup",
|
||||
"name": "plugins/singleusergroup",
|
||||
"parent": "Public-Plugins",
|
||||
"description": "GroupBackend enabling users to be directly added to access rules"
|
||||
},
|
||||
{
|
||||
"kind": "gerritcodereview#project",
|
||||
"id": "Public-Plugins",
|
||||
"name": "Public-Plugins",
|
||||
"parent": "Public-Projects",
|
||||
"description": "Parent project for plugins/*"
|
||||
}
|
||||
]
|
||||
----
|
||||
|
||||
[[get-child-project]]
|
||||
Get Child Project
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
@@ -93,6 +93,29 @@ public class ListChildProjectsIT extends AbstractDaemonTest {
|
||||
assertProjects(Arrays.asList(child1, child2), children);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listChildrenRecursively() throws IOException, JSchException {
|
||||
SshSession sshSession = new SshSession(admin);
|
||||
Project.NameKey child1 = new Project.NameKey("p1");
|
||||
createProject(sshSession, child1.get());
|
||||
createProject(sshSession, "p2");
|
||||
Project.NameKey child1_1 = new Project.NameKey("p1.1");
|
||||
createProject(sshSession, child1_1.get(), child1);
|
||||
Project.NameKey child1_2 = new Project.NameKey("p1.2");
|
||||
createProject(sshSession, child1_2.get(), child1);
|
||||
Project.NameKey child1_1_1 = new Project.NameKey("p1.1.1");
|
||||
createProject(sshSession, child1_1_1.get(), child1_1);
|
||||
Project.NameKey child1_1_1_1 = new Project.NameKey("p1.1.1.1");
|
||||
createProject(sshSession, child1_1_1_1.get(), child1_1_1);
|
||||
|
||||
RestResponse r = GET("/projects/" + child1.get() + "/children/?recursive");
|
||||
assertEquals(HttpStatus.SC_OK, r.getStatusCode());
|
||||
List<ProjectInfo> children =
|
||||
(new Gson()).fromJson(r.getReader(),
|
||||
new TypeToken<List<ProjectInfo>>() {}.getType());
|
||||
assertProjects(Arrays.asList(child1_1, child1_2, child1_1_1, child1_1_1_1), children);
|
||||
}
|
||||
|
||||
private RestResponse GET(String endpoint) throws IOException {
|
||||
return session.get(endpoint);
|
||||
}
|
||||
|
@@ -15,30 +15,49 @@
|
||||
package com.google.gerrit.server.project;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gerrit.extensions.restapi.RestReadView;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.config.AllProjectsName;
|
||||
import com.google.gerrit.server.project.ProjectJson.ProjectInfo;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.kohsuke.args4j.Option;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ListChildProjects implements RestReadView<ProjectResource> {
|
||||
|
||||
@Option(name = "--recursive", usage = "to list child projects recursively")
|
||||
private boolean recursive;
|
||||
|
||||
private final ProjectCache projectCache;
|
||||
private final AllProjectsName allProjects;
|
||||
private final ProjectJson json;
|
||||
private final ProjectNode.Factory projectNodeFactory;
|
||||
|
||||
@Inject
|
||||
ListChildProjects(ProjectCache projectCache, AllProjectsName allProjects,
|
||||
ProjectJson json) {
|
||||
ProjectJson json, ProjectNode.Factory projectNodeFactory) {
|
||||
this.projectCache = projectCache;
|
||||
this.allProjects = allProjects;
|
||||
this.json = json;
|
||||
this.projectNodeFactory = projectNodeFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProjectInfo> apply(ProjectResource rsrc) {
|
||||
if (recursive) {
|
||||
return getChildProjectsRecursively(rsrc.getNameKey(),
|
||||
rsrc.getControl().getCurrentUser());
|
||||
} else {
|
||||
return getDirectChildProjects(rsrc.getNameKey());
|
||||
}
|
||||
}
|
||||
|
||||
private List<ProjectInfo> getDirectChildProjects(Project.NameKey parent) {
|
||||
List<ProjectInfo> childProjects = Lists.newArrayList();
|
||||
for (Project.NameKey projectName : projectCache.all()) {
|
||||
ProjectState e = projectCache.get(projectName);
|
||||
@@ -46,10 +65,42 @@ public class ListChildProjects implements RestReadView<ProjectResource> {
|
||||
// If we can't get it from the cache, pretend it's not present.
|
||||
continue;
|
||||
}
|
||||
if (rsrc.getNameKey().equals(e.getProject().getParent(allProjects))) {
|
||||
if (parent.equals(e.getProject().getParent(allProjects))) {
|
||||
childProjects.add(json.format(e.getProject()));
|
||||
}
|
||||
}
|
||||
return childProjects;
|
||||
}
|
||||
|
||||
private List<ProjectInfo> getChildProjectsRecursively(Project.NameKey parent,
|
||||
CurrentUser user) {
|
||||
Map<Project.NameKey, ProjectNode> projects = Maps.newHashMap();
|
||||
for (Project.NameKey name : projectCache.all()) {
|
||||
ProjectState p = projectCache.get(name);
|
||||
if (p == null) {
|
||||
// If we can't get it from the cache, pretend it's not present.
|
||||
continue;
|
||||
}
|
||||
projects.put(name, projectNodeFactory.create(p.getProject(),
|
||||
p.controlFor(user).isVisible()));
|
||||
}
|
||||
for (ProjectNode key : projects.values()) {
|
||||
ProjectNode node = projects.get(key.getParentName());
|
||||
if (node != null) {
|
||||
node.addChild(key);
|
||||
}
|
||||
}
|
||||
return getChildProjectsRecursively(projects.get(parent));
|
||||
}
|
||||
|
||||
private List<ProjectInfo> getChildProjectsRecursively(ProjectNode p) {
|
||||
List<ProjectInfo> allChildren = Lists.newArrayList();
|
||||
for (ProjectNode c : p.getChildren()) {
|
||||
if (c.isVisible()) {
|
||||
allChildren.add(json.format(c.getProject()));
|
||||
allChildren.addAll(getChildProjectsRecursively(c));
|
||||
}
|
||||
}
|
||||
return allChildren;
|
||||
}
|
||||
}
|
||||
|
@@ -57,6 +57,10 @@ public class ProjectNode implements TreeNode, Comparable<ProjectNode> {
|
||||
return allProjectsName.equals(project.getNameKey());
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return project.getName();
|
||||
@@ -68,7 +72,7 @@ public class ProjectNode implements TreeNode, Comparable<ProjectNode> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedSet<? extends TreeNode> getChildren() {
|
||||
public SortedSet<? extends ProjectNode> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user