Merge "Fix updating of username from AccountManager"
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 610b65f..f07ac18 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -871,6 +871,17 @@
+
Default is "Submit patch set ${patchSet} into ${branch}".
+[[change.submitTooltipAncestors]]change.submitTooltipAncestors::
++
+Tooltip for the submit button if there are ancestors which would
+also be submitted by submitting the change. Additionally to the variables
+as in link:#change.submitTooltip[change.submitTooltip], there is the
+variable `${submitSize}` indicating the number of changes which are
+submitted.
++
+Default is "Submit all ${topicSize} changes of the same topic (${submitSize}
+changes including ancestors and other changes related by topic)".
+
[[change.submitWholeTopic]]change.submitWholeTopic::
+
Determines if the submit button submits the whole topic instead of
@@ -2289,10 +2300,6 @@
+
A link:http://lucene.apache.org/[Lucene] index is used.
+
-* `SOLR`
-+
-A link:https://cwiki.apache.org/confluence/display/solr/SolrCloud[
-SolrCloud] index is used.
+
By default, `LUCENE`.
@@ -2413,17 +2420,6 @@
maxBufferedDocs = 500
----
-==== Solr configuration
-
-Open and closed changes are indexed in separate indexes named
-'changes_open' and 'changes_closed' respectively.
-
-The following settings are only used when the index type is `SOLR`.
-
-[[index.url]]index.url::
-+
-URL of the index server.
-
[[ldap]]
=== Section ldap
diff --git a/Documentation/database-setup.txt b/Documentation/database-setup.txt
index 4f854fb..b3b72c4 100644
--- a/Documentation/database-setup.txt
+++ b/Documentation/database-setup.txt
@@ -146,6 +146,51 @@
Visit SAP MaxDB's link:http://maxdb.sap.com/documentation/[documentation] for further
information regarding using SAP MaxDB.
+[[createdb_db2]]
+=== DB2
+
+IBM DB2 is a supported database for running Gerrit Code Review. However it is
+recommended only for environments where you intend to run Gerrit on an existing
+DB2 installation to reduce administrative overhead.
+
+Create a system wide user for the Gerrit application, and grant the user
+full rights on the newly created database:
+
+----
+ db2 => create database gerrit
+ db2 => connect to gerrit
+ db2 => grant connect,accessctrl,dataaccess,dbadm,secadm on database to gerrit2;
+----
+
+JDBC driver db2jcc4.jar and db2jcc_license_cu.jar must be obtained
+from your DB2 distribution. Gerrit initialization process tries to copy
+it from a known location:
+
+----
+/opt/ibm/db2/V10.5/java/db2jcc4.jar
+/opt/ibm/db2/V10.5/java/db2jcc_license_cu.jar
+----
+
+If these files cannot be located at this place, then an alternative location
+can be provided during init step execution.
+
+Sample database section in $site_path/etc/gerrit.config:
+
+----
+[database]
+ type = db2
+ database = gerrit
+ hostname = localhost
+ username = gerrit2
+ port = 50001
+----
+
+Sample database section in $site_path/etc/secure.config:
+
+----
+[database]
+ password = secret_pasword
+----
GERRIT
------
diff --git a/Documentation/dev-eclipse.txt b/Documentation/dev-eclipse.txt
index b3525a1..7e1ca10 100644
--- a/Documentation/dev-eclipse.txt
+++ b/Documentation/dev-eclipse.txt
@@ -79,6 +79,26 @@
recompiling.
* To reflect your changes in the debug session, click `Dev Mode On` then `Compile`.
+
+=== Running GWT Debug Mode for Gerrit plugins
+
+A Gerrit plugin can expose GWT module and its implementation can be inspected
+in the SDM debug session.
+
+`codeserver` needs two additional inputs to expose the plugin module in the SDM
+debug session: the module name and the source folder location. For example the
+module name and source folder of `cookbook-plugin` should be added in the local
+copy of the `gerrit_gwt_debug` configuration:
+
+----
+ com.googlesource.gerrit.plugins.cookbook.HelloForm \
+ -src ${resource_loc:/gerrit}/plugins/cookbook-plugin/src/main/java \
+ -- --console-log [...]
+----
+
+After doing that, both the Gerrit core and plugin GWT modules can be activated
+during SDM (debug session)[http://imgur.com/HFXZ5No].
+
GERRIT
------
Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/dev-plugins.txt b/Documentation/dev-plugins.txt
index 6706ba7..0efc395 100644
--- a/Documentation/dev-plugins.txt
+++ b/Documentation/dev-plugins.txt
@@ -971,6 +971,20 @@
panels with custom controls:
* Change Screen:
+** `GerritUiExtensionPoint.CHANGE_SCREEN_HEADER`:
++
+Panel will be shown in the header bar to the right of the change
+status.
+
+** `GerritUiExtensionPoint.CHANGE_SCREEN_HEADER_RIGHT_OF_BUTTONS`:
++
+Panel will be shown in the header bar on the right side of the buttons.
+
+** `GerritUiExtensionPoint.CHANGE_SCREEN_HEADER_RIGHT_OF_POP_DOWNS`:
++
+Panel will be shown in the header bar on the right side of the pop down
+buttons.
+
** `GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK`:
+
Panel will be shown below the change info block.
@@ -980,12 +994,54 @@
+
The numeric change ID
+* Project Info Screen:
+** `GerritUiExtensionPoint.PROJECT_INFO_SCREEN_TOP`:
++
+Panel will be shown at the top of the screen.
+
+** `GerritUiExtensionPoint.PROJECT_INFO_SCREEN_BOTTOM`:
++
+Panel will be shown at the bottom of the screen.
+
+** The following parameters are provided:
+*** `GerritUiExtensionPoint.Key.PROJECT_NAME`:
++
+The name of the project.
+
+* User Password Screen:
+** `GerritUiExtensionPoint.PASSWORD_SCREEN_BOTTOM`:
++
+Panel will be shown at the bottom of the screen.
+
+** The following parameters are provided:
+*** `GerritUiExtensionPoint.Key.ACCOUNT_INFO`:
++
+The link:rest-api-accounts.html#account-info[AccountInfo] entity for
+the current user.
+
+* User Preferences Screen:
+** `GerritUiExtensionPoint.PREFERENCES_SCREEN_BOTTOM`:
++
+Panel will be shown at the bottom of the screen.
+
+** The following parameters are provided:
+*** `GerritUiExtensionPoint.Key.ACCOUNT_INFO`:
++
+The link:rest-api-accounts.html#account-info[AccountInfo] entity for
+the current user.
+
* User Profile Screen:
** `GerritUiExtensionPoint.PROFILE_SCREEN_BOTTOM`:
+
Panel will be shown at the bottom of the screen below the grid with the
profile data.
+** The following parameters are provided:
+*** `GerritUiExtensionPoint.Key.ACCOUNT_INFO`:
++
+The link:rest-api-accounts.html#account-info[AccountInfo] entity for
+the current user.
+
Example panel:
[source,java]
----
@@ -1706,6 +1762,31 @@
}
----
+[[user-settings-screen]]
+== Add User Settings Screen
+
+A link:#gwt_ui_extension[GWT plugin] can implement a user settings
+screen that is integrated into the Gerrit user settings menu.
+
+Example settings screen:
+[source,java]
+----
+public class MyPlugin extends PluginEntryPoint {
+ @Override
+ public void onPluginLoad() {
+ Plugin.get().settingsScreen("my-preferences", "My Preferences",
+ new Screen.EntryPoint() {
+ @Override
+ public void onLoad(Screen screen) {
+ screen.setPageTitle("Settings");
+ screen.add(new InlineLabel("My Preferences"));
+ screen.show();
+ }
+ });
+ }
+}
+----
+
[[settings-screen]]
== Plugin Settings Screen
diff --git a/Documentation/rest-api-changes.txt b/Documentation/rest-api-changes.txt
index d752c85..94f8ac9 100644
--- a/Documentation/rest-api-changes.txt
+++ b/Documentation/rest-api-changes.txt
@@ -2239,6 +2239,7 @@
)]}'
{
+ "commit": "674ac754f91e64a0efb8087e59a176484bd534d1",
"parents": [
{
"commit": "1eee2c9d8f352483781e772f35dc586a69ff5646",
@@ -3951,7 +3952,10 @@
[options="header",cols="1,^1,5"]
|===========================
|Field Name ||Description
-|`commit` ||The commit ID.
+|`commit` |Optional|
+The commit ID. Not set if included in a link:#revision-info[
+RevisionInfo] entity that is contained in a map which has the commit ID
+as key.
|`parents` ||
The parent commits of this commit as a list of
link:#commit-info[CommitInfo] entities. In each parent
@@ -4147,10 +4151,10 @@
[options="header",cols="1,6"]
|==========================
-|Field Name |Description
-|`deletePatchSetIfCommitMissing`|If true, delete patch sets from the
+|Field Name |Description
+|`delete_patch_set_if_commit_missing`|If true, delete patch sets from the
database if they refer to missing commit options.
-|`expectMergedAs` |If set, check that the change is
+|`expect_merged_as` |If set, check that the change is
merged into the destination branch as this exact SHA-1. If not, insert
a new patch set referring to this commit.
|==========================
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/AbstractDaemonTest.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
index a4cbe72..0f9ffc7 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
@@ -30,6 +30,7 @@
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.changes.RevisionApi;
import com.google.gerrit.extensions.api.projects.ProjectInput;
+import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.client.ListChangesOption;
import com.google.gerrit.extensions.common.ActionInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
@@ -490,6 +491,15 @@
saveProjectConfig(allProjects, cfg);
}
+ protected void setUseContributorAgreements(InheritableBoolean value)
+ throws Exception {
+ MetaDataUpdate md = metaDataUpdateFactory.create(project);
+ ProjectConfig config = ProjectConfig.read(md);
+ config.getProject().setUseContributorAgreements(value);
+ config.commit(md);
+ projectCache.evict(config.getProject());
+ }
+
protected void deny(String permission, AccountGroup.UUID id, String ref)
throws Exception {
ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/PushOneCommit.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/PushOneCommit.java
index 85ba6de..77c38c8 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/PushOneCommit.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/PushOneCommit.java
@@ -47,6 +47,23 @@
public static final String SUBJECT = "test commit";
public static final String FILE_NAME = "a.txt";
public static final String FILE_CONTENT = "some content";
+ public static final String PATCH =
+ "From %s Mon Sep 17 00:00:00 2001\n" +
+ "From: Administrator <admin@example.com>\n" +
+ "Date: %s\n" +
+ "Subject: [PATCH] test commit\n" +
+ "\n" +
+ "Change-Id: %s\n" +
+ "---\n" +
+ "\n" +
+ "diff --git a/a.txt b/a.txt\n" +
+ "new file mode 100644\n" +
+ "index 0000000..f0eec86\n" +
+ "--- /dev/null\n" +
+ "+++ b/a.txt\n" +
+ "@@ -0,0 +1 @@\n" +
+ "+some content\n" +
+ "\\ No newline at end of file\n";
public interface Factory {
PushOneCommit create(
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
index 980b313..967575a 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
@@ -18,6 +18,8 @@
import static com.google.gerrit.acceptance.PushOneCommit.FILE_NAME;
import static com.google.gerrit.acceptance.PushOneCommit.SUBJECT;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
+import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.server.project.Util.blockLabel;
import static com.google.gerrit.server.project.Util.category;
import static com.google.gerrit.server.project.Util.value;
@@ -242,6 +244,8 @@
assertThat(info.project).isEqualTo(in.project);
assertThat(info.branch).isEqualTo(in.branch);
assertThat(info.subject).isEqualTo(in.subject);
+ assertThat(Iterables.getOnlyElement(info.messages).message)
+ .isEqualTo("Uploaded patch set 1.");
}
@Test
@@ -470,4 +474,29 @@
.get())
.hasSize(2);
}
+
+ @Test
+ public void votable() throws Exception {
+ PushOneCommit.Result r = createChange();
+ String triplet = project.get() + "~master~" + r.getChangeId();
+ gApi.changes().id(triplet).addReviewer(user.username);
+ ChangeInfo c = gApi.changes().id(triplet).get(EnumSet.of(
+ ListChangesOption.DETAILED_LABELS));
+ LabelInfo codeReview = c.labels.get("Code-Review");
+ assertThat(codeReview.all).hasSize(1);
+ ApprovalInfo approval = codeReview.all.get(0);
+ assertThat(approval._accountId).isEqualTo(user.id.get());
+ assertThat(approval.value).isEqualTo(0);
+
+ ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
+ blockLabel(cfg, "Code-Review", REGISTERED_USERS, "refs/heads/*");
+ saveProjectConfig(project, cfg);
+ c = gApi.changes().id(triplet).get(EnumSet.of(
+ ListChangesOption.DETAILED_LABELS));
+ codeReview = c.labels.get("Code-Review");
+ assertThat(codeReview.all).hasSize(1);
+ approval = codeReview.all.get(0);
+ assertThat(approval._accountId).isEqualTo(user.id.get());
+ assertThat(approval.value).isNull();
+ }
}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java
index 23e3685..5429b95 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java
@@ -17,6 +17,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.PushOneCommit.FILE_CONTENT;
import static com.google.gerrit.acceptance.PushOneCommit.FILE_NAME;
+import static com.google.gerrit.acceptance.PushOneCommit.PATCH;
import static org.eclipse.jgit.lib.Constants.HEAD;
import com.google.common.base.Predicate;
@@ -40,6 +41,7 @@
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.common.DiffInfo;
import com.google.gerrit.extensions.common.MergeableInfo;
+import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
@@ -52,6 +54,8 @@
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
@@ -540,6 +544,25 @@
.isEqualTo(in.message);
}
+ @Test
+ public void patch() throws Exception {
+ PushOneCommit.Result r = createChange();
+ ChangeApi changeApi = gApi.changes()
+ .id(r.getChangeId());
+ BinaryResult bin = changeApi
+ .revision(r.getCommit().name())
+ .patch();
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ bin.writeTo(os);
+ String res = new String(os.toByteArray(), StandardCharsets.UTF_8);
+ DateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");
+ ChangeInfo change = changeApi.get();
+ RevisionInfo rev = change.revisions.get(change.currentRevision);
+ String date = dateFormat.format(rev.commit.author.date);
+ assertThat(res).isEqualTo(
+ String.format(PATCH, r.getCommitId().name(), date, r.getChangeId()));
+ }
+
private void merge(PushOneCommit.Result r) throws Exception {
revision(r).review(ReviewInput.approve());
revision(r).submit();
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java
index 1624da2..9fcd931 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java
@@ -19,6 +19,7 @@
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.http.HttpStatus.SC_FORBIDDEN;
import static org.apache.http.HttpStatus.SC_CONFLICT;
import static org.apache.http.HttpStatus.SC_NOT_FOUND;
import static org.apache.http.HttpStatus.SC_NO_CONTENT;
@@ -35,6 +36,7 @@
import com.google.gerrit.acceptance.TestProjectInput;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.extensions.api.changes.ReviewInput;
+import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.client.ListChangesOption;
import com.google.gerrit.extensions.common.ApprovalInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
@@ -210,6 +212,22 @@
}
@Test
+ public void publishEditRestWithoutCLA() throws Exception {
+ setUseContributorAgreements(InheritableBoolean.TRUE);
+ PatchSet oldCurrentPatchSet = getCurrentPatchSet(changeId);
+ assertThat(modifier.createEdit(change, oldCurrentPatchSet)).isEqualTo(
+ RefUpdate.Result.NEW);
+ assertThat(
+ modifier.modifyFile(editUtil.byChange(change).get(), FILE_NAME,
+ RestSession.newRawInput(CONTENT_NEW))).isEqualTo(RefUpdate.Result.FORCED);
+ RestResponse r = adminSession.post(urlPublish());
+ assertThat(r.getStatusCode()).isEqualTo(SC_FORBIDDEN);
+ setUseContributorAgreements(InheritableBoolean.FALSE);
+ r = adminSession.post(urlPublish());
+ assertThat(r.getStatusCode()).isEqualTo(SC_NO_CONTENT);
+ }
+
+ @Test
public void rebaseEdit() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
assertThat(
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/VisibleRefFilterIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/VisibleRefFilterIT.java
index 248e1fe..21efc87 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/VisibleRefFilterIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/VisibleRefFilterIT.java
@@ -276,7 +276,7 @@
}
}
- Splitter s = Splitter.on(CharMatcher.WHITESPACE).omitEmptyStrings();
+ Splitter s = Splitter.on(CharMatcher.whitespace()).omitEmptyStrings();
assertThat(filtered).containsExactlyElementsIn(
Ordering.natural().sortedCopy(s.split(out))).inOrder();
}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ActionsIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ActionsIT.java
index 66c99f1..24bb72b 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ActionsIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ActionsIT.java
@@ -52,15 +52,14 @@
commonActionsAssertions(actions);
// We want to treat a single change in a topic not as a whole topic,
// so regardless of how submitWholeTopic is configured:
- noSubmitWholeTopicAssertions(actions);
+ noSubmitWholeTopicAssertions(actions, 1);
}
@Test
- public void revisionActionsTwoChangeChangesInTopic() throws Exception {
+ public void revisionActionsTwoChangesInTopic() throws Exception {
String changeId = createChangeWithTopic().getChangeId();
approve(changeId);
- // create another change with the same topic
- createChangeWithTopic().getChangeId();
+ String changeId2 = createChangeWithTopic().getChangeId();
Map<String, ActionInfo> actions = getActions(changeId);
commonActionsAssertions(actions);
if (isSubmitWholeTopicEnabled()) {
@@ -68,14 +67,19 @@
assertThat(info.enabled).isNull();
assertThat(info.label).isEqualTo("Submit whole topic");
assertThat(info.method).isEqualTo("POST");
- assertThat(info.title).isEqualTo("Other changes in this topic are not ready");
+ assertThat(info.title).isEqualTo("This change depends on other " +
+ "changes which are not ready");
} else {
- noSubmitWholeTopicAssertions(actions);
+ noSubmitWholeTopicAssertions(actions, 1);
+
+ assertThat(getActions(changeId2).get("submit")).isNull();
+ approve(changeId2);
+ noSubmitWholeTopicAssertions(getActions(changeId2), 2);
}
}
@Test
- public void revisionActionsTwoChangeChangesInTopic_conflicting() throws Exception {
+ public void revisionActionsTwoChangesInTopic_conflicting() throws Exception {
String changeId = createChangeWithTopic().getChangeId();
approve(changeId);
@@ -99,38 +103,66 @@
assertThat(info.label).isEqualTo("Submit whole topic");
assertThat(info.method).isEqualTo("POST");
assertThat(info.title).isEqualTo(
- "Clicking the button would fail for other changes in the topic");
+ "Clicking the button would fail for other changes");
} else {
- noSubmitWholeTopicAssertions(actions);
+ noSubmitWholeTopicAssertions(actions, 1);
}
}
@Test
- public void revisionActionsTwoChangeChangesInTopicReady() throws Exception {
- String changeId = createChangeWithTopic().getChangeId();
+ public void revisionActionsTwoChangesInTopicWithAncestorReady()
+ throws Exception {
+ String changeId = createChange().getChangeId();
approve(changeId);
+ approve(changeId);
+ String changeId1 = createChangeWithTopic().getChangeId();
+ approve(changeId1);
// create another change with the same topic
String changeId2 = createChangeWithTopic().getChangeId();
approve(changeId2);
- Map<String, ActionInfo> actions = getActions(changeId);
+ Map<String, ActionInfo> actions = getActions(changeId1);
commonActionsAssertions(actions);
if (isSubmitWholeTopicEnabled()) {
ActionInfo info = actions.get("submit");
assertThat(info.enabled).isTrue();
assertThat(info.label).isEqualTo("Submit whole topic");
assertThat(info.method).isEqualTo("POST");
- assertThat(info.title).isEqualTo("Submit all 2 changes of the same topic");
+ assertThat(info.title).isEqualTo("Submit all 2 changes of the same " +
+ "topic (3 changes including ancestors " +
+ "and other changes related by topic)");
} else {
- noSubmitWholeTopicAssertions(actions);
+ noSubmitWholeTopicAssertions(actions, 2);
}
}
- private void noSubmitWholeTopicAssertions(Map<String, ActionInfo> actions) {
+ @Test
+ public void revisionActionsReadyWithAncestors() throws Exception {
+ String changeId = createChange().getChangeId();
+ approve(changeId);
+ approve(changeId);
+ String changeId1 = createChange().getChangeId();
+ approve(changeId1);
+ String changeId2 = createChangeWithTopic().getChangeId();
+ approve(changeId2);
+ Map<String, ActionInfo> actions = getActions(changeId2);
+ commonActionsAssertions(actions);
+ // The topic contains only one change, so standard text applies
+ noSubmitWholeTopicAssertions(actions, 3);
+ }
+
+ private void noSubmitWholeTopicAssertions(Map<String, ActionInfo> actions,
+ int nrChanges) {
ActionInfo info = actions.get("submit");
assertThat(info.enabled).isTrue();
assertThat(info.label).isEqualTo("Submit");
assertThat(info.method).isEqualTo("POST");
- assertThat(info.title).isEqualTo("Submit patch set 1 into master");
+ if (nrChanges == 1) {
+ assertThat(info.title).isEqualTo("Submit patch set 1 into master");
+ } else {
+ assertThat(info.title).isEqualTo(String.format(
+ "Submit patch set 1 and ancestors (%d changes " +
+ "altogether) into master", nrChanges));
+ }
}
private void commonActionsAssertions(Map<String, ActionInfo> actions) {
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/PageLinks.java b/gerrit-common/src/main/java/com/google/gerrit/common/PageLinks.java
index 80ca561..c80d867 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/PageLinks.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/PageLinks.java
@@ -33,6 +33,7 @@
public static final String SETTINGS_CONTACT = "/settings/contact";
public static final String SETTINGS_PROJECTS = "/settings/projects";
public static final String SETTINGS_NEW_AGREEMENT = "/settings/new-agreement";
+ public static final String SETTINGS_EXTENSION = "/settings/x/";
public static final String REGISTER = "/register";
public static final String MINE = "/";
@@ -128,6 +129,10 @@
return ADMIN_GROUPS + "uuid-" + uuid;
}
+ public static String toSettings(String pluginName, String path) {
+ return SETTINGS_EXTENSION + pluginName + "/" + path;
+ }
+
private static String status(Status status) {
switch (status) {
case ABANDONED:
diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/RevisionApi.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/RevisionApi.java
index cb0d5f3..44c2ba4 100644
--- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/RevisionApi.java
+++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/RevisionApi.java
@@ -18,6 +18,7 @@
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.common.FileInfo;
import com.google.gerrit.extensions.common.MergeableInfo;
+import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.NotImplementedException;
import com.google.gerrit.extensions.restapi.RestApiException;
@@ -57,6 +58,11 @@
CommentApi comment(String id) throws RestApiException;
+ /**
+ * Returns patch of revision.
+ */
+ BinaryResult patch() throws RestApiException;
+
Map<String, ActionInfo> actions() throws RestApiException;
/**
@@ -180,6 +186,11 @@
}
@Override
+ public BinaryResult patch() throws RestApiException {
+ throw new NotImplementedException();
+ }
+
+ @Override
public Map<String, ActionInfo> actions() throws RestApiException {
throw new NotImplementedException();
}
diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/ChangeInfo.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/ChangeInfo.java
index 13baf6b..cdfe0c6 100644
--- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/ChangeInfo.java
+++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/ChangeInfo.java
@@ -35,6 +35,7 @@
public Boolean starred;
public Boolean reviewed;
public Boolean mergeable;
+ public Boolean submittable;
public Integer insertions;
public Integer deletions;
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/GerritUiExtensionPoint.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/GerritUiExtensionPoint.java
index 4047c68..e22625c 100644
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/GerritUiExtensionPoint.java
+++ b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/GerritUiExtensionPoint.java
@@ -16,12 +16,24 @@
public enum GerritUiExtensionPoint {
/* ChangeScreen */
+ CHANGE_SCREEN_HEADER,
+ CHANGE_SCREEN_HEADER_RIGHT_OF_BUTTONS,
+ CHANGE_SCREEN_HEADER_RIGHT_OF_POP_DOWNS,
CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK,
+ /* MyPasswordScreen */
+ PASSWORD_SCREEN_BOTTOM,
+
+ /* MyPreferencesScreen */
+ PREFERENCES_SCREEN_BOTTOM,
+
/* MyProfileScreen */
- PROFILE_SCREEN_BOTTOM;
+ PROFILE_SCREEN_BOTTOM,
+
+ /* ProjectInfoScreen */
+ PROJECT_INFO_SCREEN_TOP, PROJECT_INFO_SCREEN_BOTTOM;
public enum Key {
- CHANGE_ID
+ ACCOUNT_INFO, CHANGE_ID, PROJECT_NAME
}
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/AccountInfo.java
similarity index 97%
rename from gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountInfo.java
rename to gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/AccountInfo.java
index 36fa98d..872861a 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountInfo.java
+++ b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/AccountInfo.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.client.account;
+package com.google.gerrit.client.info;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/AvatarImage.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/AvatarImage.java
index 4b29b49..f0379ea 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/AvatarImage.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/AvatarImage.java
@@ -14,9 +14,9 @@
package com.google.gerrit.client;
-import com.google.gerrit.client.account.AccountInfo;
-import com.google.gerrit.client.account.AccountInfo.AvatarInfo;
import com.google.gerrit.client.changes.Util;
+import com.google.gerrit.client.info.AccountInfo;
+import com.google.gerrit.client.info.AccountInfo.AvatarInfo;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gwt.event.dom.client.LoadEvent;
import com.google.gwt.event.dom.client.LoadHandler;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
index cda3060..0123869 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
@@ -28,6 +28,7 @@
import static com.google.gerrit.common.PageLinks.SETTINGS;
import static com.google.gerrit.common.PageLinks.SETTINGS_AGREEMENTS;
import static com.google.gerrit.common.PageLinks.SETTINGS_CONTACT;
+import static com.google.gerrit.common.PageLinks.SETTINGS_EXTENSION;
import static com.google.gerrit.common.PageLinks.SETTINGS_HTTP_PASSWORD;
import static com.google.gerrit.common.PageLinks.SETTINGS_MYGROUPS;
import static com.google.gerrit.common.PageLinks.SETTINGS_NEW_AGREEMENT;
@@ -65,6 +66,7 @@
import com.google.gerrit.client.admin.ProjectListScreen;
import com.google.gerrit.client.admin.ProjectScreen;
import com.google.gerrit.client.api.ExtensionScreen;
+import com.google.gerrit.client.api.ExtensionSettingsScreen;
import com.google.gerrit.client.change.ChangeScreen;
import com.google.gerrit.client.change.FileTable;
import com.google.gerrit.client.changes.AccountDashboardScreen;
@@ -720,6 +722,16 @@
return new NewAgreementScreen(skip(token));
}
+ if (matchPrefix(SETTINGS_EXTENSION, token)) {
+ ExtensionSettingsScreen view =
+ new ExtensionSettingsScreen(skip(token));
+ if (view.isFound()) {
+ return view;
+ } else {
+ return new NotFoundScreen();
+ }
+ }
+
return new NotFoundScreen();
}
});
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/FormatUtil.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/FormatUtil.java
index 56bc500..d0294f2 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/FormatUtil.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/FormatUtil.java
@@ -14,7 +14,7 @@
package com.google.gerrit.client;
-import com.google.gerrit.client.account.AccountInfo;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences;
import com.google.gwt.i18n.client.DateTimeFormat;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
index 070a868..705f111 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
@@ -20,7 +20,6 @@
import com.google.gerrit.client.account.AccountApi;
import com.google.gerrit.client.account.AccountCapabilities;
-import com.google.gerrit.client.account.AccountInfo;
import com.google.gerrit.client.account.Preferences;
import com.google.gerrit.client.admin.ProjectScreen;
import com.google.gerrit.client.api.ApiGlue;
@@ -34,6 +33,7 @@
import com.google.gerrit.client.extensions.TopMenu;
import com.google.gerrit.client.extensions.TopMenuItem;
import com.google.gerrit.client.extensions.TopMenuList;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.patches.UnifiedPatchScreen;
import com.google.gerrit.client.rpc.CallbackGroup;
import com.google.gerrit.client.rpc.GerritCallback;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritCss.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritCss.java
index 2844b5e..c6eb2de 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritCss.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritCss.java
@@ -98,6 +98,7 @@
String errorDialogErrorType();
String errorDialogGlass();
String errorDialogTitle();
+ String extensionPanel();
String loadingPluginsDialog();
String fileColumnHeader();
String fileCommentBorder();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/UserPopupPanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/UserPopupPanel.java
index 29d1b63..00036a8 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/UserPopupPanel.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/UserPopupPanel.java
@@ -14,7 +14,7 @@
package com.google.gerrit.client;
-import com.google.gerrit.client.account.AccountInfo;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.AnchorElement;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountApi.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountApi.java
index 59d65f6..02c22e1 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountApi.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountApi.java
@@ -15,6 +15,7 @@
package com.google.gerrit.client.account;
import com.google.gerrit.client.VoidResult;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.rpc.CallbackGroup;
import com.google.gerrit.client.rpc.NativeString;
import com.google.gerrit.client.rpc.RestApi;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPasswordScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPasswordScreen.java
index fb3e139..157ee46 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPasswordScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPasswordScreen.java
@@ -15,7 +15,9 @@
package com.google.gerrit.client.account;
import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.GerritUiExtensionPoint;
import com.google.gerrit.client.VoidResult;
+import com.google.gerrit.client.api.ExtensionPanel;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.NativeString;
import com.google.gerrit.client.rpc.RestApi;
@@ -91,6 +93,10 @@
@Override
protected void onLoad() {
super.onLoad();
+ ExtensionPanel extensionPanel =
+ createExtensionPoint(GerritUiExtensionPoint.PASSWORD_SCREEN_BOTTOM);
+ extensionPanel.addStyleName(Gerrit.RESOURCES.css().extensionPanel());
+ add(extensionPanel);
if (password == null) {
display();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPreferencesScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPreferencesScreen.java
index a4cfd21..18bf400 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPreferencesScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPreferencesScreen.java
@@ -18,7 +18,9 @@
import static com.google.gerrit.reviewdb.client.AccountGeneralPreferences.PAGESIZE_CHOICES;
import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.GerritUiExtensionPoint;
import com.google.gerrit.client.StringListPanel;
+import com.google.gerrit.client.api.ExtensionPanel;
import com.google.gerrit.client.config.ConfigServerApi;
import com.google.gerrit.client.extensions.TopMenuItem;
import com.google.gerrit.client.rpc.GerritCallback;
@@ -220,6 +222,11 @@
@Override
protected void onLoad() {
super.onLoad();
+ ExtensionPanel extensionPanel =
+ createExtensionPoint(GerritUiExtensionPoint.PREFERENCES_SCREEN_BOTTOM);
+ extensionPanel.addStyleName(Gerrit.RESOURCES.css().extensionPanel());
+ add(extensionPanel);
+
AccountApi.self().view("preferences")
.get(new ScreenLoadCallback<Preferences>(this) {
@Override
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyProfileScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyProfileScreen.java
index 028d553..0b2b1cc 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyProfileScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyProfileScreen.java
@@ -20,7 +20,6 @@
import com.google.gerrit.client.FormatUtil;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.GerritUiExtensionPoint;
-import com.google.gerrit.client.api.ExtensionPanel;
import com.google.gerrit.client.rpc.NativeString;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.reviewdb.client.Account;
@@ -88,7 +87,7 @@
@Override
protected void onLoad() {
super.onLoad();
- add(new ExtensionPanel(GerritUiExtensionPoint.PROFILE_SCREEN_BOTTOM));
+ add(createExtensionPoint(GerritUiExtensionPoint.PROFILE_SCREEN_BOTTOM));
display(Gerrit.getUserAccount());
display();
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/SettingsScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/SettingsScreen.java
index d00d557..b21d28d 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/SettingsScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/SettingsScreen.java
@@ -15,28 +15,70 @@
package com.google.gerrit.client.account;
import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.GerritUiExtensionPoint;
+import com.google.gerrit.client.api.ExtensionPanel;
+import com.google.gerrit.client.api.ExtensionSettingsScreen;
+import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.ui.MenuScreen;
import com.google.gerrit.common.PageLinks;
+import java.util.HashSet;
+import java.util.Set;
+
public abstract class SettingsScreen extends MenuScreen {
+ private final Set<String> allMenuNames;
+ private final Set<String> ambiguousMenuNames;
+
public SettingsScreen() {
setRequiresSignIn(true);
- link(Util.C.tabAccountSummary(), PageLinks.SETTINGS);
- link(Util.C.tabPreferences(), PageLinks.SETTINGS_PREFERENCES);
- link(Util.C.tabWatchedProjects(), PageLinks.SETTINGS_PROJECTS);
- link(Util.C.tabContactInformation(), PageLinks.SETTINGS_CONTACT);
+ allMenuNames = new HashSet<>();
+ ambiguousMenuNames = new HashSet<>();
+
+ linkByGerrit(Util.C.tabAccountSummary(), PageLinks.SETTINGS);
+ linkByGerrit(Util.C.tabPreferences(), PageLinks.SETTINGS_PREFERENCES);
+ linkByGerrit(Util.C.tabWatchedProjects(), PageLinks.SETTINGS_PROJECTS);
+ linkByGerrit(Util.C.tabContactInformation(), PageLinks.SETTINGS_CONTACT);
if (Gerrit.info().hasSshd()) {
- link(Util.C.tabSshKeys(), PageLinks.SETTINGS_SSHKEYS);
+ linkByGerrit(Util.C.tabSshKeys(), PageLinks.SETTINGS_SSHKEYS);
}
if (Gerrit.info().auth().isHttpPasswordSettingsEnabled()) {
- link(Util.C.tabHttpAccess(), PageLinks.SETTINGS_HTTP_PASSWORD);
+ linkByGerrit(Util.C.tabHttpAccess(), PageLinks.SETTINGS_HTTP_PASSWORD);
}
- link(Util.C.tabWebIdentities(), PageLinks.SETTINGS_WEBIDENT);
- link(Util.C.tabMyGroups(), PageLinks.SETTINGS_MYGROUPS);
+ linkByGerrit(Util.C.tabWebIdentities(), PageLinks.SETTINGS_WEBIDENT);
+ linkByGerrit(Util.C.tabMyGroups(), PageLinks.SETTINGS_MYGROUPS);
if (Gerrit.info().auth().useContributorAgreements()) {
- link(Util.C.tabAgreements(), PageLinks.SETTINGS_AGREEMENTS);
+ linkByGerrit(Util.C.tabAgreements(), PageLinks.SETTINGS_AGREEMENTS);
}
+
+ for (String pluginName : ExtensionSettingsScreen.Definition.plugins()) {
+ for (ExtensionSettingsScreen.Definition def :
+ Natives.asList(ExtensionSettingsScreen.Definition.get(pluginName))) {
+ if (!allMenuNames.add(def.getMenu())) {
+ ambiguousMenuNames.add(def.getMenu());
+ }
+ }
+ }
+
+ for (String pluginName : ExtensionSettingsScreen.Definition.plugins()) {
+ for (ExtensionSettingsScreen.Definition def :
+ Natives.asList(ExtensionSettingsScreen.Definition.get(pluginName))) {
+ linkByPlugin(pluginName, def.getMenu(),
+ PageLinks.toSettings(pluginName, def.getPath()));
+ }
+ }
+ }
+
+ private void linkByGerrit(String text, String target) {
+ allMenuNames.add(text);
+ link(text, target);
+ }
+
+ private void linkByPlugin(String pluginName, String text, String target) {
+ if (ambiguousMenuNames.contains(text)) {
+ text += " ("+ pluginName + ")";
+ }
+ link(text, target);
}
@Override
@@ -44,4 +86,12 @@
super.onInitUI();
setPageTitle(Util.C.settingsHeading());
}
+
+ protected ExtensionPanel createExtensionPoint(
+ GerritUiExtensionPoint extensionPoint) {
+ ExtensionPanel extensionPanel = new ExtensionPanel(extensionPoint);
+ extensionPanel.putObject(GerritUiExtensionPoint.Key.ACCOUNT_INFO,
+ Gerrit.getUserAccountInfo());
+ return extensionPanel;
+ }
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccountGroupAuditLogScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccountGroupAuditLogScreen.java
index 4f46d39..7b4f74c 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccountGroupAuditLogScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccountGroupAuditLogScreen.java
@@ -19,7 +19,7 @@
import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.Gerrit;
-import com.google.gerrit.client.account.AccountInfo;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.groups.GroupApi;
import com.google.gerrit.client.groups.GroupAuditEventInfo;
import com.google.gerrit.client.groups.GroupInfo;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccountGroupMembersScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccountGroupMembersScreen.java
index 1e3f918..7c0c8f6 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccountGroupMembersScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AccountGroupMembersScreen.java
@@ -17,9 +17,9 @@
import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.VoidResult;
-import com.google.gerrit.client.account.AccountInfo;
import com.google.gerrit.client.groups.GroupApi;
import com.google.gerrit.client.groups.GroupInfo;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.ui.AccountGroupSuggestOracle;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java
index 4edcfa6..9724000 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java
@@ -15,11 +15,13 @@
package com.google.gerrit.client.admin;
import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.GerritUiExtensionPoint;
import com.google.gerrit.client.StringListPanel;
import com.google.gerrit.client.access.AccessMap;
import com.google.gerrit.client.access.ProjectAccessInfo;
import com.google.gerrit.client.actions.ActionButton;
import com.google.gerrit.client.actions.ActionInfo;
+import com.google.gerrit.client.api.ExtensionPanel;
import com.google.gerrit.client.change.Resources;
import com.google.gerrit.client.config.DownloadInfo.DownloadCommandInfo;
import com.google.gerrit.client.config.DownloadInfo.DownloadSchemeInfo;
@@ -114,6 +116,12 @@
}
});
+ ExtensionPanel extensionPanelTop =
+ new ExtensionPanel(GerritUiExtensionPoint.PROJECT_INFO_SCREEN_TOP);
+ extensionPanelTop.put(GerritUiExtensionPoint.Key.PROJECT_NAME,
+ getProjectKey().get());
+ add(extensionPanelTop);
+
add(new ProjectDownloadPanel(getProjectKey().get(), true));
initDescription();
@@ -126,6 +134,12 @@
add(pluginOptionsPanel);
add(saveProject);
add(actionsGrid);
+
+ ExtensionPanel extensionPanelBottom =
+ new ExtensionPanel(GerritUiExtensionPoint.PROJECT_INFO_SCREEN_BOTTOM);
+ extensionPanelBottom.put(GerritUiExtensionPoint.Key.PROJECT_NAME,
+ getProjectKey().get());
+ add(extensionPanelBottom);
}
@Override
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/ApiGlue.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/ApiGlue.java
index c5f0af5..b30a1cb 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/ApiGlue.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/ApiGlue.java
@@ -16,7 +16,7 @@
import com.google.gerrit.client.ErrorDialog;
import com.google.gerrit.client.Gerrit;
-import com.google.gerrit.client.account.AccountInfo;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.user.client.History;
@@ -35,12 +35,14 @@
private static native void init0() /*-{
var serverUrl = @com.google.gwt.core.client.GWT::getHostPageBaseURL()();
var ScreenDefinition = @com.google.gerrit.client.api.ExtensionScreen.Definition::TYPE;
+ var SettingsScreenDefinition = @com.google.gerrit.client.api.ExtensionSettingsScreen.Definition::TYPE;
var PanelDefinition = @com.google.gerrit.client.api.ExtensionPanel.Definition::TYPE;
$wnd.Gerrit = {
JsonString: @com.google.gerrit.client.rpc.NativeString::TYPE,
events: {},
plugins: {},
screens: {},
+ settingsScreens: {},
panels: {},
change_actions: {},
edit_actions: {},
@@ -87,6 +89,11 @@
var s = new ScreenDefinition(r,c);
(this.screens[p] || (this.screens[p]=[])).push(s);
},
+ settingsScreen: function(p,m,c){this._settingsScreen(this.getPluginName(),p,m,c)},
+ _settingsScreen: function(n,p,m,c){
+ var s = new SettingsScreenDefinition(p,m,c);
+ (this.settingsScreens[n] || (this.settingsScreens[n]=[])).push(s);
+ },
panel: function(i,c){this._panel(this.getPluginName(),i,c)},
_panel: function(n,i,c){
var p = new PanelDefinition(n,c);
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/ExtensionPanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/ExtensionPanel.java
index 6ee9b44..0702cba 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/ExtensionPanel.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/ExtensionPanel.java
@@ -66,6 +66,12 @@
}
}
+ public void putObject(GerritUiExtensionPoint.Key key, JavaScriptObject value) {
+ for (Context ctx : contexts) {
+ ctx.putObject(key.name(), value);
+ }
+ }
+
@Override
protected void onLoad() {
super.onLoad();
@@ -122,6 +128,7 @@
final native void put(String k, String v) /*-{ this.p[k] = v; }-*/;
final native void putInt(String k, int v) /*-{ this.p[k] = v; }-*/;
final native void putBoolean(String k, boolean v) /*-{ this.p[k] = v; }-*/;
+ final native void putObject(String k, JavaScriptObject v) /*-{ this.p[k] = v; }-*/;
private static final native Context create(
JavaScriptObject T,
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/ExtensionSettingsScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/ExtensionSettingsScreen.java
new file mode 100644
index 0000000..c351bbf
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/ExtensionSettingsScreen.java
@@ -0,0 +1,144 @@
+// Copyright (C) 2015 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.client.api;
+
+import com.google.gerrit.client.account.SettingsScreen;
+import com.google.gerrit.client.rpc.NativeMap;
+import com.google.gerrit.client.rpc.NativeString;
+import com.google.gerrit.client.rpc.Natives;
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.core.client.JsArray;
+import com.google.gwt.dom.client.Element;
+
+import java.util.Set;
+
+/** SettingsScreen contributed by a plugin. */
+public class ExtensionSettingsScreen extends SettingsScreen {
+ private Context ctx;
+
+ public ExtensionSettingsScreen(String token) {
+ if (token.contains("?")) {
+ token = token.substring(0, token.indexOf('?'));
+ }
+ String name;
+ String rest;
+ int s = token.indexOf('/');
+ if (0 < s) {
+ name = token.substring(0, s);
+ rest = token.substring(s + 1);
+ } else {
+ name = token;
+ rest = "";
+ }
+ ctx = create(name, rest);
+ }
+
+ private Context create(String name, String rest) {
+ for (Definition def : Natives.asList(Definition.get(name))) {
+ if (def.matches(rest)) {
+ return Context.create(def, this);
+ }
+ }
+ return null;
+ }
+
+ public boolean isFound() {
+ return ctx != null;
+ }
+
+ @Override
+ protected void onLoad() {
+ super.onLoad();
+ setHeaderVisible(false);
+ ctx.onLoad();
+ }
+
+ @Override
+ protected void onUnload() {
+ super.onUnload();
+ for (JavaScriptObject u : Natives.asList(ctx.unload())) {
+ ApiGlue.invoke(u);
+ }
+ }
+
+ public static class Definition extends JavaScriptObject {
+ static final JavaScriptObject TYPE = init();
+ private static native JavaScriptObject init() /*-{
+ function SettingsScreenDefinition(p, m, c) {
+ this.path = p;
+ this.menu = m;
+ this.onLoad = c;
+ };
+ return SettingsScreenDefinition;
+ }-*/;
+
+ public static native JsArray<Definition> get(String n)
+ /*-{ return $wnd.Gerrit.settingsScreens[n] || [] }-*/;
+
+ public static final Set<String> plugins() {
+ return Natives.keys(settingsScreens());
+ }
+
+ private static final native NativeMap<NativeString> settingsScreens()
+ /*-{ return $wnd.Gerrit.settingsScreens; }-*/;
+
+ public final native String getPath() /*-{ return this.path; }-*/;
+ public final native String getMenu() /*-{ return this.menu; }-*/;
+
+ final native boolean matches(String t)
+ /*-{ return this.path == t; }-*/;
+
+ protected Definition() {
+ }
+ }
+
+ static class Context extends JavaScriptObject {
+ static final Context create(
+ Definition def,
+ ExtensionSettingsScreen view) {
+ return create(TYPE, def, view, view.getBody().getElement());
+ }
+
+ final native void onLoad() /*-{ this._d.onLoad(this) }-*/;
+ final native JsArray<JavaScriptObject> unload() /*-{ return this._u }-*/;
+
+ private static final native Context create(
+ JavaScriptObject T,
+ Definition d,
+ ExtensionSettingsScreen s,
+ Element e)
+ /*-{ return new T(d,s,e) }-*/;
+
+ private static final JavaScriptObject TYPE = init();
+ private static final native JavaScriptObject init() /*-{
+ var T = function(d,s,e) {
+ this._d = d;
+ this._s = s;
+ this._u = [];
+ this.body = e;
+ };
+ T.prototype = {
+ setTitle: function(t){this._s.@com.google.gerrit.client.ui.Screen::setPageTitle(Ljava/lang/String;)(t)},
+ setWindowTitle: function(t){this._s.@com.google.gerrit.client.ui.Screen::setWindowTitle(Ljava/lang/String;)(t)},
+ show: function(){$entry(this._s.@com.google.gwtexpui.user.client.View::display()())},
+ onUnload: function(f){this._u.push(f)},
+ };
+ return T;
+ }-*/;
+
+ protected Context() {
+ }
+ }
+}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/Plugin.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/Plugin.java
index 4eec47a..c3b2338 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/Plugin.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/Plugin.java
@@ -59,6 +59,7 @@
on: function(e,f){G.on(e,f)},
onAction: function(t,n,c){G._onAction(this.name,t,n,c)},
screen: function(p,c){G._screen(this.name,p,c)},
+ settingsScreen: function(p,m,c){G._settingsScreen(this.name,p,m,c)},
panel: function(i,c){G._panel(this.name,i,c)},
url: function (u){return G.url(this._url(u))},
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.java
index 5a311ec..2c7d137 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.java
@@ -19,7 +19,6 @@
import com.google.gerrit.client.FormatUtil;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.GerritUiExtensionPoint;
-import com.google.gerrit.client.account.AccountInfo.AvatarInfo;
import com.google.gerrit.client.actions.ActionInfo;
import com.google.gerrit.client.api.ChangeGlue;
import com.google.gerrit.client.api.ExtensionPanel;
@@ -37,6 +36,7 @@
import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.diff.DiffApi;
import com.google.gerrit.client.diff.FileInfo;
+import com.google.gerrit.client.info.AccountInfo.AvatarInfo;
import com.google.gerrit.client.projects.ConfigInfoCache;
import com.google.gerrit.client.projects.ConfigInfoCache.Entry;
import com.google.gerrit.client.rpc.CallbackGroup;
@@ -87,6 +87,7 @@
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.ListBox;
+import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.ToggleButton;
import com.google.gwtexpui.globalkey.client.GlobalKey;
@@ -149,6 +150,9 @@
private FileTable.Mode fileTableMode;
@UiField HTMLPanel headerLine;
+ @UiField SimplePanel headerExtension;
+ @UiField SimplePanel headerExtensionMiddle;
+ @UiField SimplePanel headerExtensionRight;
@UiField Style style;
@UiField ToggleButton star;
@UiField Anchor permalink;
@@ -226,10 +230,7 @@
@Override
protected void onLoad() {
super.onLoad();
- ExtensionPanel extensionPanel =
- new ExtensionPanel(GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK);
- extensionPanel.putInt(GerritUiExtensionPoint.Key.CHANGE_ID, changeId.get());
- changeExtension.add(extensionPanel);
+ addExtensionPoints();
CallbackGroup group = new CallbackGroup();
if (Gerrit.isSignedIn()) {
ChangeList.query("change:" + changeId.get() + " has:draft",
@@ -266,6 +267,24 @@
}));
}
+ private void addExtensionPoints() {
+ addExtensionPoint(GerritUiExtensionPoint.CHANGE_SCREEN_HEADER,
+ headerExtension);
+ addExtensionPoint(GerritUiExtensionPoint.CHANGE_SCREEN_HEADER_RIGHT_OF_BUTTONS,
+ headerExtensionMiddle);
+ addExtensionPoint(GerritUiExtensionPoint.CHANGE_SCREEN_HEADER_RIGHT_OF_POP_DOWNS,
+ headerExtensionRight);
+ addExtensionPoint(
+ GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK,
+ changeExtension);
+ }
+
+ private void addExtensionPoint(GerritUiExtensionPoint extensionPoint, Panel p) {
+ ExtensionPanel extensionPanel = new ExtensionPanel(extensionPoint);
+ extensionPanel.putInt(GerritUiExtensionPoint.Key.CHANGE_ID, changeId.get());
+ p.add(extensionPanel);
+ }
+
void loadChangeInfo(boolean fg, AsyncCallback<ChangeInfo> cb) {
RestApi call = ChangeApi.detail(changeId.get());
ChangeList.addOptions(call, EnumSet.of(
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.ui.xml
index ed3be38..06ae4ca 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.ui.xml
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen.ui.xml
@@ -81,7 +81,6 @@
display: inline-block;
position: relative;
height: HEADER_HEIGHT;
- width: 300px;
}
.star {
position: absolute;
@@ -323,6 +322,15 @@
vertical-align: bottom;
}
+ .headerExtension {
+ display: inline-block;
+ float: right;
+ }
+
+ .headerExtension>div>div {
+ float: left;
+ }
+
.changeExtension {
padding-top: 5px;
}
@@ -337,6 +345,7 @@
<ui:attribute name='title'/>
</g:Anchor> - <span ui:field='statusText' class='{style.statusText}'/></ui:msg>
</span>
+ <g:SimplePanel ui:field='headerExtension' styleName='{style.headerExtension}'/>
</div>
</div>
@@ -374,6 +383,7 @@
<g:Button ui:field='deleteRevision' styleName='' visible='false'>
<div><ui:msg>Delete Revision</ui:msg></div>
</g:Button>
+ <g:SimplePanel ui:field='headerExtensionMiddle' styleName='{style.headerExtension}'/>
</div>
</div>
@@ -388,6 +398,7 @@
<g:Button ui:field='download' styleName=''>
<div><ui:msg>Download</ui:msg></div>
</g:Button>
+ <g:SimplePanel ui:field='headerExtensionRight' styleName='{style.headerExtension}'/>
</g:FlowPanel>
<c:StarIcon ui:field='star' styleName='{style.star}' title='Star the change (Shortcut: s)'>
<ui:attribute name='title'/>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/CommitBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/CommitBox.java
index 68b230f..bfaff93 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/CommitBox.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/CommitBox.java
@@ -18,12 +18,12 @@
import com.google.gerrit.client.FormatUtil;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.WebLinkInfo;
-import com.google.gerrit.client.account.AccountInfo;
import com.google.gerrit.client.changes.ChangeInfo;
import com.google.gerrit.client.changes.ChangeInfo.CommitInfo;
import com.google.gerrit.client.changes.ChangeInfo.GitPerson;
import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo;
import com.google.gerrit.client.config.GitwebInfo;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.client.ui.InlineHyperlink;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/DownloadBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/DownloadBox.java
index ce2a104..6d39198 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/DownloadBox.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/DownloadBox.java
@@ -265,7 +265,8 @@
AccountGeneralPreferences pref =
Gerrit.getUserAccount().getGeneralPreferences();
- if (scheme != null && scheme != pref.getDownloadUrl()) {
+ if (Gerrit.isSignedIn() && scheme != null
+ && scheme != pref.getDownloadUrl()) {
pref.setDownloadUrl(scheme);
PreferenceInput in = PreferenceInput.create();
in.downloadScheme(scheme);
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Labels.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Labels.java
index f192a71..aceed57 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Labels.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Labels.java
@@ -15,13 +15,13 @@
package com.google.gerrit.client.change;
import com.google.gerrit.client.Gerrit;
-import com.google.gerrit.client.account.AccountInfo;
-import com.google.gerrit.client.account.AccountInfo.AvatarInfo;
import com.google.gerrit.client.changes.ChangeApi;
import com.google.gerrit.client.changes.ChangeInfo;
import com.google.gerrit.client.changes.ChangeInfo.ApprovalInfo;
import com.google.gerrit.client.changes.ChangeInfo.LabelInfo;
import com.google.gerrit.client.changes.Util;
+import com.google.gerrit.client.info.AccountInfo;
+import com.google.gerrit.client.info.AccountInfo.AvatarInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.common.PageLinks;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReviewerSuggestOracle.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReviewerSuggestOracle.java
index 7af247a..1c0486d 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReviewerSuggestOracle.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReviewerSuggestOracle.java
@@ -15,10 +15,10 @@
package com.google.gerrit.client.change;
import com.google.gerrit.client.FormatUtil;
-import com.google.gerrit.client.account.AccountInfo;
import com.google.gerrit.client.admin.Util;
import com.google.gerrit.client.changes.ChangeApi;
import com.google.gerrit.client.groups.GroupBaseInfo;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.ui.SuggestAfterTypingNCharsOracle;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Reviewers.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Reviewers.java
index ce35747..22a7155 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Reviewers.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Reviewers.java
@@ -17,12 +17,12 @@
import com.google.gerrit.client.ConfirmationCallback;
import com.google.gerrit.client.ConfirmationDialog;
import com.google.gerrit.client.Gerrit;
-import com.google.gerrit.client.account.AccountInfo;
import com.google.gerrit.client.changes.ChangeApi;
import com.google.gerrit.client.changes.ChangeInfo;
import com.google.gerrit.client.changes.ChangeInfo.ApprovalInfo;
import com.google.gerrit.client.changes.ChangeInfo.LabelInfo;
import com.google.gerrit.client.changes.Util;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.NativeString;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeInfo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeInfo.java
index 7f93500..5b7e304 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeInfo.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeInfo.java
@@ -15,9 +15,9 @@
package com.google.gerrit.client.changes;
import com.google.gerrit.client.WebLinkInfo;
-import com.google.gerrit.client.account.AccountInfo;
import com.google.gerrit.client.actions.ActionInfo;
import com.google.gerrit.client.diff.FileInfo;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.NativeString;
import com.google.gerrit.client.rpc.Natives;
@@ -93,7 +93,7 @@
public final native String branch() /*-{ return this.branch; }-*/;
public final native String topic() /*-{ return this.topic; }-*/;
public final native String changeId() /*-{ return this.change_id; }-*/;
- public final native boolean mergeable() /*-{ return this.mergeable || false; }-*/;
+ public final native boolean mergeable() /*-{ return this.mergeable ? true : false; }-*/;
public final native int insertions() /*-{ return this.insertions; }-*/;
public final native int deletions() /*-{ return this.deletions; }-*/;
private final native String statusRaw() /*-{ return this.status; }-*/;
@@ -107,7 +107,6 @@
public final native LabelInfo label(String n) /*-{ return this.labels[n]; }-*/;
public final native String currentRevision() /*-{ return this.current_revision; }-*/;
public final native void setCurrentRevision(String r) /*-{ this.current_revision = r; }-*/;
- private final native void setSubmittable(boolean x) /*-{ this.submittable = x; }-*/;
public final native NativeMap<RevisionInfo> revisions() /*-{ return this.revisions; }-*/;
public final native RevisionInfo revision(String n) /*-{ return this.revisions[n]; }-*/;
public final native JsArray<MessageInfo> messages() /*-{ return this.messages; }-*/;
@@ -135,7 +134,6 @@
public final boolean submittable() {
init();
- getMissingLabelIndex();
return _submittable();
}
@@ -143,8 +141,6 @@
/*-{ return this.submittable ? true : false; }-*/;
/**
- * As a side effect this.submittable is evaluated and set accordingly.
- *
* @return the index of the missing label or -1
* if no label is missing, or if more than one label is missing.
*/
@@ -168,7 +164,6 @@
if (ret != -1) {
// more than one label is missing, so it's unclear which to quick
// approve, return -1
- setSubmittable(false);
return -1;
} else {
ret = i;
@@ -181,11 +176,9 @@
case REJECT: // Submit cannot happen, do not quick approve.
case IMPOSSIBLE:
- setSubmittable(false);
return -1;
}
}
- setSubmittable(ret == -1);
return ret;
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeTable.java
index f955264..ae1dfb2 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeTable.java
@@ -18,8 +18,8 @@
import static com.google.gerrit.client.FormatUtil.shortFormat;
import com.google.gerrit.client.Gerrit;
-import com.google.gerrit.client.account.AccountInfo;
import com.google.gerrit.client.changes.ChangeInfo.LabelInfo;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.ui.AccountLinkPanel;
import com.google.gerrit.client.ui.BranchLink;
import com.google.gerrit.client.ui.ChangeLink;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/CommentInfo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/CommentInfo.java
index c69ee57..9088c1c 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/CommentInfo.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/CommentInfo.java
@@ -14,8 +14,8 @@
package com.google.gerrit.client.changes;
-import com.google.gerrit.client.account.AccountInfo;
import com.google.gerrit.client.diff.CommentRange;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.extensions.client.Side;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwtjsonrpc.client.impl.ser.JavaSqlTimestamp_JsonSerializer;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.java
index 498799c..4265203 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.java
@@ -122,20 +122,18 @@
}
}
}, KeyDownEvent.getType());
+
updateContextTimer = new Timer() {
@Override
public void run() {
if (prefs.context() == WHOLE_FILE_CONTEXT) {
contextEntireFile.setValue(true);
}
- if (view.canEnableRenderEntireFile(prefs)) {
+ if (view.canRenderEntireFile(prefs)) {
renderEntireFile.setEnabled(true);
+ renderEntireFile.setValue(prefs.renderEntireFile());
} else {
- if (prefs.renderEntireFile()) {
- prefs.renderEntireFile(false);
- renderEntireFile.setValue(false);
- view.updateRenderEntireFile();
- }
+ renderEntireFile.setValue(false);
renderEntireFile.setEnabled(false);
}
view.setContext(prefs.context());
@@ -167,10 +165,16 @@
autoHideDiffTableHeader.setValue(!prefs.autoHideDiffTableHeader());
manualReview.setValue(prefs.manualReview());
expandAllComments.setValue(prefs.expandAllComments());
- renderEntireFile.setValue(prefs.renderEntireFile());
- renderEntireFile.setEnabled(view.canEnableRenderEntireFile(prefs));
setTheme(prefs.theme());
+ if (view.canRenderEntireFile(prefs)) {
+ renderEntireFile.setValue(prefs.renderEntireFile());
+ renderEntireFile.setEnabled(true);
+ } else {
+ renderEntireFile.setValue(false);
+ renderEntireFile.setEnabled(false);
+ }
+
mode.setEnabled(prefs.syntaxHighlighting());
if (prefs.syntaxHighlighting()) {
setMode(view.getCmFromSide(DisplaySide.B).getStringOption("mode"));
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide.java
index a8b6065..3d01aee 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide.java
@@ -435,7 +435,7 @@
keyMap.on("C", commentManager.insertNewDraft(cm));
}
cm.addKeyMap(keyMap);
- if (prefs.renderEntireFile()) {
+ if (renderEntireFile()) {
cm.addKeyMap(RENDER_ENTIRE_FILE_KEYMAP);
}
}
@@ -580,11 +580,6 @@
chunkManager = new ChunkManager(this, cmA, cmB, diffTable.scrollbar);
skipManager = new SkipManager(this, commentManager);
- if (prefs.renderEntireFile() && !canEnableRenderEntireFile(prefs)) {
- // CodeMirror is too slow to layout an entire huge file.
- prefs.renderEntireFile(false);
- }
-
operation(new Runnable() {
@Override
public void run() {
@@ -650,14 +645,19 @@
.set("keyMap", "vim_ro")
.set("theme", prefs.theme().name().toLowerCase())
.set("value", meta != null ? contents : "")
- .set("viewportMargin", prefs.renderEntireFile() ? POSITIVE_INFINITY : 10));
+ .set("viewportMargin", renderEntireFile() ? POSITIVE_INFINITY : 10));
}
DiffInfo.IntraLineStatus getIntraLineStatus() {
return diff.intralineStatus();
}
- boolean canEnableRenderEntireFile(DiffPreferences prefs) {
+ boolean renderEntireFile() {
+ return prefs.renderEntireFile() && canRenderEntireFile(prefs);
+ }
+
+ boolean canRenderEntireFile(DiffPreferences prefs) {
+ // CodeMirror is too slow to layout an entire huge file.
return fileSize.compareTo(FileSize.HUGE) < 0
|| (prefs.context() != WHOLE_FILE_CONTEXT && prefs.context() < 100);
}
@@ -738,6 +738,7 @@
public void run() {
skipManager.removeAll();
skipManager.render(context, diff);
+ updateRenderEntireFile();
}
});
}
@@ -960,13 +961,14 @@
void updateRenderEntireFile() {
cmA.removeKeyMap(RENDER_ENTIRE_FILE_KEYMAP);
cmB.removeKeyMap(RENDER_ENTIRE_FILE_KEYMAP);
- if (prefs.renderEntireFile()) {
+
+ boolean entireFile = renderEntireFile();
+ if (entireFile) {
cmA.addKeyMap(RENDER_ENTIRE_FILE_KEYMAP);
cmB.addKeyMap(RENDER_ENTIRE_FILE_KEYMAP);
}
-
- cmA.setOption("viewportMargin", prefs.renderEntireFile() ? POSITIVE_INFINITY : 10);
- cmB.setOption("viewportMargin", prefs.renderEntireFile() ? POSITIVE_INFINITY : 10);
+ cmA.setOption("viewportMargin", entireFile ? POSITIVE_INFINITY : 10);
+ cmB.setOption("viewportMargin", entireFile ? POSITIVE_INFINITY : 10);
}
void resizeCodeMirror() {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/download/DownloadUrlLink.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/download/DownloadUrlLink.java
index d1f53a5..1e6c8e3 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/download/DownloadUrlLink.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/download/DownloadUrlLink.java
@@ -78,7 +78,7 @@
private final DownloadPanel downloadPanel;
private final DownloadSchemeInfo schemeInfo;
- private final DownloadScheme urlType;
+ private final DownloadScheme scheme;
public DownloadUrlLink(DownloadPanel downloadPanel,
DownloadSchemeInfo schemeInfo, String text) {
@@ -94,11 +94,11 @@
this.downloadPanel = downloadPanel;
this.schemeInfo = schemeInfo;
- this.urlType = urlType;
+ this.scheme = urlType;
}
public DownloadScheme getUrlType() {
- return urlType;
+ return scheme;
}
@Override
@@ -108,12 +108,13 @@
select();
- if (Gerrit.isSignedIn() && urlType != null) {
+ AccountGeneralPreferences pref =
+ Gerrit.getUserAccount().getGeneralPreferences();
+ if (Gerrit.isSignedIn() && scheme != null
+ && scheme != pref.getDownloadUrl()) {
// If the user is signed-in, remember this choice for future panels.
//
- AccountGeneralPreferences pref =
- Gerrit.getUserAccount().getGeneralPreferences();
- pref.setDownloadUrl(urlType);
+ pref.setDownloadUrl(scheme);
com.google.gerrit.client.account.Util.ACCOUNT_SVC.changePreferences(pref,
new AsyncCallback<VoidResult>() {
@Override
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/editor/EditScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/editor/EditScreen.java
index e463607..698546d 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/editor/EditScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/editor/EditScreen.java
@@ -239,7 +239,9 @@
super.registerKeys();
cm.addKeyMap(KeyMap.create()
.on("Ctrl-L", gotoLine())
- .on("Cmd-L", gotoLine()));
+ .on("Cmd-L", gotoLine())
+ .on("Cmd-S", save())
+ .on("Ctrl-S", save()));
}
private Runnable gotoLine() {
@@ -367,9 +369,6 @@
.set("keyMap", "default")
.set("theme", prefs.theme().name().toLowerCase())
.set("mode", mode != null ? mode.mode() : null));
- cm.addKeyMap(KeyMap.create()
- .on("Cmd-S", save())
- .on("Ctrl-S", save()));
}
private void renderLinks(EditFileInfo editInfo,
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
index 2fca8b2..c26c437 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
@@ -118,6 +118,10 @@
cursor: pointer;
}
+.extensionPanel {
+ padding-top: 10px;
+}
+
/** MenuScreen **/
.menuScreenMenuBar {
background: topMenuColor;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/GroupApi.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/GroupApi.java
index 02deb28..93be87b 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/GroupApi.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/GroupApi.java
@@ -15,7 +15,7 @@
package com.google.gerrit.client.groups;
import com.google.gerrit.client.VoidResult;
-import com.google.gerrit.client.account.AccountInfo;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.rpc.NativeString;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.rpc.RestApi;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/GroupAuditEventInfo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/GroupAuditEventInfo.java
index 2d1de67..f62ae22 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/GroupAuditEventInfo.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/GroupAuditEventInfo.java
@@ -14,7 +14,7 @@
package com.google.gerrit.client.groups;
-import com.google.gerrit.client.account.AccountInfo;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwtjsonrpc.client.impl.ser.JavaSqlTimestamp_JsonSerializer;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/GroupInfo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/GroupInfo.java
index f1e4e87..6142e5b 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/GroupInfo.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/GroupInfo.java
@@ -14,7 +14,7 @@
package com.google.gerrit.client.groups;
-import com.google.gerrit.client.account.AccountInfo;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/MemberList.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/MemberList.java
index d788a1d..d63c212 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/MemberList.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/groups/MemberList.java
@@ -14,7 +14,7 @@
package com.google.gerrit.client.groups;
-import com.google.gerrit.client.account.AccountInfo;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.rpc.RestApi;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gwt.core.client.JsArray;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/AbstractPatchContentTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/AbstractPatchContentTable.java
index 63823ea..2420e7a 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/AbstractPatchContentTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/AbstractPatchContentTable.java
@@ -16,9 +16,9 @@
import com.google.gerrit.client.FormatUtil;
import com.google.gerrit.client.Gerrit;
-import com.google.gerrit.client.account.AccountInfo;
import com.google.gerrit.client.changes.CommentApi;
import com.google.gerrit.client.changes.CommentInfo;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.client.ui.CommentPanel;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/AccountLinkPanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/AccountLinkPanel.java
index 2633e3b..288549f 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/AccountLinkPanel.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/AccountLinkPanel.java
@@ -17,7 +17,7 @@
import com.google.gerrit.client.AvatarImage;
import com.google.gerrit.client.FormatUtil;
import com.google.gerrit.client.Gerrit;
-import com.google.gerrit.client.account.AccountInfo;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.AccountInfoCache;
import com.google.gerrit.reviewdb.client.Account;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/AccountSuggestOracle.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/AccountSuggestOracle.java
index 78350db..60c23df 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/AccountSuggestOracle.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/AccountSuggestOracle.java
@@ -16,7 +16,7 @@
import com.google.gerrit.client.FormatUtil;
import com.google.gerrit.client.account.AccountApi;
-import com.google.gerrit.client.account.AccountInfo;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.Natives;
import com.google.gwt.core.client.JsArray;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/CommentPanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/CommentPanel.java
index 748cd3c..77f40df 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/CommentPanel.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/CommentPanel.java
@@ -17,7 +17,7 @@
import com.google.gerrit.client.AvatarImage;
import com.google.gerrit.client.FormatUtil;
import com.google.gerrit.client.Gerrit;
-import com.google.gerrit.client.account.AccountInfo;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/MenuScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/MenuScreen.java
index cf49ce7..d944690 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/MenuScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/MenuScreen.java
@@ -49,6 +49,11 @@
}
@Override
+ protected FlowPanel getBody() {
+ return body;
+ }
+
+ @Override
protected void add(final Widget w) {
body.add(w);
}
diff --git a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java
index 33c1e70..53d6713 100644
--- a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java
+++ b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java
@@ -312,7 +312,6 @@
return schema;
}
- @SuppressWarnings("unchecked")
@Override
public void replace(ChangeData cd) throws IOException {
Term id = QueryBuilder.idTerm(cd);
@@ -332,7 +331,6 @@
}
}
- @SuppressWarnings("unchecked")
@Override
public void delete(Change.Id id) throws IOException {
Term idTerm = QueryBuilder.idTerm(id);
diff --git a/gerrit-pgm/BUCK b/gerrit-pgm/BUCK
index c975ef9..b52e7af 100644
--- a/gerrit-pgm/BUCK
+++ b/gerrit-pgm/BUCK
@@ -103,7 +103,6 @@
'//gerrit-lucene:lucene',
'//gerrit-oauth:oauth',
'//gerrit-openid:openid',
- '//gerrit-solr:solr',
'//lib:args4j',
'//lib:gwtorm',
'//lib:protobuf',
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
index 139af9e..0a0d000 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
@@ -77,7 +77,6 @@
import com.google.gerrit.server.ssh.NoSshKeyCache;
import com.google.gerrit.server.ssh.NoSshModule;
import com.google.gerrit.server.ssh.SshAddressesModule;
-import com.google.gerrit.solr.SolrIndexModule;
import com.google.gerrit.sshd.SshHostKeyModule;
import com.google.gerrit.sshd.SshKeyCacheImpl;
import com.google.gerrit.sshd.SshModule;
@@ -383,8 +382,6 @@
switch (indexType) {
case LUCENE:
return luceneModule != null ? luceneModule : new LuceneIndexModule();
- case SOLR:
- return new SolrIndexModule();
default:
throw new IllegalStateException("unsupported index.type = " + indexType);
}
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/RebuildNotedb.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/RebuildNotedb.java
index db436d5..8b90e54 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/RebuildNotedb.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/RebuildNotedb.java
@@ -141,7 +141,7 @@
MoreExecutors.directExecutor());
}
- mpm.waitFor(Futures.transform(Futures.successfulAsList(futures),
+ mpm.waitFor(Futures.transformAsync(Futures.successfulAsList(futures),
new AsyncFunction<List<?>, Void>() {
@Override
public ListenableFuture<Void> apply(List<?> input)
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Reindex.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Reindex.java
index 64dd514..5bedfe3 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Reindex.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Reindex.java
@@ -35,7 +35,6 @@
import com.google.gerrit.server.index.IndexModule;
import com.google.gerrit.server.index.IndexModule.IndexType;
import com.google.gerrit.server.index.SiteIndexer;
-import com.google.gerrit.solr.SolrIndexModule;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
@@ -122,9 +121,6 @@
case LUCENE:
changeIndexModule = new LuceneIndexModule(version, threads, outputBase);
break;
- case SOLR:
- changeIndexModule = new SolrIndexModule(false, threads, outputBase);
- break;
default:
throw new IllegalStateException("unsupported index.type");
}
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/DB2Initializer.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/DB2Initializer.java
new file mode 100644
index 0000000..3f6abcf
--- /dev/null
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/DB2Initializer.java
@@ -0,0 +1,33 @@
+// Copyright (C) 2015 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.pgm.init;
+
+import static com.google.gerrit.pgm.init.api.InitUtil.username;
+
+import com.google.gerrit.pgm.init.api.Section;
+
+
+public class DB2Initializer implements DatabaseConfigInitializer {
+
+ @Override
+ public void initConfig(Section databaseSection) {
+ final String defPort = "50001";
+ databaseSection.string("Server hostname", "hostname", "localhost");
+ databaseSection.string("Server port", "port", defPort, false);
+ databaseSection.string("Database name", "database", "gerrit");
+ databaseSection.string("Database username", "username", username());
+ databaseSection.password("username", "password");
+ }
+}
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/DatabaseConfigModule.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/DatabaseConfigModule.java
index 607d6b4..a0c24a6 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/DatabaseConfigModule.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/DatabaseConfigModule.java
@@ -30,6 +30,8 @@
protected void configure() {
bind(SitePaths.class).toInstance(site);
bind(DatabaseConfigInitializer.class).annotatedWith(
+ Names.named("db2")).to(DB2Initializer.class);
+ bind(DatabaseConfigInitializer.class).annotatedWith(
Names.named("h2")).to(H2Initializer.class);
bind(DatabaseConfigInitializer.class).annotatedWith(
Names.named("jdbc")).to(JDBCInitializer.class);
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitDatabase.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitDatabase.java
index 3fcc911..abea521 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitDatabase.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitDatabase.java
@@ -84,6 +84,8 @@
libraries.mysqlDriver.downloadRequired();
} else if (dci instanceof OracleInitializer) {
libraries.oracleDriver.downloadRequired();
+ } else if (dci instanceof DB2Initializer) {
+ libraries.db2Driver.downloadRequired();
}
dci.initConfig(database);
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitIndex.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitIndex.java
index acb8a6b..a177fe7 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitIndex.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitIndex.java
@@ -51,9 +51,6 @@
ui.header("Index");
IndexType type = index.select("Type", "type", IndexType.LUCENE);
- if (type == IndexType.SOLR) {
- index.string("Solr Index URL", "url", "localhost:9983");
- }
if (site.isNew && type == IndexType.LUCENE) {
LuceneChangeIndex.setReady(
site, ChangeSchemas.getLatest().getVersion(), true);
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/Libraries.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/Libraries.java
index 7c7b14d..869e1c4 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/Libraries.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/Libraries.java
@@ -39,6 +39,8 @@
/* final */LibraryDownloader bouncyCastleProvider;
/* final */LibraryDownloader bouncyCastleSSL;
+ /* final */LibraryDownloader db2Driver;
+ /* final */LibraryDownloader db2DriverLicense;
/* final */LibraryDownloader mysqlDriver;
/* final */LibraryDownloader oracleDriver;
@@ -87,16 +89,25 @@
LibraryDownloader dl = (LibraryDownloader) field.get(this);
dl.setName(get(cfg, n, "name"));
dl.setJarUrl(get(cfg, n, "url"));
- dl.setSHA1(get(cfg, n, "sha1"));
+ dl.setSHA1(getOptional(cfg, n, "sha1"));
dl.setRemove(get(cfg, n, "remove"));
for (String d : cfg.getStringList("library", n, "needs")) {
dl.addNeeds((LibraryDownloader) getClass().getDeclaredField(d).get(this));
}
}
+ private static String getOptional(Config cfg, String name, String key) {
+ return doGet(cfg, name, key, false);
+ }
+
private static String get(Config cfg, String name, String key) {
+ return doGet(cfg, name, key, true);
+ }
+
+ private static final String doGet(Config cfg, String name, String key,
+ boolean required) {
String val = cfg.getString("library", name, key);
- if (val == null || val.isEmpty()) {
+ if ((val == null || val.isEmpty()) && required) {
throw new IllegalStateException("Variable library." + name + "." + key
+ " is required within " + RESOURCE_FILE);
}
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/LibraryDownloader.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/LibraryDownloader.java
index 00c7c58..9c9843e 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/LibraryDownloader.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/LibraryDownloader.java
@@ -300,6 +300,8 @@
private void verifyFileChecksum() {
if (sha1 == null) {
+ System.err.println();
+ System.err.flush();
return;
}
Hasher h = Hashing.sha1().newHasher();
diff --git a/gerrit-pgm/src/main/resources/com/google/gerrit/pgm/init/libraries.config b/gerrit-pgm/src/main/resources/com/google/gerrit/pgm/init/libraries.config
index 36e8921..20dc4ce 100644
--- a/gerrit-pgm/src/main/resources/com/google/gerrit/pgm/init/libraries.config
+++ b/gerrit-pgm/src/main/resources/com/google/gerrit/pgm/init/libraries.config
@@ -39,3 +39,17 @@
url = file:///u01/app/oracle/product/11.2.0/xe/jdbc/lib/ojdbc6.jar
sha1 = 2f89cd9176772c3a6c261ce6a8e3d0d4425f5679
remove = ojdbc6.jar
+
+[library "db2Driver"]
+ name = DB2 Type 4 JDBC driver (10.5)
+ url = file:///opt/ibm/db2/V10.5/java/db2jcc4.jar
+ sha1 = 9344d4fd41d6511f2d1d1deb7759056495b3a39b
+ needs = db2DriverLicense
+ remove = db2jcc4.jar
+
+# Omit SHA-1 for license JAR as it's not stable and depends on the product
+# the customer has purchased.
+[library "db2DriverLicense"]
+ name = DB2 Type 4 JDBC driver license (10.5)
+ url = file:///opt/ibm/db2/V10.5/java/db2jcc_license_cu.jar
+ remove = db2jcc_license_cu.jar
diff --git a/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/Plugin.java b/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/Plugin.java
index b5fd373..23fa308 100644
--- a/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/Plugin.java
+++ b/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/Plugin.java
@@ -15,6 +15,7 @@
package com.google.gerrit.plugin.client;
import com.google.gerrit.client.GerritUiExtensionPoint;
+import com.google.gerrit.client.info.AccountInfo;
import com.google.gerrit.plugin.client.extension.Panel;
import com.google.gerrit.plugin.client.screen.Screen;
import com.google.gwt.core.client.GWT;
@@ -56,6 +57,10 @@
public final native void refreshMenuBar()
/*-{ return this.refreshMenuBar() }-*/;
+ /** @return the current user */
+ public final native AccountInfo getCurrentUser()
+ /*-{ return this.getCurrentUser() }-*/;
+
/** Check if user is signed in. */
public final native boolean isSignedIn()
/*-{ return this.isSignedIn() }-*/;
@@ -94,6 +99,19 @@
/*-{ this.screen(new $wnd.RegExp(p), e) }-*/;
/**
+ * Register a settings screen displayed at {@code /#/settings/x/plugin/token}.
+ *
+ * @param token literal anchor token appearing after the plugin name.
+ * @param entry callback function invoked to create the settings screen widgets.
+ */
+ public final void settingsScreen(String token, String menu, Screen.EntryPoint entry) {
+ settingsScreen(token, menu, wrap(entry));
+ }
+
+ private final native void settingsScreen(String t, String m, JavaScriptObject e)
+ /*-{ this.settingsScreen(t, m, e) }-*/;
+
+ /**
* Register a panel for a UI extension point.
*
* @param extensionPoint the UI extension point for which the panel should be
diff --git a/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/extension/Panel.java b/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/extension/Panel.java
index b09d477..6d4e719 100644
--- a/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/extension/Panel.java
+++ b/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/extension/Panel.java
@@ -69,6 +69,8 @@
final native int getBoolean(String k, boolean d) /*-{
return this.p.hasOwnProperty(k) ? this.p[k] : d
}-*/;
+ final native JavaScriptObject getObject(String k)
+ /*-{ return this.p[k]; }-*/;
final native void detach(Panel p) /*-{
@@ -101,4 +103,8 @@
public int getBoolean(GerritUiExtensionPoint.Key key, boolean defaultValue) {
return ctx.getBoolean(key.name(), defaultValue);
}
+
+ public JavaScriptObject getObject(GerritUiExtensionPoint.Key key) {
+ return ctx.getObject(key.name());
+ }
}
diff --git a/gerrit-server/BUCK b/gerrit-server/BUCK
index bea53ec..c7bd8c9 100644
--- a/gerrit-server/BUCK
+++ b/gerrit-server/BUCK
@@ -211,6 +211,7 @@
'//gerrit-server/src/main/prolog:common',
'//lib:args4j',
'//lib:grappa',
+ '//lib:guava',
'//lib:gwtorm',
'//lib:truth',
'//lib/bouncycastle:bcprov',
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java
index 1f8aa0c..0569e5f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java
@@ -31,6 +31,7 @@
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.common.FileInfo;
import com.google.gerrit.extensions.common.MergeableInfo;
+import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestModifyView;
@@ -41,6 +42,7 @@
import com.google.gerrit.server.change.DraftComments;
import com.google.gerrit.server.change.FileResource;
import com.google.gerrit.server.change.Files;
+import com.google.gerrit.server.change.GetPatch;
import com.google.gerrit.server.change.GetRevisionActions;
import com.google.gerrit.server.change.ListRevisionComments;
import com.google.gerrit.server.change.ListRevisionDrafts;
@@ -79,6 +81,7 @@
private final RevisionResource revision;
private final Provider<Files> files;
private final Provider<Files.ListFiles> listFiles;
+ private final Provider<GetPatch> getPatch;
private final Provider<PostReview> review;
private final Provider<Mergeable> mergeable;
private final FileApiImpl.Factory fileApi;
@@ -103,6 +106,7 @@
Reviewed.DeleteReviewed deleteReviewed,
Provider<Files> files,
Provider<Files.ListFiles> listFiles,
+ Provider<GetPatch> getPatch,
Provider<PostReview> review,
Provider<Mergeable> mergeable,
FileApiImpl.Factory fileApi,
@@ -127,6 +131,7 @@
this.putReviewed = putReviewed;
this.deleteReviewed = deleteReviewed;
this.listFiles = listFiles;
+ this.getPatch = getPatch;
this.mergeable = mergeable;
this.fileApi = fileApi;
this.listComments = listComments;
@@ -357,6 +362,15 @@
}
@Override
+ public BinaryResult patch() throws RestApiException {
+ try {
+ return getPatch.get().apply(revision);
+ } catch (IOException e) {
+ throw new RestApiException("Cannot get patch", e);
+ }
+ }
+
+ @Override
public Map<String, ActionInfo> actions() throws RestApiException {
return revisionActions.apply(revision).value();
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java
index 0c38c29..acdf004 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java
@@ -137,6 +137,7 @@
private final GitRepositoryManager repoManager;
private final ProjectCache projectCache;
private final MergeUtil.Factory mergeUtilFactory;
+ private final Submit submit;
private final IdentifiedUser.GenericFactory userFactory;
private final ChangeData.Factory changeDataFactory;
private final FileInfoJson fileInfoJson;
@@ -161,6 +162,7 @@
GitRepositoryManager repoManager,
ProjectCache projectCache,
MergeUtil.Factory mergeUtilFactory,
+ Submit submit,
IdentifiedUser.GenericFactory uf,
ChangeData.Factory cdf,
FileInfoJson fileInfoJson,
@@ -180,6 +182,7 @@
this.repoManager = repoManager;
this.userFactory = uf;
this.projectCache = projectCache;
+ this.submit = submit;
this.mergeUtilFactory = mergeUtilFactory;
this.fileInfoJson = fileInfoJson;
this.accountLoaderFactory = ailf;
@@ -383,6 +386,7 @@
// the response and avoid making a request to /submit_type from the UI.
out.mergeable = in.getStatus() == Change.Status.MERGED
? null : cd.isMergeable();
+ out.submittable = submit.submittable(cd);
ChangedLines changedLines = cd.changedLines();
if (changedLines != null) {
out.insertions = changedLines.insertions;
@@ -597,6 +601,12 @@
PatchSetApproval psa = current.get(accountId, lt.getName());
if (psa != null) {
value = Integer.valueOf(psa.getValue());
+ if (value == 0) {
+ // This may be a dummy approval that was inserted when the reviewer
+ // was added. Explicitly check whether the user can vote on this
+ // label.
+ value = labelNormalizer.canVote(ctl, lt, accountId) ? 0 : null;
+ }
date = psa.getGranted();
} else {
// Either the user cannot vote on this label, or they were added as a
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/CreateChange.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/CreateChange.java
index 3ec18f3..6c0ee3b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/CreateChange.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/CreateChange.java
@@ -32,6 +32,7 @@
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.ChangeMessage;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
@@ -207,6 +208,15 @@
changeInserterFactory.create(refControl.getProjectControl(),
change, c);
+ ChangeMessage msg = new ChangeMessage(new ChangeMessage.Key(change.getId(),
+ ChangeUtil.messageUUID(db.get())),
+ me.getAccountId(),
+ ins.getPatchSet().getCreatedOn(),
+ ins.getPatchSet().getId());
+ msg.setMessage(String.format("Uploaded patch set %s.",
+ ins.getPatchSet().getPatchSetId()));
+
+ ins.setMessage(msg);
validateCommit(git, refControl, c, me, ins);
updateRef(git, rw, c, change, ins.getPatchSet());
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/GetCommit.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/GetCommit.java
index a7f8dea..72f8c35 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/GetCommit.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/GetCommit.java
@@ -54,6 +54,7 @@
rw.parseBody(commit);
CommitInfo info = json.create(ChangeJson.NO_OPTIONS)
.toCommit(rsrc.getControl(), rw, commit, addLinks);
+ info.commit = commit.name();
Response<CommitInfo> r = Response.ok(info);
if (rsrc.isCacheable()) {
r.caching(CacheControl.PRIVATE(7, TimeUnit.DAYS));
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/GetPatch.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/GetPatch.java
index afd11569..3c4d79d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/GetPatch.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/GetPatch.java
@@ -144,7 +144,7 @@
}
b.append("From ").append(commit.getName())
.append(' ')
- .append("Mon Sep 17 00:00:00 2001\n")
+ .append("Mon Sep 17 00:00:00 2001\n") // Fixed timestamp to match output of C Git's format-patch
.append("From: ").append(author.getName())
.append(" <").append(author.getEmailAddress()).append(">\n")
.append("Date: ").append(formatDate(author)).append('\n')
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/HashtagsUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/HashtagsUtil.java
index cd3b3b1..9f7eb93 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/HashtagsUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/HashtagsUtil.java
@@ -14,8 +14,6 @@
package com.google.gerrit.server.change;
-import static com.google.common.base.CharMatcher.WHITESPACE;
-
import com.google.common.base.CharMatcher;
import com.google.common.base.Strings;
import com.google.gerrit.common.ChangeHooks;
@@ -45,7 +43,8 @@
@Singleton
public class HashtagsUtil {
- private static final CharMatcher LEADER = WHITESPACE.or(CharMatcher.is('#'));
+ private static final CharMatcher LEADER =
+ CharMatcher.whitespace().or(CharMatcher.is('#'));
private static final String PATTERN = "(?:\\s|\\A)#[\\p{L}[0-9]-_]+";
private final ChangeUpdate.Factory updateFactory;
@@ -69,7 +68,7 @@
public static String cleanupHashtag(String hashtag) {
hashtag = LEADER.trimLeadingFrom(hashtag);
- hashtag = WHITESPACE.trimTrailingFrom(hashtag);
+ hashtag = CharMatcher.whitespace().trimTrailingFrom(hashtag);
return hashtag;
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/PublishChangeEdit.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/PublishChangeEdit.java
index 5db46ae..b88931e 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/PublishChangeEdit.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/PublishChangeEdit.java
@@ -15,6 +15,7 @@
package com.google.gerrit.server.change;
import com.google.common.base.Optional;
+import com.google.gerrit.common.data.Capable;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.AcceptsPost;
import com.google.gerrit.extensions.restapi.AuthException;
@@ -84,6 +85,12 @@
public Response<?> apply(ChangeResource rsrc, Publish.Input in)
throws AuthException, ResourceConflictException, NoSuchChangeException,
IOException, OrmException {
+ Capable r =
+ rsrc.getControl().getProjectControl().canPushToAtLeastOneRef();
+ if (r != Capable.OK) {
+ throw new AuthException(r.getMessage());
+ }
+
Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getChange());
if (!edit.isPresent()) {
throw new ResourceConflictException(String.format(
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Submit.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Submit.java
index 3d4dc26..6bba656 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Submit.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Submit.java
@@ -14,18 +14,12 @@
package com.google.gerrit.server.change;
-import static com.google.gerrit.common.data.SubmitRecord.Status.OK;
-
import com.google.common.base.MoreObjects;
-import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Strings;
import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
import com.google.gerrit.common.data.ParameterizedString;
-import com.google.gerrit.common.data.SubmitRecord;
import com.google.gerrit.extensions.api.changes.SubmitInput;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.restapi.AuthException;
@@ -46,9 +40,9 @@
import com.google.gerrit.server.git.ChangeSet;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MergeOp;
+import com.google.gerrit.server.git.MergeSuperSet;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
-import com.google.gerrit.server.project.SubmitRuleEvaluator;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gwtorm.server.OrmException;
@@ -64,9 +58,6 @@
import org.slf4j.LoggerFactory;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -77,16 +68,21 @@
private static final String DEFAULT_TOOLTIP =
"Submit patch set ${patchSet} into ${branch}";
+ private static final String DEFAULT_TOOLTIP_ANCESTORS =
+ "Submit patch set ${patchSet} and ancestors (${submitSize} changes " +
+ "altogether) into ${branch}";
private static final String DEFAULT_TOPIC_TOOLTIP =
- "Submit all ${topicSize} changes of the same topic";
- private static final String BLOCKED_TOPIC_TOOLTIP =
- "Other changes in this topic are not ready";
- private static final String BLOCKED_HIDDEN_TOPIC_TOOLTIP =
- "Other hidden changes in this topic are not ready";
- private static final String CLICK_FAILURE_OTHER_TOOLTIP =
- "Clicking the button would fail for other changes in the topic";
+ "Submit all ${topicSize} changes of the same topic " +
+ "(${submitSize} changes including ancestors and other " +
+ "changes related by topic)";
+ private static final String BLOCKED_SUBMIT_TOOLTIP =
+ "This change depends on other changes which are not ready";
+ private static final String BLOCKED_HIDDEN_SUBMIT_TOOLTIP =
+ "This change depends on other hidden changes which are not ready";
private static final String CLICK_FAILURE_TOOLTIP =
- "Clicking the button would fail.";
+ "Clicking the button would fail";
+ private static final String CLICK_FAILURE_OTHER_TOOLTIP =
+ "Clicking the button would fail for other changes";
public static class Output {
transient Change change;
@@ -100,11 +96,14 @@
private final GitRepositoryManager repoManager;
private final ChangeData.Factory changeDataFactory;
private final ChangeMessagesUtil cmUtil;
+ private final ChangeControl.GenericFactory changeControlFactory;
private final Provider<MergeOp> mergeOpProvider;
+ private final MergeSuperSet mergeSuperSet;
private final AccountsCollection accounts;
private final ChangesCollection changes;
private final String label;
private final ParameterizedString titlePattern;
+ private final ParameterizedString titlePatternWithAncestors;
private final String submitTopicLabel;
private final ParameterizedString submitTopicTooltip;
private final boolean submitWholeTopic;
@@ -115,7 +114,9 @@
GitRepositoryManager repoManager,
ChangeData.Factory changeDataFactory,
ChangeMessagesUtil cmUtil,
+ ChangeControl.GenericFactory changeControlFactory,
Provider<MergeOp> mergeOpProvider,
+ MergeSuperSet mergeSuperSet,
AccountsCollection accounts,
ChangesCollection changes,
@GerritServerConfig Config cfg,
@@ -124,7 +125,9 @@
this.repoManager = repoManager;
this.changeDataFactory = changeDataFactory;
this.cmUtil = cmUtil;
+ this.changeControlFactory = changeControlFactory;
this.mergeOpProvider = mergeOpProvider;
+ this.mergeSuperSet = mergeSuperSet;
this.accounts = accounts;
this.changes = changes;
this.label = MoreObjects.firstNonNull(
@@ -133,6 +136,10 @@
this.titlePattern = new ParameterizedString(MoreObjects.firstNonNull(
cfg.getString("change", null, "submitTooltip"),
DEFAULT_TOOLTIP));
+ this.titlePatternWithAncestors = new ParameterizedString(
+ MoreObjects.firstNonNull(
+ cfg.getString("change", null, "submitTooltipAncestors"),
+ DEFAULT_TOOLTIP_ANCESTORS));
submitWholeTopic = wholeTopicEnabled(cfg);
this.submitTopicLabel = MoreObjects.firstNonNull(
Strings.emptyToNull(cfg.getString("change", null, "submitTopicLabel")),
@@ -170,16 +177,7 @@
rsrc.getPatchSet().getRevision().get()));
}
- List<Change> changes;
- if (submitWholeTopic && !Strings.isNullOrEmpty(change.getTopic())) {
- changes = new ArrayList<>();
- for (ChangeData cd : getChangesByTopic(change.getTopic())) {
- changes.add(cd.change());
- }
- } else {
- changes = Arrays.asList(change);
- }
- ChangeSet submittedChanges = ChangeSet.create(changes);
+ ChangeSet submittedChanges = ChangeSet.create(change);
try {
ReviewDb db = dbProvider.get();
@@ -207,22 +205,24 @@
}
/**
- * @param changeList list of changes to be submitted at once
+ * @param cs set of changes to be submitted at once
* @param identifiedUser the user who is checking to submit
* @return a reason why any of the changes is not submittable or null
*/
- private String problemsForSubmittingChanges(
- List<ChangeData> changeList,
- IdentifiedUser identifiedUser) {
+ private String problemsForSubmittingChangeset(
+ ChangeSet cs, IdentifiedUser identifiedUser) {
try {
- for (ChangeData c : changeList) {
- ChangeControl changeControl = c.changeControl().forUser(
- identifiedUser);
- if (!changeControl.isVisible(dbProvider.get())) {
- return BLOCKED_HIDDEN_TOPIC_TOOLTIP;
+ ReviewDb db = dbProvider.get();
+ for (PatchSet.Id psId : cs.patchIds()) {
+ ChangeControl changeControl = changeControlFactory
+ .controlFor(psId.getParentKey(), identifiedUser);
+ ChangeData c = changeDataFactory.create(db, changeControl);
+
+ if (!changeControl.isVisible(db)) {
+ return BLOCKED_HIDDEN_SUBMIT_TOOLTIP;
}
if (!changeControl.canSubmit()) {
- return BLOCKED_TOPIC_TOOLTIP;
+ return BLOCKED_SUBMIT_TOOLTIP;
}
// Recheck mergeability rather than using value stored in the index,
// which may be stale.
@@ -237,17 +237,33 @@
if (!mergeable) {
return CLICK_FAILURE_OTHER_TOOLTIP;
}
- checkSubmitRule(c, c.currentPatchSet(), false);
+ MergeOp.checkSubmitRule(c);
}
} catch (ResourceConflictException e) {
- return BLOCKED_TOPIC_TOOLTIP;
- } catch (OrmException e) {
+ return BLOCKED_SUBMIT_TOOLTIP;
+ } catch (NoSuchChangeException | OrmException e) {
log.error("Error checking if change is submittable", e);
throw new OrmRuntimeException("Could not determine problems for the change", e);
}
return null;
}
+ /**
+ * Check if there are any problems with the given change. It doesn't take
+ * any problems of related changes into account.
+ * <p>
+ * @param cd the change to check for submittability
+ * @return if the change has any problems for submission
+ */
+ public boolean submittable(ChangeData cd) {
+ try {
+ MergeOp.checkSubmitRule(cd);
+ return true;
+ } catch (ResourceConflictException | OrmException e) {
+ return false;
+ }
+ }
+
@Override
public UiAction.Description getDescription(RevisionResource resource) {
PatchSet.Id current = resource.getChange().currentPatchSetId();
@@ -260,7 +276,7 @@
ChangeData cd = changeDataFactory.create(db, resource.getControl());
try {
- checkSubmitRule(cd, cd.currentPatchSet(), false);
+ MergeOp.checkSubmitRule(cd);
} catch (ResourceConflictException e) {
visible = false;
} catch (OrmException e) {
@@ -282,40 +298,55 @@
throw new OrmRuntimeException("Could not determine mergeability", e);
}
- List<ChangeData> changesByTopic = null;
- if (submitWholeTopic && !Strings.isNullOrEmpty(topic)) {
- changesByTopic = getChangesByTopic(topic);
+ ChangeSet cs;
+ try {
+ cs = mergeSuperSet.completeChangeSet(db,
+ ChangeSet.create(cd.change()));
+ } catch (OrmException | IOException e) {
+ throw new OrmRuntimeException("Could not determine complete set of " +
+ "changes to be submitted", e);
}
- if (submitWholeTopic
+
+ int topicSize = 0;
+ if (!Strings.isNullOrEmpty(topic)) {
+ topicSize = getChangesByTopic(topic).size();
+ }
+ boolean treatWithTopic = submitWholeTopic
&& !Strings.isNullOrEmpty(topic)
- && changesByTopic.size() > 1) {
+ && topicSize > 1;
+
+ String submitProblems = problemsForSubmittingChangeset(cs,
+ resource.getUser());
+ if (submitProblems != null) {
+ return new UiAction.Description()
+ .setLabel(treatWithTopic ? submitTopicLabel : label)
+ .setTitle(submitProblems)
+ .setVisible(true)
+ .setEnabled(false);
+ }
+
+ if (treatWithTopic) {
Map<String, String> params = ImmutableMap.of(
- "topicSize", String.valueOf(changesByTopic.size()));
- String topicProblems = problemsForSubmittingChanges(changesByTopic,
- resource.getUser());
- if (topicProblems != null) {
- return new UiAction.Description()
- .setLabel(submitTopicLabel)
- .setTitle(topicProblems)
- .setVisible(true)
- .setEnabled(false);
- } else {
- return new UiAction.Description()
+ "topicSize", String.valueOf(topicSize),
+ "submitSize", String.valueOf(cs.size()));
+ return new UiAction.Description()
.setLabel(submitTopicLabel)
.setTitle(Strings.emptyToNull(
submitTopicTooltip.replace(params)))
.setVisible(true)
.setEnabled(Boolean.TRUE.equals(enabled));
- }
} else {
RevId revId = resource.getPatchSet().getRevision();
Map<String, String> params = ImmutableMap.of(
"patchSet", String.valueOf(resource.getPatchSet().getPatchSetId()),
"branch", resource.getChange().getDest().getShortName(),
- "commit", ObjectId.fromString(revId.get()).abbreviate(7).name());
+ "commit", ObjectId.fromString(revId.get()).abbreviate(7).name(),
+ "submitSize", String.valueOf(cs.size()));
+ ParameterizedString tp = cs.size() > 1 ? titlePatternWithAncestors :
+ titlePattern;
return new UiAction.Description()
.setLabel(label)
- .setTitle(Strings.emptyToNull(titlePattern.replace(params)))
+ .setTitle(Strings.emptyToNull(tp.replace(params)))
.setVisible(true)
.setEnabled(Boolean.TRUE.equals(enabled));
}
@@ -340,95 +371,6 @@
.orNull();
}
- private List<SubmitRecord> checkSubmitRule(ChangeData cd,
- PatchSet patchSet, boolean force)
- throws ResourceConflictException, OrmException {
- List<SubmitRecord> results = new SubmitRuleEvaluator(cd)
- .setPatchSet(patchSet)
- .evaluate();
- Optional<SubmitRecord> ok = findOkRecord(results);
- if (ok.isPresent()) {
- // Rules supplied a valid solution.
- return ImmutableList.of(ok.get());
- } else if (force) {
- return results;
- } else if (results.isEmpty()) {
- throw new IllegalStateException(String.format(
- "SubmitRuleEvaluator.evaluate returned empty list for %s in %s",
- patchSet.getId(),
- cd.change().getProject().get()));
- }
-
- for (SubmitRecord record : results) {
- switch (record.status) {
- case CLOSED:
- throw new ResourceConflictException("change is closed");
-
- case RULE_ERROR:
- throw new ResourceConflictException(String.format(
- "rule error: %s",
- record.errorMessage));
-
- case NOT_READY:
- StringBuilder msg = new StringBuilder();
- for (SubmitRecord.Label lbl : record.labels) {
- switch (lbl.status) {
- case OK:
- case MAY:
- continue;
-
- case REJECT:
- if (msg.length() > 0) {
- msg.append("; ");
- }
- msg.append("blocked by ").append(lbl.label);
- continue;
-
- case NEED:
- if (msg.length() > 0) {
- msg.append("; ");
- }
- msg.append("needs ").append(lbl.label);
- continue;
-
- case IMPOSSIBLE:
- if (msg.length() > 0) {
- msg.append("; ");
- }
- msg.append("needs ").append(lbl.label)
- .append(" (check project access)");
- continue;
-
- default:
- throw new IllegalStateException(String.format(
- "Unsupported SubmitRecord.Label %s for %s in %s",
- lbl.toString(),
- patchSet.getId(),
- cd.change().getProject().get()));
- }
- }
- throw new ResourceConflictException(msg.toString());
-
- default:
- throw new IllegalStateException(String.format(
- "Unsupported SubmitRecord %s for %s in %s",
- record,
- patchSet.getId().getId(),
- cd.change().getProject().get()));
- }
- }
- throw new IllegalStateException();
- }
-
- private static Optional<SubmitRecord> findOkRecord(Collection<SubmitRecord> in) {
- return Iterables.tryFind(in, new Predicate<SubmitRecord>() {
- @Override
- public boolean apply(SubmitRecord input) {
- return input.status == OK;
- }
- });
- }
-
static String status(Change change) {
return change != null ? change.getStatus().name().toLowerCase() : "deleted";
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/SubmittedTogether.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/SubmittedTogether.java
index 71e25a5..1f6dfe4 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/SubmittedTogether.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/SubmittedTogether.java
@@ -64,9 +64,7 @@
if (cs.ids().size() > 1) {
return json.create(EnumSet.of(
ListChangesOption.CURRENT_REVISION,
- ListChangesOption.CURRENT_COMMIT,
- ListChangesOption.DETAILED_LABELS,
- ListChangesOption.LABELS))
+ ListChangesOption.CURRENT_COMMIT))
.format(cs.ids());
} else {
return Collections.emptyList();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/ListCapabilities.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/ListCapabilities.java
index b01ae2f1..c6ba605 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/ListCapabilities.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/ListCapabilities.java
@@ -80,7 +80,7 @@
}
private static boolean isPluginNameSane(String pluginName) {
- return CharMatcher.JAVA_LETTER_OR_DIGIT
+ return CharMatcher.javaLetterOrDigit()
.or(CharMatcher.is('-'))
.matchesAllOf(pluginName);
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ChangeSet.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ChangeSet.java
index 6c3b499..a18a3a3 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ChangeSet.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ChangeSet.java
@@ -20,6 +20,7 @@
import com.google.common.collect.ImmutableSetMultimap;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
/** A set of changes grouped together to be submitted atomically.*/
@@ -29,6 +30,7 @@
ImmutableSet.Builder<Project.NameKey> pb = ImmutableSet.builder();
ImmutableSet.Builder<Branch.NameKey> bb = ImmutableSet.builder();
ImmutableSet.Builder<Change.Id> ib = ImmutableSet.builder();
+ ImmutableSet.Builder<PatchSet.Id> psb = ImmutableSet.builder();
ImmutableSetMultimap.Builder<Project.NameKey, Branch.NameKey> pbb =
ImmutableSetMultimap.builder();
ImmutableSetMultimap.Builder<Project.NameKey, Change.Id> pcb =
@@ -42,13 +44,14 @@
pb.add(project);
bb.add(branch);
ib.add(c.getId());
+ psb.add(c.currentPatchSetId());
pbb.put(project, branch);
pcb.put(project, c.getId());
cbb.put(branch, c.getId());
}
- return new AutoValue_ChangeSet(pb.build(), bb.build(),
- ib.build(), pbb.build(), pcb.build(), cbb.build());
+ return new AutoValue_ChangeSet(pb.build(), bb.build(), ib.build(),
+ psb.build(), pbb.build(), pcb.build(), cbb.build());
}
public static ChangeSet create(Change change) {
@@ -58,6 +61,7 @@
public abstract ImmutableSet<Project.NameKey> projects();
public abstract ImmutableSet<Branch.NameKey> branches();
public abstract ImmutableSet<Change.Id> ids();
+ public abstract ImmutableSet<PatchSet.Id> patchIds();
public abstract ImmutableSetMultimap<Project.NameKey, Branch.NameKey>
branchesByProject();
public abstract ImmutableSetMultimap<Project.NameKey, Change.Id>
@@ -69,4 +73,8 @@
public int hashCode() {
return ids().hashCode();
}
+
+ public int size() {
+ return ids().size();
+ }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/EmailMerge.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/EmailMerge.java
index 8fa5d4e..7b1161c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/EmailMerge.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/EmailMerge.java
@@ -19,7 +19,6 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.change.EmailReviewComments;
import com.google.gerrit.server.mail.MergedSender;
import com.google.gerrit.server.util.RequestContext;
import com.google.gerrit.server.util.ThreadLocalRequestContext;
@@ -37,7 +36,7 @@
import java.util.concurrent.ExecutorService;
public class EmailMerge implements Runnable, RequestContext {
- private static final Logger log = LoggerFactory.getLogger(EmailReviewComments.class);
+ private static final Logger log = LoggerFactory.getLogger(EmailMerge.class);
public interface Factory {
EmailMerge create(Change.Id changeId, Account.Id submitter);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
index 648d125..d945f77 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
@@ -225,7 +225,7 @@
});
}
- private List<SubmitRecord> checkSubmitRule(ChangeData cd)
+ public static List<SubmitRecord> checkSubmitRule(ChangeData cd)
throws ResourceConflictException, OrmException {
PatchSet patchSet = cd.currentPatchSet();
List<SubmitRecord> results = new SubmitRuleEvaluator(cd)
@@ -237,7 +237,9 @@
return ImmutableList.of(ok.get());
} else if (results.isEmpty()) {
throw new IllegalStateException(String.format(
- "SubmitRuleEvaluator.evaluate returned empty list for %s in %s",
+ "SubmitRuleEvaluator.evaluate for change %s " +
+ "returned empty list for %s in %s",
+ cd.getId(),
patchSet.getId(),
cd.change().getProject().get()));
}
@@ -245,15 +247,17 @@
for (SubmitRecord record : results) {
switch (record.status) {
case CLOSED:
- throw new ResourceConflictException("change is closed");
+ throw new ResourceConflictException(String.format(
+ "change %s is closed", cd.getId()));
case RULE_ERROR:
throw new ResourceConflictException(String.format(
- "rule error: %s",
- record.errorMessage));
+ "rule error for change %s: %s",
+ cd.getId(), record.errorMessage));
case NOT_READY:
StringBuilder msg = new StringBuilder();
+ msg.append(cd.getId() + ":");
for (SubmitRecord.Label lbl : record.labels) {
switch (lbl.status) {
case OK:
@@ -261,32 +265,27 @@
continue;
case REJECT:
- if (msg.length() > 0) {
- msg.append("; ");
- }
- msg.append("blocked by ").append(lbl.label);
+ msg.append(" blocked by ").append(lbl.label);
+ msg.append(";");
continue;
case NEED:
- if (msg.length() > 0) {
- msg.append("; ");
- }
- msg.append("needs ").append(lbl.label);
+ msg.append(" needs ").append(lbl.label);
+ msg.append(";");
continue;
case IMPOSSIBLE:
- if (msg.length() > 0) {
- msg.append("; ");
- }
- msg.append("needs ").append(lbl.label)
+ msg.append(" needs ").append(lbl.label)
.append(" (check project access)");
+ msg.append(";");
continue;
default:
throw new IllegalStateException(String.format(
- "Unsupported SubmitRecord.Label %s for %s in %s",
+ "Unsupported SubmitRecord.Label %s for %s in %s in %s",
lbl.toString(),
patchSet.getId(),
+ cd.getId(),
cd.change().getProject().get()));
}
}
@@ -303,21 +302,37 @@
throw new IllegalStateException();
}
- private void checkPermissions(ChangeSet cs)
+ private void checkSubmitRulesAndState(ChangeSet cs)
throws ResourceConflictException, OrmException {
+
+ StringBuilder msgbuf = new StringBuilder();
+ List<Change.Id> problemChanges = new ArrayList<>();
for (Change.Id id : cs.ids()) {
- ChangeData cd = changeDataFactory.create(db, id);
- if (cd.change().getStatus() != Change.Status.NEW){
- throw new OrmException("Change " + cd.change().getChangeId()
- + " is in state " + cd.change().getStatus());
- } else {
- records.put(cd.change().getId(), checkSubmitRule(cd));
+ try {
+ ChangeData cd = changeDataFactory.create(db, id);
+ if (cd.change().getStatus() != Change.Status.NEW){
+ throw new ResourceConflictException("Change " +
+ cd.change().getChangeId() + " is in state " +
+ cd.change().getStatus());
+ } else {
+ records.put(cd.change().getId(), checkSubmitRule(cd));
+ }
+ } catch (ResourceConflictException e) {
+ msgbuf.append(e.getMessage() + "\n");
+ problemChanges.add(id);
}
}
+ String reason = msgbuf.toString();
+ if (!reason.isEmpty()) {
+ throw new ResourceConflictException("The change could not be " +
+ "submitted because it depends on change(s) " +
+ problemChanges.toString() + ", which could not be submitted " +
+ "because:\n" + reason);
+ }
}
public void merge(ReviewDb db, ChangeSet changes, IdentifiedUser caller,
- boolean checkPermissions) throws NoSuchChangeException,
+ boolean checkSubmitRules) throws NoSuchChangeException,
OrmException, ResourceConflictException {
logPrefix = String.format("[%s]: ", String.valueOf(changes.hashCode()));
this.db = db;
@@ -325,9 +340,9 @@
try {
ChangeSet cs = mergeSuperSet.completeChangeSet(db, changes);
logDebug("Calculated to merge {}", cs);
- if (checkPermissions) {
- logDebug("Checking permissions");
- checkPermissions(cs);
+ if (checkSubmitRules) {
+ logDebug("Checking submit rules and state");
+ checkSubmitRulesAndState(cs);
}
try {
integrateIntoHistory(cs, caller);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
index b0107cc..52932c4 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
@@ -635,7 +635,7 @@
private static LabelValue parseLabelValue(String src) {
List<String> parts = ImmutableList.copyOf(
- Splitter.on(CharMatcher.WHITESPACE).omitEmptyStrings().limit(2)
+ Splitter.on(CharMatcher.whitespace()).omitEmptyStrings().limit(2)
.split(src));
if (parts.isEmpty()) {
throw new IllegalArgumentException("empty value");
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexModule.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexModule.java
index 28f7f7e..afb7c22 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexModule.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexModule.java
@@ -38,7 +38,7 @@
*/
public class IndexModule extends LifecycleModule {
public enum IndexType {
- LUCENE, SOLR
+ LUCENE
}
/** Type of secondary index. */
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/ReindexAfterUpdate.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/ReindexAfterUpdate.java
index 45b7c4d..31fbb40 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/ReindexAfterUpdate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/ReindexAfterUpdate.java
@@ -69,7 +69,7 @@
@Override
public void onGitReferenceUpdated(final Event event) {
- Futures.transform(
+ Futures.transformAsync(
executor.submit(new GetChanges(event)),
new AsyncFunction<List<Change>, List<Void>>() {
@Override
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/SiteIndexer.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/SiteIndexer.java
index 775e967..1bc6b05 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/SiteIndexer.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/SiteIndexer.java
@@ -213,7 +213,7 @@
}
try {
- mpm.waitFor(Futures.transform(Futures.successfulAsList(futures),
+ mpm.waitFor(Futures.transformAsync(Futures.successfulAsList(futures),
new AsyncFunction<List<?>, Void>() {
@Override
public ListenableFuture<Void> apply(List<?> input) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/PutConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/PutConfig.java
index d73a95d..7a4fb6e 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/PutConfig.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/PutConfig.java
@@ -318,7 +318,7 @@
}
private static boolean isValidParameterName(String name) {
- return CharMatcher.JAVA_LETTER_OR_DIGIT
+ return CharMatcher.javaLetterOrDigit()
.or(CharMatcher.is('-'))
.matchesAllOf(name) && !name.startsWith("-");
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/DB2.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/DB2.java
new file mode 100644
index 0000000..4ad8e2f
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/DB2.java
@@ -0,0 +1,46 @@
+// Copyright (C) 2015 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.schema;
+
+import static com.google.gerrit.server.schema.JdbcUtil.hostname;
+import static com.google.gerrit.server.schema.JdbcUtil.port;
+
+import com.google.gerrit.server.config.ConfigSection;
+import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.inject.Inject;
+
+import org.eclipse.jgit.lib.Config;
+
+public class DB2 extends BaseDataSourceType {
+ private Config cfg;
+
+ @Inject
+ public DB2(@GerritServerConfig final Config cfg) {
+ super("com.ibm.db2.jcc.DB2Driver");
+ this.cfg = cfg;
+ }
+
+ @Override
+ public String getUrl() {
+ final StringBuilder b = new StringBuilder();
+ final ConfigSection dbc = new ConfigSection(cfg, "database");
+ b.append("jdbc:db2://");
+ b.append(hostname(dbc.optional("hostname")));
+ b.append(port(dbc.optional("port")));
+ b.append("/");
+ b.append(dbc.required("database"));
+ return b.toString();
+ }
+}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/DataSourceModule.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/DataSourceModule.java
index f500444..f50f123 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/DataSourceModule.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/DataSourceModule.java
@@ -21,6 +21,7 @@
@Override
protected void configure() {
+ bind(DataSourceType.class).annotatedWith(Names.named("db2")).to(DB2.class);
bind(DataSourceType.class).annotatedWith(Names.named("h2")).to(H2.class);
bind(DataSourceType.class).annotatedWith(Names.named("jdbc")).to(JDBC.class);
bind(DataSourceType.class).annotatedWith(Names.named("mysql")).to(MySql.class);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java
index 038da50..7918df4 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java
@@ -32,7 +32,7 @@
/** A version of the database schema. */
public abstract class SchemaVersion {
/** The current schema version. */
- public static final Class<Schema_109> C = Schema_109.class;
+ public static final Class<Schema_110> C = Schema_110.class;
public static int getBinaryVersion() {
return guessVersion(C);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_110.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_110.java
new file mode 100644
index 0000000..9e0f112
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_110.java
@@ -0,0 +1,25 @@
+// Copyright (C) 2015 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.schema;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+public class Schema_110 extends SchemaVersion {
+ @Inject
+ Schema_110(Provider<Schema_109> prior) {
+ super(prior);
+ }
+}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/util/SubmoduleSectionParser.java b/gerrit-server/src/main/java/com/google/gerrit/server/util/SubmoduleSectionParser.java
index 195a3e0..ad2ab90 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/util/SubmoduleSectionParser.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/util/SubmoduleSectionParser.java
@@ -84,6 +84,7 @@
final String url = bbc.getString("submodule", id, "url");
final String path = bbc.getString("submodule", id, "path");
String branch = bbc.getString("submodule", id, "branch");
+ SubmoduleSubscription ss = null;
try {
if (url != null && url.length() > 0 && path != null && path.length() > 0
@@ -116,8 +117,10 @@
}
Project.NameKey projectKey = new Project.NameKey(projectName);
if (projectCache.get(projectKey) != null) {
- return new SubmoduleSubscription(superProjectBranch,
- new Branch.NameKey(projectKey, branch), path);
+ ss = new SubmoduleSubscription(
+ superProjectBranch,
+ new Branch.NameKey(new Project.NameKey(projectName), branch),
+ path);
}
}
}
@@ -126,6 +129,6 @@
// Error in url syntax (in fact it is uri syntax)
}
- return null;
+ return ss;
}
}
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/project/Util.java b/gerrit-server/src/test/java/com/google/gerrit/server/project/Util.java
index 32bc9c6..6c3a39a 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/project/Util.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/project/Util.java
@@ -25,6 +25,7 @@
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelValue;
+import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRange;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.reviewdb.client.AccountGroup;
@@ -177,6 +178,16 @@
return r;
}
+ public static PermissionRule blockLabel(ProjectConfig project,
+ String labelName, AccountGroup.UUID group, String ref) {
+ PermissionRule r =
+ grant(project, Permission.LABEL + labelName, newRule(project, group),
+ ref);
+ r.setBlock();
+ r.setRange(-1, 1);
+ return r;
+ }
+
public static PermissionRule deny(ProjectConfig project,
String permissionName, AccountGroup.UUID group, String ref) {
PermissionRule r = grant(project, permissionName, newRule(project, group), ref);
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/util/SubmoduleSectionParserTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/util/SubmoduleSectionParserTest.java
index bd672f3..3945da7 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/util/SubmoduleSectionParserTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/util/SubmoduleSectionParserTest.java
@@ -190,6 +190,28 @@
expectedSubscriptions);
}
+ @Test
+ public void testSubmodulesParseWithSubProjectFound() throws Exception {
+ Map<String, SubmoduleSection> sectionsToReturn = new TreeMap<>();
+ sectionsToReturn.put("a/b", new SubmoduleSection(
+ "ssh://localhost/a/b", "a/b", "."));
+
+ Map<String, String> reposToBeFound = new HashMap<>();
+ reposToBeFound.put("a/b", "a/b");
+ reposToBeFound.put("b", "b");
+
+ Branch.NameKey superBranchNameKey =
+ new Branch.NameKey(new Project.NameKey("super-project"),
+ "refs/heads/master");
+
+ Set<SubmoduleSubscription> expectedSubscriptions = Sets.newHashSet();
+ expectedSubscriptions
+ .add(new SubmoduleSubscription(superBranchNameKey, new Branch.NameKey(
+ new Project.NameKey("a/b"), "refs/heads/master"), "a/b"));
+ execute(superBranchNameKey, sectionsToReturn, reposToBeFound,
+ expectedSubscriptions);
+ }
+
private void execute(final Branch.NameKey superProjectBranch,
final Map<String, SubmoduleSection> sectionsToReturn,
final Map<String, String> reposToBeFound,
@@ -217,10 +239,9 @@
projectNameCandidate = projectNameCandidate.substring(0, //
projectNameCandidate.length() - Constants.DOT_GIT_EXT.length());
}
- if (projectNameCandidate.equals(reposToBeFound.get(id))) {
+ if (reposToBeFound.containsValue(projectNameCandidate)) {
expect(projectCache.get(new Project.NameKey(projectNameCandidate)))
.andReturn(createNiceMock(ProjectState.class));
- break;
} else {
expect(projectCache.get(new Project.NameKey(projectNameCandidate)))
.andReturn(null);
diff --git a/gerrit-solr/BUCK b/gerrit-solr/BUCK
deleted file mode 100644
index ec3c728..0000000
--- a/gerrit-solr/BUCK
+++ /dev/null
@@ -1,20 +0,0 @@
-java_library(
- name = 'solr',
- srcs = glob(['src/main/java/**/*.java']),
- deps = [
- '//gerrit-antlr:query_exception',
- '//gerrit-extension-api:api',
- '//gerrit-lucene:query_builder',
- '//gerrit-reviewdb:server',
- '//gerrit-server:server',
- '//lib:guava',
- '//lib:gwtorm',
- '//lib/guice:guice',
- '//lib/jgit:jgit',
- '//lib/log:api',
- '//lib/lucene:analyzers-common',
- '//lib/lucene:core',
- '//lib/solr:solrj',
- ],
- visibility = ['PUBLIC'],
-)
diff --git a/gerrit-solr/src/main/java/com/google/gerrit/solr/IndexVersionCheck.java b/gerrit-solr/src/main/java/com/google/gerrit/solr/IndexVersionCheck.java
deleted file mode 100644
index 0faa691..0000000
--- a/gerrit-solr/src/main/java/com/google/gerrit/solr/IndexVersionCheck.java
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (C) 2013 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.solr;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.gerrit.extensions.events.LifecycleListener;
-import com.google.gerrit.server.config.SitePaths;
-import com.google.gerrit.server.index.ChangeSchemas;
-import com.google.inject.Inject;
-import com.google.inject.ProvisionException;
-
-import org.eclipse.jgit.errors.ConfigInvalidException;
-import org.eclipse.jgit.storage.file.FileBasedConfig;
-import org.eclipse.jgit.util.FS;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.Map;
-
-class IndexVersionCheck implements LifecycleListener {
- public static final Map<String, Integer> SCHEMA_VERSIONS = ImmutableMap.of(
- SolrChangeIndex.CHANGES_OPEN, ChangeSchemas.getLatest().getVersion(),
- SolrChangeIndex.CHANGES_CLOSED, ChangeSchemas.getLatest().getVersion());
-
- public static Path solrIndexConfig(SitePaths sitePaths) {
- return sitePaths.index_dir.resolve("gerrit_index.config");
- }
-
- private final SitePaths sitePaths;
-
- @Inject
- IndexVersionCheck(SitePaths sitePaths) {
- this.sitePaths = sitePaths;
- }
-
- @Override
- public void start() {
- // TODO Query schema version from a special meta-document
- Path path = solrIndexConfig(sitePaths);
- try {
- FileBasedConfig cfg = new FileBasedConfig(path.toFile(), FS.detect());
- cfg.load();
- for (Map.Entry<String, Integer> e : SCHEMA_VERSIONS.entrySet()) {
- int schemaVersion = cfg.getInt("index", e.getKey(), "schemaVersion", 0);
- if (schemaVersion != e.getValue()) {
- throw new ProvisionException(String.format(
- "wrong index schema version for \"%s\": expected %d, found %d%s",
- e.getKey(), e.getValue(), schemaVersion, upgrade()));
- }
- }
- } catch (IOException e) {
- throw new ProvisionException("unable to read " + path);
- } catch (ConfigInvalidException e) {
- throw new ProvisionException("invalid config file " + path);
- }
- }
-
- @Override
- public void stop() {
- // Do nothing.
- }
-
- private final String upgrade() {
- return "\nRun reindex to rebuild the index:\n"
- + "$ java -jar gerrit.war reindex -d "
- + sitePaths.site_path.toAbsolutePath();
- }
-}
diff --git a/gerrit-solr/src/main/java/com/google/gerrit/solr/SolrChangeIndex.java b/gerrit-solr/src/main/java/com/google/gerrit/solr/SolrChangeIndex.java
deleted file mode 100644
index b9e47954..0000000
--- a/gerrit-solr/src/main/java/com/google/gerrit/solr/SolrChangeIndex.java
+++ /dev/null
@@ -1,338 +0,0 @@
-// Copyright (C) 2013 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.solr;
-
-import static com.google.gerrit.server.index.IndexRewriteImpl.CLOSED_STATUSES;
-import static com.google.gerrit.server.index.IndexRewriteImpl.OPEN_STATUSES;
-import static com.google.gerrit.solr.IndexVersionCheck.SCHEMA_VERSIONS;
-import static com.google.gerrit.solr.IndexVersionCheck.solrIndexConfig;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.google.gerrit.extensions.events.LifecycleListener;
-import com.google.gerrit.lucene.QueryBuilder;
-import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.config.GerritServerConfig;
-import com.google.gerrit.server.config.SitePaths;
-import com.google.gerrit.server.index.ChangeField;
-import com.google.gerrit.server.index.ChangeIndex;
-import com.google.gerrit.server.index.FieldDef.FillArgs;
-import com.google.gerrit.server.index.FieldType;
-import com.google.gerrit.server.index.IndexCollection;
-import com.google.gerrit.server.index.IndexRewriteImpl;
-import com.google.gerrit.server.index.Schema;
-import com.google.gerrit.server.index.Schema.Values;
-import com.google.gerrit.server.query.Predicate;
-import com.google.gerrit.server.query.QueryParseException;
-import com.google.gerrit.server.query.change.ChangeData;
-import com.google.gerrit.server.query.change.ChangeDataSource;
-import com.google.gwtorm.server.OrmException;
-import com.google.gwtorm.server.ResultSet;
-import com.google.inject.Provider;
-
-import org.apache.lucene.analysis.standard.StandardAnalyzer;
-import org.apache.lucene.analysis.util.CharArraySet;
-import org.apache.lucene.search.Query;
-import org.apache.solr.client.solrj.SolrQuery;
-import org.apache.solr.client.solrj.SolrQuery.SortClause;
-import org.apache.solr.client.solrj.SolrServer;
-import org.apache.solr.client.solrj.SolrServerException;
-import org.apache.solr.client.solrj.impl.CloudSolrServer;
-import org.apache.solr.common.SolrDocument;
-import org.apache.solr.common.SolrDocumentList;
-import org.apache.solr.common.SolrInputDocument;
-import org.eclipse.jgit.lib.Config;
-import org.eclipse.jgit.storage.file.FileBasedConfig;
-import org.eclipse.jgit.util.FS;
-
-import java.io.IOException;
-import java.sql.Timestamp;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/** Secondary index implementation using a remote Solr instance. */
-class SolrChangeIndex implements ChangeIndex, LifecycleListener {
- public static final String CHANGES_OPEN = "changes_open";
- public static final String CHANGES_CLOSED = "changes_closed";
- private static final String ID_FIELD = ChangeField.LEGACY_ID.getName();
-
- private final Provider<ReviewDb> db;
- private final ChangeData.Factory changeDataFactory;
- private final FillArgs fillArgs;
- private final SitePaths sitePaths;
- private final IndexCollection indexes;
- private final CloudSolrServer openIndex;
- private final CloudSolrServer closedIndex;
- private final Schema<ChangeData> schema;
- private final QueryBuilder queryBuilder;
-
- SolrChangeIndex(
- @GerritServerConfig Config cfg,
- Provider<ReviewDb> db,
- ChangeData.Factory changeDataFactory,
- FillArgs fillArgs,
- SitePaths sitePaths,
- IndexCollection indexes,
- Schema<ChangeData> schema,
- String base) throws IOException {
- this.db = db;
- this.changeDataFactory = changeDataFactory;
- this.fillArgs = fillArgs;
- this.sitePaths = sitePaths;
- this.indexes = indexes;
- this.schema = schema;
-
- String url = cfg.getString("index", null, "url");
- if (Strings.isNullOrEmpty(url)) {
- throw new IllegalStateException("index.url must be supplied");
- }
-
- queryBuilder = new QueryBuilder(
- new StandardAnalyzer(CharArraySet.EMPTY_SET));
-
- base = Strings.nullToEmpty(base);
- openIndex = new CloudSolrServer(url);
- openIndex.setDefaultCollection(base + CHANGES_OPEN);
-
- closedIndex = new CloudSolrServer(url);
- closedIndex.setDefaultCollection(base + CHANGES_CLOSED);
- }
-
- @Override
- public void start() {
- indexes.setSearchIndex(this);
- indexes.addWriteIndex(this);
- }
-
- @Override
- public void stop() {
- openIndex.shutdown();
- closedIndex.shutdown();
- }
-
- @Override
- public Schema<ChangeData> getSchema() {
- return schema;
- }
-
- @Override
- public void close() {
- stop();
- }
-
- @Override
- public void replace(ChangeData cd) throws IOException {
- String id = cd.getId().toString();
- SolrInputDocument doc = toDocument(cd);
- try {
- if (cd.change().getStatus().isOpen()) {
- closedIndex.deleteById(id);
- openIndex.add(doc);
- } else {
- openIndex.deleteById(id);
- closedIndex.add(doc);
- }
- } catch (OrmException | SolrServerException e) {
- throw new IOException(e);
- }
- commit(openIndex);
- commit(closedIndex);
- }
-
- @Override
- public void delete(Change.Id id) throws IOException {
- String idString = Integer.toString(id.get());
- delete(idString, openIndex);
- delete(idString, closedIndex);
- }
-
- private void delete(String id, CloudSolrServer index) throws IOException {
- try {
- index.deleteById(id);
- commit(index);
- } catch (SolrServerException e) {
- throw new IOException(e);
- }
- }
-
- @Override
- public void deleteAll() throws IOException {
- try {
- openIndex.deleteByQuery("*:*");
- closedIndex.deleteByQuery("*:*");
- } catch (SolrServerException e) {
- throw new IOException(e);
- }
- commit(openIndex);
- commit(closedIndex);
- }
-
- @Override
- public ChangeDataSource getSource(Predicate<ChangeData> p, int start, int limit)
- throws QueryParseException {
- Set<Change.Status> statuses = IndexRewriteImpl.getPossibleStatus(p);
- List<SolrServer> indexes = Lists.newArrayListWithCapacity(2);
- if (!Sets.intersection(statuses, OPEN_STATUSES).isEmpty()) {
- indexes.add(openIndex);
- }
- if (!Sets.intersection(statuses, CLOSED_STATUSES).isEmpty()) {
- indexes.add(closedIndex);
- }
- return new QuerySource(indexes, queryBuilder.toQuery(p), start, limit,
- getSorts());
- }
-
- private static List<SortClause> getSorts() {
- return ImmutableList.of(
- new SortClause(
- ChangeField.UPDATED.getName(), SolrQuery.ORDER.desc),
- new SortClause(
- ChangeField.LEGACY_ID.getName(), SolrQuery.ORDER.desc));
- }
-
- private void commit(SolrServer server) throws IOException {
- try {
- server.commit();
- } catch (SolrServerException e) {
- throw new IOException(e);
- }
- }
-
- private class QuerySource implements ChangeDataSource {
- private final List<SolrServer> servers;
- private final SolrQuery query;
-
- public QuerySource(List<SolrServer> indexes, Query q, int start, int limit,
- List<SortClause> sorts) {
- this.servers = indexes;
-
- query = new SolrQuery(q.toString());
- query.setParam("shards.tolerant", true);
- query.setParam("rows", Integer.toString(limit));
- if (start != 0) {
- query.setParam("start", Integer.toString(start));
- }
- query.setFields(ID_FIELD);
- query.setSorts(sorts);
- }
-
- @Override
- public int getCardinality() {
- return 10; // TODO: estimate from solr?
- }
-
- @Override
- public boolean hasChange() {
- return false;
- }
-
- @Override
- public String toString() {
- return query.getQuery();
- }
-
- @Override
- public ResultSet<ChangeData> read() throws OrmException {
- try {
- // TODO Sort documents during merge to select only top N.
- SolrDocumentList docs = new SolrDocumentList();
- for (SolrServer index : servers) {
- docs.addAll(index.query(query).getResults());
- }
-
- List<ChangeData> result = Lists.newArrayListWithCapacity(docs.size());
- for (SolrDocument doc : docs) {
- Integer v = (Integer) doc.getFieldValue(ID_FIELD);
- result.add(
- changeDataFactory.create(db.get(), new Change.Id(v.intValue())));
- }
-
- final List<ChangeData> r = Collections.unmodifiableList(result);
- return new ResultSet<ChangeData>() {
- @Override
- public Iterator<ChangeData> iterator() {
- return r.iterator();
- }
-
- @Override
- public List<ChangeData> toList() {
- return r;
- }
-
- @Override
- public void close() {
- // Do nothing.
- }
- };
- } catch (SolrServerException e) {
- throw new OrmException(e);
- }
- }
- }
-
- private SolrInputDocument toDocument(ChangeData cd) {
- SolrInputDocument result = new SolrInputDocument();
- for (Values<ChangeData> values : schema.buildFields(cd, fillArgs)) {
- add(result, values);
- }
- return result;
- }
-
- private void add(SolrInputDocument doc, Values<ChangeData> values) {
- String name = values.getField().getName();
- FieldType<?> type = values.getField().getType();
-
- if (type == FieldType.INTEGER) {
- for (Object value : values.getValues()) {
- doc.addField(name, value);
- }
- } else if (type == FieldType.LONG) {
- for (Object value : values.getValues()) {
- doc.addField(name, value);
- }
- } else if (type == FieldType.TIMESTAMP) {
- for (Object value : values.getValues()) {
- doc.addField(name, ((Timestamp) value).getTime());
- }
- } else if (type == FieldType.EXACT
- || type == FieldType.PREFIX
- || type == FieldType.FULL_TEXT) {
- for (Object value : values.getValues()) {
- doc.addField(name, value);
- }
- } else {
- throw FieldType.badFieldType(type);
- }
- }
-
- @Override
- public void markReady(boolean ready) throws IOException {
- // TODO Move the schema version information to a special meta-document
- FileBasedConfig cfg = new FileBasedConfig(
- solrIndexConfig(sitePaths).toFile(),
- FS.detect());
- for (Map.Entry<String, Integer> e : SCHEMA_VERSIONS.entrySet()) {
- cfg.setInt("index", e.getKey(), "schemaVersion",
- ready ? e.getValue() : -1);
- }
- cfg.save();
- }
-}
diff --git a/gerrit-solr/src/main/java/com/google/gerrit/solr/SolrIndexModule.java b/gerrit-solr/src/main/java/com/google/gerrit/solr/SolrIndexModule.java
deleted file mode 100644
index 0133e33..0000000
--- a/gerrit-solr/src/main/java/com/google/gerrit/solr/SolrIndexModule.java
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (C) 2013 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.solr;
-
-import com.google.gerrit.lifecycle.LifecycleModule;
-import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.config.GerritServerConfig;
-import com.google.gerrit.server.config.SitePaths;
-import com.google.gerrit.server.index.ChangeIndex;
-import com.google.gerrit.server.index.ChangeSchemas;
-import com.google.gerrit.server.index.FieldDef.FillArgs;
-import com.google.gerrit.server.index.IndexCollection;
-import com.google.gerrit.server.index.IndexConfig;
-import com.google.gerrit.server.index.IndexModule;
-import com.google.gerrit.server.query.change.ChangeData;
-import com.google.inject.Provider;
-import com.google.inject.Provides;
-import com.google.inject.Singleton;
-
-import org.eclipse.jgit.lib.Config;
-
-import java.io.IOException;
-
-public class SolrIndexModule extends LifecycleModule {
- private final boolean checkVersion;
- private final int threads;
- private final String base;
-
- public SolrIndexModule() {
- this(true, 0, null);
- }
-
- public SolrIndexModule(boolean checkVersion, int threads, String base) {
- this.checkVersion = checkVersion;
- this.threads = threads;
- this.base = base;
- }
-
- @Override
- protected void configure() {
- install(new IndexModule(threads));
- bind(ChangeIndex.class).to(SolrChangeIndex.class);
- listener().to(SolrChangeIndex.class);
- if (checkVersion) {
- listener().to(IndexVersionCheck.class);
- }
- }
-
- @Provides
- @Singleton
- IndexConfig getIndexConfig(@GerritServerConfig Config cfg) {
- return IndexConfig.fromConfig(cfg);
- }
-
- @Provides
- @Singleton
- public SolrChangeIndex getChangeIndex(@GerritServerConfig Config cfg,
- Provider<ReviewDb> db,
- ChangeData.Factory changeDataFactory,
- SitePaths sitePaths,
- IndexCollection indexes,
- FillArgs fillArgs) throws IOException {
- return new SolrChangeIndex(cfg, db, changeDataFactory, fillArgs, sitePaths,
- indexes, ChangeSchemas.getLatest(), base);
- }
-}
diff --git a/gerrit-war/BUCK b/gerrit-war/BUCK
index 35f6084..1f82849 100644
--- a/gerrit-war/BUCK
+++ b/gerrit-war/BUCK
@@ -17,7 +17,6 @@
'//gerrit-reviewdb:server',
'//gerrit-server:server',
'//gerrit-server/src/main/prolog:common',
- '//gerrit-solr:solr',
'//gerrit-sshd:sshd',
'//lib:guava',
'//lib:gwtorm',
diff --git a/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java b/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java
index 22f3f0b..50c822e 100644
--- a/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java
+++ b/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java
@@ -61,7 +61,6 @@
import com.google.gerrit.server.securestore.SecureStoreClassName;
import com.google.gerrit.server.ssh.NoSshModule;
import com.google.gerrit.server.ssh.SshAddressesModule;
-import com.google.gerrit.solr.SolrIndexModule;
import com.google.gerrit.sshd.SshHostKeyModule;
import com.google.gerrit.sshd.SshKeyCacheImpl;
import com.google.gerrit.sshd.SshModule;
@@ -302,9 +301,6 @@
case LUCENE:
changeIndexModule = new LuceneIndexModule();
break;
- case SOLR:
- changeIndexModule = new SolrIndexModule();
- break;
default:
throw new IllegalStateException("unsupported index.type");
}
diff --git a/lib/BUCK b/lib/BUCK
index 6a6871e..1dbac0a 100644
--- a/lib/BUCK
+++ b/lib/BUCK
@@ -26,9 +26,9 @@
maven_jar(
name = 'gwtorm_client',
- id = 'com.google.gerrit:gwtorm:1.14-14-gf54f1f1',
- bin_sha1 = 'c02267e0245dd06930ea64a2d7c5ddc5ba6d9cfb',
- src_sha1 = '3d17ae8a173eb34d89098c748f28cddd5080adbc',
+ id = 'com.google.gerrit:gwtorm:1.14-16-gc4e356a',
+ bin_sha1 = '01225468065812bbe5f27972df6dafa9d796d833',
+ src_sha1 = '3622460ed58684cb33f786e3748637c8eea324f9',
license = 'Apache2.0',
repository = GERRIT,
)
@@ -58,8 +58,8 @@
maven_jar(
name = 'guava',
- id = 'com.google.guava:guava:18.0',
- sha1 = 'cce0823396aa693798f8882e64213b1772032b09',
+ id = 'com.google.guava:guava:19.0-rc1',
+ sha1 = '0364538ac107b8943a1f4d68ac50f1b0421bb983',
license = 'Apache2.0',
)
@@ -78,15 +78,15 @@
maven_jar(
name = 'jsch',
- id = 'com.jcraft:jsch:0.1.51',
- sha1 = '6ceee2696b07cc320d0e1aaea82c7b40768aca0f',
+ id = 'com.jcraft:jsch:0.1.53',
+ sha1 = '658b682d5c817b27ae795637dfec047c63d29935',
license = 'jsch',
)
maven_jar(
name = 'servlet-api-3_1',
- id = 'org.apache.tomcat:tomcat-servlet-api:8.0.5',
- sha1 = '9ef01afc25481b82aa8f3615db536869f2dc961e',
+ id = 'org.apache.tomcat:tomcat-servlet-api:8.0.24',
+ sha1 = '5d9e2e895e3111622720157d0aa540066d5fce3a',
license = 'Apache2.0',
exclude = ['META-INF/NOTICE', 'META-INF/LICENSE'],
)
@@ -193,8 +193,8 @@
maven_jar(
name = 'truth',
- id = 'com.google.truth:truth:0.26',
- sha1 = 'b5802815625d82f39c33219299771f3d64301b06',
+ id = 'com.google.truth:truth:0.27',
+ sha1 = 'bd17774d2dc0fffa884d42c07d2537e86c67acd6',
license = 'DO_NOT_DISTRIBUTE',
exported_deps = [
':guava',
diff --git a/lib/asciidoctor/BUCK b/lib/asciidoctor/BUCK
index 66a12c1..f8feb63 100644
--- a/lib/asciidoctor/BUCK
+++ b/lib/asciidoctor/BUCK
@@ -43,8 +43,8 @@
maven_jar(
name = 'asciidoctor',
- id = 'org.asciidoctor:asciidoctorj:1.5.0',
- sha1 = '192df5660f72a0fb76966dcc64193b94fba65f99',
+ id = 'org.asciidoctor:asciidoctorj:1.5.2',
+ sha1 = '39d33f739ec1c46f6e908a725264eb74b23c9f99',
license = 'Apache2.0',
visibility = [],
attach_source = False,
@@ -52,8 +52,8 @@
maven_jar(
name = 'jruby',
- id = 'org.jruby:jruby-complete:1.7.4',
- sha1 = '74984d84846523bd7da49064679ed1ccf199e1db',
+ id = 'org.jruby:jruby-complete:1.7.18',
+ sha1 = 'a1be3e1790aace5c99614a87785454d875eb21c2',
license = 'DO_NOT_DISTRIBUTE',
visibility = [],
attach_source = False,
diff --git a/lib/codemirror/BUCK b/lib/codemirror/BUCK
index bdc2709..a7244f2 100644
--- a/lib/codemirror/BUCK
+++ b/lib/codemirror/BUCK
@@ -3,8 +3,8 @@
include_defs('//lib/codemirror/closure.defs')
REPO = MAVEN_CENTRAL
-VERSION = '5.3'
-SHA1 = 'd39474aece4e58c2b0fcc71530ae223ec0d4d855'
+VERSION = '5.5'
+SHA1 = 'd9cee6fe3de8e02372b1ac1e9a627224a4f649a7'
if REPO == MAVEN_CENTRAL:
URL = REPO + 'org/webjars/codemirror/%s/codemirror-%s.jar' % (VERSION, VERSION)
diff --git a/lib/jetty/BUCK b/lib/jetty/BUCK
index 2e65abc..d02916f 100644
--- a/lib/jetty/BUCK
+++ b/lib/jetty/BUCK
@@ -1,12 +1,12 @@
include_defs('//lib/maven.defs')
-VERSION = '9.2.10.v20150310'
+VERSION = '9.2.12.v20150709'
EXCLUDE = ['about.html']
maven_jar(
name = 'servlet',
id = 'org.eclipse.jetty:jetty-servlet:' + VERSION,
- sha1 = '9e923adf1671af7da09dba778e132ab0a9c62415',
+ sha1 = '50116cac18ad893c9628f0a1984390464b133921',
license = 'Apache2.0',
deps = [':security'],
exclude = EXCLUDE,
@@ -15,7 +15,7 @@
maven_jar(
name = 'security',
id = 'org.eclipse.jetty:jetty-security:' + VERSION,
- sha1 = 'b56228088355023117ba9a9de0da00d652a7e655',
+ sha1 = '9ace95998fbaae8425b2621c90230a229a554784',
license = 'Apache2.0',
deps = [':server'],
exclude = EXCLUDE,
@@ -25,7 +25,7 @@
maven_jar(
name = 'servlets',
id = 'org.eclipse.jetty:jetty-servlets:' + VERSION,
- sha1 = 'b48a9bb30e9d5e73dcedf8039f96abdb04a3892c',
+ sha1 = 'a1f9e7874e1db2f664213f524463d12bd5ab5db4',
license = 'Apache2.0',
exclude = EXCLUDE,
visibility = [
@@ -37,7 +37,7 @@
maven_jar(
name = 'server',
id = 'org.eclipse.jetty:jetty-server:' + VERSION,
- sha1 = '0e6b8bff28b3e9ca6254415d2aa49603a5887fe8',
+ sha1 = '8c90ceffb6954385b024899d334192947d0e4077',
license = 'Apache2.0',
exported_deps = [
':continuation',
@@ -49,7 +49,7 @@
maven_jar(
name = 'jmx',
id = 'org.eclipse.jetty:jetty-jmx:' + VERSION,
- sha1 = 'fa94eb39f1dd63c40efe44471664f8f70bc7ca2e',
+ sha1 = '8bc0288abba26dbbf4e9225d6fe6fa6348f8da05',
license = 'Apache2.0',
exported_deps = [
':continuation',
@@ -61,7 +61,7 @@
maven_jar(
name = 'continuation',
id = 'org.eclipse.jetty:jetty-continuation:' + VERSION,
- sha1 = '1c9bc80037e9898974ada7318f11c984363d4707',
+ sha1 = '0578cb87b78b71eeda91f5dfa3e8bfbafb55cced',
license = 'Apache2.0',
exclude = EXCLUDE,
)
@@ -69,7 +69,7 @@
maven_jar(
name = 'http',
id = 'org.eclipse.jetty:jetty-http:' + VERSION,
- sha1 = '886b628f62cd518bbb04b37bd1b308fa19340a53',
+ sha1 = '9a6c83f52c70c28e2272d83866b4111cd15ddbc5',
license = 'Apache2.0',
exported_deps = [':io'],
exclude = EXCLUDE,
@@ -78,7 +78,7 @@
maven_jar(
name = 'io',
id = 'org.eclipse.jetty:jetty-io:' + VERSION,
- sha1 = '29bc6a5e2049d9858bfa811f2728a7a8efcdc1c0',
+ sha1 = 'c02e9e303d231a589e0c8866c1ee89bcdeb40a55',
license = 'Apache2.0',
exported_deps = [':util'],
exclude = EXCLUDE,
@@ -88,7 +88,7 @@
maven_jar(
name = 'util',
id = 'org.eclipse.jetty:jetty-util:' + VERSION,
- sha1 = '90cc75668dc9a9885108733d4d46420907cf863c',
+ sha1 = 'd99d38adfdb5ec677643f04fa862554b0bb8b42e',
license = 'Apache2.0',
exclude = EXCLUDE,
visibility = [],
diff --git a/lib/solr/BUCK b/lib/solr/BUCK
deleted file mode 100644
index cd39742..0000000
--- a/lib/solr/BUCK
+++ /dev/null
@@ -1,33 +0,0 @@
-include_defs('//lib/maven.defs')
-
-# Java client library to use Solr over the network.
-maven_jar(
- name = 'solrj',
- id = 'org.apache.solr:solr-solrj:4.3.1',
- sha1 = '433fe37796e67eaeb4452f69eb1fae2de27cb7a8',
- license = 'Apache2.0',
- deps = [
- ':noggit',
- ':zookeeper',
- '//lib/httpcomponents:httpclient',
- '//lib/httpcomponents:httpmime',
- '//lib/commons:io',
- ],
-)
-
-maven_jar(
- name = 'noggit',
- id = 'org.noggit:noggit:0.5',
- sha1 = '8e6e65624d2e09a30190c6434abe23b7d4e5413c',
- license = 'Apache2.0',
- visibility = [],
-)
-
-maven_jar(
- name = 'zookeeper',
- id = 'org.apache.zookeeper:zookeeper:3.4.5',
- sha1 = 'c0f69fb36526552a8f0bc548a6c33c49cf08e562',
- license = 'Apache2.0',
- deps = ['//lib/log:api'],
- visibility = [],
-)
diff --git a/plugins/cookbook-plugin b/plugins/cookbook-plugin
index c70b288..2ff713f 160000
--- a/plugins/cookbook-plugin
+++ b/plugins/cookbook-plugin
@@ -1 +1 @@
-Subproject commit c70b2881cbb9ad706603d7f6fa855b233aea6135
+Subproject commit 2ff713f3d3f0bbabf00b73c74705cd3741f61a70
diff --git a/plugins/replication b/plugins/replication
index 7a3a89f..cb9e977 160000
--- a/plugins/replication
+++ b/plugins/replication
@@ -1 +1 @@
-Subproject commit 7a3a89fc983b9bcb5b2c965affd7a83bb6b10bb2
+Subproject commit cb9e977ddbaa76214c8cefbeb74aa8420ce1d912
diff --git a/tools/eclipse/gerrit_gwt_debug.launch b/tools/eclipse/gerrit_gwt_debug.launch
index 3533211..c3c58ff 100644
--- a/tools/eclipse/gerrit_gwt_debug.launch
+++ b/tools/eclipse/gerrit_gwt_debug.launch
@@ -16,7 +16,7 @@
</listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gerrit.gwtdebug.GerritGwtDebugLauncher"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-noprecompile -src ${resource_loc:/gerrit} -workDir ${resource_loc:/gerrit}/buck-out/gen/gerrit-gwtui com.google.gerrit.GerritGwtUI -- --console-log --show-stack-trace -d ${resource_loc:/gerrit}/../gerrit_testsite"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-noprecompile -src ${resource_loc:/gerrit} -workDir ${resource_loc:/gerrit}/buck-out/gen/gerrit-gwtui com.google.gerrit.GerritGwtUI -src ${resource_loc:/gerrit}/gerrit-plugin-gwtui/src/main/java -- --console-log --show-stack-trace -d ${resource_loc:/gerrit}/../gerrit_testsite"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="gerrit"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx1024M -XX:MaxPermSize=256M -Dgerrit.disable-gwtui-recompile=true"/>
</launchConfiguration>