diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectCache.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectCache.java index e7f2e3a747..0e5cecbde3 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectCache.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectCache.java @@ -47,6 +47,9 @@ public interface ProjectCache { /** Invalidate the cached information about the given project. */ public void evict(Project p); + /** Invalidate the cached information about the given project. */ + public void evict(Project.NameKey p); + /** * Remove information about the given project from the cache. It will no * longer be returned from {@link #all()}. diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectCacheImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectCacheImpl.java index 58af4e12ff..8ccbca3dbd 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectCacheImpl.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectCacheImpl.java @@ -142,6 +142,13 @@ public class ProjectCacheImpl implements ProjectCache { } } + /** Invalidate the cached information about the given project. */ + public void evict(final Project.NameKey p) { + if (p != null) { + byName.invalidate(p.get()); + } + } + @Override public void remove(final Project p) { listLock.lock(); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectResource.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectResource.java index 39a51878e8..f4449f01b5 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectResource.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectResource.java @@ -25,7 +25,7 @@ public class ProjectResource implements RestResource { private final ProjectControl control; - ProjectResource(ProjectControl control) { + public ProjectResource(ProjectControl control) { this.control = control; } diff --git a/gerrit-server/src/test/java/com/google/gerrit/rules/GerritCommonTest.java b/gerrit-server/src/test/java/com/google/gerrit/rules/GerritCommonTest.java index 504d2d6e55..117c57b8a4 100644 --- a/gerrit-server/src/test/java/com/google/gerrit/rules/GerritCommonTest.java +++ b/gerrit-server/src/test/java/com/google/gerrit/rules/GerritCommonTest.java @@ -105,6 +105,11 @@ public class GerritCommonTest extends PrologTestCase { throw new UnsupportedOperationException(); } + @Override + public void evict(Project.NameKey p) { + throw new UnsupportedOperationException(); + } + @Override public void remove(Project p) { throw new UnsupportedOperationException(); diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java index 919a5a7dd6..968d661def 100644 --- a/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java +++ b/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java @@ -428,6 +428,10 @@ public class RefControlTest extends TestCase { public void evict(Project p) { } + @Override + public void evict(Project.NameKey p) { + } + @Override public void remove(Project p) { } diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/AdminSetParent.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/AdminSetParent.java index faf222499e..e83963a0e1 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/AdminSetParent.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/AdminSetParent.java @@ -17,18 +17,23 @@ package com.google.gerrit.sshd.commands; import com.google.common.base.Function; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; import com.google.gerrit.common.data.GlobalCapability; import com.google.gerrit.extensions.annotations.RequiresCapability; import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.server.config.AllProjectsName; import com.google.gerrit.server.git.MetaDataUpdate; import com.google.gerrit.server.git.ProjectConfig; +import com.google.gerrit.server.project.ListChildProjects; import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectControl; +import com.google.gerrit.server.project.ProjectJson.ProjectInfo; +import com.google.gerrit.server.project.ProjectResource; import com.google.gerrit.server.project.ProjectState; import com.google.gerrit.sshd.CommandMetaData; import com.google.gerrit.sshd.SshCommand; import com.google.inject.Inject; +import com.google.inject.Provider; import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.errors.RepositoryNotFoundException; @@ -73,6 +78,9 @@ final class AdminSetParent extends SshCommand { @Inject private AllProjectsName allProjectsName; + @Inject + private Provider listChildProjects; + private Project.NameKey newParentKey = null; @Override @@ -108,17 +116,16 @@ final class AdminSetParent extends SshCommand { } } - final List childProjects = new ArrayList(); + final List childProjects = Lists.newArrayList(); for (final ProjectControl pc : children) { - childProjects.add(pc.getProject()); + childProjects.add(pc.getProject().getNameKey()); } if (oldParent != null) { childProjects.addAll(getChildrenForReparenting(oldParent)); } - for (final Project project : childProjects) { - final String name = project.getName(); - final Project.NameKey nameKey = project.getNameKey(); + for (final Project.NameKey nameKey : childProjects) { + final String name = nameKey.get(); if (allProjectsName.equals(nameKey)) { // Don't allow the wild card project to have a parent. @@ -159,7 +166,7 @@ final class AdminSetParent extends SshCommand { err.append("error: " + msg + "\n"); } - projectCache.evict(project); + projectCache.evict(nameKey); } if (err.length() > 0) { @@ -175,8 +182,8 @@ final class AdminSetParent extends SshCommand { * reparented. The returned list of child projects does not contain projects * that were specified to be excluded from reparenting. */ - private List getChildrenForReparenting(final ProjectControl parent) { - final List childProjects = new ArrayList(); + private List getChildrenForReparenting(final ProjectControl parent) { + final List childProjects = Lists.newArrayList(); final List excluded = new ArrayList(excludedChildren.size()); for (final ProjectControl excludedChild : excludedChildren) { @@ -187,11 +194,12 @@ final class AdminSetParent extends SshCommand { if (newParentKey != null) { automaticallyExcluded.addAll(getAllParents(newParentKey)); } - for (final Project child : getChildren(parent.getProject().getNameKey())) { - final Project.NameKey childName = child.getNameKey(); + for (final ProjectInfo child : listChildProjects.get().apply( + new ProjectResource(parent))) { + final Project.NameKey childName = new Project.NameKey(child.name); if (!excluded.contains(childName)) { if (!automaticallyExcluded.contains(childName)) { - childProjects.add(child); + childProjects.add(childName); } else { stdout.println("Automatically excluded '" + childName + "' " + "from reparenting because it is in the parent " + @@ -213,20 +221,4 @@ final class AdminSetParent extends SshCommand { } })); } - - private List getChildren(final Project.NameKey parentName) { - final List childProjects = new ArrayList(); - for (final Project.NameKey projectName : projectCache.all()) { - final ProjectState e = projectCache.get(projectName); - if (e == null) { - // If we can't get it from the cache, pretend it's not present. - continue; - } - - if (parentName.equals(e.getProject().getParent(allProjectsName))) { - childProjects.add(e.getProject()); - } - } - return childProjects; - } }