Merge branch 'stable-3.2' into stable-3.3

* stable-3.2:
  Introduce an optional configuration to define a regex for naming rules
  Upgrade bazlets to latest stable-3.1 to build with 3.1.12 API
  Upgrade bazlets to latest stable-3.2 to build with 3.2.6 API
  Upgrade bazlets to latest stable-3.1 to build with 3.1.11 API

Change-Id: Ic4e881927a5057b4209cac7d60d1bd8d9afccff4
diff --git a/WORKSPACE b/WORKSPACE
index b22385d..ae94609 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,7 @@
 load("//:bazlets.bzl", "load_bazlets")
 
 load_bazlets(
-    commit = "8dc0767541f16b35d2136eccebffd9ebe2b81133",
+    commit = "cf0bbc90e09a8a1d7c042d79f1555e3fa40984e1",
     #local_path = "/home/<user>/projects/bazlets",
 )
 
@@ -12,4 +12,4 @@
     "gerrit_api",
 )
 
-gerrit_api()
+gerrit_api(version = "3.3.0-SNAPSHOT")
diff --git a/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRights.java b/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRights.java
index b491d16..974b231 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRights.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRights.java
@@ -14,11 +14,11 @@
 
 package com.ericsson.gerrit.plugins.projectgroupstructure;
 
-import com.google.gerrit.common.data.AccessSection;
-import com.google.gerrit.common.data.GroupReference;
-import com.google.gerrit.common.data.Permission;
-import com.google.gerrit.common.data.PermissionRule;
+import com.google.gerrit.entities.AccessSection;
 import com.google.gerrit.entities.AccountGroup;
+import com.google.gerrit.entities.GroupReference;
+import com.google.gerrit.entities.Permission;
+import com.google.gerrit.entities.PermissionRule;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.exceptions.InvalidNameException;
 import com.google.gerrit.extensions.annotations.PluginData;
@@ -118,27 +118,30 @@
   private void setAccessRights(ProjectConfig config, ProjectState project) {
     for (String refName : defaultAccessRightsConfig.getSubsections(ProjectConfig.ACCESS)) {
       if (AccessSection.isValidRefSectionName(refName) && isValidRegex(refName)) {
-        AccessSection as = config.getAccessSection(refName, true);
-        getPermissions(refName, as);
-        setPermissions(refName, as, getOwnerGroupName(project));
+        config.upsertAccessSection(
+            refName,
+            as -> {
+              getPermissions(refName, as);
+              setPermissions(refName, as, getOwnerGroupName(project));
+            });
       }
     }
   }
 
