Merge "git-exproll.sh: Return nonzero on errors."
diff --git a/.gitmodules b/.gitmodules
index 0f7fdab..e45868b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -9,3 +9,7 @@
[submodule "plugins/commit-message-length-validator"]
path = plugins/commit-message-length-validator
url = https://gerrit.googlesource.com/plugins/commit-message-length-validator
+
+[submodule "plugins/helloworld"]
+ path = plugins/helloworld
+ url = https://gerrit.googlesource.com/plugins/helloworld
diff --git a/Documentation/rest-api-accounts.txt b/Documentation/rest-api-accounts.txt
index a78385a..9850c40 100644
--- a/Documentation/rest-api-accounts.txt
+++ b/Documentation/rest-api-accounts.txt
@@ -161,6 +161,67 @@
HTTP/1.1 204 No Content
----
+[[get-active]]
+Get Active
+~~~~~~~~~~
+[verse]
+'GET /accounts/link:#account-id[\{account-id\}]/active'
+
+Checks if an account is active.
+
+.Request
+----
+ GET /accounts/john.doe@example.com/active HTTP/1.0
+----
+
+As response `200 OK` is returned for an active account and
+`404 Not Found` is returned for an inactive account.
+
+.Response
+----
+ HTTP/1.1 200 OK
+----
+
+[[set-active]]
+Set Active
+~~~~~~~~~~
+[verse]
+'PUT /accounts/link:#account-id[\{account-id\}]/active'
+
+Sets the account state to active.
+
+.Request
+----
+ PUT /accounts/john.doe@example.com/active HTTP/1.0
+----
+
+.Response
+----
+ HTTP/1.1 201 Created
+----
+
+If the account was already active the response is `200 OK`.
+
+[[delete-active]]
+Delete Active
+~~~~~~~~~~~~~
+[verse]
+'DELETE /accounts/link:#account-id[\{account-id\}]/active'
+
+Sets the account state to inactive.
+
+.Request
+----
+ DELETE /accounts/john.doe@example.com/active HTTP/1.0
+----
+
+.Response
+----
+ HTTP/1.1 204 No Content
+----
+
+If the account was already inactive the response is `404 Not Found`.
+
[[list-account-emails]]
List Account Emails
~~~~~~~~~~~~~~~~~~~
@@ -244,11 +305,6 @@
.Request
----
PUT /accounts/self/emails/john.doe@example.com HTTP/1.0
- Content-Type: application/json;charset=UTF-8
-
- {
- "preferred": true
- }
----
As response the new email address is returned as
@@ -263,10 +319,28 @@
)]}'
{
"email": "john.doe@example.com",
- "preferred": true
+ "pending_confirmation": true
}
----
+[[delete-account-email]]
+Delete Account Email
+~~~~~~~~~~~~~~~~~~~~
+[verse]
+'DELETE /accounts/link:#account-id[\{account-id\}]/emails/link:#email-id[\{email-id\}]'
+
+Deletes an email address of an account.
+
+.Request
+----
+ DELETE /accounts/self/emails/john.doe@example.com HTTP/1.0
+----
+
+.Response
+----
+ HTTP/1.1 204 No Content
+----
+
[[set-preferred-email]]
Set Preferred Email
~~~~~~~~~~~~~~~~~~~
@@ -882,7 +956,8 @@
URL.
|`preferred` |`false` if not set|
Whether the new email address should become the preferred email address
-of the user.
+of the user (only supported if `no_confirmation` is set or if the
+authentication type is `DEVELOPMENT_BECOME_ANY_ACCOUNT`).
|`no_confirmation`|`false` if not set|
Whether the email address should be added without confirmation. In this
case no verification email is sent to the user. +
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/ContactPanelShort.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/ContactPanelShort.java
index 053146b..ddec7d5 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/ContactPanelShort.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/ContactPanelShort.java
@@ -423,6 +423,14 @@
}
}
if (emailPick.getItemCount() > 0) {
+ if (currentEmail == null) {
+ int index = emailListIndexOf("");
+ if (index != -1) {
+ emailPick.removeItem(index);
+ }
+ emailPick.insertItem("", 0);
+ emailPick.setSelectedIndex(0);
+ }
emailPick.setVisible(true);
emailPick.setEnabled(true);
if (canRegisterNewEmail()) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CodeMirrorDemo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CodeMirrorDemo.java
index 66abe88..70b9ff9 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CodeMirrorDemo.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CodeMirrorDemo.java
@@ -14,19 +14,24 @@
package com.google.gerrit.client.diff;
+import com.google.gerrit.client.diff.DiffInfo.Region;
import com.google.gerrit.client.rpc.CallbackGroup;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.Screen;
import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gwt.core.client.JsArray;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Window;
import net.codemirror.lib.CodeMirror;
+import net.codemirror.lib.CodeMirror.LineClassWhere;
import net.codemirror.lib.Configuration;
+import net.codemirror.lib.LineCharacter;
import net.codemirror.lib.ModeInjector;
public class CodeMirrorDemo extends Screen {
@@ -116,6 +121,7 @@
private void display(DiffInfo diff) {
cmA = displaySide(diff.meta_a(), diff.text_a(), diffTable.getCmA());
cmB = displaySide(diff.meta_b(), diff.text_b(), diffTable.getCmB());
+ render(diff);
resizeHandler = Window.addResizeHandler(new ResizeHandler() {
@Override
public void onResize(ResizeEvent event) {
@@ -141,13 +147,65 @@
.set("lineNumbers", true)
.set("tabSize", 2)
.set("mode", getContentType(meta))
- .set("value", contents);
+ .set("value", contents)
+ .setInfinity("viewportMargin");
final CodeMirror cm = CodeMirror.create(ele, cfg);
cm.setWidth("100%");
cm.setHeight(Window.getClientHeight() - HEADER_FOOTER);
return cm;
}
+ private void addPadding(CodeMirror cm, int line) {
+ Element div = DOM.createDiv();
+ div.setClassName(diffTable.style.padding());
+ cm.addLineWidget(line, div, null);
+ }
+
+ private void render(DiffInfo diff) {
+ JsArray<Region> regions = diff.content();
+ Configuration insertOpt = Configuration.create()
+ .set("className", diffTable.style.insert())
+ .set("readOnly", true);
+ Configuration deleteOpt = Configuration.create()
+ .set("className", diffTable.style.delete())
+ .set("readOnly", true);
+ int lineA = 0, lineB = 0;
+ for (int i = 0; i < regions.length(); i++) {
+ Region current = regions.get(i);
+ if (current.ab() != null) {
+ lineA += current.ab().length();
+ lineB += current.ab().length();
+ } else if (current.a() == null && current.b() != null) {
+ int delta = current.b().length();
+ for (int j = 0; j < delta; j++) {
+ addPadding(cmA, lineA - 1);
+ }
+ for (int j = 0; j < delta; j++) {
+ cmB.addLineClass(lineB, LineClassWhere.WRAP,
+ diffTable.style.insert());
+ LineCharacter from = LineCharacter.create(lineB, 0);
+ cmB.markText(from, from, insertOpt);
+ lineB++;
+ }
+ } else if (current.a() != null && current.b() == null) {
+ int delta = current.a().length();
+ for (int j = 0; j < delta; j++) {
+ addPadding(cmB, lineB - 1);
+ }
+ for (int j = 0; j < delta; j++) {
+ cmA.addLineClass(lineA, LineClassWhere.WRAP,
+ diffTable.style.delete());
+ LineCharacter from = LineCharacter.create(lineA, 0);
+ cmA.markText(from, from, deleteOpt);
+ lineA++;
+ }
+ } else { // TODO: Handle intraline edit.
+ lineA += current.a().length();
+ lineB += current.a().length();
+ }
+ }
+ }
+
private static String getContentType(DiffInfo.FileMeta meta) {
return meta != null && meta.content_type() != null
? ModeInjector.getContentType(meta.content_type())
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.java
index bb223e1..e681630 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.java
@@ -16,6 +16,7 @@
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
+import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
@@ -29,12 +30,22 @@
interface Binder extends UiBinder<HTMLPanel, DiffTable> {}
private static Binder uiBinder = GWT.create(Binder.class);
+ interface LineStyle extends CssResource {
+ String insert();
+ String delete();
+ String intraline();
+ String padding();
+ }
+
@UiField
DivElement cmA;
@UiField
DivElement cmB;
+ @UiField
+ LineStyle style;
+
DiffTable() {
initWidget(uiBinder.createAndBindUi(this));
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.ui.xml
index 735a0e6..5e4cf0d 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.ui.xml
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.ui.xml
@@ -16,7 +16,49 @@
-->
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
- <g:HTMLPanel>
+ <ui:style field='css'>
+ @external .CodeMirror, .CodeMirror-selectedtext, .CodeMirror-scroll;
+
+ .difftable .CodeMirror {
+ border: 1px solid #eee;
+ height: auto;
+ }
+ .difftable .CodeMirror pre {
+ padding: 0;
+ overflow: hidden;
+ }
+ .difftable .CodeMirror-selectedtext.intraline,
+ .difftable .CodeMirror-selectedtext.insert {
+ opacity: 0.5;
+ }
+ .difftable .CodeMirror-scroll {
+ overflow-x: hidden;
+ overflow-y: hidden;
+ }
+ <!--.difftable .CodeMirror-vscrollbar {
+ display: none !important;
+ }-->
+ </ui:style>
+ <ui:style type='com.google.gerrit.client.diff.DiffTable.LineStyle'>
+ @external .CodeMirror-linenumber;
+
+ .insert,
+ .insert .CodeMirror-linenumber {
+ background-color: #dfd;
+ }
+ .delete,
+ .delete .CodeMirror-linenumber {
+ background-color: #fee;
+ }
+ .intraline {
+ background-color: #9f9;
+ }
+ .padding {
+ background-color: #eee;
+ height: 1em;
+ }
+ </ui:style>
+ <g:HTMLPanel styleName='{css.difftable}'>
<table>
<tr>
<td><div ui:field='cmA'></div></td>
diff --git a/gerrit-gwtui/src/main/java/net/codemirror/CodeMirror.gwt.xml b/gerrit-gwtui/src/main/java/net/codemirror/CodeMirror.gwt.xml
index 64ac16d..a3641a553 100644
--- a/gerrit-gwtui/src/main/java/net/codemirror/CodeMirror.gwt.xml
+++ b/gerrit-gwtui/src/main/java/net/codemirror/CodeMirror.gwt.xml
@@ -16,6 +16,7 @@
<module>
<inherits name='com.google.gwt.logging.Logging'/>
<inherits name='com.google.gwt.resources.Resources'/>
+ <source path='addon'/>
<source path='lib'/>
<source path='mode'/>
</module>
diff --git a/gerrit-gwtui/src/main/java/net/codemirror/addon/Addons.java b/gerrit-gwtui/src/main/java/net/codemirror/addon/Addons.java
new file mode 100644
index 0000000..1cddc7f
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/net/codemirror/addon/Addons.java
@@ -0,0 +1,28 @@
+// 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 net.codemirror.addon;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.DataResource;
+import com.google.gwt.resources.client.DataResource.DoNotEmbed;
+
+public interface Addons extends ClientBundle {
+ public static final Addons I = GWT.create(Addons.class);
+
+ @Source("selection/mark-selection.js")
+ @DoNotEmbed
+ DataResource mark_selection();
+}
diff --git a/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java b/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java
index 11d10df..42664b7 100644
--- a/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java
+++ b/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java
@@ -28,7 +28,8 @@
Loader.initLibrary(cb);
}
- public static native CodeMirror create(Element parent, Configuration cfg) /*-{
+ public static native CodeMirror create(Element parent,
+ Configuration cfg) /*-{
return $wnd.CodeMirror(parent, cfg);
}-*/;
@@ -42,6 +43,30 @@
public final native void refresh() /*-{ this.refresh(); }-*/;
public final native Element getWrapperElement() /*-{ return this.getWrapperElement(); }-*/;
+ public final native void markText(LineCharacter from, LineCharacter to,
+ Configuration options) /*-{
+ this.markText(from, to, options);
+ }-*/;
+
+ public enum LineClassWhere {
+ TEXT, BACKGROUND, WRAP;
+ }
+
+ public final void addLineClass(int line, LineClassWhere where,
+ String className) {
+ addLineClassNative(line, where.name().toLowerCase(), className);
+ }
+
+ private final native void addLineClassNative(int line, String where,
+ String lineClass) /*-{
+ this.addLineClass(line, where, lineClass);
+ }-*/;
+
+ public final native void addLineWidget(int line, Element node,
+ Configuration options) /*-{
+ this.addLineWidget(line, node, options);
+ }-*/;
+
protected CodeMirror() {
}
}
diff --git a/gerrit-gwtui/src/main/java/net/codemirror/lib/Configuration.java b/gerrit-gwtui/src/main/java/net/codemirror/lib/Configuration.java
index a121697..57fcc2b 100644
--- a/gerrit-gwtui/src/main/java/net/codemirror/lib/Configuration.java
+++ b/gerrit-gwtui/src/main/java/net/codemirror/lib/Configuration.java
@@ -36,6 +36,9 @@
public final native Configuration set(String name, boolean val)
/*-{ this[name] = val; return this; }-*/;
+ public final native Configuration setInfinity(String name)
+ /*-{ this[name] = Infinity; return this; }-*/;
+
protected Configuration() {
}
}
diff --git a/gerrit-gwtui/src/main/java/net/codemirror/lib/LineCharacter.java b/gerrit-gwtui/src/main/java/net/codemirror/lib/LineCharacter.java
new file mode 100644
index 0000000..8a8e9d5
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/net/codemirror/lib/LineCharacter.java
@@ -0,0 +1,39 @@
+// 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 net.codemirror.lib;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+/** {line, ch} objects used within CodeMirror. */
+public class LineCharacter extends JavaScriptObject {
+ public static LineCharacter create(int line, int ch) {
+ LineCharacter lineCh = createObject().cast();
+ return lineCh.setLine(line).setCh(ch);
+ }
+
+ private final native LineCharacter setLine(int line) /*-{
+ this.line = line; return this;
+ }-*/;
+
+ private final native LineCharacter setCh(int ch) /*-{
+ this.ch = ch; return this;
+ }-*/;
+
+ public final native int getLine() /*-{ return this.line; }-*/;
+ public final native int getCh() /*-{ return this.ch; }-*/;
+
+ protected LineCharacter() {
+ }
+}
diff --git a/gerrit-gwtui/src/main/java/net/codemirror/lib/Loader.java b/gerrit-gwtui/src/main/java/net/codemirror/lib/Loader.java
index 0637a1b..6373906 100644
--- a/gerrit-gwtui/src/main/java/net/codemirror/lib/Loader.java
+++ b/gerrit-gwtui/src/main/java/net/codemirror/lib/Loader.java
@@ -14,6 +14,7 @@
package net.codemirror.lib;
+import com.google.gerrit.client.rpc.CallbackGroup;
import com.google.gwt.core.client.Callback;
import com.google.gwt.core.client.ScriptInjector;
import com.google.gwt.dom.client.ScriptElement;
@@ -25,6 +26,8 @@
import com.google.gwt.safehtml.shared.SafeUri;
import com.google.gwt.user.client.rpc.AsyncCallback;
+import net.codemirror.addon.Addons;
+
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -36,8 +39,14 @@
if (isLibLoaded()) {
cb.onSuccess(null);
} else {
+ CallbackGroup group = new CallbackGroup();
injectCss(Lib.I.css());
- injectScript(Lib.I.js().getSafeUri(), cb);
+ injectScript(
+ Lib.I.js().getSafeUri(), group.add(new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {}
+ public void onSuccess(Void result) {}
+ }));
+ injectScript(Addons.I.mark_selection().getSafeUri(), group.add(cb));
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java
index 9228714..62d29dd 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java
@@ -15,14 +15,11 @@
package com.google.gerrit.server;
import com.google.gerrit.common.ChangeHooks;
-import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.common.errors.EmailException;
-import com.google.gerrit.reviewdb.client.Account;
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.PatchSetAncestor;
-import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.client.RevId;
import com.google.gerrit.reviewdb.client.TrackingId;
import com.google.gerrit.reviewdb.server.ReviewDb;
@@ -196,7 +193,7 @@
ReviewDb db, RevertedSender.Factory revertedSenderFactory,
ChangeHooks hooks, Repository git,
PatchSetInfoFactory patchSetInfoFactory, PersonIdent myIdent,
- ChangeInserter changeInserter)
+ ChangeInserter.Factory changeInserterFactory)
throws NoSuchChangeException, EmailException,
OrmException, MissingObjectException, IncorrectObjectTypeException,
IOException, InvalidChangeOperationException {
@@ -251,13 +248,9 @@
user.getAccountId(),
changeToRevert.getDest());
change.setTopic(changeToRevert.getTopic());
-
- PatchSet.Id id =
- new PatchSet.Id(change.getId(), Change.INITIAL_PATCH_SET_ID);
- final PatchSet ps = new PatchSet(id);
- ps.setCreatedOn(change.getCreatedOn());
- ps.setUploader(change.getOwner());
- ps.setRevision(new RevId(revertCommit.name()));
+ ChangeInserter ins =
+ changeInserterFactory.create(refControl, change, revertCommit);
+ PatchSet ps = ins.getPatchSet();
CommitReceivedEvent commitReceivedEvent =
new CommitReceivedEvent(new ReceiveCommand(ObjectId.zeroId(),
@@ -271,11 +264,6 @@
throw new InvalidChangeOperationException(e.getMessage());
}
- PatchSetInfo info = patchSetInfoFactory.get(revertCommit, ps.getId());
- change.setCurrentPatchSet(info);
- ChangeUtil.updated(change);
-
-
final RefUpdate ru = git.updateRef(ps.getRefName());
ru.setExpectedOldObjectId(ObjectId.zeroId());
ru.setNewObjectId(revertCommit);
@@ -295,9 +283,7 @@
msgBuf.append("This patchset was reverted in change: " + change.getKey().get());
cmsg.setMessage(msgBuf.toString());
- LabelTypes labelTypes = refControl.getProjectControl().getLabelTypes();
- changeInserter.insertChange(db, change, cmsg, ps, revertCommit,
- labelTypes, info, Collections.<Account.Id> emptySet());
+ ins.setMessage(cmsg).insert();
final RevertedSender cm = revertedSenderFactory.create(change);
cm.setFrom(user.getAccountId());
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountManager.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountManager.java
index c21d375..10b34ac 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountManager.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountManager.java
@@ -435,42 +435,38 @@
* cannot be unlinked at this time.
*/
public AuthResult unlink(final Account.Id from, AuthRequest who)
- throws AccountException {
+ throws AccountException, OrmException {
+ final ReviewDb db = schema.open();
try {
- final ReviewDb db = schema.open();
- try {
- who = realm.unlink(db, from, who);
+ who = realm.unlink(db, from, who);
- final AccountExternalId.Key key = id(who);
- AccountExternalId extId = db.accountExternalIds().get(key);
- if (extId != null) {
- if (!extId.getAccountId().equals(from)) {
- throw new AccountException("Identity in use by another account");
+ final AccountExternalId.Key key = id(who);
+ AccountExternalId extId = db.accountExternalIds().get(key);
+ if (extId != null) {
+ if (!extId.getAccountId().equals(from)) {
+ throw new AccountException("Identity in use by another account");
+ }
+ db.accountExternalIds().delete(Collections.singleton(extId));
+
+ if (who.getEmailAddress() != null) {
+ final Account a = db.accounts().get(from);
+ if (a.getPreferredEmail() != null
+ && a.getPreferredEmail().equals(who.getEmailAddress())) {
+ a.setPreferredEmail(null);
+ db.accounts().update(Collections.singleton(a));
}
- db.accountExternalIds().delete(Collections.singleton(extId));
-
- if (who.getEmailAddress() != null) {
- final Account a = db.accounts().get(from);
- if (a.getPreferredEmail() != null
- && a.getPreferredEmail().equals(who.getEmailAddress())) {
- a.setPreferredEmail(null);
- db.accounts().update(Collections.singleton(a));
- }
- byEmailCache.evict(who.getEmailAddress());
- byIdCache.evict(from);
- }
-
- } else {
- throw new AccountException("Identity not found");
+ byEmailCache.evict(who.getEmailAddress());
+ byIdCache.evict(from);
}
- return new AuthResult(from, key, false);
-
- } finally {
- db.close();
+ } else {
+ throw new AccountException("Identity not found");
}
- } catch (OrmException e) {
- throw new AccountException("Cannot unlink identity", e);
+
+ return new AuthResult(from, key, false);
+
+ } finally {
+ db.close();
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteActive.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteActive.java
new file mode 100644
index 0000000..8342d77
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteActive.java
@@ -0,0 +1,60 @@
+// 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.server.account;
+
+import com.google.gerrit.common.data.GlobalCapability;
+import com.google.gerrit.extensions.annotations.RequiresCapability;
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
+import com.google.gerrit.extensions.restapi.Response;
+import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.account.DeleteActive.Input;
+import com.google.gwtorm.server.OrmException;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+import java.util.Collections;
+
+@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
+public class DeleteActive implements RestModifyView<AccountResource, Input> {
+ static class Input {
+ }
+
+ private final Provider<ReviewDb> dbProvider;
+ private final AccountCache byIdCache;
+
+ @Inject
+ DeleteActive(Provider<ReviewDb> dbProvider, AccountCache byIdCache) {
+ this.dbProvider = dbProvider;
+ this.byIdCache = byIdCache;
+ }
+
+ @Override
+ public Object apply(AccountResource rsrc, Input input)
+ throws ResourceNotFoundException, OrmException {
+ Account a = dbProvider.get().accounts().get(rsrc.getUser().getAccountId());
+ if (a == null) {
+ throw new ResourceNotFoundException("account not found");
+ }
+ if (!a.isActive()) {
+ throw new ResourceNotFoundException();
+ }
+ a.setActive(false);
+ dbProvider.get().accounts().update(Collections.singleton(a));
+ byIdCache.evict(a.getId());
+ return Response.none();
+ }
+}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteEmail.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteEmail.java
new file mode 100644
index 0000000..67bb968
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteEmail.java
@@ -0,0 +1,75 @@
+// 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.server.account;
+
+import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
+import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
+import com.google.gerrit.extensions.restapi.Response;
+import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.reviewdb.client.Account.FieldName;
+import com.google.gerrit.reviewdb.client.AccountExternalId;
+import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.account.DeleteEmail.Input;
+import com.google.gwtorm.server.OrmException;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+public class DeleteEmail implements RestModifyView<AccountResource.Email, Input> {
+ static class Input {
+ }
+
+ private final Provider<CurrentUser> self;
+ private final Realm realm;
+ private final Provider<ReviewDb> dbProvider;
+ private final AccountManager accountManager;
+
+ @Inject
+ DeleteEmail(Provider<CurrentUser> self, Realm realm,
+ Provider<ReviewDb> dbProvider, AccountManager accountManager) {
+ this.self = self;
+ this.realm = realm;
+ this.dbProvider = dbProvider;
+ this.accountManager = accountManager;
+ }
+
+ @Override
+ public Object apply(AccountResource.Email rsrc, Input input)
+ throws AuthException, ResourceNotFoundException,
+ ResourceConflictException, MethodNotAllowedException, OrmException {
+ if (self.get() != rsrc.getUser()
+ && !self.get().getCapabilities().canAdministrateServer()) {
+ throw new AuthException("not allowed to delete email address");
+ }
+ if (!realm.allowsEdit(FieldName.REGISTER_NEW_EMAIL)) {
+ throw new MethodNotAllowedException("realm does not allow deleting emails");
+ }
+ AccountExternalId.Key key = new AccountExternalId.Key(
+ AccountExternalId.SCHEME_MAILTO, rsrc.getEmail());
+ AccountExternalId extId = dbProvider.get().accountExternalIds().get(key);
+ if (extId == null) {
+ throw new ResourceNotFoundException(rsrc.getEmail());
+ }
+ try {
+ accountManager.unlink(rsrc.getUser().getAccountId(),
+ AuthRequest.forEmail(rsrc.getEmail()));
+ } catch (AccountException e) {
+ throw new ResourceConflictException(e.getMessage());
+ }
+ return Response.none();
+ }
+}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/GetActive.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/GetActive.java
new file mode 100644
index 0000000..76c7ddb
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/GetActive.java
@@ -0,0 +1,29 @@
+// 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.server.account;
+
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
+import com.google.gerrit.extensions.restapi.Response;
+import com.google.gerrit.extensions.restapi.RestReadView;
+
+public class GetActive implements RestReadView<AccountResource> {
+ @Override
+ public Object apply(AccountResource rsrc) throws ResourceNotFoundException {
+ if (rsrc.getUser().getAccount().isActive()) {
+ return Response.ok("");
+ }
+ throw new ResourceNotFoundException();
+ }
+}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/Module.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/Module.java
index 860a96e..335ac79 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/Module.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/Module.java
@@ -37,9 +37,13 @@
get(ACCOUNT_KIND, "name").to(GetName.class);
put(ACCOUNT_KIND, "name").to(PutName.class);
delete(ACCOUNT_KIND, "name").to(PutName.class);
+ get(ACCOUNT_KIND, "active").to(GetActive.class);
+ put(ACCOUNT_KIND, "active").to(PutActive.class);
+ delete(ACCOUNT_KIND, "active").to(DeleteActive.class);
child(ACCOUNT_KIND, "emails").to(Emails.class);
get(EMAIL_KIND).to(GetEmail.class);
put(EMAIL_KIND).to(PutEmail.class);
+ delete(EMAIL_KIND).to(DeleteEmail.class);
put(EMAIL_KIND, "preferred").to(PutPreferred.class);
get(ACCOUNT_KIND, "avatar").to(GetAvatar.class);
get(ACCOUNT_KIND, "avatar.change.url").to(GetAvatarChangeUrl.class);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutActive.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutActive.java
new file mode 100644
index 0000000..18a1329
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutActive.java
@@ -0,0 +1,60 @@
+// 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.server.account;
+
+import com.google.gerrit.common.data.GlobalCapability;
+import com.google.gerrit.extensions.annotations.RequiresCapability;
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
+import com.google.gerrit.extensions.restapi.Response;
+import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.account.PutActive.Input;
+import com.google.gwtorm.server.OrmException;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+import java.util.Collections;
+
+@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
+public class PutActive implements RestModifyView<AccountResource, Input> {
+ static class Input {
+ }
+
+ private final Provider<ReviewDb> dbProvider;
+ private final AccountCache byIdCache;
+
+ @Inject
+ PutActive(Provider<ReviewDb> dbProvider, AccountCache byIdCache) {
+ this.dbProvider = dbProvider;
+ this.byIdCache = byIdCache;
+ }
+
+ @Override
+ public Object apply(AccountResource rsrc, Input input)
+ throws ResourceNotFoundException, OrmException {
+ Account a = dbProvider.get().accounts().get(rsrc.getUser().getAccountId());
+ if (a == null) {
+ throw new ResourceNotFoundException("account not found");
+ }
+ if (a.isActive()) {
+ return Response.ok("");
+ }
+ a.setActive(true);
+ dbProvider.get().accounts().update(Collections.singleton(a));
+ byIdCache.evict(a.getId());
+ return Response.created("");
+ }
+}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeInserter.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeInserter.java
index afe3f74..8a169b8 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeInserter.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeInserter.java
@@ -14,6 +14,8 @@
package com.google.gerrit.server.change;
+import static com.google.gerrit.reviewdb.client.Change.INITIAL_PATCH_SET_ID;
+
import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.reviewdb.client.Account;
@@ -21,13 +23,18 @@
import com.google.gerrit.reviewdb.client.ChangeMessage;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
+import com.google.gerrit.reviewdb.client.RevId;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.config.TrackingFooters;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
+import com.google.gerrit.server.patch.PatchSetInfoFactory;
+import com.google.gerrit.server.project.RefControl;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.assistedinject.Assisted;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
@@ -36,40 +43,95 @@
import java.util.Set;
public class ChangeInserter {
+ public static interface Factory {
+ ChangeInserter create(RefControl ctl, Change c, RevCommit rc);
+ }
+
+ private final Provider<ReviewDb> dbProvider;
private final GitReferenceUpdated gitRefUpdated;
private final ChangeHooks hooks;
private final ApprovalsUtil approvalsUtil;
private final TrackingFooters trackingFooters;
+ private final RefControl refControl;
+ private final Change change;
+ private final PatchSet patchSet;
+ private final RevCommit commit;
+ private final PatchSetInfo patchSetInfo;
+
+ private ChangeMessage changeMessage;
+ private Set<Account.Id> reviewers;
+ private boolean draft;
+
@Inject
- public ChangeInserter(final GitReferenceUpdated gitRefUpdated,
- ChangeHooks hooks, ApprovalsUtil approvalsUtil,
- TrackingFooters trackingFooters) {
+ ChangeInserter(Provider<ReviewDb> dbProvider,
+ PatchSetInfoFactory patchSetInfoFactory,
+ GitReferenceUpdated gitRefUpdated,
+ ChangeHooks hooks,
+ ApprovalsUtil approvalsUtil,
+ TrackingFooters trackingFooters,
+ @Assisted RefControl refControl,
+ @Assisted Change change,
+ @Assisted RevCommit commit) {
+ this.dbProvider = dbProvider;
this.gitRefUpdated = gitRefUpdated;
this.hooks = hooks;
this.approvalsUtil = approvalsUtil;
this.trackingFooters = trackingFooters;
+ this.refControl = refControl;
+ this.change = change;
+ this.commit = commit;
+
+ this.reviewers = Collections.emptySet();
+
+ patchSet =
+ new PatchSet(new PatchSet.Id(change.getId(), INITIAL_PATCH_SET_ID));
+ patchSet.setCreatedOn(change.getCreatedOn());
+ patchSet.setUploader(change.getOwner());
+ patchSet.setRevision(new RevId(commit.name()));
+ if (draft) {
+ change.setStatus(Change.Status.DRAFT);
+ patchSet.setDraft(true);
+ }
+ patchSetInfo = patchSetInfoFactory.get(commit, patchSet.getId());
+ change.setCurrentPatchSet(patchSetInfo);
+ ChangeUtil.computeSortKey(change);
}
- public void insertChange(ReviewDb db, Change change, PatchSet ps,
- RevCommit commit, LabelTypes labelTypes, PatchSetInfo info,
- Set<Account.Id> reviewers) throws OrmException {
- insertChange(db, change, null, ps, commit, labelTypes, info, reviewers);
+ public ChangeInserter setMessage(ChangeMessage changeMessage) {
+ this.changeMessage = changeMessage;
+ return this;
}
- public void insertChange(ReviewDb db, Change change,
- ChangeMessage changeMessage, PatchSet ps, RevCommit commit,
- LabelTypes labelTypes, PatchSetInfo info, Set<Account.Id> reviewers)
- throws OrmException {
+ public ChangeInserter setReviewers(Set<Account.Id> reviewers) {
+ this.reviewers = reviewers;
+ return this;
+ }
+ public ChangeInserter setDraft(boolean draft) {
+ this.draft = draft;
+ return this;
+ }
+
+ public PatchSet getPatchSet() {
+ return patchSet;
+ }
+
+ public PatchSetInfo getPatchSetInfo() {
+ return patchSetInfo;
+ }
+
+ public void insert() throws OrmException {
+ ReviewDb db = dbProvider.get();
db.changes().beginTransaction(change.getId());
try {
- ChangeUtil.insertAncestors(db, ps.getId(), commit);
- db.patchSets().insert(Collections.singleton(ps));
+ ChangeUtil.insertAncestors(db, patchSet.getId(), commit);
+ db.patchSets().insert(Collections.singleton(patchSet));
db.changes().insert(Collections.singleton(change));
ChangeUtil.updateTrackingIds(db, change, trackingFooters, commit.getFooterLines());
- approvalsUtil.addReviewers(db, labelTypes, change, ps, info, reviewers,
- Collections.<Account.Id> emptySet());
+ LabelTypes labelTypes = refControl.getProjectControl().getLabelTypes();
+ approvalsUtil.addReviewers(db, labelTypes, change, patchSet, patchSetInfo,
+ reviewers, Collections.<Account.Id> emptySet());
db.commit();
} finally {
db.rollback();
@@ -78,8 +140,8 @@
db.changeMessages().insert(Collections.singleton(changeMessage));
}
- gitRefUpdated.fire(change.getProject(), ps.getRefName(), ObjectId.zeroId(),
- commit);
- hooks.doPatchsetCreatedHook(change, ps, db);
+ gitRefUpdated.fire(change.getProject(), patchSet.getRefName(),
+ ObjectId.zeroId(), commit);
+ hooks.doPatchsetCreatedHook(change, patchSet, db);
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/CherryPickChange.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/CherryPickChange.java
index 3c5e83d..945118c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/CherryPickChange.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/CherryPickChange.java
@@ -14,16 +14,12 @@
package com.google.gerrit.server.change;
-import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.common.errors.EmailException;
-import com.google.gerrit.reviewdb.client.Account;
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.PatchSetInfo;
import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.client.RevId;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.GerritPersonIdent;
@@ -59,8 +55,6 @@
import org.eclipse.jgit.util.ChangeIdUtil;
import java.io.IOException;
-import java.sql.Timestamp;
-import java.util.Collections;
import java.util.List;
public class CherryPickChange {
@@ -73,7 +67,7 @@
private final PersonIdent myIdent;
private final IdentifiedUser currentUser;
private final CommitValidators.Factory commitValidatorsFactory;
- private final ChangeInserter changeInserter;
+ private final ChangeInserter.Factory changeInserterFactory;
private final PatchSetInserter.Factory patchSetInserterFactory;
final MergeUtil.Factory mergeUtilFactory;
@@ -82,7 +76,7 @@
final ReviewDb db, @GerritPersonIdent final PersonIdent myIdent,
final GitRepositoryManager gitManager, final IdentifiedUser currentUser,
final CommitValidators.Factory commitValidatorsFactory,
- final ChangeInserter changeInserter,
+ final ChangeInserter.Factory changeInserterFactory,
final PatchSetInserter.Factory patchSetInserterFactory,
final MergeUtil.Factory mergeUtilFactory) {
this.patchSetInfoFactory = patchSetInfoFactory;
@@ -91,7 +85,7 @@
this.myIdent = myIdent;
this.currentUser = currentUser;
this.commitValidatorsFactory = commitValidatorsFactory;
- this.changeInserter = changeInserter;
+ this.changeInserterFactory = changeInserterFactory;
this.patchSetInserterFactory = patchSetInserterFactory;
this.mergeUtilFactory = mergeUtilFactory;
}
@@ -217,11 +211,9 @@
new Change(changeKey, new Change.Id(db.nextChangeId()),
currentUser.getAccountId(), new Branch.NameKey(project,
destRef.getName()));
- PatchSet.Id id = new PatchSet.Id(change.getId(), Change.INITIAL_PATCH_SET_ID);
- PatchSet newPatchSet = new PatchSet(id);
- newPatchSet.setCreatedOn(new Timestamp(System.currentTimeMillis()));
- newPatchSet.setUploader(change.getOwner());
- newPatchSet.setRevision(new RevId(cherryPickCommit.name()));
+ ChangeInserter ins =
+ changeInserterFactory.create(refControl, change, cherryPickCommit);
+ PatchSet newPatchSet = ins.getPatchSet();
CommitValidators commitValidators =
commitValidatorsFactory.create(refControl, new NoSshInfo(), git);
@@ -247,18 +239,7 @@
change.getDest().getParentKey().get(), ru.getResult()));
}
- LabelTypes labelTypes =
- refControl.getProjectControl().getLabelTypes();
-
- PatchSetInfo newPatchSetInfo =
- patchSetInfoFactory.get(cherryPickCommit, newPatchSet.getId());
- change.setCurrentPatchSet(newPatchSetInfo);
- ChangeUtil.updated(change);
-
- changeInserter.insertChange(db, change,
- buildChangeMessage(patchSetId, change), newPatchSet,
- cherryPickCommit, labelTypes, newPatchSetInfo,
- Collections.<Account.Id> emptySet());
+ ins.setMessage(buildChangeMessage(patchSetId, change)).insert();
return change.getId();
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java
index 146e58c..72c07b6 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java
@@ -93,6 +93,7 @@
factory(ReviewerResource.Factory.class);
factory(AccountInfo.Loader.Factory.class);
factory(EmailReviewComments.Factory.class);
+ factory(ChangeInserter.Factory.class);
factory(PatchSetInserter.Factory.class);
}
});
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Revert.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Revert.java
index 154bd64..a2f0a9b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Revert.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Revert.java
@@ -49,7 +49,7 @@
private final GitRepositoryManager gitManager;
private final PersonIdent myIdent;
private final PatchSetInfoFactory patchSetInfoFactory;
- private final ChangeInserter changeInserter;
+ private final ChangeInserter.Factory changeInserterFactory;
public static class Input {
public String message;
@@ -64,7 +64,7 @@
GitRepositoryManager gitManager,
final PatchSetInfoFactory patchSetInfoFactory,
@GerritPersonIdent final PersonIdent myIdent,
- final ChangeInserter changeInserter) {
+ final ChangeInserter.Factory changeInserterFactory) {
this.hooks = hooks;
this.revertedSenderFactory = revertedSenderFactory;
this.commitValidatorsFactory = commitValidatorsFactory;
@@ -72,7 +72,7 @@
this.json = json;
this.gitManager = gitManager;
this.myIdent = myIdent;
- this.changeInserter = changeInserter;
+ this.changeInserterFactory = changeInserterFactory;
this.patchSetInfoFactory = patchSetInfoFactory;
}
@@ -97,7 +97,7 @@
commitValidators,
Strings.emptyToNull(input.message), dbProvider.get(),
revertedSenderFactory, hooks, git, patchSetInfoFactory,
- myIdent, changeInserter);
+ myIdent, changeInserterFactory);
return json.format(revertedChangeId);
} catch (InvalidChangeOperationException e) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java
index 2b8521b..9370a89 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java
@@ -65,7 +65,6 @@
import com.google.gerrit.server.auth.ldap.LdapModule;
import com.google.gerrit.server.avatar.AvatarProvider;
import com.google.gerrit.server.cache.CacheRemovalListener;
-import com.google.gerrit.server.change.ChangeInserter;
import com.google.gerrit.server.events.EventFactory;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.ChangeCache;
@@ -222,7 +221,6 @@
bind(TransferConfig.class);
bind(ApprovalsUtil.class);
- bind(ChangeInserter.class);
bind(ChangeMergeQueue.class).in(SINGLETON);
bind(MergeQueue.class).to(ChangeMergeQueue.class).in(SINGLETON);
factory(ReloadSubmitQueueOp.Factory.class);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
index 2177954..482a211 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
@@ -14,10 +14,10 @@
package com.google.gerrit.server.git;
-import static com.google.gerrit.reviewdb.client.Change.INITIAL_PATCH_SET_ID;
import static com.google.gerrit.server.git.MultiProgressMonitor.UNKNOWN;
import static com.google.gerrit.server.mail.MailUtil.getRecipientsFromApprovals;
import static com.google.gerrit.server.mail.MailUtil.getRecipientsFromFooters;
+
import static org.eclipse.jgit.lib.Constants.R_HEADS;
import static org.eclipse.jgit.transport.ReceiveCommand.Result.NOT_ATTEMPTED;
import static org.eclipse.jgit.transport.ReceiveCommand.Result.OK;
@@ -259,7 +259,7 @@
private final CommitValidators.Factory commitValidatorsFactory;
private final TrackingFooters trackingFooters;
private final TagCache tagCache;
- private final ChangeInserter changeInserter;
+ private final ChangeInserter.Factory changeInserterFactory;
private final WorkQueue workQueue;
private final ListeningExecutorService changeUpdateExector;
private final RequestScopePropagator requestScopePropagator;
@@ -315,7 +315,7 @@
final GitRepositoryManager repoManager,
final TagCache tagCache,
final ChangeCache changeCache,
- final ChangeInserter changeInserter,
+ final ChangeInserter.Factory changeInserterFactory,
final CommitValidators.Factory commitValidatorsFactory,
@CanonicalWebUrl @Nullable final String canonicalWebUrl,
@GerritPersonIdent final PersonIdent gerritIdent,
@@ -348,7 +348,7 @@
this.canonicalWebUrl = canonicalWebUrl;
this.trackingFooters = trackingFooters;
this.tagCache = tagCache;
- this.changeInserter = changeInserter;
+ this.changeInserterFactory = changeInserterFactory;
this.commitValidatorsFactory = commitValidatorsFactory;
this.workQueue = workQueue;
this.changeUpdateExector = changeUpdateExector;
@@ -1342,7 +1342,7 @@
Change.Key changeKey = new Change.Key("I" + c.name());
final List<String> idList = c.getFooterLines(CHANGE_ID);
if (idList.isEmpty()) {
- newChanges.add(new CreateRequest(c, changeKey));
+ newChanges.add(new CreateRequest(magicBranch.ctl, c, changeKey));
continue;
}
@@ -1392,7 +1392,7 @@
newChangeIds.add(p.changeKey);
}
- newChanges.add(new CreateRequest(p.commit, p.changeKey));
+ newChanges.add(new CreateRequest(magicBranch.ctl, p.commit, p.changeKey));
}
} catch (IOException e) {
// Should never happen, the core receive process would have
@@ -1458,34 +1458,21 @@
private class CreateRequest {
final RevCommit commit;
final Change change;
- final PatchSet ps;
final ReceiveCommand cmd;
- private final PatchSetInfo info;
+ final ChangeInserter ins;
boolean created;
- CreateRequest(RevCommit c, Change.Key changeKey) throws OrmException {
+ CreateRequest(RefControl ctl, RevCommit c, Change.Key changeKey)
+ throws OrmException {
commit = c;
-
change = new Change(changeKey,
new Change.Id(db.nextChangeId()),
currentUser.getAccountId(),
magicBranch.dest);
change.setTopic(magicBranch.topic);
-
- ps = new PatchSet(new PatchSet.Id(change.getId(), INITIAL_PATCH_SET_ID));
- ps.setCreatedOn(change.getCreatedOn());
- ps.setUploader(change.getOwner());
- ps.setRevision(toRevId(c));
-
- if (magicBranch.isDraft()) {
- change.setStatus(Change.Status.DRAFT);
- ps.setDraft(true);
- }
-
- info = patchSetInfoFactory.get(c, ps.getId());
- change.setCurrentPatchSet(info);
- ChangeUtil.updated(change);
- cmd = new ReceiveCommand(ObjectId.zeroId(), c, ps.getRefName());
+ ins = changeInserterFactory.create(ctl, change, c);
+ cmd = new ReceiveCommand(ObjectId.zeroId(), c,
+ ins.getPatchSet().getRefName());
}
CheckedFuture<Void, OrmException> insertChange() throws IOException {
@@ -1516,6 +1503,7 @@
}
private void insertChange(ReviewDb db) throws OrmException {
+ final PatchSet ps = ins.getPatchSet();
final Account.Id me = currentUser.getAccountId();
final List<FooterLine> footerLines = commit.getFooterLines();
final MailRecipients recipients = new MailRecipients();
@@ -1525,9 +1513,7 @@
recipients.add(getRecipientsFromFooters(accountResolver, ps, footerLines));
recipients.remove(me);
- changeInserter.insertChange(db, change, ps, commit, labelTypes, info,
- recipients.getReviewers());
-
+ ins.setReviewers(recipients.getReviewers()).insert();
created = true;
workQueue.getDefaultQueue()
@@ -1538,7 +1524,7 @@
CreateChangeSender cm =
createChangeSenderFactory.create(change);
cm.setFrom(me);
- cm.setPatchSet(ps, info);
+ cm.setPatchSet(ps, ins.getPatchSetInfo());
cm.addReviewers(recipients.getReviewers());
cm.addExtraCC(recipients.getCcOnly());
cm.send();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/CommentSender.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/CommentSender.java
index b16ab2a..716a22b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/CommentSender.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/CommentSender.java
@@ -14,6 +14,7 @@
package com.google.gerrit.server.mail;
+import com.google.common.collect.Ordering;
import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.reviewdb.client.AccountProjectWatch.NotifyType;
import com.google.gerrit.reviewdb.client.Change;
@@ -29,7 +30,6 @@
import org.eclipse.jgit.lib.Repository;
import java.io.IOException;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -62,9 +62,7 @@
paths.add(p.getFileName());
}
}
- String[] names = paths.toArray(new String[paths.size()]);
- Arrays.sort(names);
- changeData.setCurrentFilePaths(names);
+ changeData.setCurrentFilePaths(Ordering.natural().sortedCopy(paths));
}
@Override
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeData.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeData.java
index bf3b605..d1fe4ec 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeData.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeData.java
@@ -51,7 +51,6 @@
import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -141,7 +140,7 @@
private ListMultimap<PatchSet.Id, PatchSetApproval> limitedApprovals;
private ListMultimap<PatchSet.Id, PatchSetApproval> allApprovals;
private List<PatchSetApproval> currentApprovals;
- private String[] currentFiles;
+ private List<String> currentFiles;
private Collection<PatchLineComment> comments;
private Collection<TrackingId> trackingIds;
private CurrentUser visibleTo;
@@ -180,11 +179,11 @@
return limitedIds;
}
- public void setCurrentFilePaths(String[] filePaths) {
+ public void setCurrentFilePaths(List<String> filePaths) {
currentFiles = filePaths;
}
- public String[] currentFilePaths(Provider<ReviewDb> db,
+ public List<String> currentFilePaths(Provider<ReviewDb> db,
PatchListCache cache) throws OrmException {
if (currentFiles == null) {
Change c = change(db);
@@ -200,7 +199,7 @@
try {
p = cache.get(c, ps);
} catch (PatchListNotAvailableException e) {
- currentFiles = new String[0];
+ currentFiles = Collections.emptyList();
return currentFiles;
}
@@ -226,8 +225,8 @@
break;
}
}
- currentFiles = r.toArray(new String[r.size()]);
- Arrays.sort(currentFiles);
+ Collections.sort(r);
+ currentFiles = Collections.unmodifiableList(r);
}
return currentFiles;
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeStatusPredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeStatusPredicate.java
index 6e9e79c..cb64801 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeStatusPredicate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeStatusPredicate.java
@@ -14,6 +14,9 @@
package com.google.gerrit.server.query.change;
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.common.collect.ImmutableBiMap;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.query.OperatorPredicate;
@@ -22,11 +25,7 @@
import com.google.inject.Provider;
import java.util.ArrayList;
-import java.util.EnumMap;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-
/**
* Predicate for a {@link Change.Status}.
@@ -36,17 +35,15 @@
* searching for changes. Either operator name has the same meaning.
*/
final class ChangeStatusPredicate extends OperatorPredicate<ChangeData> {
- private static final Map<String, Change.Status> byName;
- private static final EnumMap<Change.Status, String> byEnum;
+ private static final ImmutableBiMap<Change.Status, String> VALUES;
static {
- byName = new HashMap<String, Change.Status>();
- byEnum = new EnumMap<Change.Status, String>(Change.Status.class);
- for (final Change.Status s : Change.Status.values()) {
- final String name = s.name().toLowerCase();
- byName.put(name, s);
- byEnum.put(s, name);
+ ImmutableBiMap.Builder<Change.Status, String> values =
+ ImmutableBiMap.builder();
+ for (Change.Status s : Change.Status.values()) {
+ values.put(s, s.name().toLowerCase());
}
+ VALUES = values.build();
}
static Predicate<ChangeData> open(Provider<ReviewDb> dbProvider) {
@@ -69,23 +66,18 @@
return r.size() == 1 ? r.get(0) : or(r);
}
- private static Change.Status parse(final String value) {
- final Change.Status s = byName.get(value);
- if (s == null) {
- throw new IllegalArgumentException();
- }
- return s;
- }
-
private final Provider<ReviewDb> dbProvider;
private final Change.Status status;
ChangeStatusPredicate(Provider<ReviewDb> dbProvider, String value) {
- this(dbProvider, parse(value));
+ super(ChangeQueryBuilder.FIELD_STATUS, value);
+ this.dbProvider = dbProvider;
+ status = VALUES.inverse().get(value);
+ checkArgument(status != null, "invalid change status: %s", value);
}
ChangeStatusPredicate(Provider<ReviewDb> dbProvider, Change.Status status) {
- super(ChangeQueryBuilder.FIELD_STATUS, byEnum.get(status));
+ super(ChangeQueryBuilder.FIELD_STATUS, VALUES.get(status));
this.dbProvider = dbProvider;
this.status = status;
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/RegexFilePredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/RegexFilePredicate.java
index 11856e4..e642860 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/RegexFilePredicate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/RegexFilePredicate.java
@@ -24,7 +24,8 @@
import dk.brics.automaton.RegExp;
import dk.brics.automaton.RunAutomaton;
-import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
class RegexFilePredicate extends OperatorPredicate<ChangeData> {
private final Provider<ReviewDb> db;
@@ -67,7 +68,7 @@
@Override
public boolean match(ChangeData object) throws OrmException {
- String[] files = object.currentFilePaths(db, cache);
+ List<String> files = object.currentFilePaths(db, cache);
if (files != null) {
int begin, end;
@@ -76,7 +77,7 @@
end = find(files, prefixEnd);
} else {
begin = 0;
- end = files.length;
+ end = files.size();
}
if (prefixOnly) {
@@ -84,7 +85,7 @@
}
while (begin < end) {
- if (pattern.run(files[begin++])) {
+ if (pattern.run(files.get(begin++))) {
return true;
}
}
@@ -100,8 +101,8 @@
}
}
- private static int find(String[] files, String p) {
- int r = Arrays.binarySearch(files, p);
+ private static int find(List<String> files, String p) {
+ int r = Collections.binarySearch(files, p);
return r < 0 ? -(r + 1) : r;
}
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/query/change/RegexFilePredicateTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/query/change/RegexFilePredicateTest.java
index ce7b25c..1500272 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/query/change/RegexFilePredicateTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/query/change/RegexFilePredicateTest.java
@@ -76,7 +76,7 @@
private static ChangeData change(String... files) {
Arrays.sort(files);
ChangeData cd = new ChangeData(new Change.Id(1));
- cd.setCurrentFilePaths(files);
+ cd.setCurrentFilePaths(Arrays.asList(files));
return cd;
}
}
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetAccountCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetAccountCommand.java
index 4c23833..8d24757 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetAccountCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetAccountCommand.java
@@ -260,6 +260,8 @@
manager.unlink(id, AuthRequest.forEmail(mailAddress));
} catch (AccountException ex) {
throw die(ex.getMessage());
+ } catch (OrmException ex) {
+ throw die(ex.getMessage());
}
}
diff --git a/lib/codemirror/BUCK b/lib/codemirror/BUCK
index 5c64335..cd2804b 100644
--- a/lib/codemirror/BUCK
+++ b/lib/codemirror/BUCK
@@ -2,10 +2,17 @@
SHA1 = '7a83ae686d75afd30bb152d7683f2dc27e59ea82'
URL = 'http://codemirror.net/codemirror-%s.zip' % VERSION
+prebuilt_jar(
+ name = 'codemirror',
+ binary_jar = genfile('codemirror.jar'),
+ deps = [':codemirror__jar'],
+ visibility = ['PUBLIC'],
+)
+
# TODO(sop) Repackage by license boundaries.
# TODO(sop) Minify with Closure JS compiler.
genrule(
- name = 'codemirror',
+ name = 'codemirror__jar',
cmd = ';'.join([
'cd $TMP',
'mkdir net META-INF',
@@ -20,7 +27,6 @@
'//lib:LICENSE-codemirror',
],
out = 'codemirror.jar',
- visibility = ['PUBLIC'],
)
genrule(
diff --git a/plugins/helloworld b/plugins/helloworld
new file mode 160000
index 0000000..d3c7dcc
--- /dev/null
+++ b/plugins/helloworld
@@ -0,0 +1 @@
+Subproject commit d3c7dccd0824d1500976a0cd9077c1b878564bba