Merge "Suggest parent for 'create-project' in the UI."
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectAdminService.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectAdminService.java
index 2d79759..4d10a42 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectAdminService.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectAdminService.java
@@ -31,6 +31,7 @@
   void visibleProjects(AsyncCallback<ProjectList> callback);
 
   void visibleProjectDetails(AsyncCallback<List<ProjectDetail>> callback);
+  void suggestParentCandidates(AsyncCallback<List<Project>> callback);
 
   void projectDetail(Project.NameKey projectName,
       AsyncCallback<ProjectDetail> callback);
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
index e08b03a..c928eb9 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
@@ -48,6 +48,7 @@
   String descriptionNotifications();
   String buttonSaveGroupOptions();
   String suggestedGroupLabel();
+  String parentSuggestions();
 
   String headingGroupUUID();
   String headingOwner();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
index 137f32d..f2a8ad6 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
@@ -26,6 +26,7 @@
 buttonSaveGroupOptions = Save Group Options
 suggestedGroupLabel = group
 headingParentProjectName = Rights Inherit From
+parentSuggestions = Parent Suggestion
 columnProjectName = Project Name
 
 emailOnlyAuthors = Authors
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/CreateProjectScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/CreateProjectScreen.java
index 5f12e4d..7f2ae07 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/CreateProjectScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/CreateProjectScreen.java
@@ -20,6 +20,7 @@
 import com.google.gerrit.client.rpc.GerritCallback;
 import com.google.gerrit.client.ui.HintTextBox;
 import com.google.gerrit.client.ui.ProjectNameSuggestOracle;
+import com.google.gerrit.client.ui.ProjectsTable;
 import com.google.gerrit.client.ui.Screen;
 import com.google.gerrit.reviewdb.Project;
 import com.google.gwt.event.dom.client.ClickEvent;
@@ -28,6 +29,7 @@
 import com.google.gwt.event.dom.client.KeyPressEvent;
 import com.google.gwt.event.dom.client.KeyPressHandler;
 import com.google.gwt.user.client.History;
+import com.google.gwt.user.client.ui.Anchor;
 import com.google.gwt.user.client.ui.Button;
 import com.google.gwt.user.client.ui.CheckBox;
 import com.google.gwt.user.client.ui.Grid;
@@ -36,6 +38,8 @@
 import com.google.gwtexpui.globalkey.client.NpTextBox;
 import com.google.gwtjsonrpc.client.VoidResult;
 