-  private void getPermissions(String refName, AccessSection as) {
+  private void getPermissions(String refName, AccessSection.Builder as) {
     for (String varName :
         defaultAccessRightsConfig.getStringList(
             ProjectConfig.ACCESS, refName, "exclusiveGroupPermissions")) {
       Arrays.stream(varName.split("[, \t]{1,}"))
           .filter(Permission::isPermission)
-          .forEach(n -> as.getPermission(n, true).setExclusiveGroup(true));
+          .forEach(n -> as.upsertPermission(n).setExclusiveGroup(true));
     }
   }
 
-  private void setPermissions(String refName, AccessSection as, String ownerGroupName) {
+  private void setPermissions(String refName, AccessSection.Builder as, String ownerGroupName) {
     for (String value : defaultAccessRightsConfig.getNames(ProjectConfig.ACCESS, refName)) {
       if (Permission.isPermission(value)) {
-        Permission perm = as.getPermission(value, true);
+        Permission.Builder perm = as.upsertPermission(value);
         setPermissionRules(ownerGroupName, perm, refName, value);
       } else {
         log.error("Invalid permission {}", value);
@@ -168,15 +171,16 @@
   }
 
   private void setPermissionRules(
-      String ownerGroupName, Permission perm, String refName, String value) {
+      String ownerGroupName, Permission.Builder perm, String refName, String value) {
     for (String ruleString :
         defaultAccessRightsConfig.getStringList(ProjectConfig.ACCESS, refName, value)) {
-      PermissionRule rule;
+      PermissionRule.Builder rule;
       try {
         rule =
             PermissionRule.fromString(
-                ruleString.replaceAll(Pattern.quote(OWNER_TOKEN), ownerGroupName),
-                Permission.hasRange(value));
+                    ruleString.replaceAll(Pattern.quote(OWNER_TOKEN), ownerGroupName),
+                    Permission.hasRange(value))
+                .toBuilder();
 
       } catch (IllegalArgumentException notRule) {
         log.error(
@@ -199,7 +203,7 @@
           log.error("Group {} not found", rule.getGroup().getName());
           continue;
         }
-        rule.setGroup(new GroupReference(group.get().getGroupUUID(), rule.getGroup().getName()));
+        rule.setGroup(GroupReference.create(group.get().getGroupUUID(), rule.getGroup().getName()));
       }
       perm.add(rule);
     }
diff --git a/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidator.java b/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidator.java
index 089ca92..9a71293 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidator.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidator.java
@@ -18,8 +18,8 @@
 
 import com.google.common.base.Charsets;
 import com.google.common.hash.Hashing;
-import com.google.gerrit.common.data.GroupReference;
 import com.google.gerrit.entities.AccountGroup;
+import com.google.gerrit.entities.GroupReference;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.extensions.annotations.PluginCanonicalWebUrl;
 import com.google.gerrit.extensions.annotations.PluginName;
@@ -43,6 +43,7 @@
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
+import java.util.Optional;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -145,6 +146,11 @@
       // continuing
     }
 
+    if (name.contains(" ")) {
+      throw new ValidationException(
+          String.format(PROJECT_CANNOT_CONTAINS_SPACES_MSG, documentationUrl));
+    }
+
     if (allProjectsName.get().equals(newParent)) {
       validateRootProject(name, args.permissionsOnly);
     } else {
@@ -245,18 +251,18 @@
 
   private boolean isInDelegatingGroup(Project.NameKey parentCtrl) {
     try {
-      GroupReference delegateProjectCreationTo =
+      Optional<GroupReference> groupReference =
           cfg.getFromProjectConfigWithInheritance(parentCtrl, pluginName)
               .getGroupReference(DELEGATE_PROJECT_CREATION_TO);
-      if (delegateProjectCreationTo == null) {
-        return false;
+      if (groupReference.isPresent()) {
+        GroupReference delegateProjectCreationTo = groupReference.get();
+        log.debug("delegateProjectCreationTo: {}", delegateProjectCreationTo);
+        GroupMembership effectiveGroups = self.get().getEffectiveGroups();
+        return effectiveGroups.contains(delegateProjectCreationTo.getUUID());
       }
-      log.debug("delegateProjectCreationTo: {}", delegateProjectCreationTo);
-      GroupMembership effectiveGroups = self.get().getEffectiveGroups();
-      return effectiveGroups.contains(delegateProjectCreationTo.getUUID());
     } catch (NoSuchProjectException e) {
       log.error("isInDelegatingGroup with error ({}): {}", e.getClass().getName(), e.getMessage());
-      return false;
     }
+    return false;
   }
 }
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md
index 216ccc2..7c0d4b4 100644
--- a/src/main/resources/Documentation/about.md
+++ b/src/main/resources/Documentation/about.md
@@ -3,6 +3,10 @@
 enforce for the project group structure, it also enforce other naming
 rules like project name cannot contain spaces.
 
+Below description of plugins functionality is not applicable if user is an
+administrator. Administrators continue creating projects like this plugin does
+not exist.
+
 To start creating a project group structure, simply create a root project, i.e.
 a project which inherits rights from `All-Projects`. The root project name
 cannot contains slashes, e.g. `some-organization` and must be created with
@@ -83,9 +87,9 @@
 - Click `Publish` button, review, vote and submit the change to apply new
 configuration
 
-Ownership of a project created by delegated user is given automatically to that
-user by adding him to a group named `<root-project-name>-admins`. It is
-possible to disable granting the ownership by configuring
+Ownership of a project `<project-name>` created by delegated user is given
+automatically to that user by adding him to a group named `<project-name>-admins`.
+It is possible to disable granting the ownership by configuring
 `disableGrantingProjectOwnership` in the `project.config` of
 `refs/meta/config` branch of the parent project:
 
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 64af68d..b9eb8aa 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -1,4 +1,5 @@
 # Config
+
 The only configuration required is to grant `Create-group` and `Create-project`
 global permissions to `Registered Users` group.
 
@@ -22,8 +23,10 @@
   push = group ${owner}
   label-Code-Review = -2..+2 group ${owner}
   submit = group ${owner}
-
 ```
+
+Note: default access rights configuration is bypassed for projects created by admins.
+
 Also, this plugin offers a way to restrict the new names of the projects to match an optionally
 configured regex in the gerrit.config. For example:
 
diff --git a/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRightsIT.java b/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRightsIT.java
index 2f93c5b..1c2f3cd 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRightsIT.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/DefaultAccessRightsIT.java
@@ -21,10 +21,11 @@
 import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
 import com.google.gerrit.acceptance.TestPlugin;
 import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
-import com.google.gerrit.common.data.AccessSection;
 import com.google.gerrit.common.data.GlobalCapability;
-import com.google.gerrit.common.data.Permission;
+import com.google.gerrit.entities.AccessSection;
 import com.google.gerrit.entities.AccountGroup;
+import com.google.gerrit.entities.CachedProjectConfig;
+import com.google.gerrit.entities.Permission;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.extensions.api.projects.ProjectInput;
 import com.google.gerrit.extensions.restapi.Url;
@@ -88,11 +89,11 @@
 
     Optional<ProjectState> projectState = projectCache.get(Project.nameKey(projectName));
     AccountGroup.UUID ownerUUID = projectState.get().getOwners().iterator().next();
-    ProjectConfig projectConfig = projectState.get().getConfig();
+    CachedProjectConfig projectConfig = projectState.get().getConfig();
 
     assertThat(projectConfig.getAccessSections().size()).isEqualTo(2);
 
-    AccessSection refsSection = projectConfig.getAccessSection("refs/*");
+    AccessSection refsSection = projectConfig.getAccessSection("refs/*").get();
     assertThat(refsSection.getPermissions().size()).isEqualTo(3);
     assertThat(refsSection.getPermission(Permission.OWNER).getRules().get(0).getGroup().getUUID())
         .isEqualTo(ownerUUID);
@@ -102,7 +103,7 @@
     assertThat(refsSection.getPermission(Permission.PUSH).getRules().get(0).getGroup().getName())
         .isEqualTo("Administrators");
 
-    AccessSection refsHeadsSection = projectConfig.getAccessSection("refs/heads/*");
+    AccessSection refsHeadsSection = projectConfig.getAccessSection("refs/heads/*").get();
     assertThat(refsHeadsSection.getPermissions().size()).isEqualTo(4);
     assertThat(
             refsHeadsSection
diff --git a/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidatorIT.java b/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidatorIT.java
index 0f434f7..d6394e5 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidatorIT.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/projectgroupstructure/ProjectCreationValidatorIT.java
@@ -28,8 +28,8 @@
 import com.google.gerrit.acceptance.config.GerritConfig;
 import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
 import com.google.gerrit.common.data.GlobalCapability;
-import com.google.gerrit.common.data.GroupReference;
 import com.google.gerrit.entities.AccountGroup;
+import com.google.gerrit.entities.GroupReference;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.extensions.api.groups.GroupApi;
 import com.google.gerrit.extensions.api.projects.ProjectInput;
@@ -271,10 +271,12 @@
     try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
       ProjectConfig cfg = cfgUpdate.getConfig();
       String gId = gApi.groups().id(delegatingGroup).get().id;
-      cfg.getPluginConfig(PLUGIN_NAME)
-          .setGroupReference(
-              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
-              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
+      cfg.updatePluginConfig(
+          PLUGIN_NAME,
+          pluginCfg ->
+              pluginCfg.setGroupReference(
+                  ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
+                  GroupReference.create(AccountGroup.UUID.parse(gId), delegatingGroup)));
       cfgUpdate.save();
     }
     userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertCreated();
@@ -294,10 +296,12 @@
     try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
       ProjectConfig cfg = cfgUpdate.getConfig();
       String gId = gApi.groups().id(delegatingGroup).get().id;
-      cfg.getPluginConfig(PLUGIN_NAME)
-          .setGroupReference(
-              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
-              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
+      cfg.updatePluginConfig(
+          PLUGIN_NAME,
+          pluginCfg ->
+              pluginCfg.setGroupReference(
+                  ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
+                  GroupReference.create(AccountGroup.UUID.parse(gId), delegatingGroup)));
       cfgUpdate.save();
     }
 
@@ -345,12 +349,17 @@
     try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
       ProjectConfig cfg = cfgUpdate.getConfig();
       String gId = gApi.groups().id(delegatingGroup).get().id;
-      cfg.getPluginConfig(PLUGIN_NAME)
-          .setGroupReference(
-              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
-              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
-      cfg.getPluginConfig(PLUGIN_NAME)
-          .setBoolean(ProjectCreationValidator.DISABLE_GRANTING_PROJECT_OWNERSHIP, true);
+      cfg.updatePluginConfig(
+          PLUGIN_NAME,
+          pluginCfg ->
+              pluginCfg.setGroupReference(
+                  ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
+                  GroupReference.create(AccountGroup.UUID.parse(gId), delegatingGroup)));
+      cfg.updatePluginConfig(
+          PLUGIN_NAME,
+          pluginCfg ->
+              pluginCfg.setBoolean(
+                  ProjectCreationValidator.DISABLE_GRANTING_PROJECT_OWNERSHIP, true));
       cfgUpdate.save();
     }
 
@@ -387,8 +396,11 @@
     Project.NameKey parentNameKey = Project.nameKey(parent);
     try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
       ProjectConfig cfg = cfgUpdate.getConfig();
-      cfg.getPluginConfig(PLUGIN_NAME)
-          .setString(ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO, delegatingGroup);
+      cfg.updatePluginConfig(
+          PLUGIN_NAME,
+          pluginCfg ->
+              pluginCfg.setString(
+                  ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO, delegatingGroup));
       cfgUpdate.save();
     }
     userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertConflict();
@@ -425,10 +437,12 @@
     try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
       ProjectConfig cfg = cfgUpdate.getConfig();
       String gId = gApi.groups().id(delegatingGroup).get().id;
-      cfg.getPluginConfig(PLUGIN_NAME)
-          .setGroupReference(
-              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
-              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
+      cfg.updatePluginConfig(
+          PLUGIN_NAME,
+          pluginCfg ->
+              pluginCfg.setGroupReference(
+                  ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
+                  GroupReference.create(AccountGroup.UUID.parse(gId), delegatingGroup)));
       cfgUpdate.save();
     }
     userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertCreated();
@@ -460,10 +474,12 @@
     try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
       ProjectConfig cfg = cfgUpdate.getConfig();
       String gId = gApi.groups().id(delegatingGroup).get().id;
-      cfg.getPluginConfig(PLUGIN_NAME)
-          .setGroupReference(
-              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
-              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
+      cfg.updatePluginConfig(
+          PLUGIN_NAME,
+          pluginCfg ->
+              pluginCfg.setGroupReference(
+                  ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
+                  GroupReference.create(AccountGroup.UUID.parse(gId), delegatingGroup)));
       cfgUpdate.save();
     }
     userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertConflict();
@@ -493,10 +509,12 @@
     try (ProjectConfigUpdate cfgUpdate = updateProject(parentNameKey)) {
       ProjectConfig cfg = cfgUpdate.getConfig();
       String gId = "fake-gId";
-      cfg.getPluginConfig(PLUGIN_NAME)
-          .setGroupReference(
-              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
-              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
+      cfg.updatePluginConfig(
+          PLUGIN_NAME,
+          pluginCfg ->
+              pluginCfg.setGroupReference(
+                  ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
+                  GroupReference.create(AccountGroup.UUID.parse(gId), delegatingGroup)));
       cfgUpdate.save();
     }
     userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertConflict();
@@ -531,14 +549,16 @@
       ProjectConfig cfg = cfgUpdate.getConfig();
 
       String gId = gApi.groups().id(delegatingGroup).get().id;
-      cfg.getPluginConfig("project-group-structure")
-          .setGroupReference(
-              ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
-              new GroupReference(AccountGroup.UUID.parse(gId), delegatingGroup));
+      cfg.updatePluginConfig(
+          PLUGIN_NAME,
+          pluginCfg ->
+              pluginCfg.setGroupReference(
+                  ProjectCreationValidator.DELEGATE_PROJECT_CREATION_TO,
+                  GroupReference.create(AccountGroup.UUID.parse(gId), delegatingGroup)));
       cfgUpdate.save();
 
       String newDelegatingGroup = name("groupC");
-      gApi.groups().id(delegatingGroup).name(newDelegatingGroup);
+      cfg.renameGroup(cfg.getGroup(delegatingGroup).getUUID(), newDelegatingGroup);
     }
 
     userRestSession.put("/projects/" + Url.encode(parent + "/childProject"), in).assertCreated();