summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn O. Pearce <sop@google.com>2009-08-04 17:14:16 -0700
committerShawn O. Pearce <sop@google.com>2009-08-04 17:14:16 -0700
commitaf70a696b7224298970565478fd4253f96d928e7 (patch)
treebe5996f616e170781eb045486a7d9062bc8822d7
parent9706c38b7713c2fbe621d2d27c04724b6f0dddfd (diff)
Change project to use Project.NameKey as the primary key
Almost. We still keep Project.Id around, but all code does lookups and foreign keys now by Project.NameKey. The only real value we now get from Project.Id is the magical meaning of Project.Id(0), which is the wild card project. We obtain the name of that project from the database during startup, but otherwise look for the wildcard project by name rather than by id anytime we need to do conditional logic on an entity that might or might not be a member of the wildcard project. This change facilitates a future change we're looking at making, which is to move the data store for each project into its own Git repository, where global assignment of an integer identity just won't make sense. Since Project.NameKey already cannot be changed without a great deal of pain, adding to the pain by not being able to easily move the ProjectRight or AccountWatchedProjects makes sense. Signed-off-by: Shawn O. Pearce <sop@google.com>
-rw-r--r--src/main/java/com/google/gerrit/client/admin/ProjectAdminScreen.java3
-rw-r--r--src/main/java/com/google/gerrit/client/admin/ProjectInfoPanel.java3
-rw-r--r--src/main/java/com/google/gerrit/client/admin/ProjectRightsPanel.java6
-rw-r--r--src/main/java/com/google/gerrit/client/data/GerritConfig.java10
-rw-r--r--src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatch.java14
-rw-r--r--src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatchAccess.java12
-rw-r--r--src/main/java/com/google/gerrit/client/reviewdb/ApprovalCategory.java2
-rw-r--r--src/main/java/com/google/gerrit/client/reviewdb/ProjectRight.java25
-rw-r--r--src/main/java/com/google/gerrit/client/reviewdb/ProjectRightAccess.java4
-rw-r--r--src/main/java/com/google/gerrit/git/PushAllProjectsOp.java7
-rw-r--r--src/main/java/com/google/gerrit/server/config/GerritConfigProvider.java7
-rw-r--r--src/main/java/com/google/gerrit/server/config/GerritServerModule.java3
-rw-r--r--src/main/java/com/google/gerrit/server/config/SystemConfigProvider.java28
-rw-r--r--src/main/java/com/google/gerrit/server/config/WildProjectName.java33
-rw-r--r--src/main/java/com/google/gerrit/server/config/WildProjectNameProvider.java45
-rw-r--r--src/main/java/com/google/gerrit/server/mail/CreateChangeSender.java8
-rw-r--r--src/main/java/com/google/gerrit/server/mail/MergedSender.java8
-rw-r--r--src/main/java/com/google/gerrit/server/mail/OutgoingEmail.java41
-rw-r--r--src/main/java/com/google/gerrit/server/project/NoSuchProjectException.java8
-rw-r--r--src/main/java/com/google/gerrit/server/project/ProjectCache.java45
-rw-r--r--src/main/java/com/google/gerrit/server/project/ProjectControl.java18
-rw-r--r--src/main/java/com/google/gerrit/server/project/ProjectState.java2
-rw-r--r--src/main/java/com/google/gerrit/server/rpc/AccountServiceImpl.java35
-rw-r--r--src/main/java/com/google/gerrit/server/rpc/project/ProjectAdminServiceImpl.java26
-rw-r--r--src/main/java/com/google/gerrit/server/rpc/project/ProjectDetailFactory.java10
-rw-r--r--src/main/java/com/google/gerrit/server/ssh/commands/AbstractGitCommand.java5
-rw-r--r--src/main/java/com/google/gerrit/server/ssh/commands/ListProjects.java8
-rw-r--r--src/main/webapp/WEB-INF/sql/index_generic.sql6
-rw-r--r--src/main/webapp/WEB-INF/sql/index_postgres.sql6
-rw-r--r--src/main/webapp/WEB-INF/sql/upgrade015_016_part1_mysql.sql42
-rw-r--r--src/main/webapp/WEB-INF/sql/upgrade015_016_part1_postgres.sql47
31 files changed, 334 insertions, 183 deletions
diff --git a/src/main/java/com/google/gerrit/client/admin/ProjectAdminScreen.java b/src/main/java/com/google/gerrit/client/admin/ProjectAdminScreen.java
index fec6e8e2a1..a79e3bd75e 100644
--- a/src/main/java/com/google/gerrit/client/admin/ProjectAdminScreen.java
+++ b/src/main/java/com/google/gerrit/client/admin/ProjectAdminScreen.java
@@ -18,6 +18,7 @@ import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.Link;
import com.google.gerrit.client.reviewdb.Project;
import com.google.gerrit.client.reviewdb.ProjectRight;
+import com.google.gerrit.client.rpc.Common;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.AccountScreen;
import com.google.gwt.event.logical.shared.SelectionEvent;
@@ -73,7 +74,7 @@ public class ProjectAdminScreen extends AccountScreen {
}, Util.C.projectAdminTabGeneral());
tabTokens.add(Link.toProjectAdmin(projectName, INFO_TAB));
- if (!ProjectRight.WILD_PROJECT.equals(projectName)) {
+ if (!Common.getGerritConfig().getWildProject().equals(projectName)) {
tabs.add(new LazyPanel() {
@Override
protected ProjectBranchesPanel createWidget() {
diff --git a/src/main/java/com/google/gerrit/client/admin/ProjectInfoPanel.java b/src/main/java/com/google/gerrit/client/admin/ProjectInfoPanel.java
index 36ccf8c6fe..011db11e5c 100644
--- a/src/main/java/com/google/gerrit/client/admin/ProjectInfoPanel.java
+++ b/src/main/java/com/google/gerrit/client/admin/ProjectInfoPanel.java
@@ -163,7 +163,8 @@ public class ProjectInfoPanel extends Composite {
void display(final ProjectDetail result) {
project = result.project;
- final boolean isall = ProjectRight.WILD_PROJECT.equals(project.getId());
+ final boolean isall =
+ Common.getGerritConfig().getWildProject().equals(project.getNameKey());
submitTypePanel.setVisible(!isall);
agreementsPanel.setVisible(!isall);
useContributorAgreements.setVisible(Common.getGerritConfig()
diff --git a/src/main/java/com/google/gerrit/client/admin/ProjectRightsPanel.java b/src/main/java/com/google/gerrit/client/admin/ProjectRightsPanel.java
index cf425580e2..635ec4734a 100644
--- a/src/main/java/com/google/gerrit/client/admin/ProjectRightsPanel.java
+++ b/src/main/java/com/google/gerrit/client/admin/ProjectRightsPanel.java
@@ -119,7 +119,7 @@ public class ProjectRightsPanel extends Composite {
}
for (final ApprovalType at : Common.getGerritConfig().getActionTypes()) {
final ApprovalCategory c = at.getCategory();
- if (ProjectRight.WILD_PROJECT.equals(projectName)
+ if (Common.getGerritConfig().getWildProject().equals(projectName)
&& ApprovalCategory.OWN.equals(c.getId())) {
// Giving out control of the WILD_PROJECT to other groups beyond
// Administrators is dangerous. Having control over WILD_PROJECT
@@ -370,8 +370,8 @@ public class ProjectRightsPanel extends Composite {
final ApprovalType ar = config.getApprovalType(k.getApprovalCategoryId());
final AccountGroup group = groups.get(k.getAccountGroupId());
- if (ProjectRight.WILD_PROJECT.equals(k.getProjectId())
- && !ProjectRight.WILD_PROJECT.equals(projectName)) {
+ if (Common.getGerritConfig().getWildProject().equals(k.getProjectNameKey())
+ && !Common.getGerritConfig().getWildProject().equals(projectName)) {
table.setText(row, 1, "");
} else {
table.setWidget(row, 1, new CheckBox());
diff --git a/src/main/java/com/google/gerrit/client/data/GerritConfig.java b/src/main/java/com/google/gerrit/client/data/GerritConfig.java
index 4920317c6a..72bb1b7bcd 100644
--- a/src/main/java/com/google/gerrit/client/data/GerritConfig.java
+++ b/src/main/java/com/google/gerrit/client/data/GerritConfig.java
@@ -16,6 +16,7 @@ package com.google.gerrit.client.data;
import com.google.gerrit.client.reviewdb.ApprovalCategory;
import com.google.gerrit.client.reviewdb.LoginType;
+import com.google.gerrit.client.reviewdb.Project;
import java.util.ArrayList;
import java.util.HashMap;
@@ -34,6 +35,7 @@ public class GerritConfig implements Cloneable {
protected boolean useRepoDownload;
protected String gitDaemonUrl;
protected String sshdAddress;
+ protected Project.NameKey wildProject;
private transient Map<ApprovalCategory.Id, ApprovalType> byCategoryId;
public GerritConfig() {
@@ -163,4 +165,12 @@ public class GerritConfig implements Cloneable {
public void setSshdAddress(final String addr) {
sshdAddress = addr;
}
+
+ public Project.NameKey getWildProject() {
+ return wildProject;
+ }
+
+ public void setWildProject(final Project.NameKey wp) {
+ wildProject = wp;
+ }
}
diff --git a/src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatch.java b/src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatch.java
index 6133c710e5..9a0be5d13e 100644
--- a/src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatch.java
+++ b/src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatch.java
@@ -26,16 +26,16 @@ public final class AccountProjectWatch {
protected Account.Id accountId;
@Column
- protected Project.Id projectId;
+ protected Project.NameKey projectName;
protected Key() {
accountId = new Account.Id();
- projectId = new Project.Id();
+ projectName = new Project.NameKey();
}
- public Key(final Account.Id a, final Project.Id g) {
+ public Key(final Account.Id a, final Project.NameKey g) {
accountId = a;
- projectId = g;
+ projectName = g;
}
@Override
@@ -45,7 +45,7 @@ public final class AccountProjectWatch {
@Override
public com.google.gwtorm.client.Key<?>[] members() {
- return new com.google.gwtorm.client.Key<?>[] {projectId};
+ return new com.google.gwtorm.client.Key<?>[] {projectName};
}
}
@@ -79,8 +79,8 @@ public final class AccountProjectWatch {
return key.accountId;
}
- public Project.Id getProjectId() {
- return key.projectId;
+ public Project.NameKey getProjectNameKey() {
+ return key.projectName;
}
public boolean isNotifyNewChanges() {
diff --git a/src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatchAccess.java b/src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatchAccess.java
index 2d8929bc21..2aaeab71ae 100644
--- a/src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatchAccess.java
+++ b/src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatchAccess.java
@@ -28,15 +28,15 @@ public interface AccountProjectWatchAccess extends
@Query("WHERE key.accountId = ?")
ResultSet<AccountProjectWatch> byAccount(Account.Id id) throws OrmException;
- @Query("WHERE notifyNewChanges = true AND key.projectId = ?")
- ResultSet<AccountProjectWatch> notifyNewChanges(Project.Id id)
+ @Query("WHERE notifyNewChanges = true AND key.projectName = ?")
+ ResultSet<AccountProjectWatch> notifyNewChanges(Project.NameKey name)
throws OrmException;
- @Query("WHERE notifyAllComments = true AND key.projectId = ?")
- ResultSet<AccountProjectWatch> notifyAllComments(Project.Id id)
+ @Query("WHERE notifyAllComments = true AND key.projectName = ?")
+ ResultSet<AccountProjectWatch> notifyAllComments(Project.NameKey name)
throws OrmException;
- @Query("WHERE notifySubmittedChanges = true AND key.projectId = ?")
- ResultSet<AccountProjectWatch> notifySubmittedChanges(Project.Id id)
+ @Query("WHERE notifySubmittedChanges = true AND key.projectName = ?")
+ ResultSet<AccountProjectWatch> notifySubmittedChanges(Project.NameKey name)
throws OrmException;
}
diff --git a/src/main/java/com/google/gerrit/client/reviewdb/ApprovalCategory.java b/src/main/java/com/google/gerrit/client/reviewdb/ApprovalCategory.java
index cf7c6cbdde..c543c88122 100644
--- a/src/main/java/com/google/gerrit/client/reviewdb/ApprovalCategory.java
+++ b/src/main/java/com/google/gerrit/client/reviewdb/ApprovalCategory.java
@@ -69,7 +69,7 @@ public final class ApprovalCategory {
id = newValue;
}
- /** True if the right can inherit from {@link ProjectRight#WILD_PROJECT}. */
+ /** True if the right can inherit from {@link ProjectRight#WILD_PROJECT_ID}. */
public boolean canInheritFromWildProject() {
if (OWN.equals(this)) {
return false;
diff --git a/src/main/java/com/google/gerrit/client/reviewdb/ProjectRight.java b/src/main/java/com/google/gerrit/client/reviewdb/ProjectRight.java
index 4806a5fe51..46b6d60710 100644
--- a/src/main/java/com/google/gerrit/client/reviewdb/ProjectRight.java
+++ b/src/main/java/com/google/gerrit/client/reviewdb/ProjectRight.java
@@ -19,14 +19,11 @@ import com.google.gwtorm.client.CompoundKey;
/** Grant to use an {@link ApprovalCategory} in the scope of a {@link Project}. */
public final class ProjectRight {
- /** Project.Id meaning "any and all projects on this server". */
- public static final Project.Id WILD_PROJECT = new Project.Id(0);
-
- public static class Key extends CompoundKey<Project.Id> {
+ public static class Key extends CompoundKey<Project.NameKey> {
private static final long serialVersionUID = 1L;
@Column
- protected Project.Id projectId;
+ protected Project.NameKey projectName;
@Column
protected ApprovalCategory.Id categoryId;
@@ -35,25 +32,25 @@ public final class ProjectRight {
protected AccountGroup.Id groupId;
protected Key() {
- projectId = new Project.Id();
+ projectName = new Project.NameKey();
categoryId = new ApprovalCategory.Id();
groupId = new AccountGroup.Id();
}
- public Key(final Project.Id p, final ApprovalCategory.Id a,
+ public Key(final Project.NameKey p, final ApprovalCategory.Id a,
final AccountGroup.Id g) {
- projectId = p;
+ projectName = p;
categoryId = a;
groupId = g;
}
@Override
- public Project.Id getParentKey() {
- return projectId;
+ public Project.NameKey getParentKey() {
+ return projectName;
}
- public Project.Id getProjectId() {
- return projectId;
+ public Project.NameKey getProjectNameKey() {
+ return projectName;
}
@Override
@@ -82,8 +79,8 @@ public final class ProjectRight {
return key;
}
- public Project.Id getProjectId() {
- return key.projectId;
+ public Project.NameKey getProjectNameKey() {
+ return key.projectName;
}
public ApprovalCategory.Id getApprovalCategoryId() {
diff --git a/src/main/java/com/google/gerrit/client/reviewdb/ProjectRightAccess.java b/src/main/java/com/google/gerrit/client/reviewdb/ProjectRightAccess.java
index 3623b7eadf..4f722f9608 100644
--- a/src/main/java/com/google/gerrit/client/reviewdb/ProjectRightAccess.java
+++ b/src/main/java/com/google/gerrit/client/reviewdb/ProjectRightAccess.java
@@ -25,8 +25,8 @@ public interface ProjectRightAccess extends
@PrimaryKey("key")
ProjectRight get(ProjectRight.Key key) throws OrmException;
- @Query("WHERE key.projectId = ?")
- ResultSet<ProjectRight> byProject(Project.Id id) throws OrmException;
+ @Query("WHERE key.projectName = ?")
+ ResultSet<ProjectRight> byProject(Project.NameKey name) throws OrmException;
@Query("WHERE key.categoryId = ? AND key.groupId = ?")
ResultSet<ProjectRight> byCategoryGroup(ApprovalCategory.Id cat,
diff --git a/src/main/java/com/google/gerrit/git/PushAllProjectsOp.java b/src/main/java/com/google/gerrit/git/PushAllProjectsOp.java
index fefd70c8c3..ee314ed4f5 100644
--- a/src/main/java/com/google/gerrit/git/PushAllProjectsOp.java
+++ b/src/main/java/com/google/gerrit/git/PushAllProjectsOp.java
@@ -16,9 +16,9 @@ package com.google.gerrit.git;
import com.google.gerrit.client.reviewdb.Branch;
import com.google.gerrit.client.reviewdb.Project;
-import com.google.gerrit.client.reviewdb.ProjectRight;
import com.google.gerrit.client.reviewdb.ReviewDb;
import com.google.gerrit.server.config.Nullable;
+import com.google.gerrit.server.config.WildProjectName;
import com.google.gwtorm.client.OrmException;
import com.google.gwtorm.client.SchemaFactory;
import com.google.inject.Inject;
@@ -40,15 +40,18 @@ public class PushAllProjectsOp extends DefaultQueueOp {
private final SchemaFactory<ReviewDb> schema;
private final ReplicationQueue replication;
+ private final Project.NameKey wildProject;
private final String urlMatch;
@Inject
public PushAllProjectsOp(final WorkQueue wq,
final SchemaFactory<ReviewDb> sf, final ReplicationQueue rq,
+ @WildProjectName final Project.NameKey wp,
@Assisted @Nullable final String urlMatch) {
super(wq);
this.schema = sf;
this.replication = rq;
+ this.wildProject = wp;
this.urlMatch = urlMatch;
}
@@ -65,7 +68,7 @@ public class PushAllProjectsOp extends DefaultQueueOp {
final ReviewDb db = schema.open();
try {
for (final Project project : db.projects().all()) {
- if (!ProjectRight.WILD_PROJECT.equals(project.getId())) {
+ if (!project.getNameKey().equals(wildProject)) {
replication.scheduleFullSync(project.getNameKey(), urlMatch);
}
}
diff --git a/src/main/java/com/google/gerrit/server/config/GerritConfigProvider.java b/src/main/java/com/google/gerrit/server/config/GerritConfigProvider.java
index 56aadceac6..c252c77013 100644
--- a/src/main/java/com/google/gerrit/server/config/GerritConfigProvider.java
+++ b/src/main/java/com/google/gerrit/server/config/GerritConfigProvider.java
@@ -18,6 +18,7 @@ import com.google.gerrit.client.data.ApprovalType;
import com.google.gerrit.client.data.GerritConfig;
import com.google.gerrit.client.data.GitwebLink;
import com.google.gerrit.client.reviewdb.ApprovalCategory;
+import com.google.gerrit.client.reviewdb.Project;
import com.google.gerrit.client.reviewdb.ReviewDb;
import com.google.gerrit.client.rpc.Common;
import com.google.gerrit.server.ContactStore;
@@ -45,6 +46,7 @@ public class GerritConfigProvider implements Provider<GerritConfig> {
private final String canonicalWebUrl;
private final AuthConfig authConfig;
private final SchemaFactory<ReviewDb> schema;
+ private final Project.NameKey wildProject;
private SshInfo sshd;
private EmailSender emailSender;
@@ -53,11 +55,13 @@ public class GerritConfigProvider implements Provider<GerritConfig> {
@Inject
GerritConfigProvider(@GerritServerConfig final Config gsc,
@CanonicalWebUrl @Nullable final String cwu, final AuthConfig ac,
- final SchemaFactory<ReviewDb> sf) {
+ final SchemaFactory<ReviewDb> sf,
+ @WildProjectName final Project.NameKey wp) {
cfg = gsc;
canonicalWebUrl = cwu;
authConfig = ac;
schema = sf;
+ wildProject = wp;
}
@Inject(optional = true)
@@ -87,6 +91,7 @@ public class GerritConfigProvider implements Provider<GerritConfig> {
config.setAllowRegisterNewEmail(emailSender != null
&& emailSender.isEnabled());
config.setLoginType(authConfig.getLoginType());
+ config.setWildProject(wildProject);
final String gitwebUrl = cfg.getString("gitweb", null, "url");
if (gitwebUrl != null) {
diff --git a/src/main/java/com/google/gerrit/server/config/GerritServerModule.java b/src/main/java/com/google/gerrit/server/config/GerritServerModule.java
index 592cb6b657..240fec9c92 100644
--- a/src/main/java/com/google/gerrit/server/config/GerritServerModule.java
+++ b/src/main/java/com/google/gerrit/server/config/GerritServerModule.java
@@ -16,6 +16,7 @@ package com.google.gerrit.server.config;
import static com.google.inject.Scopes.SINGLETON;
+import com.google.gerrit.client.reviewdb.Project;
import com.google.gerrit.git.ChangeMergeQueue;
import com.google.gerrit.git.MergeOp;
import com.google.gerrit.git.MergeQueue;
@@ -61,6 +62,8 @@ public class GerritServerModule extends FactoryModule {
protected void configure() {
bind(File.class).annotatedWith(SitePath.class).toProvider(
SitePathProvider.class).in(SINGLETON);
+ bind(Project.NameKey.class).annotatedWith(WildProjectName.class)
+ .toProvider(WildProjectNameProvider.class).in(SINGLETON);
bind(Config.class).annotatedWith(GerritServerConfig.class).toProvider(
GerritServerConfigProvider.class).in(SINGLETON);
bind(AuthConfig.class).in(SINGLETON);
diff --git a/src/main/java/com/google/gerrit/server/config/SystemConfigProvider.java b/src/main/java/com/google/gerrit/server/config/SystemConfigProvider.java
index 375411f4ac..1fa2984015 100644
--- a/src/main/java/com/google/gerrit/server/config/SystemConfigProvider.java
+++ b/src/main/java/com/google/gerrit/server/config/SystemConfigProvider.java
@@ -40,6 +40,8 @@ import java.util.List;
/** Loads the {@link SystemConfig} from the database. */
class SystemConfigProvider implements Provider<SystemConfig> {
+ private static final Project.NameKey DEFAULT_WILD_NAME =
+ new Project.NameKey("-- All Projects --");
private final SchemaFactory<ReviewDb> schema;
@Inject
@@ -183,14 +185,12 @@ class SystemConfigProvider implements Provider<SystemConfig> {
}
private void initWildCardProject(final ReviewDb c) throws OrmException {
- final Project proj;
-
- proj =
- new Project(new Project.NameKey("-- All Projects --"),
- ProjectRight.WILD_PROJECT);
- proj.setDescription("Rights inherited by all other projects");
- proj.setUseContributorAgreements(false);
- c.projects().insert(Collections.singleton(proj));
+ final Project p;
+
+ p = new Project(DEFAULT_WILD_NAME, WildProjectNameProvider.WILD_PROJECT_ID);
+ p.setDescription("Rights inherited by all other projects");
+ p.setUseContributorAgreements(false);
+ c.projects().insert(Collections.singleton(p));
}
private void initVerifiedCategory(final ReviewDb c) throws OrmException {
@@ -228,8 +228,8 @@ class SystemConfigProvider implements Provider<SystemConfig> {
txn.commit();
final ProjectRight approve =
- new ProjectRight(new ProjectRight.Key(ProjectRight.WILD_PROJECT, cat
- .getId(), sConfig.registeredGroupId));
+ new ProjectRight(new ProjectRight.Key(DEFAULT_WILD_NAME, cat.getId(),
+ sConfig.registeredGroupId));
approve.setMaxValue((short) 1);
approve.setMinValue((short) -1);
c.projectRights().insert(Collections.singleton(approve));
@@ -267,16 +267,16 @@ class SystemConfigProvider implements Provider<SystemConfig> {
txn.commit();
{
final ProjectRight read =
- new ProjectRight(new ProjectRight.Key(ProjectRight.WILD_PROJECT, cat
- .getId(), sConfig.anonymousGroupId));
+ new ProjectRight(new ProjectRight.Key(DEFAULT_WILD_NAME, cat.getId(),
+ sConfig.anonymousGroupId));
read.setMaxValue((short) 1);
read.setMinValue((short) 1);
c.projectRights().insert(Collections.singleton(read));
}
{
final ProjectRight read =
- new ProjectRight(new ProjectRight.Key(ProjectRight.WILD_PROJECT, cat
- .getId(), sConfig.adminGroupId));
+ new ProjectRight(new ProjectRight.Key(DEFAULT_WILD_NAME, cat.getId(),
+ sConfig.adminGroupId));
read.setMaxValue((short) 1);
read.setMinValue((short) 1);
c.projectRights().insert(Collections.singleton(read));
diff --git a/src/main/java/com/google/gerrit/server/config/WildProjectName.java b/src/main/java/com/google/gerrit/server/config/WildProjectName.java
new file mode 100644
index 0000000000..7c7bfa92dc
--- /dev/null
+++ b/src/main/java/com/google/gerrit/server/config/WildProjectName.java
@@ -0,0 +1,33 @@
+// Copyright (C) 2009 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.config;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.google.gerrit.client.reviewdb.Project;
+import com.google.inject.BindingAnnotation;
+
+import java.lang.annotation.Retention;
+
+/**
+ * Marker on a {@link Project.NameKey} for the current wildcard project.
+ * <p>
+ * This is the name of the project whose rights inherit into every other project
+ * in the system.
+ */
+@Retention(RUNTIME)
+@BindingAnnotation
+public @interface WildProjectName {
+}
diff --git a/src/main/java/com/google/gerrit/server/config/WildProjectNameProvider.java b/src/main/java/com/google/gerrit/server/config/WildProjectNameProvider.java
new file mode 100644
index 0000000000..1d67491de7
--- /dev/null
+++ b/src/main/java/com/google/gerrit/server/config/WildProjectNameProvider.java
@@ -0,0 +1,45 @@
+package com.google.gerrit.server.config;
+
+import com.google.gerrit.client.reviewdb.Project;
+import com.google.gerrit.client.reviewdb.ReviewDb;
+import com.google.gerrit.client.reviewdb.SystemConfig;
+import com.google.gwtorm.client.OrmException;
+import com.google.gwtorm.client.SchemaFactory;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.ProvisionException;
+
+class WildProjectNameProvider implements Provider<Project.NameKey> {
+ /** Project.Id meaning "any and all projects on this server". */
+ static final Project.Id WILD_PROJECT_ID = new Project.Id(0);
+
+ private final SchemaFactory<ReviewDb> schema;
+
+ @Inject
+ WildProjectNameProvider(final SchemaFactory<ReviewDb> schema,
+ /*
+ * Unused, but we need to force it to load before we do, otherwise we risk
+ * reading an empty database without the wild project being in the database.
+ * Asking for it should ensures Guice loads it first.
+ */
+ final SystemConfig config) {
+ this.schema = schema;
+ }
+
+ public Project.NameKey get() {
+ try {
+ final ReviewDb db = schema.open();
+ try {
+ final Project p = db.projects().get(WILD_PROJECT_ID);
+ if (p == null) {
+ throw new ProvisionException("No project " + WILD_PROJECT_ID);
+ }
+ return p.getNameKey();
+ } finally {
+ db.close();
+ }
+ } catch (OrmException e) {
+ throw new ProvisionException("Cannot load " + WILD_PROJECT_ID, e);
+ }
+ }
+}
diff --git a/src/main/java/com/google/gerrit/server/mail/CreateChangeSender.java b/src/main/java/com/google/gerrit/server/mail/CreateChangeSender.java
index b0fe702ebf..1c0bee7596 100644
--- a/src/main/java/com/google/gerrit/server/mail/CreateChangeSender.java
+++ b/src/main/java/com/google/gerrit/server/mail/CreateChangeSender.java
@@ -19,7 +19,7 @@ import com.google.gerrit.client.reviewdb.AccountGroup;
import com.google.gerrit.client.reviewdb.AccountGroupMember;
import com.google.gerrit.client.reviewdb.AccountProjectWatch;
import com.google.gerrit.client.reviewdb.Change;
-import com.google.gerrit.client.reviewdb.Project;
+import com.google.gerrit.server.project.ProjectState;
import com.google.gwtorm.client.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@@ -50,8 +50,8 @@ public class CreateChangeSender extends NewChangeSender {
try {
// BCC anyone else who has interest in this project's changes
//
- final Project project = getProject();
- if (project != null) {
+ final ProjectState ps = getProjectState();
+ if (ps != null) {
// Try to mark interested owners with a TO and not a BCC line.
//
final Set<Account.Id> owners = new HashSet<Account.Id>();
@@ -64,7 +64,7 @@ public class CreateChangeSender extends NewChangeSender {
// BCC anyone who has interest in this project's changes
//
for (AccountProjectWatch w : db.accountProjectWatches()
- .notifyNewChanges(project.getId())) {
+ .notifyNewChanges(ps.getProject().getNameKey())) {
if (owners.contains(w.getAccountId())) {
add(RecipientType.TO, w.getAccountId());
} else {
diff --git a/src/main/java/com/google/gerrit/server/mail/MergedSender.java b/src/main/java/com/google/gerrit/server/mail/MergedSender.java
index 04478f31bc..ddacd4729c 100644
--- a/src/main/java/com/google/gerrit/server/mail/MergedSender.java
+++ b/src/main/java/com/google/gerrit/server/mail/MergedSender.java
@@ -23,7 +23,7 @@ import com.google.gerrit.client.reviewdb.ApprovalCategoryValue;
import com.google.gerrit.client.reviewdb.Branch;
import com.google.gerrit.client.reviewdb.Change;
import com.google.gerrit.client.reviewdb.ChangeApproval;
-import com.google.gerrit.client.reviewdb.Project;
+import com.google.gerrit.server.project.ProjectState;
import com.google.gwtorm.client.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@@ -160,10 +160,10 @@ public class MergedSender extends ReplyToChangeSender {
try {
// BCC anyone else who has interest in this project's changes
//
- final Project project = getProject();
- if (project != null) {
+ final ProjectState ps = getProjectState();
+ if (ps != null) {
for (AccountProjectWatch w : db.accountProjectWatches()
- .notifySubmittedChanges(project.getId())) {
+ .notifySubmittedChanges(ps.getProject().getNameKey())) {
add(RecipientType.BCC, w.getAccountId());
}
}
diff --git a/src/main/java/com/google/gerrit/server/mail/OutgoingEmail.java b/src/main/java/com/google/gerrit/server/mail/OutgoingEmail.java
index b3a844a560..4c6b8d5323 100644
--- a/src/main/java/com/google/gerrit/server/mail/OutgoingEmail.java
+++ b/src/main/java/com/google/gerrit/server/mail/OutgoingEmail.java
@@ -23,12 +23,12 @@ import com.google.gerrit.client.reviewdb.ChangeMessage;
import com.google.gerrit.client.reviewdb.Patch;
import com.google.gerrit.client.reviewdb.PatchSet;
import com.google.gerrit.client.reviewdb.PatchSetInfo;
-import com.google.gerrit.client.reviewdb.Project;
import com.google.gerrit.client.reviewdb.ReviewDb;
import com.google.gerrit.client.reviewdb.StarredChange;
import com.google.gerrit.client.reviewdb.UserIdentity;
import com.google.gerrit.client.rpc.Common;
import com.google.gerrit.server.GerritServer;
+import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.config.Nullable;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
@@ -90,15 +90,27 @@ public abstract class OutgoingEmail {
private PatchSetInfoFactory patchSetInfoFactory;
@Inject
+ private IdentifiedUser.GenericFactory identifiedUserFactory;
+
+ @Inject
@CanonicalWebUrl
@Nullable
private Provider<String> urlProvider;
+ private ProjectState projectState;
protected OutgoingEmail(final Change c, final String mc) {
change = c;
- projectName = change != null ? change.getDest().getParentKey().get() : null;
messageClass = mc;
headers = new LinkedHashMap<String, EmailHeader>();
+
+ if (change != null) {
+ projectState = projectCache.get(change.getDest().getParentKey());
+ projectName =
+ projectState != null ? projectState.getProject().getName() : null;
+ } else {
+ projectState = null;
+ projectName = null;
+ }
}
protected OutgoingEmail(final String mc) {
@@ -463,11 +475,8 @@ public abstract class OutgoingEmail {
}
/** Get the project entity the change is in; null if its been deleted. */
- protected Project getProject() {
- final ProjectState r;
-
- r = projectCache.get(change.getDest().getParentKey());
- return r != null ? r.getProject() : null;
+ protected ProjectState getProjectState() {
+ return projectState;
}
/** Get the groups which own the project. */
@@ -526,10 +535,10 @@ public abstract class OutgoingEmail {
try {
// BCC anyone else who has interest in this project's changes
//
- final Project project = getProject();
- if (project != null) {
- for (AccountProjectWatch w : db.accountProjectWatches()
- .notifyAllComments(project.getId())) {
+ final ProjectState ps = getProjectState();
+ if (ps != null) {
+ for (final AccountProjectWatch w : db.accountProjectWatches()
+ .notifyAllComments(ps.getProject().getNameKey())) {
add(RecipientType.BCC, w.getAccountId());
}
}
@@ -569,11 +578,19 @@ public abstract class OutgoingEmail {
/** Schedule delivery of this message to the given account. */
protected void add(final RecipientType rt, final Account.Id to) {
- if (rcptTo.add(to)) {
+ if (!rcptTo.contains(to) && isVisibleTo(to)) {
+ rcptTo.add(to);
add(rt, toAddress(to));
}
}
+ private boolean isVisibleTo(final Account.Id to) {
+ return projectState == null
+ || change == null
+ || projectState.controlFor(identifiedUserFactory.create(to))
+ .controlFor(change).isVisible();
+ }
+
/** Schedule delivery of this message to the given account. */
protected void add(final RecipientType rt, final Address addr) {
if (addr != null && addr.email != null && addr.email.length() > 0) {
diff --git a/src/main/java/com/google/gerrit/server/project/NoSuchProjectException.java b/src/main/java/com/google/gerrit/server/project/NoSuchProjectException.java
index ea6515b2db..55c7de3155 100644
--- a/src/main/java/com/google/gerrit/server/project/NoSuchProjectException.java
+++ b/src/main/java/com/google/gerrit/server/project/NoSuchProjectException.java
@@ -25,12 +25,4 @@ public class NoSuchProjectException extends Exception {
public NoSuchProjectException(final Project.NameKey key, final Throwable why) {
super(key.toString(), why);
}
-
- public NoSuchProjectException(final Project.Id key) {
- this(key, null);
- }
-
- public NoSuchProjectException(final Project.Id key, final Throwable why) {
- super(key.toString(), why);
- }
}
diff --git a/src/main/java/com/google/gerrit/server/project/ProjectCache.java b/src/main/java/com/google/gerrit/server/project/ProjectCache.java
index a92309cbaa..0e517dec2d 100644
--- a/src/main/java/com/google/gerrit/server/project/ProjectCache.java
+++ b/src/main/java/com/google/gerrit/server/project/ProjectCache.java
@@ -18,6 +18,7 @@ import com.google.gerrit.client.reviewdb.Project;
import com.google.gerrit.client.reviewdb.ProjectRight;
import com.google.gerrit.client.reviewdb.ReviewDb;
import com.google.gerrit.server.AnonymousUser;
+import com.google.gerrit.server.config.WildProjectName;
import com.google.gwtorm.client.OrmException;
import com.google.gwtorm.client.SchemaFactory;
import com.google.inject.Inject;
@@ -42,38 +43,31 @@ public class ProjectCache {
final AnonymousUser anonymousUser;
private final SchemaFactory<ReviewDb> schema;
+ private final Project.NameKey wildProject;
private final Cache raw;
private final SelfPopulatingCache auto;
@Inject
ProjectCache(final AnonymousUser au, final SchemaFactory<ReviewDb> sf,
- final CacheManager mgr) {
+ @WildProjectName final Project.NameKey wp, final CacheManager mgr) {
anonymousUser = au;
schema = sf;
+ wildProject = wp;
raw = mgr.getCache("projects");
auto = new SelfPopulatingCache(raw, new CacheEntryFactory() {
@Override
public Object createEntry(final Object key) throws Exception {
- return lookup(key);
+ return lookup((Project.NameKey) key);
}
});
mgr.replaceCacheWithDecoratedCache(raw, auto);
}
- private ProjectState lookup(final Object key) throws OrmException {
+ private ProjectState lookup(final Project.NameKey key) throws OrmException {
final ReviewDb db = schema.open();
try {
- final Project p;
- if (key instanceof Project.Id) {
- p = db.projects().get((Project.Id) key);
-
- } else if (key instanceof Project.NameKey) {
- p = db.projects().get((Project.NameKey) key);
-
- } else {
- p = null;
- }
+ final Project p = db.projects().get(key);
return p != null ? new ProjectState(this, db, p) : null;
} finally {
db.close();
@@ -82,40 +76,17 @@ public class ProjectCache {
/** Get the rights which are applied to all projects in the system. */
public Collection<ProjectRight> getWildcardRights() {
- return get(ProjectRight.WILD_PROJECT).getRights();
+ return get(wildProject).getRights();
}
/** Invalidate the cached information about the given project. */
public void invalidate(final Project p) {
if (p != null) {
auto.remove(p.getNameKey());
- auto.remove(p.getId());
- }
- }
-
- /** Invalidate the cached information about the given project. */
- public void invalidate(final Project.Id projectId) {
- if (projectId != null) {
- final Element e = raw.get(projectId);
- if (e != null && e.getObjectValue() != null) {
- invalidate(((ProjectState) e.getObjectValue()).getProject());
- } else {
- auto.remove(projectId);
- }
}
}
/**
- * Get the cached data for a project by its unique id.
- *
- * @param projectId id of the project.
- * @return the cached data; null if no such project exists.
- */
- public ProjectState get(final Project.Id projectId) {
- return get0(projectId);
- }
-
- /**
* Get the cached data for a project by its unique name.
*
* @param projectName name of the project.
diff --git a/src/main/java/com/google/gerrit/server/project/ProjectControl.java b/src/main/java/com/google/gerrit/server/project/ProjectControl.java
index 8bca51e98b..59b2795d03 100644
--- a/src/main/java/com/google/gerrit/server/project/ProjectControl.java
+++ b/src/main/java/com/google/gerrit/server/project/ProjectControl.java
@@ -46,15 +46,6 @@ public class ProjectControl {
return p.controlFor(user.get());
}
- public ProjectControl controlFor(final Project.Id projectId)
- throws NoSuchProjectException {
- final ProjectState p = projectCache.get(projectId);
- if (p == null) {
- throw new NoSuchProjectException(projectId);
- }
- return p.controlFor(user.get());
- }
-
public ProjectControl validateFor(final Project.NameKey nameKey)
throws NoSuchProjectException {
final ProjectControl c = controlFor(nameKey);
@@ -63,15 +54,6 @@ public class ProjectControl {
}
return c;
}
-
- public ProjectControl validateFor(final Project.Id projectId)
- throws NoSuchProjectException {
- final ProjectControl c = controlFor(projectId);
- if (!c.isVisible()) {
- throw new NoSuchProjectException(projectId);
- }
- return c;
- }
}
private final CurrentUser user;
diff --git a/src/main/java/com/google/gerrit/server/project/ProjectState.java b/src/main/java/com/google/gerrit/server/project/ProjectState.java
index 04f857dfb4..9e4742b0dd 100644
--- a/src/main/java/com/google/gerrit/server/project/ProjectState.java
+++ b/src/main/java/com/google/gerrit/server/project/ProjectState.java
@@ -40,7 +40,7 @@ public class ProjectState {
project = p;
rights =
Collections.unmodifiableCollection(db.projectRights().byProject(
- project.getId()).toList());
+ project.getNameKey()).toList());
final HashSet<AccountGroup.Id> groups = new HashSet<AccountGroup.Id>();
for (final ProjectRight right : rights) {
diff --git a/src/main/java/com/google/gerrit/server/rpc/AccountServiceImpl.java b/src/main/java/com/google/gerrit/server/rpc/AccountServiceImpl.java
index 2618ee8e69..e2030ee508 100644
--- a/src/main/java/com/google/gerrit/server/rpc/AccountServiceImpl.java
+++ b/src/main/java/com/google/gerrit/server/rpc/AccountServiceImpl.java
@@ -25,8 +25,9 @@ import com.google.gerrit.client.reviewdb.ReviewDb;
import com.google.gerrit.client.rpc.Common;
import com.google.gerrit.client.rpc.NoSuchEntityException;
import com.google.gerrit.server.BaseServiceImplementation;
-import com.google.gerrit.server.project.ProjectCache;
-import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.project.NoSuchProjectException;
+import com.google.gerrit.server.project.ProjectControl;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwtjsonrpc.client.VoidResult;
import com.google.gwtorm.client.OrmException;
@@ -42,13 +43,13 @@ import java.util.Set;
class AccountServiceImpl extends BaseServiceImplementation implements
AccountService {
- private final ProjectCache projectCache;
+ private final ProjectControl.Factory projectControlFactory;
@Inject
AccountServiceImpl(final Provider<ReviewDb> sf,
- final ProjectCache projectCache) {
+ final ProjectControl.Factory projectControlFactory) {
super(sf);
- this.projectCache = projectCache;
+ this.projectControlFactory = projectControlFactory;
}
public void myAccount(final AsyncCallback<Account> callback) {
@@ -89,12 +90,14 @@ class AccountServiceImpl extends BaseServiceImplementation implements
for (final AccountProjectWatch w : db.accountProjectWatches()
.byAccount(Common.getAccountId()).toList()) {
- final ProjectState project = projectCache.get(w.getProjectId());
- if (project == null) {
+ final ProjectControl ctl;
+ try {
+ ctl = projectControlFactory.validateFor(w.getProjectNameKey());
+ } catch (NoSuchProjectException e) {
db.accountProjectWatches().delete(Collections.singleton(w));
continue;
}
- r.add(new AccountProjectWatchInfo(w, project.getProject()));
+ r.add(new AccountProjectWatchInfo(w, ctl.getProject()));
}
Collections.sort(r, new Comparator<AccountProjectWatchInfo>() {
public int compare(final AccountProjectWatchInfo a,
@@ -111,18 +114,16 @@ class AccountServiceImpl extends BaseServiceImplementation implements
final AsyncCallback<AccountProjectWatchInfo> callback) {
run(callback, new Action<AccountProjectWatchInfo>() {
public AccountProjectWatchInfo run(ReviewDb db) throws OrmException,
- Failure {
- final ProjectState project =
- projectCache.get(new Project.NameKey(projectName));
- if (project == null) {
- throw new Failure(new NoSuchEntityException());
- }
+ NoSuchProjectException {
+ final Project.NameKey nameKey = new Project.NameKey(projectName);
+ final ProjectControl ctl = projectControlFactory.validateFor(nameKey);
final AccountProjectWatch watch =
- new AccountProjectWatch(new AccountProjectWatch.Key(Common
- .getAccountId(), project.getProject().getId()));
+ new AccountProjectWatch(
+ new AccountProjectWatch.Key(((IdentifiedUser) ctl
+ .getCurrentUser()).getAccountId(), nameKey));
db.accountProjectWatches().insert(Collections.singleton(watch));
- return new AccountProjectWatchInfo(watch, project.getProject());
+ return new AccountProjectWatchInfo(watch, ctl.getProject());
}
});
}
diff --git a/src/main/java/com/google/gerrit/server/rpc/project/ProjectAdminServiceImpl.java b/src/main/java/com/google/gerrit/server/rpc/project/ProjectAdminServiceImpl.java
index 475c9941c4..238135399c 100644
--- a/src/main/java/com/google/gerrit/server/rpc/project/ProjectAdminServiceImpl.java
+++ b/src/main/java/com/google/gerrit/server/rpc/project/ProjectAdminServiceImpl.java
@@ -33,6 +33,7 @@ import com.google.gerrit.git.ReplicationQueue;
import com.google.gerrit.server.BaseServiceImplementation;
import com.google.gerrit.server.GerritServer;
import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.config.WildProjectName;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectControl;
@@ -60,7 +61,6 @@ import org.spearce.jgit.revwalk.RevCommit;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
@@ -72,6 +72,7 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements
private final Logger log = LoggerFactory.getLogger(getClass());
private final GerritServer server;
private final ProjectCache projectCache;
+ private final Project.NameKey wildProject;
private final ProjectControl.Factory projectControlFactory;
private final ReplicationQueue replication;
private final Provider<IdentifiedUser> identifiedUser;
@@ -82,12 +83,14 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements
ProjectAdminServiceImpl(final Provider<ReviewDb> sf, final GerritServer gs,
final ProjectCache pc, final ReplicationQueue rq,
final Provider<IdentifiedUser> iu,
+ @WildProjectName final Project.NameKey wp,
final ProjectControl.Factory projectControlFactory,
final ProjectDetailFactory.Factory projectDetailFactory) {
super(sf);
this.server = gs;
this.projectCache = pc;
this.replication = rq;
+ this.wildProject = wp;
this.identifiedUser = iu;
this.projectControlFactory = projectControlFactory;
this.projectDetailFactory = projectDetailFactory;
@@ -126,7 +129,7 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements
db.projects().update(Collections.singleton(proj));
projectCache.invalidate(proj);
- if (!ProjectRight.WILD_PROJECT.equals(update.getId())) {
+ if (!wildProject.equals(projectName)) {
// Update git's description file, in case gitweb is being used
//
try {
@@ -175,7 +178,7 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements
throw new NoSuchProjectException(name);
}
for (final ProjectRight.Key k : keys) {
- if (!control.getProject().getId().equals(k.getProjectId())) {
+ if (!name.equals(k.getProjectNameKey())) {
throw new Failure(new NoSuchEntityException());
}
}
@@ -212,7 +215,7 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements
throw new Failure(new NoSuchEntityException());
}
- if (ProjectRight.WILD_PROJECT.equals(proj.getId())
+ if (wildProject.equals(projectName)
&& ApprovalCategory.OWN.equals(categoryId)) {
// Giving out control of the WILD_PROJECT to other groups beyond
// Administrators is dangerous. Having control over WILD_PROJECT
@@ -244,7 +247,7 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements
}
final ProjectRight.Key key =
- new ProjectRight.Key(proj.getId(), categoryId, group.getId());
+ new ProjectRight.Key(projectName, categoryId, group.getId());
ProjectRight pr = db.projectRights().get(key);
if (pr == null) {
pr = new ProjectRight(key);
@@ -485,22 +488,17 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements
return db.projects().all().toList();
}
- final HashSet<Project.Id> seen = new HashSet<Project.Id>();
+ final HashSet<Project.NameKey> seen = new HashSet<Project.NameKey>();
final List<Project> own = new ArrayList<Project>();
for (final AccountGroup.Id groupId : myGroups()) {
for (final ProjectRight r : db.projectRights().byCategoryGroup(
ApprovalCategory.OWN, groupId)) {
- if (!seen.add(r.getProjectId())) {
+ final Project.NameKey name = r.getProjectNameKey();
+ if (!seen.add(name)) {
continue;
}
-
- final Project p = db.projects().get(r.getProjectId());
- if (p == null) {
- continue;
- }
-
try {
- ProjectControl c = projectControlFactory.controlFor(p.getNameKey());
+ ProjectControl c = projectControlFactory.controlFor(name);
if (c.isOwner()) {
own.add(c.getProject());
}
diff --git a/src/main/java/com/google/gerrit/server/rpc/project/ProjectDetailFactory.java b/src/main/java/com/google/gerrit/server/rpc/project/ProjectDetailFactory.java
index 7a7849f110..f2f566134b 100644
--- a/src/main/java/com/google/gerrit/server/rpc/project/ProjectDetailFactory.java
+++ b/src/main/java/com/google/gerrit/server/rpc/project/ProjectDetailFactory.java
@@ -20,6 +20,7 @@ import com.google.gerrit.client.reviewdb.Project;
import com.google.gerrit.client.reviewdb.ProjectRight;
import com.google.gerrit.client.reviewdb.ReviewDb;
import com.google.gerrit.client.rpc.NoSuchEntityException;
+import com.google.gerrit.server.config.WildProjectName;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.rpc.Handler;
@@ -35,11 +36,12 @@ import java.util.Map;
class ProjectDetailFactory extends Handler<ProjectDetail> {
interface Factory {
- ProjectDetailFactory create(Project.NameKey name);
+ ProjectDetailFactory create(@Assisted("name") Project.NameKey name);
}
private final ProjectCache projectCache;
private final ReviewDb db;
+ private final Project.NameKey wildProject;
private final Project.NameKey projectName;
private ProjectDetail detail;
@@ -47,9 +49,11 @@ class ProjectDetailFactory extends Handler<ProjectDetail> {
@Inject
ProjectDetailFactory(final ProjectCache projectCache, final ReviewDb db,
- @Assisted final Project.NameKey name) {
+ @WildProjectName final Project.NameKey wp,
+ @Assisted("name") final Project.NameKey name) {
this.projectCache = projectCache;
this.db = db;
+ this.wildProject = wp;
this.projectName = name;
}
@@ -70,7 +74,7 @@ class ProjectDetailFactory extends Handler<ProjectDetail> {
rights.add(p);
wantGroup(p.getAccountGroupId());
}
- if (!ProjectRight.WILD_PROJECT.equals(e.getProject().getId())) {
+ if (!wildProject.equals(e.getProject().getNameKey())) {
for (final ProjectRight p : projectCache.getWildcardRights()) {
rights.add(p);
wantGroup(p.getAccountGroupId());
diff --git a/src/main/java/com/google/gerrit/server/ssh/commands/AbstractGitCommand.java b/src/main/java/com/google/gerrit/server/ssh/commands/AbstractGitCommand.java
index 0c5d96b0f9..d0ee1ebe19 100644
--- a/src/main/java/com/google/gerrit/server/ssh/commands/AbstractGitCommand.java
+++ b/src/main/java/com/google/gerrit/server/ssh/commands/AbstractGitCommand.java
@@ -16,7 +16,6 @@ package com.google.gerrit.server.ssh.commands;
import com.google.gerrit.client.reviewdb.ApprovalCategory;
import com.google.gerrit.client.reviewdb.Project;
-import com.google.gerrit.client.reviewdb.ProjectRight;
import com.google.gerrit.server.GerritServer;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.project.ProjectCache;
@@ -81,10 +80,6 @@ abstract class AbstractGitCommand extends BaseCommand {
}
proj = cachedProj.getProject();
- if (ProjectRight.WILD_PROJECT.equals(proj.getId())) {
- throw new Failure(1, "fatal: '" + reqProjName + "': not a valid project",
- new IllegalArgumentException("Cannot access the wildcard project"));
- }
if (!canPerform(ApprovalCategory.READ, (short) 1)) {
throw new Failure(1, "fatal: '" + reqProjName + "': unknown project",
new SecurityException("Account lacks Read permission"));
diff --git a/src/main/java/com/google/gerrit/server/ssh/commands/ListProjects.java b/src/main/java/com/google/gerrit/server/ssh/commands/ListProjects.java
index 6cb65f8f5e..3274464811 100644
--- a/src/main/java/com/google/gerrit/server/ssh/commands/ListProjects.java
+++ b/src/main/java/com/google/gerrit/server/ssh/commands/ListProjects.java
@@ -15,9 +15,9 @@
package com.google.gerrit.server.ssh.commands;
import com.google.gerrit.client.reviewdb.Project;
-import com.google.gerrit.client.reviewdb.ProjectRight;
import com.google.gerrit.client.reviewdb.ReviewDb;
import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.config.WildProjectName;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.ssh.BaseCommand;
@@ -36,6 +36,10 @@ final class ListProjects extends BaseCommand {
@Inject
private ProjectCache projectCache;
+ @Inject
+ @WildProjectName
+ private Project.NameKey wildProject;
+
@Override
public void start() {
startThread(new CommandRunnable() {
@@ -51,7 +55,7 @@ final class ListProjects extends BaseCommand {
final PrintWriter stdout = toPrintWriter(out);
try {
for (final Project p : db.projects().all()) {
- if (ProjectRight.WILD_PROJECT.equals(p.getId())) {
+ if (p.getNameKey().equals(wildProject)) {
// This project "doesn't exist". At least not as a repository.
//
continue;
diff --git a/src/main/webapp/WEB-INF/sql/index_generic.sql b/src/main/webapp/WEB-INF/sql/index_generic.sql
index 0e508af115..253a478238 100644
--- a/src/main/webapp/WEB-INF/sql/index_generic.sql
+++ b/src/main/webapp/WEB-INF/sql/index_generic.sql
@@ -55,15 +55,15 @@ ON account_group_members (group_id);
-- @PrimaryKey covers: byAccount
-- covers: notifyNewChanges
CREATE INDEX account_project_watches_ntNew
-ON account_project_watches (notify_new_changes, project_id);
+ON account_project_watches (notify_new_changes, project_name);
-- covers: notifyAllComments
CREATE INDEX account_project_watches_ntCmt
-ON account_project_watches (notify_all_comments, project_id);
+ON account_project_watches (notify_all_comments, project_name);
-- covers: notifySubmittedChanges
CREATE INDEX account_project_watches_ntSub
-ON account_project_watches (notify_submitted_changes, project_id);
+ON account_project_watches (notify_submitted_changes, project_name);
-- *********************************************************************
diff --git a/src/main/webapp/WEB-INF/sql/index_postgres.sql b/src/main/webapp/WEB-INF/sql/index_postgres.sql
index 52e1695d26..4356c64d61 100644
--- a/src/main/webapp/WEB-INF/sql/index_postgres.sql
+++ b/src/main/webapp/WEB-INF/sql/index_postgres.sql
@@ -68,17 +68,17 @@ ON account_group_members (group_id);
-- @PrimaryKey covers: byAccount
-- covers: notifyNewChanges
CREATE INDEX account_project_watches_ntNew
-ON account_project_watches (project_id)
+ON account_project_watches (project_name)
WHERE notify_new_changes = 'Y';
-- covers: notifyAllComments
CREATE INDEX account_project_watches_ntCmt
-ON account_project_watches (project_id)
+ON account_project_watches (project_name)
WHERE notify_all_comments = 'Y';
-- covers: notifySubmittedChanges
CREATE INDEX account_project_watches_ntSub
-ON account_project_watches (project_id)
+ON account_project_watches (project_name)
WHERE notify_submitted_changes = 'Y';
diff --git a/src/main/webapp/WEB-INF/sql/upgrade015_016_part1_mysql.sql b/src/main/webapp/WEB-INF/sql/upgrade015_016_part1_mysql.sql
new file mode 100644
index 0000000000..9dfa4d3a98
--- /dev/null
+++ b/src/main/webapp/WEB-INF/sql/upgrade015_016_part1_mysql.sql
@@ -0,0 +1,42 @@
+-- Upgrade: schema_version 15 to 16 (MySQL)
+--
+
+-- account_project_watches
+--
+DELETE FROM account_project_watches WHERE project_id NOT IN (SELECT project_id FROM projects);
+ALTER TABLE account_project_watches ADD project_name VARCHAR(255);
+UPDATE account_project_watches SET project_name =
+(SELECT name FROM projects
+ WHERE account_project_watches.project_id = projects.project_id);
+ALTER TABLE account_project_watches MODIFY COLUMN project_name VARCHAR(255) NOT NULL;
+ALTER TABLE account_project_watches DROP PRIMARY KEY;
+ALTER TABLE account_project_watches ADD PRIMARY KEY (account_id, project_name);
+ALTER TABLE account_project_watches DROP COLUMN project_id;
+
+DROP INDEX account_project_watches_ntcmt ON account_project_watches;
+DROP INDEX account_project_watches_ntnew ON account_project_watches;
+DROP INDEX account_project_watches_ntsub ON account_project_watches;
+
+CREATE INDEX account_project_watches_ntNew
+ON account_project_watches (notify_new_changes, project_name);
+
+CREATE INDEX account_project_watches_ntCmt
+ON account_project_watches (notify_all_comments, project_name);
+
+CREATE INDEX account_project_watches_ntSub
+ON account_project_watches (notify_submitted_changes, project_name);
+
+
+-- project_rights
+--
+DELETE FROM project_rights WHERE project_id NOT IN (SELECT project_id FROM projects);
+ALTER TABLE project_rights ADD project_name VARCHAR(255);
+UPDATE project_rights SET project_name =
+(SELECT name FROM projects
+ WHERE project_rights.project_id = projects.project_id);
+ALTER TABLE project_rights MODIFY COLUMN project_name VARCHAR(255) NOT NULL;
+ALTER TABLE project_rights DROP PRIMARY KEY;
+ALTER TABLE project_rights ADD PRIMARY KEY (project_name, category_id, group_id);
+ALTER TABLE project_rights DROP COLUMN project_id;
+
+UPDATE schema_version SET version_nbr = 16;
diff --git a/src/main/webapp/WEB-INF/sql/upgrade015_016_part1_postgres.sql b/src/main/webapp/WEB-INF/sql/upgrade015_016_part1_postgres.sql
new file mode 100644
index 0000000000..133e984a4a
--- /dev/null
+++ b/src/main/webapp/WEB-INF/sql/upgrade015_016_part1_postgres.sql
@@ -0,0 +1,47 @@
+-- Upgrade: schema_version 15 to 16 (PostgreSQL)
+--
+
+-- account_project_watches
+--
+DROP INDEX account_project_watches_ntcmt;
+DROP INDEX account_project_watches_ntnew;
+DROP INDEX account_project_watches_ntsub;
+
+DELETE FROM account_project_watches WHERE project_id NOT IN (SELECT project_id FROM projects);
+ALTER TABLE account_project_watches ADD project_name VARCHAR(255);
+UPDATE account_project_watches SET project_name =
+(SELECT name FROM projects
+ WHERE account_project_watches.project_id = projects.project_id);
+ALTER TABLE account_project_watches ALTER COLUMN project_name SET NOT NULL;
+ALTER TABLE account_project_watches DROP CONSTRAINT account_project_watches_pkey;
+ALTER TABLE account_project_watches ADD PRIMARY KEY (account_id, project_name);
+ALTER TABLE account_project_watches DROP COLUMN project_id;
+
+CREATE INDEX account_project_watches_ntNew
+ON account_project_watches (project_name)
+WHERE notify_new_changes = 'Y';
+
+CREATE INDEX account_project_watches_ntCmt
+ON account_project_watches (project_name)
+WHERE notify_all_comments = 'Y';
+
+CREATE INDEX account_project_watches_ntSub
+ON account_project_watches (project_name)
+WHERE notify_submitted_changes = 'Y';
+
+
+-- project_rights
+--
+DELETE FROM project_rights WHERE project_id NOT IN (SELECT project_id FROM projects);
+ALTER TABLE project_rights ADD project_name VARCHAR(255);
+UPDATE project_rights SET project_name =
+(SELECT name FROM projects
+ WHERE project_rights.project_id = projects.project_id)
+ WHERE project_id IS NOT NULL;
+ALTER TABLE project_rights ALTER COLUMN project_name SET NOT NULL;
+ALTER TABLE project_rights DROP CONSTRAINT project_rights_pkey;
+ALTER TABLE project_rights ADD PRIMARY KEY (project_name, category_id, group_id);
+ALTER TABLE project_rights DROP COLUMN project_id;
+
+
+UPDATE schema_version SET version_nbr = 16;