+import java.util.List;
+
 public class CreateProjectScreen extends Screen {
   private NpTextBox project;
   private Button create;
@@ -43,6 +47,7 @@
   private SuggestBox sugestParent;
   private CheckBox emptyCommit;
   private CheckBox permissionsOnly;
+  private ProjectsTable suggestedParentsTab;
 
   public CreateProjectScreen() {
     super();
@@ -59,7 +64,6 @@
   protected void onInitUI() {
     super.onInitUI();
     setPageTitle(Util.C.createProjectTitle());
-
     addCreateProjectPanel();
   }
 
@@ -78,7 +82,12 @@
     fp.add(emptyCommit);
     fp.add(permissionsOnly);
     fp.add(create);
-    add(fp);
+    VerticalPanel vp=new VerticalPanel();
+    vp.add(fp);
+    initSuggestedParents();
+    vp.add(suggestedParentsTab);
+    add(vp);
+
   }
 
   private void initCreateTxt() {
@@ -111,6 +120,44 @@
     parent.setVisibleLength(50);
   }
 
+  private void initSuggestedParents() {
+    suggestedParentsTab = new ProjectsTable() {
+      {
+        table.setText(0, 1, Util.C.parentSuggestions());
+      }
+
+      @Override
+      protected void populate(final int row, final Project k) {
+        final Anchor projectLink = new Anchor(k.getName());
+        projectLink.addClickHandler(new ClickHandler() {
+
+          @Override
+          public void onClick(ClickEvent event) {
+            sugestParent.setText(getRowItem(row).getName());
+          }
+        });
+
+        table.setWidget(row, 1, projectLink);
+        table.setText(row, 2, k.getDescription());
+
+        setRowItem(row, k);
+      }
+    };
+    suggestedParentsTab.setVisible(false);
+
+    Util.PROJECT_SVC
+        .suggestParentCandidates(new GerritCallback<List<Project>>() {
+          @Override
+          public void onSuccess(List<Project> result) {
+            if (result != null && !result.isEmpty()) {
+              suggestedParentsTab.setVisible(true);
+              suggestedParentsTab.display(result);
+              suggestedParentsTab.finishDisplay();
+            }
+          }
+        });
+  }
+
   private void addGrid(final VerticalPanel fp) {
     final Grid grid = new Grid(2, 2);
     grid.setStyleName(Gerrit.RESOURCES.css().infoBlock());
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectAdminServiceImpl.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectAdminServiceImpl.java
index 7c6584a..bf7eeae 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectAdminServiceImpl.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectAdminServiceImpl.java
@@ -42,6 +42,7 @@
   private final ProjectAccessFactory.Factory projectAccessFactory;
   private final CreateProjectHandler.Factory createProjectHandlerFactory;
   private final ProjectDetailFactory.Factory projectDetailFactory;
+  private final SuggestParentCandidatesHandler.Factory suggestParentCandidatesHandlerFactory;
 
   @Inject
   ProjectAdminServiceImpl(final AddBranch.Factory addBranchFactory,
@@ -53,6 +54,7 @@
       final VisibleProjectDetails.Factory visibleProjectDetailsFactory,
       final ProjectAccessFactory.Factory projectAccessFactory,
       final ProjectDetailFactory.Factory projectDetailFactory,
+      final SuggestParentCandidatesHandler.Factory parentCandidatesFactory,
       final CreateProjectHandler.Factory createNewProjectFactory) {
     this.addBranchFactory = addBranchFactory;
     this.changeProjectAccessFactory = changeProjectAccessFactory;
@@ -64,6 +66,7 @@
     this.projectAccessFactory = projectAccessFactory;
     this.projectDetailFactory = projectDetailFactory;
     this.createProjectHandlerFactory = createNewProjectFactory;
+    this.suggestParentCandidatesHandlerFactory = parentCandidatesFactory;
   }
 
   @Override
@@ -77,6 +80,11 @@
   }
 
   @Override
+  public void suggestParentCandidates(AsyncCallback<List<Project>> callback) {
+    suggestParentCandidatesHandlerFactory.create().to(callback);
+  }
+
+  @Override
   public void projectDetail(final Project.NameKey projectName,
       final AsyncCallback<ProjectDetail> callback) {
     projectDetailFactory.create(projectName).to(callback);
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectModule.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectModule.java
index 5678045..2eb55b3 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectModule.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectModule.java
@@ -38,6 +38,7 @@
         factory(VisibleProjectDetails.Factory.class);
         factory(ProjectAccessFactory.Factory.class);
         factory(ProjectDetailFactory.Factory.class);
+        factory(SuggestParentCandidatesHandler.Factory.class);
       }
     });
     rpc(ProjectAdminServiceImpl.class);
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/SuggestParentCandidatesHandler.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/SuggestParentCandidatesHandler.java
new file mode 100644
index 0000000..a6442e3
--- /dev/null
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/SuggestParentCandidatesHandler.java
@@ -0,0 +1,40 @@
+// Copyright (C) 2011 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.project;
+
+import com.google.gerrit.httpd.rpc.Handler;
+import com.google.gerrit.reviewdb.Project;
+import com.google.gerrit.server.project.SuggestParentCandidates;
+import com.google.inject.Inject;
+
+import java.util.List;
+
+public class SuggestParentCandidatesHandler extends Handler<List<Project>> {
+  interface Factory {
+    SuggestParentCandidatesHandler create();
+  }
+
+  private final SuggestParentCandidates suggestParentCandidates;
+
+  @Inject
+  SuggestParentCandidatesHandler(final SuggestParentCandidates suggestParentCandidates) {
+    this.suggestParentCandidates = suggestParentCandidates;
+  }
+
+  @Override
+  public List<Project> call() throws Exception {
+    return suggestParentCandidates.getProjects();
+  }
+}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritRequestModule.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritRequestModule.java
index 26a33b6..54445c5 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritRequestModule.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritRequestModule.java
@@ -53,7 +53,7 @@
 import com.google.gerrit.server.project.CreateProject;
 import com.google.gerrit.server.project.PerRequestProjectControlCache;
 import com.google.gerrit.server.project.ProjectControl;
-import com.google.gerrit.server.project.RetrieveParentCandidates;
+import com.google.gerrit.server.project.SuggestParentCandidates;
 import com.google.gerrit.server.query.change.ChangeQueryBuilder;
 import com.google.gerrit.server.query.change.ChangeQueryRewriter;
 import com.google.inject.servlet.RequestScoped;
@@ -108,6 +108,6 @@
     factory(GroupMembers.Factory.class);
     factory(CreateProject.Factory.class);
     factory(Submit.Factory.class);
-    factory(RetrieveParentCandidates.Factory.class);
+    factory(SuggestParentCandidates.Factory.class);
   }
 }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/RetrieveParentCandidates.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/RetrieveParentCandidates.java
deleted file mode 100644
index ee0ac82..0000000
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/RetrieveParentCandidates.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (C) 2011 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.server.project;
-
-import com.google.gerrit.reviewdb.Project;
-import com.google.gerrit.server.config.AllProjectsName;
-import com.google.gwtorm.client.OrmException;
-import com.google.inject.Inject;
-
-import java.util.Set;
-import java.util.TreeSet;
-
-public class RetrieveParentCandidates {
-  public interface Factory {
-    RetrieveParentCandidates create();
-  }
-
-  private final ProjectControl.Factory projectControlFactory;
-  private final ProjectCache projectCache;
-  private final AllProjectsName allProject;
-
-  @Inject
-  RetrieveParentCandidates(final ProjectControl.Factory projectControlFactory,
-      final ProjectCache projectCache, final AllProjectsName allProject) {
-    this.projectControlFactory = projectControlFactory;
-    this.projectCache = projectCache;
-    this.allProject = allProject;
-  }
-
-  public Set<Project.NameKey> get() throws OrmException {
-    final Set<Project.NameKey> r = new TreeSet<Project.NameKey>();
-
-    for (Project.NameKey p : projectCache.all()) {
-      try {
-        final ProjectControl project = projectControlFactory.controlFor(p);
-        final Project.NameKey parent = project.getProject().getParent();
-
-        if (parent != null) {
-          ProjectControl c = projectControlFactory.controlFor(parent);
-          if (c.isVisible() || c.isOwner()) {
-              r.add(parent);
-          }
-        }
-      } catch (NoSuchProjectException e) {
-        continue;
-      }
-    }
-    r.add(allProject);
-    return r;
-  }
-}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/SuggestParentCandidates.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/SuggestParentCandidates.java
new file mode 100644
index 0000000..9585e1e
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/SuggestParentCandidates.java
@@ -0,0 +1,81 @@
+// Copyright (C) 2011 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.server.project;
+
+import com.google.gerrit.reviewdb.Project;
+import com.google.gerrit.server.config.AllProjectsName;
+import com.google.gwtorm.client.OrmException;
+import com.google.inject.Inject;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+public class SuggestParentCandidates {
+  public interface Factory {
+    SuggestParentCandidates create();
+  }
+
+  private final ProjectControl.Factory projectControlFactory;
+  private final ProjectCache projectCache;
+  private final AllProjectsName allProject;
+
+  @Inject
+  SuggestParentCandidates(final ProjectControl.Factory projectControlFactory,
+      final ProjectCache projectCache, final AllProjectsName allProject) {
+    this.projectControlFactory = projectControlFactory;
+    this.projectCache = projectCache;
+    this.allProject = allProject;
+  }
+
+  public List<Project.NameKey> getNameKeys() throws OrmException,
+      NoSuchProjectException {
+    List<Project> pList = getProjects();
+    final List<Project.NameKey> nameKeys =
+        new ArrayList<Project.NameKey>(pList.size());
+    for (Project p : pList) {
+      nameKeys.add(p.getNameKey());
+    }
+    return nameKeys;
+  }
+
+  public List<Project> getProjects() throws OrmException,
+      NoSuchProjectException {
+    Set<Project> projects = new TreeSet<Project>(new Comparator<Project>() {
+      @Override
+      public int compare(Project o1, Project o2) {
+        return o1.getName().compareTo(o2.getName());
+      }
+    });
+    for (Project.NameKey p : projectCache.all()) {
+      try {
+        final ProjectControl control = projectControlFactory.controlFor(p);
+        final Project.NameKey parentK = control.getProject().getParent();
+        if (parentK != null) {
+          ProjectControl pControl = projectControlFactory.controlFor(parentK);
+          if (pControl.isVisible() || pControl.isOwner()) {
+            projects.add(pControl.getProject());
+          }
+        }
+      } catch (NoSuchProjectException e) {
+        continue;
+      }
+    }
+    projects.add(projectControlFactory.controlFor(allProject).getProject());
+    return new ArrayList<Project>(projects);
+  }
+}
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java
index af888fd..f0327c5 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/CreateProjectCommand.java
@@ -22,7 +22,7 @@
 import com.google.gerrit.server.project.CreateProject;
 import com.google.gerrit.server.project.CreateProjectArgs;
 import com.google.gerrit.server.project.ProjectControl;
-import com.google.gerrit.server.project.RetrieveParentCandidates;
+import com.google.gerrit.server.project.SuggestParentCandidates;
 import com.google.gerrit.sshd.BaseCommand;
 import com.google.inject.Inject;
 
@@ -34,7 +34,6 @@
 import java.io.PrintWriter;
 
 import java.util.List;
-import java.util.Set;
 
 /** Create a new project. **/
 final class CreateProjectCommand extends BaseCommand {
@@ -104,7 +103,7 @@
   private CreateProject.Factory CreateProjectFactory;
 
   @Inject
-  private RetrieveParentCandidates.Factory retrieveParentCandidatesFactory;
+  private SuggestParentCandidates.Factory suggestParentCandidatesFactory;
 
   @Override
   public void start(final Environment env) {
@@ -143,8 +142,8 @@
                 CreateProjectFactory.create(args);
             createProject.createProject();
           } else {
-            Set<Project.NameKey> parentCandidates =
-                retrieveParentCandidatesFactory.create().get();
+            List<Project.NameKey> parentCandidates =
+                suggestParentCandidatesFactory.create().getNameKeys();
 
             for (Project.NameKey parent : parentCandidates) {
               p.print(parent + "\n");