aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn O. Pearce <sop@google.com>2010-08-12 16:42:02 -0700
committerShawn O. Pearce <sop@google.com>2010-08-12 16:42:02 -0700
commit78a63ddfea66014cea68a4f7541a0770e358cf68 (patch)
tree39dc954c22a4b2657552a1d41462f4919b777c66
parentdfd895e35147953d362b29b78123f8558e57d684 (diff)
parentf855f399f8ce740e08ddc48c0694c1c076fa69dd (diff)
downloadgerrit-exp-nosql.tar.gz
Merge branch 'master' into exp-nosqlexp-nosql
* master: Fix all of our pom.xml versions to be 2.1-SNAPSHOT Use internal templates to simplify minor formatting commands. Convert 3 email classes to file based templates. Convert the Abandoned and MergeFail email classes to templates Use a template to set the contents of the CommentEmails. Use a template to set the footer on ChangeEmails. Use a template to set the contents of the MergedEmails. Use a template to set the subject line. Add framework for using velocity templates in email classes Add ability to deactivate a user when they leave the project. Conflicts: gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectDigestFilter.java gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/SuggestServiceImpl.java gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java gerrit-server/src/main/java/com/google/gerrit/server/mail/ChangeEmail.java gerrit-server/src/main/java/com/google/gerrit/server/mail/OutgoingEmail.java gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java Change-Id: Iac92b56e10f9cc4063fc0ec3cea6c79a5a087994
-rw-r--r--Documentation/config-mail.txt172
-rw-r--r--Documentation/index.txt1
-rw-r--r--Documentation/licenses.txt1
-rw-r--r--gerrit-common/pom.xml2
-rw-r--r--gerrit-common/src/main/java/com/google/gerrit/common/data/ReviewerResult.java3
-rw-r--r--gerrit-common/src/main/java/com/google/gerrit/common/data/SuggestService.java2
-rw-r--r--gerrit-common/src/main/java/com/google/gerrit/common/errors/InactiveAccountException.java26
-rw-r--r--gerrit-ehcache/pom.xml2
-rw-r--r--gerrit-gwtdebug/pom.xml2
-rw-r--r--gerrit-gwtui/pom.xml2
-rw-r--r--gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java2
-rw-r--r--gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties2
-rw-r--r--gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ApprovalTable.java4
-rw-r--r--gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.java1
-rw-r--r--gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.properties1
-rw-r--r--gerrit-gwtui/src/main/java/com/google/gerrit/client/rpc/GerritCallback.java9
-rw-r--r--gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/AccountSuggestOracle.java3
-rw-r--r--gerrit-httpd/pom.xml2
-rw-r--r--gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectDigestFilter.java5
-rw-r--r--gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/SuggestServiceImpl.java20
-rw-r--r--gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/account/GroupAdminServiceImpl.java4
-rw-r--r--gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/AddReviewer.java5
-rw-r--r--gerrit-launcher/pom.xml2
-rw-r--r--gerrit-main/pom.xml2
-rw-r--r--gerrit-patch-commonsnet/pom.xml2
-rw-r--r--gerrit-patch-jgit/pom.xml2
-rw-r--r--gerrit-pgm/pom.xml2
-rw-r--r--gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/SitePathInitializer.java19
-rw-r--r--gerrit-prettify/pom.xml2
-rw-r--r--gerrit-reviewdb/pom.xml2
-rw-r--r--gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/Account.java12
-rw-r--r--gerrit-server/pom.xml12
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/account/AccountManager.java13
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java40
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/config/SitePaths.java2
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/mail/AbandonedSender.java9
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/mail/AddReviewerSender.java2
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/mail/ChangeEmail.java136
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/mail/CommentSender.java40
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/mail/CreateChangeSender.java2
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/mail/EmailArguments.java6
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/mail/MergeFailSender.java15
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/mail/MergedSender.java86
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/mail/NewChangeSender.java74
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/mail/OutgoingEmail.java102
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/mail/RegisterNewEmailSender.java37
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/mail/ReplacePatchSetSender.java77
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/mail/ReplyToChangeSender.java2
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_103.java2
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_41.java25
-rw-r--r--gerrit-server/src/main/resources/com/google/gerrit/server/mail/Abandoned.vm40
-rw-r--r--gerrit-server/src/main/resources/com/google/gerrit/server/mail/ChangeFooter.vm49
-rw-r--r--gerrit-server/src/main/resources/com/google/gerrit/server/mail/ChangeSubject.vm37
-rw-r--r--gerrit-server/src/main/resources/com/google/gerrit/server/mail/Comment.vm47
-rw-r--r--gerrit-server/src/main/resources/com/google/gerrit/server/mail/MergeFail.vm41
-rw-r--r--gerrit-server/src/main/resources/com/google/gerrit/server/mail/Merged.vm38
-rw-r--r--gerrit-server/src/main/resources/com/google/gerrit/server/mail/NewChange.vm57
-rw-r--r--gerrit-server/src/main/resources/com/google/gerrit/server/mail/RegisterNewEmail.vm49
-rw-r--r--gerrit-server/src/main/resources/com/google/gerrit/server/mail/ReplacePatchSet.vm57
-rw-r--r--gerrit-sshd/pom.xml2
-rw-r--r--gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java5
-rw-r--r--gerrit-util-cli/pom.xml2
-rw-r--r--gerrit-util-ssl/pom.xml2
-rw-r--r--gerrit-war/pom.xml2
-rw-r--r--pom.xml8
65 files changed, 1035 insertions, 399 deletions
diff --git a/Documentation/config-mail.txt b/Documentation/config-mail.txt
new file mode 100644
index 00000000..168bbfe1
--- /dev/null
+++ b/Documentation/config-mail.txt
@@ -0,0 +1,172 @@
+Gerrit Code Review - Mail Templates
+===================================
+
+Gerrit uses velocity templates for the bulk of the standard mails it sends out.
+There are builtin default templates which are used if they are not overridden.
+These defaults are also provided as examples so that administrators may copy
+them and easily modify them to tweak their contents.
+
+
+Template Locations and Extensions:
+----------------------------------
+
+The default example templates reside under: `'$site_path'/etc/mail` and are
+terminated with the double extension `.vm.example`. Modifying these example
+files will have no effect on the behavior of Gerrit. However, copying an
+example template to an equivalently named file without the `.example` extension
+and modifying it will allow an administrator to customize the template.
+
+
+Supported Mail Templates:
+-------------------------
+
+Each mail that Gerrit sends out is controlled by at least one template, these
+are listed below. Change emails are influenced by two additional templates,
+one to set the subject line, and one to set the footer which gets appended to
+all the change emails (see `ChangeSubject.vm` and `ChangeFooter.vm` below.)
+
+Abandoned.vm
+~~~~~~~~~~~~
+
+The `Abandoned.vm` template will determine the contents of the email related
+to a change being abandoned. It is a `ChangeEmail`: see `ChangeSubject.vm` and
+`ChangeFooter.vm`.
+
+ChangeFooter.vm
+~~~~~~~~~~~~~~~
+
+The `ChangeFooter.vm` template will determine the contents of the footer
+text that will be appended to emails related to changes (all `ChangeEmails)`.
+
+ChangeSubject.vm
+~~~~~~~~~~~~~~~~
+
+The `ChangeSubject.vm` template will determine the contents of the email
+subject line for ALL emails related to changes.
+
+Comment.vm
+~~~~~~~~~~
+
+The `Comment.vm` template will determine the contents of the email related to
+a user submitting comments on changes. It is a `ChangeEmail`: see
+
+Merged.vm
+~~~~~~~~~
+
+The `Merged.vm` template will determine the contents of the email related to
+a change successfully merged to the head. It is a `ChangeEmail`: see
+`ChangeSubject.vm` and `ChangeFooter.vm`.
+
+MergeFail.vm
+~~~~~~~~~~~~
+
+The `MergeFail.vm` template will determine the contents of the email related
+to a failure upon attempting to merge a change to the head. It is a
+
+NewChange.vm
+~~~~~~~~~~~~
+
+The `NewChange.vm` template will determine the contents of the email related
+to a user submitting a new change for review. It is a `ChangeEmail`: see
+`ChangeSubject.vm` and `ChangeFooter.vm`.
+
+RegisterNewEmail.vm
+~~~~~~~~~~~~~~~~~~~
+
+The `RegisterNewEmail.vm` template will determine the contents of the email
+related to registering new email accounts.
+
+ReplacePatchSet.vm
+~~~~~~~~~~~~~~~~~~
+
+The `ReplacePatchSet.vm` template will determine the contents of the email
+related to a user submitting a new patchset for a change. It is a
+`ChangeEmail`: see `ChangeSubject.vm` and `ChangeFooter.vm`.
+
+
+Mail Variables and Methods
+--------------------------
+
+Mail templates can access and display objects currently made available to them
+via the velocity context. While the base objects are documented here, it is
+possible to call public methods on these objects from templates. Those methods
+are not documented here since they could change with every release. As these
+templates are meant to be modified only by a qualified sysadmin, it is accepted
+that writing templates for Gerrit emails is likely to require some basic
+knowledge of the class structure to be useful. Browsing the source code might
+be necessary for anything more than a minor formatting change.
+
+Warning
+~~~~~~~
+
+Be aware that modifying templates can cause them to fail to parse and therefor
+not send out the actual email, or worse, calling methods on the available
+objects could have internal side effects which would adversely affect the
+health of your Gerrit server and/or data.
+
+All OutgoingEmails
+~~~~~~~~~~~~~~~~~~
+
+All outgoing emails have the following variables available to them:
+
+$email::
++
+A reference to the class constructing the current `OutgoingEmail`. With this
+reference it is possible to call any public method on the OutgoingEmail class
+or the current child class inherited from it.
+
+$messageClass::
++
+A String containing the messageClass
+
+$StringUtils::
++
+A reference to the Apache `StringUtils` class. This can be very useful for
+formatting strings.
+
+Change Emails
+~~~~~~~~~~~~~
+
+All change related emails have the following additional variables available to them:
+
+$change::
++
+A reference to the current `Change` object
+
+$changeId::
++
+Id of the current change (a `Change.Key`)
+
+$coverLetter::
++
+The text of the `ChangeMessage`
+
+$branch::
++
+A reference to the branch of this change (a `Branch.NameKey`)
+
+$fromName::
++
+The name of the from user
+
+$projectName::
++
+The name of this change's project
+
+$patchSet::
++
+A reference to the current `PatchSet`
+
+$patchSetInfo::
++
+A reference to the current `PatchSetInfo`
+
+
+See Also
+--------
+
+* link:http://velocity.apache.org/[velocity]
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/index.txt b/Documentation/index.txt
index 1e13e8d8..e4194552 100644
--- a/Documentation/index.txt
+++ b/Documentation/index.txt
@@ -31,6 +31,7 @@ Configuration
* link:config-sso.html[Single Sign-On Systems]
* link:config-apache2.html[Apache 2 Reverse Proxy]
* link:config-hooks.html[Hooks]
+* link:config-mail.html[Mail Templates]
Developer Documentation
-----------------------
diff --git a/Documentation/licenses.txt b/Documentation/licenses.txt
index 6e76303f..6d543d5a 100644
--- a/Documentation/licenses.txt
+++ b/Documentation/licenses.txt
@@ -31,6 +31,7 @@ Apache Log4J <<apache2,Apache License 2.0>>
Apache MINA <<apache2,Apache License 2.0>>
Apache Tomact Servlet API <<apache2,Apache License 2.0>>
Apache SSHD <<apache2,Apache License 2.0>>, see also <<sshd,NOTICE>>
+Apache Velocity <<apache2,Apache License 2.0>>
Apache Xerces <<apache2,Apache License 2.0>>
OpenID4Java <<apache2,Apache License 2.0>>
Neko HTML <<apache2,Apache License 2.0>>
diff --git a/gerrit-common/pom.xml b/gerrit-common/pom.xml
index adac3a80..af031913 100644
--- a/gerrit-common/pom.xml
+++ b/gerrit-common/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
</parent>
<artifactId>gerrit-common</artifactId>
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ReviewerResult.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ReviewerResult.java
index 19772fcf..678ec79a 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ReviewerResult.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ReviewerResult.java
@@ -50,6 +50,9 @@ public class ReviewerResult {
/** Name supplied does not match to a registered account. */
ACCOUNT_NOT_FOUND,
+ /** The account is inactive. */
+ ACCOUNT_INACTIVE,
+
/** The account is not permitted to see the change. */
CHANGE_NOT_VISIBLE,
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/SuggestService.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/SuggestService.java
index 164df439..9dae1698 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/SuggestService.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/SuggestService.java
@@ -28,7 +28,7 @@ public interface SuggestService extends RemoteJsonService {
void suggestProjectNameKey(String query, int limit,
AsyncCallback<List<Project.NameKey>> callback);
- void suggestAccount(String query, int limit,
+ void suggestAccount(String query, Boolean enabled, int limit,
AsyncCallback<List<AccountInfo>> callback);
void suggestAccountGroup(String query, int limit,
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/errors/InactiveAccountException.java b/gerrit-common/src/main/java/com/google/gerrit/common/errors/InactiveAccountException.java
new file mode 100644
index 00000000..6ae5eb6d
--- /dev/null
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/errors/InactiveAccountException.java
@@ -0,0 +1,26 @@
+// Copyright (C) 2010 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.common.errors;
+
+/** Error indicating the account is currently inactive. */
+public class InactiveAccountException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public static final String MESSAGE = "Account Inactive: ";
+
+ public InactiveAccountException(String who) {
+ super(MESSAGE + who);
+ }
+}
diff --git a/gerrit-ehcache/pom.xml b/gerrit-ehcache/pom.xml
index 8e2e2dd3..a7c6cf51 100644
--- a/gerrit-ehcache/pom.xml
+++ b/gerrit-ehcache/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
</parent>
<artifactId>gerrit-ehcache</artifactId>
diff --git a/gerrit-gwtdebug/pom.xml b/gerrit-gwtdebug/pom.xml
index 95572275..d5a67e13 100644
--- a/gerrit-gwtdebug/pom.xml
+++ b/gerrit-gwtdebug/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
</parent>
<artifactId>gerrit-gwtdebug</artifactId>
diff --git a/gerrit-gwtui/pom.xml b/gerrit-gwtui/pom.xml
index 29c5b01c..9a27d12b 100644
--- a/gerrit-gwtui/pom.xml
+++ b/gerrit-gwtui/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
</parent>
<artifactId>gerrit-gwtui</artifactId>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java
index 3f263d23..b32a32d0 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java
@@ -46,6 +46,8 @@ public interface GerritConstants extends Constants {
String nameAlreadyUsedBody();
String noSuchAccountTitle();
+ String inactiveAccountBody();
+
String menuAll();
String menuAllOpen();
String menuAllMerged();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties
index 83a06e47..33630150 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties
@@ -29,6 +29,8 @@ notFoundBody = The page you requested was not found.
nameAlreadyUsedBody = The name is already in use.
noSuchAccountTitle = Code Review - Unknown User
+inactiveAccountBody = This user is currently inactive.
+
menuAll = All
menuAllOpen = Open
menuAllMerged = Merged
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ApprovalTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ApprovalTable.java
index f850a33e..23dd6357 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ApprovalTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ApprovalTable.java
@@ -188,6 +188,10 @@ public class ApprovalTable extends Composite {
r.append(Util.M.accountNotFound(e.getName()));
break;
+ case ACCOUNT_INACTIVE:
+ r.append(Util.M.accountInactive(e.getName()));
+ break;
+
case CHANGE_NOT_VISIBLE:
r.append(Util.M.changeNotVisibleTo(e.getName()));
break;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.java
index 51e2bc58..fd7c3631 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.java
@@ -47,6 +47,7 @@ public interface ChangeMessages extends Messages {
String changeQueryPageTitle(String query);
String accountNotFound(String who);
+ String accountInactive(String who);
String changeNotVisibleTo(String who);
String anonymousDownload(String protocol);
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.properties
index 5d2d3a50..80f9dabc 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.properties
@@ -28,6 +28,7 @@ changeQueryWindowTitle = {0}
changeQueryPageTitle = Search for {0}
accountNotFound = {0} is not a registered user.
+accountInactive = {0} is not an active user.
changeNotVisibleTo = {0} cannot access the change.
anonymousDownload = Anonymous {0}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/rpc/GerritCallback.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/rpc/GerritCallback.java
index fa028d75..f29742ad 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/rpc/GerritCallback.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/rpc/GerritCallback.java
@@ -17,6 +17,7 @@ package com.google.gerrit.client.rpc;
import com.google.gerrit.client.ErrorDialog;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.NotSignedInDialog;
+import com.google.gerrit.common.errors.InactiveAccountException;
import com.google.gerrit.common.errors.NameAlreadyUsedException;
import com.google.gerrit.common.errors.NoSuchAccountException;
import com.google.gerrit.common.errors.NoSuchEntityException;
@@ -37,6 +38,9 @@ public abstract class GerritCallback<T> implements AsyncCallback<T> {
} else if (isNoSuchEntity(caught)) {
new ErrorDialog(Gerrit.C.notFoundBody()).center();
+ } else if (isInactiveAccount(caught)) {
+ new ErrorDialog(Gerrit.C.inactiveAccountBody()).center();
+
} else if (isNoSuchAccount(caught)) {
final String msg = caught.getMessage();
final String who = msg.substring(NoSuchAccountException.MESSAGE.length());
@@ -71,6 +75,11 @@ public abstract class GerritCallback<T> implements AsyncCallback<T> {
&& caught.getMessage().equals(NoSuchEntityException.MESSAGE);
}
+ protected static boolean isInactiveAccount(final Throwable caught) {
+ return caught instanceof RemoteJsonException
+ && caught.getMessage().startsWith(InactiveAccountException.MESSAGE);
+ }
+
private static boolean isNoSuchAccount(final Throwable caught) {
return caught instanceof RemoteJsonException
&& caught.getMessage().startsWith(NoSuchAccountException.MESSAGE);
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 441878f4..bcf6438e 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
@@ -30,7 +30,8 @@ public class AccountSuggestOracle extends HighlightSuggestOracle {
public void onRequestSuggestions(final Request req, final Callback callback) {
RpcStatus.hide(new Runnable() {
public void run() {
- SuggestUtil.SVC.suggestAccount(req.getQuery(), req.getLimit(),
+ SuggestUtil.SVC.suggestAccount(req.getQuery(), Boolean.TRUE,
+ req.getLimit(),
new GerritCallback<List<AccountInfo>>() {
public void onSuccess(final List<AccountInfo> result) {
final ArrayList<AccountSuggestion> r =
diff --git a/gerrit-httpd/pom.xml b/gerrit-httpd/pom.xml
index b02b1425..39b27887 100644
--- a/gerrit-httpd/pom.xml
+++ b/gerrit-httpd/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
</parent>
<artifactId>gerrit-httpd</artifactId>
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectDigestFilter.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectDigestFilter.java
index de1eb15c..2118b9c2 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectDigestFilter.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectDigestFilter.java
@@ -146,6 +146,11 @@ class ProjectDigestFilter implements Filter {
return false;
}
+ if (!FutureUtil.get(accountCache.getAccount(who.getAccountId())).isActive()) {
+ rsp.sendError(SC_UNAUTHORIZED);
+ return false;
+ }
+
final String A1 = username + ":" + realm + ":" + passwd;
final String A2 = method + ":" + uri;
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/SuggestServiceImpl.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/SuggestServiceImpl.java
index dc8fba55..45955207 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/SuggestServiceImpl.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/SuggestServiceImpl.java
@@ -84,8 +84,8 @@ class SuggestServiceImpl extends BaseServiceImplementation implements
});
}
- public void suggestAccount(final String query, final int limit,
- final AsyncCallback<List<AccountInfo>> callback) {
+ public void suggestAccount(final String query, final Boolean active,
+ final int limit, final AsyncCallback<List<AccountInfo>> callback) {
run(callback, new Action<List<AccountInfo>>() {
public List<AccountInfo> run(final ReviewDb db) throws OrmException {
final String a = query;
@@ -95,12 +95,16 @@ class SuggestServiceImpl extends BaseServiceImplementation implements
LinkedHashMap<Account.Id, AccountInfo> res = Maps.newLinkedHashMap();
for (Account p : db.accounts().suggestByFullName(a, b, n)) {
- res.put(p.getId(), new AccountInfo(p));
+ if (active == null || active == p.isActive()) {
+ res.put(p.getId(), new AccountInfo(p));
+ }
}
if (res.size() < n) {
for (Account p : db.accounts().suggestByPreferredEmail(a, b,
n - res.size())) {
- res.put(p.getId(), new AccountInfo(p));
+ if (active == null || active == p.isActive()) {
+ res.put(p.getId(), new AccountInfo(p));
+ }
}
}
if (res.size() < n) {
@@ -115,9 +119,11 @@ class SuggestServiceImpl extends BaseServiceImplementation implements
for (Map.Entry<String, Future<Account>> ent : want.entrySet()) {
Account p = FutureUtil.get(ent.getValue());
- AccountInfo info = new AccountInfo(p);
- info.setPreferredEmail(ent.getKey());
- res.put(p.getId(), info);
+ if (active == null || active == p.isActive()) {
+ AccountInfo info = new AccountInfo(p);
+ info.setPreferredEmail(ent.getKey());
+ res.put(p.getId(), info);
+ }
}
}
return new ArrayList<AccountInfo>(res.values());
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/account/GroupAdminServiceImpl.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/account/GroupAdminServiceImpl.java
index 5dfc09e6..eb12537a 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/account/GroupAdminServiceImpl.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/account/GroupAdminServiceImpl.java
@@ -17,6 +17,7 @@ package com.google.gerrit.httpd.rpc.account;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.gerrit.common.data.GroupAdminService;
import com.google.gerrit.common.data.GroupDetail;
+import com.google.gerrit.common.errors.InactiveAccountException;
import com.google.gerrit.common.errors.NameAlreadyUsedException;
import com.google.gerrit.common.errors.NoSuchAccountException;
import com.google.gerrit.common.errors.NoSuchEntityException;
@@ -225,6 +226,9 @@ class GroupAdminServiceImpl extends BaseServiceImplementation implements
}
final Account a = findAccount(nameOrEmail);
+ if (!a.isActive()) {
+ throw new Failure(new InactiveAccountException(a.getFullName()));
+ }
if (!control.canAdd(a.getId())) {
throw new Failure(new NoSuchEntityException());
}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/AddReviewer.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/AddReviewer.java
index ae36388d..9d508e2f 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/AddReviewer.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/AddReviewer.java
@@ -94,6 +94,11 @@ class AddReviewer extends Handler<ReviewerResult> {
ReviewerResult.Error.Type.ACCOUNT_NOT_FOUND, nameOrEmail));
continue;
}
+ if (!account.isActive()) {
+ result.addError(new ReviewerResult.Error(
+ ReviewerResult.Error.Type.ACCOUNT_INACTIVE, nameOrEmail));
+ continue;
+ }
final IdentifiedUser user = identifiedUserFactory.create(account.getId());
if (!control.forUser(user).isVisible()) {
diff --git a/gerrit-launcher/pom.xml b/gerrit-launcher/pom.xml
index 10007772..3c9c9796 100644
--- a/gerrit-launcher/pom.xml
+++ b/gerrit-launcher/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
</parent>
<artifactId>gerrit-launcher</artifactId>
diff --git a/gerrit-main/pom.xml b/gerrit-main/pom.xml
index 10cb14ae..a46aa4ff 100644
--- a/gerrit-main/pom.xml
+++ b/gerrit-main/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
</parent>
<artifactId>gerrit-main</artifactId>
diff --git a/gerrit-patch-commonsnet/pom.xml b/gerrit-patch-commonsnet/pom.xml
index df64d138..5bbae035 100644
--- a/gerrit-patch-commonsnet/pom.xml
+++ b/gerrit-patch-commonsnet/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
</parent>
<artifactId>gerrit-patch-commonsnet</artifactId>
diff --git a/gerrit-patch-jgit/pom.xml b/gerrit-patch-jgit/pom.xml
index 68a08c3d..f30eaced 100644
--- a/gerrit-patch-jgit/pom.xml
+++ b/gerrit-patch-jgit/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
</parent>
<artifactId>gerrit-patch-jgit</artifactId>
diff --git a/gerrit-pgm/pom.xml b/gerrit-pgm/pom.xml
index 8dbf3247..d3eee423 100644
--- a/gerrit-pgm/pom.xml
+++ b/gerrit-pgm/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
</parent>
<artifactId>gerrit-pgm</artifactId>
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/SitePathInitializer.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/SitePathInitializer.java
index 74e75483..dae08934 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/SitePathInitializer.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/SitePathInitializer.java
@@ -25,11 +25,13 @@ import static com.google.gerrit.pgm.init.InitUtil.version;
import com.google.gerrit.pgm.Init;
import com.google.gerrit.pgm.util.ConsoleUI;
import com.google.gerrit.server.config.SitePaths;
+import com.google.gerrit.server.mail.OutgoingEmail;
import com.google.inject.Binding;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.TypeLiteral;
+import java.io.File;
import java.util.ArrayList;
import java.util.List;
@@ -66,6 +68,7 @@ public class SitePathInitializer {
mkdir(site.etc_dir);
mkdir(site.lib_dir);
mkdir(site.logs_dir);
+ mkdir(site.mail_dir);
mkdir(site.static_dir);
for (InitStep step : steps) {
@@ -82,11 +85,27 @@ public class SitePathInitializer {
extract(site.gerrit_sh, Init.class, "gerrit.sh");
chmod(0755, site.gerrit_sh);
+ extractMailExample("Abandoned.vm");
+ extractMailExample("ChangeFooter.vm");
+ extractMailExample("ChangeSubject.vm");
+ extractMailExample("Comment.vm");
+ extractMailExample("Merged.vm");
+ extractMailExample("MergeFail.vm");
+ extractMailExample("NewChange.vm");
+ extractMailExample("RegisterNewEmail.vm");
+ extractMailExample("ReplacePatchSet.vm");
+
if (!ui.isBatch()) {
System.err.println();
}
}
+ private void extractMailExample(String orig) throws Exception {
+ File ex = new File(site.mail_dir, orig + ".example");
+ extract(ex, OutgoingEmail.class, orig);
+ chmod(0444, ex);
+ }
+
private static List<InitStep> stepsOf(final Injector injector) {
final ArrayList<InitStep> r = new ArrayList<InitStep>();
for (Binding<InitStep> b : all(injector)) {
diff --git a/gerrit-prettify/pom.xml b/gerrit-prettify/pom.xml
index 053d399a..18ba6746 100644
--- a/gerrit-prettify/pom.xml
+++ b/gerrit-prettify/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
</parent>
<artifactId>gerrit-prettify</artifactId>
diff --git a/gerrit-reviewdb/pom.xml b/gerrit-reviewdb/pom.xml
index 5626739a..d81b068b 100644
--- a/gerrit-reviewdb/pom.xml
+++ b/gerrit-reviewdb/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
</parent>
<artifactId>gerrit-reviewdb</artifactId>
diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/Account.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/Account.java
index 8468834c..ee65c55d 100644
--- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/Account.java
+++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/Account.java
@@ -130,6 +130,10 @@ public final class Account {
@Column(id = 6, name = Column.NONE)
protected AccountGeneralPreferences generalPreferences;
+ /** Is this user active */
+ @Column(id = 7)
+ protected boolean inactive;
+
/** <i>computed</i> the username selected from the identities. */
protected String userName;
@@ -199,6 +203,14 @@ public final class Account {
contactFiledOn = new Timestamp(System.currentTimeMillis());
}
+ public boolean isActive() {
+ return ! inactive;
+ }
+
+ public void setActive(boolean active) {
+ inactive = ! active;
+ }
+
/** @return the computed user name for this account */
public String getUserName() {
return userName;
diff --git a/gerrit-server/pom.xml b/gerrit-server/pom.xml
index 947930c7..d056ab3d 100644
--- a/gerrit-server/pom.xml
+++ b/gerrit-server/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
</parent>
<artifactId>gerrit-server</artifactId>
@@ -34,6 +34,16 @@ limitations under the License.
<dependencies>
<dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.velocity</groupId>
+ <artifactId>velocity</artifactId>
+ </dependency>
+
+ <dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
</dependency>
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 fcef20cf..3a241d36 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
@@ -97,7 +97,7 @@ public class AccountManager {
* @param who identity of the user, with any details we received about them.
* @return the result of authenticating the user.
* @throws AccountException the account does not exist, and cannot be created,
- * or exists, but cannot be located.
+ * or exists, but cannot be located, or is inactive.
*/
public AuthResult authenticate(AuthRequest who) throws AccountException {
who = realm.authenticate(who);
@@ -111,9 +111,14 @@ public class AccountManager {
//
return create(db, who);
- } else {
- // Account exists, return the identity to the caller.
- //
+ } else { // Account exists
+
+ Account act = db.accounts().get(id.getAccountId());
+ if (act == null || !act.isActive()) {
+ throw new AccountException("Authentication error, account inactive");
+ }
+
+ // return the identity to the caller.
update(db, who, id);
return new AuthResult(id.getAccountId(), key, false);
}
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 e98e2971..5ebaada6 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
@@ -17,6 +17,7 @@ package com.google.gerrit.server.config;
import static com.google.inject.Scopes.SINGLETON;
import com.google.gerrit.common.data.ApprovalTypes;
+import com.google.gerrit.lifecycle.LifecycleListener;
import com.google.gerrit.lifecycle.LifecycleModule;
import com.google.gerrit.reviewdb.AccountGroup;
import com.google.gerrit.reviewdb.AuthType;
@@ -63,15 +64,53 @@ import com.google.gerrit.server.workflow.FunctionState;
import com.google.inject.Inject;
import com.google.inject.TypeLiteral;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.runtime.RuntimeConstants;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.PersonIdent;
+import java.util.Properties;
import java.util.Set;
+
/** Starts global state with standard dependencies. */
public class GerritGlobalModule extends FactoryModule {
private final AuthType loginType;
+ public static class VelocityLifecycle implements LifecycleListener {
+ private final SitePaths site;
+
+ @Inject
+ VelocityLifecycle(final SitePaths site) {
+ this.site = site;
+ }
+
+ @Override
+ public void start() {
+ String rl = "resource.loader";
+ String pkg = "org.apache.velocity.runtime.resource.loader";
+ Properties p = new Properties();
+
+ p.setProperty(rl, "file, class");
+ p.setProperty("file." + rl + ".class", pkg + ".FileResourceLoader");
+ p.setProperty("file." + rl + ".path", site.mail_dir.getAbsolutePath());
+ p.setProperty("class." + rl + ".class", pkg + ".ClasspathResourceLoader");
+ p.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS,
+ "org.apache.velocity.runtime.log.SimpleLog4JLogSystem" );
+ p.setProperty("runtime.log.logsystem.log4j.category", "velocity");
+
+ try {
+ Velocity.init(p);
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void stop() {
+ }
+ }
+
@Inject
GerritGlobalModule(final AuthConfig authConfig,
@GerritServerConfig final Config config) {
@@ -147,6 +186,7 @@ public class GerritGlobalModule extends FactoryModule {
@Override
protected void configure() {
listener().to(WorkQueue.Lifecycle.class);
+ listener().to(VelocityLifecycle.class);
}
});
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/SitePaths.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/SitePaths.java
index 1faa672a..c3a5fb7a 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/SitePaths.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/SitePaths.java
@@ -28,6 +28,7 @@ public final class SitePaths {
public final File etc_dir;
public final File lib_dir;
public final File logs_dir;
+ public final File mail_dir;
public final File hooks_dir;
public final File static_dir;
@@ -61,6 +62,7 @@ public final class SitePaths {
etc_dir = new File(site_path, "etc");
lib_dir = new File(site_path, "lib");
logs_dir = new File(site_path, "logs");
+ mail_dir = new File(etc_dir, "mail");
hooks_dir = new File(site_path, "hooks");
static_dir = new File(site_path, "static");
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/AbandonedSender.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/AbandonedSender.java
index d2b5c29c..e6798497 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/AbandonedSender.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/AbandonedSender.java
@@ -30,7 +30,7 @@ public class AbandonedSender extends ReplyToChangeSender {
}
@Override
- protected void init() {
+ protected void init() throws EmailException {
super.init();
ccAllApprovals();
@@ -39,10 +39,7 @@ public class AbandonedSender extends ReplyToChangeSender {
}
@Override
- protected void formatChange() {
- appendText(getNameFor(fromId));
- appendText(" has abandoned change " + change.getKey().abbreviate() + ":\n");
- appendText("\n");
- formatCoverLetter();
+ protected void formatChange() throws EmailException {
+ appendText(velocifyFile("Abandoned.vm"));
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/AddReviewerSender.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/AddReviewerSender.java
index be62ba07..e5437cfa 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/AddReviewerSender.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/AddReviewerSender.java
@@ -32,7 +32,7 @@ public class AddReviewerSender extends NewChangeSender {
}
@Override
- protected void init() {
+ protected void init() throws EmailException {
super.init();
ccExistingReviewers();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/ChangeEmail.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/ChangeEmail.java
index e3a0f727..931fc37b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/ChangeEmail.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/ChangeEmail.java
@@ -53,7 +53,6 @@ public abstract class ChangeEmail extends OutgoingEmail {
private ProjectState projectState;
protected ChangeData changeData;
- private boolean inFooter;
protected ChangeEmail(EmailArguments ea, final Change c, final String mc) {
super(ea, mc);
@@ -75,31 +74,9 @@ public abstract class ChangeEmail extends OutgoingEmail {
}
/** Format the message body by calling {@link #appendText(String)}. */
- protected void format() {
+ protected void format() throws EmailException {
formatChange();
- if (getChangeUrl() != null) {
- openFooter();
- appendText("To view visit ");
- appendText(getChangeUrl());
- appendText("\n");
- }
- if (getSettingsUrl() != null) {
- openFooter();
- appendText("To unsubscribe, visit ");
- appendText(getSettingsUrl());
- appendText("\n");
- }
-
- if (inFooter) {
- appendText("\n");
- } else {
- openFooter();
- }
- appendText("Gerrit-MessageType: " + messageClass + "\n");
- appendText("Gerrit-Project: " + projectName + "\n");
- appendText("Gerrit-Branch: " + change.getDest().getShortName() + "\n");
- appendText("Gerrit-Owner: " + getNameEmailFor(change.getOwner()) + "\n");
-
+ appendText(velocifyFile("ChangeFooter.vm"));
try {
HashSet<Account.Id> reviewers = new HashSet<Account.Id>();
for (PatchSetApproval p : args.db.get().patchSetApprovals().byChange(
@@ -120,13 +97,11 @@ public abstract class ChangeEmail extends OutgoingEmail {
}
/** Format the message body by calling {@link #appendText(String)}. */
- protected abstract void formatChange();
+ protected abstract void formatChange() throws EmailException;
/** Setup the message headers and envelope (TO, CC, BCC). */
@Override
- protected void init() {
- super.init();
-
+ protected void init() throws EmailException {
projectState = FutureUtil.get(args.projectCache.get(change.getProject()));
projectName = projectState != null //
? projectState.getProject().getName() //
@@ -148,6 +123,8 @@ public abstract class ChangeEmail extends OutgoingEmail {
}
}
+ super.init();
+
if (changeMessage != null && changeMessage.getWrittenOn() != null) {
setHeader("Date", new Date(changeMessage.getWrittenOn().getTime()));
}
@@ -156,27 +133,21 @@ public abstract class ChangeEmail extends OutgoingEmail {
setListIdHeader();
setChangeUrlHeader();
setCommitIdHeader();
-
- inFooter = false;
}
- private void setListIdHeader() {
+ private void setListIdHeader() throws EmailException {
// Set a reasonable list id so that filters can be used to sort messages
- //
- final StringBuilder listid = new StringBuilder();
- listid.append("gerrit-");
- listid.append(projectName.replace('/', '-'));
- listid.append("@");
- listid.append(getGerritHost());
-
- final String listidStr = listid.toString();
- setHeader("Mailing-List", "list " + listidStr);
- setHeader("List-Id", "<" + listidStr.replace('@', '.') + ">");
+ setVHeader("Mailing-List", "list $email.listId");
+ setVHeader("List-Id", "<$email.listId.replace('@', '.')>");
if (getSettingsUrl() != null) {
- setHeader("List-Unsubscribe", "<" + getSettingsUrl() + ">");
+ setVHeader("List-Unsubscribe", "<$email.settingsUrl>");
}
}
+ public String getListId() throws EmailException {
+ return velocify("gerrit-$projectName.replace('/', '-')@$email.gerritHost");
+ }
+
private void setChangeUrlHeader() {
final String u = getChangeUrl();
if (u != null) {
@@ -192,27 +163,12 @@ public abstract class ChangeEmail extends OutgoingEmail {
}
}
- private void setChangeSubjectHeader() {
- final StringBuilder subj = new StringBuilder();
- subj.append("[");
- subj.append(change.getDest().getShortName());
- subj.append("] ");
- subj.append("Change ");
- subj.append(change.getKey().abbreviate());
- subj.append(": (");
- subj.append(projectName);
- subj.append(") ");
- if (change.getSubject().length() > 60) {
- subj.append(change.getSubject().substring(0, 60));
- subj.append("...");
- } else {
- subj.append(change.getSubject());
- }
- setHeader("Subject", subj.toString());
+ private void setChangeSubjectHeader() throws EmailException {
+ setHeader("Subject", velocifyFile("ChangeSubject.vm"));
}
/** Get a link to the change; null if the server doesn't know its own address. */
- protected String getChangeUrl() {
+ public String getChangeUrl() {
if (change != null && getGerritUrl() != null) {
final StringBuilder r = new StringBuilder();
r.append(getGerritUrl());
@@ -222,25 +178,9 @@ public abstract class ChangeEmail extends OutgoingEmail {
return null;
}
- protected String getChangeMessageThreadId() {
- final StringBuilder r = new StringBuilder();
- r.append('<');
- r.append("gerrit");
- r.append('.');
- r.append(change.getCreatedOn().getTime());
- r.append('.');
- r.append(change.getKey().get());
- r.append('@');
- r.append(getGerritHost());
- r.append('>');
- return r.toString();
- }
-
- private void openFooter() {
- if (!inFooter) {
- inFooter = true;
- appendText("-- \n");
- }
+ public String getChangeMessageThreadId() throws EmailException {
+ return velocify("<gerrit.${change.createdOn.time}.$change.key.get()" +
+ "@$email.gerritHost>");
}
/** Format the sender's "cover letter", {@link #getCoverLetter()}. */
@@ -253,7 +193,7 @@ public abstract class ChangeEmail extends OutgoingEmail {
}
/** Get the text of the "cover letter", from {@link ChangeMessage}. */
- protected String getCoverLetter() {
+ public String getCoverLetter() {
if (changeMessage != null) {
final String txt = changeMessage.getMessage();
if (txt != null) {
@@ -265,23 +205,30 @@ public abstract class ChangeEmail extends OutgoingEmail {
/** Format the change message and the affected file list. */
protected void formatChangeDetail() {
+ appendText(getChangeDetail());
+ }
+
+ /** Create the change message and the affected file list. */
+ public String getChangeDetail() {
+ StringBuilder detail = new StringBuilder();
+
if (patchSetInfo != null) {
- appendText(patchSetInfo.getMessage().trim());
- appendText("\n");
+ detail.append(patchSetInfo.getMessage().trim() + "\n");
} else {
- appendText(change.getSubject().trim());
- appendText("\n");
+ detail.append(change.getSubject().trim() + "\n");
}
if (patchSet != null) {
- appendText("---\n");
+ detail.append("---\n");
for (PatchListEntry p : getPatchList().getPatches()) {
- appendText(p.getChangeType().getCode() + " " + p.getNewName() + "\n");
+ detail.append(p.getChangeType().getCode() + " " + p.getNewName() + "\n");
}
- appendText("\n");
+ detail.append("\n");
}
+ return detail.toString();
}
+
/** Get the patch list corresponding to this patch set. */
protected PatchList getPatchList() {
if (patchSet != null) {
@@ -423,4 +370,17 @@ public abstract class ChangeEmail extends OutgoingEmail {
|| projectState.controlFor(args.identifiedUserFactory.create(to))
.controlFor(change).isVisible();
}
+
+ @Override
+ protected void setupVelocityContext() {
+ super.setupVelocityContext();
+ velocityContext.put("change", change);
+ velocityContext.put("changeId", change.getKey());
+ velocityContext.put("coverLetter", getCoverLetter());
+ velocityContext.put("branch", change.getDest());
+ velocityContext.put("fromName", getNameFor(fromId));
+ velocityContext.put("projectName", projectName);
+ velocityContext.put("patchSet", patchSet);
+ velocityContext.put("patchSetInfo", patchSetInfo);
+ }
}
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 be6360fe..d3c3b7a2 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
@@ -56,7 +56,7 @@ public class CommentSender extends ReplyToChangeSender {
}
@Override
- protected void init() {
+ protected void init() throws EmailException {
super.init();
ccAllApprovals();
@@ -65,20 +65,13 @@ public class CommentSender extends ReplyToChangeSender {
}
@Override
- protected void formatChange() {
- if (!"".equals(getCoverLetter()) || !inlineComments.isEmpty()) {
- appendText("Comments on Patch Set " + patchSet.getPatchSetId() + ":\n");
- appendText("\n");
- formatCoverLetter();
- formatInlineComments();
- if (getChangeUrl() != null) {
- appendText("To respond, visit " + getChangeUrl() + "\n");
- appendText("\n");
- }
- }
+ protected void formatChange() throws EmailException {
+ appendText(velocifyFile("Comment.vm"));
}
- private void formatInlineComments() {
+ public String getInlineComments() {
+ StringBuilder cmts = new StringBuilder();
+
final Repository repo = getRepository();
try {
final PatchList patchList = repo != null ? getPatchList() : null;
@@ -91,10 +84,10 @@ public class CommentSender extends ReplyToChangeSender {
final short side = c.getSide();
if (!pk.equals(currentFileKey)) {
- appendText("....................................................\n");
- appendText("File ");
- appendText(pk.get());
- appendText("\n");
+ cmts.append("....................................................\n");
+ cmts.append("File ");
+ cmts.append(pk.get());
+ cmts.append("\n");
currentFileKey = pk;
if (patchList != null) {
@@ -109,26 +102,27 @@ public class CommentSender extends ReplyToChangeSender {
}
}
- appendText("Line " + lineNbr);
+ cmts.append("Line " + lineNbr);
if (currentFileData != null) {
try {
final String lineStr = currentFileData.getLine(side, lineNbr);
- appendText(": ");
- appendText(lineStr);
+ cmts.append(": ");
+ cmts.append(lineStr);
} catch (Throwable cce) {
// Don't quote the line if we can't safely convert it.
}
}
- appendText("\n");
+ cmts.append("\n");
- appendText(c.getMessage().trim());
- appendText("\n\n");
+ cmts.append(c.getMessage().trim());
+ cmts.append("\n\n");
}
} finally {
if (repo != null) {
repo.close();
}
}
+ return cmts.toString();
}
private Repository getRepository() {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/CreateChangeSender.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/CreateChangeSender.java
index 5ea9e204..be830b94 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/CreateChangeSender.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/CreateChangeSender.java
@@ -43,7 +43,7 @@ public class CreateChangeSender extends NewChangeSender {
}
@Override
- protected void init() {
+ protected void init() throws EmailException {
super.init();
bccWatchers();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/EmailArguments.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/EmailArguments.java
index e9b1a5b0..196db4b0 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/EmailArguments.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/EmailArguments.java
@@ -22,6 +22,7 @@ import com.google.gerrit.server.IdentifiedUser.GenericFactory;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountProjectWatchCache;
import com.google.gerrit.server.config.CanonicalWebUrl;
+import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.config.WildProjectName;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.patch.PatchListCache;
@@ -51,6 +52,7 @@ class EmailArguments {
final ChangeQueryBuilder.Factory queryBuilder;
final Provider<ChangeQueryRewriter> queryRewriter;
final Provider<ReviewDb> db;
+ final SitePaths site;
@Inject
EmailArguments(GitRepositoryManager server, ProjectCache projectCache,
@@ -63,7 +65,8 @@ class EmailArguments {
@CanonicalWebUrl @Nullable Provider<String> urlProvider,
@WildProjectName Project.NameKey wildProject,
ChangeQueryBuilder.Factory queryBuilder,
- Provider<ChangeQueryRewriter> queryRewriter, Provider<ReviewDb> db) {
+ Provider<ChangeQueryRewriter> queryRewriter, Provider<ReviewDb> db,
+ SitePaths site) {
this.server = server;
this.projectCache = projectCache;
this.accountCache = accountCache;
@@ -79,5 +82,6 @@ class EmailArguments {
this.queryBuilder = queryBuilder;
this.queryRewriter = queryRewriter;
this.db = db;
+ this.site = site;
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/MergeFailSender.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/MergeFailSender.java
index 00750ef3..cf8f590b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/MergeFailSender.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/MergeFailSender.java
@@ -30,23 +30,14 @@ public class MergeFailSender extends ReplyToChangeSender {
}
@Override
- protected void init() {
+ protected void init() throws EmailException {
super.init();
ccExistingReviewers();
}
@Override
- protected void formatChange() {
- appendText("Change " + change.getKey().abbreviate());
- if (patchSetInfo != null && patchSetInfo.getAuthor() != null
- && patchSetInfo.getAuthor().getName() != null) {
- appendText(" by ");
- appendText(patchSetInfo.getAuthor().getName());
- }
- appendText(" FAILED to submit to ");
- appendText(change.getDest().getShortName());
- appendText(".\n\n");
- formatCoverLetter();
+ protected void formatChange() throws EmailException {
+ appendText(velocifyFile("MergeFail.vm"));
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/MergedSender.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/MergedSender.java
index caf19e47..40f47907 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/MergedSender.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/MergedSender.java
@@ -51,7 +51,7 @@ public class MergedSender extends ReplyToChangeSender {
}
@Override
- protected void init() {
+ protected void init() throws EmailException {
super.init();
ccAllApprovals();
@@ -61,58 +61,47 @@ public class MergedSender extends ReplyToChangeSender {
}
@Override
- protected void formatChange() {
- appendText("Change " + change.getKey().abbreviate());
- if (patchSetInfo != null && patchSetInfo.getAuthor() != null
- && patchSetInfo.getAuthor().getName() != null) {
- appendText(" by ");
- appendText(patchSetInfo.getAuthor().getName());
- }
- appendText(" submitted to ");
- appendText(dest.getShortName());
- appendText(":\n\n");
- formatChangeDetail();
- formatApprovals();
+ protected void formatChange() throws EmailException {
+ appendText(velocifyFile("Merged.vm"));
}
- private void formatApprovals() {
- if (patchSet != null) {
- try {
- final Map<Account.Id, Map<ApprovalCategory.Id, PatchSetApproval>> pos =
- new HashMap<Account.Id, Map<ApprovalCategory.Id, PatchSetApproval>>();
-
- final Map<Account.Id, Map<ApprovalCategory.Id, PatchSetApproval>> neg =
- new HashMap<Account.Id, Map<ApprovalCategory.Id, PatchSetApproval>>();
-
- for (PatchSetApproval ca : args.db.get().patchSetApprovals()
- .byPatchSet(patchSet.getId())) {
- if (ca.getValue() > 0) {
- insert(pos, ca);
- } else if (ca.getValue() < 0) {
- insert(neg, ca);
- }
+ public String getApprovals() {
+ try {
+ final Map<Account.Id, Map<ApprovalCategory.Id, PatchSetApproval>> pos =
+ new HashMap<Account.Id, Map<ApprovalCategory.Id, PatchSetApproval>>();
+
+ final Map<Account.Id, Map<ApprovalCategory.Id, PatchSetApproval>> neg =
+ new HashMap<Account.Id, Map<ApprovalCategory.Id, PatchSetApproval>>();
+
+ for (PatchSetApproval ca : args.db.get().patchSetApprovals()
+ .byPatchSet(patchSet.getId())) {
+ if (ca.getValue() > 0) {
+ insert(pos, ca);
+ } else if (ca.getValue() < 0) {
+ insert(neg, ca);
}
-
- format("Approvals", pos);
- format("Objections", neg);
- } catch (OrmException err) {
- // Don't list the approvals
}
+
+ return format("Approvals", pos) + format("Objections", neg);
+ } catch (OrmException err) {
+ // Don't list the approvals
}
+ return "";
}
- private void format(final String type,
+ private String format(final String type,
final Map<Account.Id, Map<ApprovalCategory.Id, PatchSetApproval>> list) {
+ StringBuilder txt = new StringBuilder();
if (list.isEmpty()) {
- return;
+ return "";
}
- appendText(type + ":\n");
+ txt.append(type + ":\n");
for (final Map.Entry<Account.Id, Map<ApprovalCategory.Id, PatchSetApproval>> ent : list
.entrySet()) {
final Map<ApprovalCategory.Id, PatchSetApproval> l = ent.getValue();
- appendText(" ");
- appendText(getNameFor(ent.getKey()));
- appendText(": ");
+ txt.append(" ");
+ txt.append(getNameFor(ent.getKey()));
+ txt.append(": ");
boolean first = true;
for (ApprovalType at : approvalTypes.getApprovalTypes()) {
final PatchSetApproval ca = l.get(at.getCategory().getId());
@@ -123,24 +112,25 @@ public class MergedSender extends ReplyToChangeSender {
if (first) {
first = false;
} else {
- appendText("; ");
+ txt.append("; ");
}
final ApprovalCategoryValue v = at.getValue(ca);
if (v != null) {
- appendText(v.getName());
+ txt.append(v.getName());
} else {
- appendText(at.getCategory().getName());
- appendText("=");
+ txt.append(at.getCategory().getName());
+ txt.append("=");
if (ca.getValue() > 0) {
- appendText("+");
+ txt.append("+");
}
- appendText("" + ca.getValue());
+ txt.append("" + ca.getValue());
}
}
- appendText("\n");
+ txt.append("\n");
}
- appendText("\n");
+ txt.append("\n");
+ return txt.toString();
}
private void insert(
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/NewChangeSender.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/NewChangeSender.java
index dc8c2c2b..9e78cabf 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/NewChangeSender.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/NewChangeSender.java
@@ -20,6 +20,7 @@ import com.google.gerrit.server.ssh.SshInfo;
import com.jcraft.jsch.HostKey;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
@@ -46,7 +47,7 @@ public abstract class NewChangeSender extends ChangeEmail {
}
@Override
- protected void init() {
+ protected void init() throws EmailException {
super.init();
setHeader("Message-ID", getChangeMessageThreadId());
@@ -57,74 +58,19 @@ public abstract class NewChangeSender extends ChangeEmail {
}
@Override
- protected void formatChange() {
- formatSalutation();
- formatChangeDetail();
-
- appendText("\n");
- appendText(" " + getPullUrl() + "\n");
+ protected void formatChange() throws EmailException {
+ appendText(velocifyFile("NewChange.vm"));
}
- private void formatSalutation() {
- final String changeUrl = getChangeUrl();
-
+ public List<String> getReviewerNames() {
if (reviewers.isEmpty()) {
- formatDest();
- if (changeUrl != null) {
- appendText("\n");
- appendText(" " + changeUrl + "\n");
- appendText("\n");
- }
- appendText("\n");
-
- } else {
- appendText("Hello");
- for (final Iterator<Account.Id> i = reviewers.iterator(); i.hasNext();) {
- appendText(" ");
- appendText(getNameFor(i.next()));
- appendText(",");
- }
- appendText("\n");
- appendText("\n");
-
- appendText("I'd like you to do a code review.");
- if (changeUrl != null) {
- appendText(" Please visit\n");
- appendText("\n");
- appendText(" " + changeUrl + "\n");
- appendText("\n");
- appendText("to review the following change:\n");
- }
- appendText("\n");
-
- formatDest();
- appendText("\n");
+ return null;
}
- }
-
- private void formatDest() {
- appendText("Change " + change.getKey().abbreviate());
- appendText(" for ");
- appendText(change.getDest().getShortName());
- appendText(" in ");
- appendText(projectName);
- appendText(":\n");
- }
-
- private String getPullUrl() {
- final String host = getSshHost();
- if (host == null) {
- return "";
+ List<String> names = new ArrayList<String>();
+ for (Account.Id id : reviewers) {
+ names.add(getNameFor(id));
}
-
- final StringBuilder r = new StringBuilder();
- r.append("git pull ssh://");
- r.append(host);
- r.append("/");
- r.append(projectName);
- r.append(" ");
- r.append(patchSet.getRefName());
- return r.toString();
+ return names;
}
public String getSshHost() {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/OutgoingEmail.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/OutgoingEmail.java
index ea577358..587aeca8 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/OutgoingEmail.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/OutgoingEmail.java
@@ -18,11 +18,19 @@ import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.reviewdb.UserIdentity;
import com.google.gerrit.server.mail.EmailHeader.AddressList;
import com.google.gerrit.server.util.FutureUtil;
+import com.google.gerrit.server.account.AccountState;
+import com.google.gerrit.server.mail.EmailHeader.AddressList;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.VelocityContext;
import org.eclipse.jgit.util.SystemReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
@@ -47,6 +55,7 @@ public abstract class OutgoingEmail {
private final List<Address> smtpRcptTo = new ArrayList<Address>();
private Address smtpFromAddress;
private StringBuilder body;
+ protected VelocityContext velocityContext;
protected final EmailArguments args;
protected Account.Id fromId;
@@ -114,10 +123,12 @@ public abstract class OutgoingEmail {
}
/** Format the message body by calling {@link #appendText(String)}. */
- protected abstract void format();
+ protected abstract void format() throws EmailException;
/** Setup the message headers and envelope (TO, CC, BCC). */
- protected void init() {
+ protected void init() throws EmailException {
+ setupVelocityContext();
+
smtpFromAddress = args.fromAddressGenerator.from(fromId);
setHeader("Date", new Date());
headers.put("From", new EmailHeader.AddressList(smtpFromAddress));
@@ -141,26 +152,32 @@ public abstract class OutgoingEmail {
body = new StringBuilder();
if (fromId != null && args.fromAddressGenerator.isGenericAddress(fromId)) {
- final Account account =
- FutureUtil.get(args.accountCache.getAccount(fromId));
- final String name = account.getFullName();
- final String email = account.getPreferredEmail();
-
- if ((name != null && !name.isEmpty())
- || (email != null && !email.isEmpty())) {
- body.append("From");
- if (name != null && !name.isEmpty()) {
- body.append(" ").append(name);
- }
- if (email != null && !email.isEmpty()) {
- body.append(" <").append(email).append(">");
- }
- body.append(":\n\n");
+ appendText(getFromLine());
+ }
+ }
+
+ protected String getFromLine() {
+ final Account account =
+ FutureUtil.get(args.accountCache.getAccount(fromId));
+ final String name = account.getFullName();
+ final String email = account.getPreferredEmail();
+ StringBuilder f = new StringBuilder();
+
+ if ((name != null && !name.isEmpty())
+ || (email != null && !email.isEmpty())) {
+ f.append("From");
+ if (name != null && !name.isEmpty()) {
+ f.append(" ").append(name);
+ }
+ if (email != null && !email.isEmpty()) {
+ f.append(" <").append(email).append(">");
}
+ f.append(":\n\n");
}
+ return f.toString();
}
- protected String getGerritHost() {
+ public String getGerritHost() {
if (getGerritUrl() != null) {
try {
return new URL(getGerritUrl()).getHost();
@@ -186,10 +203,16 @@ public abstract class OutgoingEmail {
return null;
}
- protected String getGerritUrl() {
+ public String getGerritUrl() {
return args.urlProvider.get();
}
+ /** Set a header in the outgoing message using a template. */
+ protected void setVHeader(final String name, final String value) throws
+ EmailException {
+ setHeader(name, velocify(value));
+ }
+
/** Set a header in the outgoing message. */
protected void setHeader(final String name, final String value) {
headers.put(name, new EmailHeader.String(value));
@@ -224,7 +247,7 @@ public abstract class OutgoingEmail {
return name;
}
- protected String getNameEmailFor(Account.Id accountId) {
+ public String getNameEmailFor(Account.Id accountId) {
Account who = FutureUtil.get(args.accountCache.getAccount(accountId));
String name = who.getFullName();
String email = who.getPreferredEmail();
@@ -313,9 +336,46 @@ public abstract class OutgoingEmail {
private Address toAddress(final Account.Id id) {
final Account a = FutureUtil.get(args.accountCache.getAccount(id));
final String e = a.getPreferredEmail();
- if (e == null) {
+ if (!a.isActive() || e == null) {
return null;
}
return new Address(a.getFullName(), e);
}
+
+ protected void setupVelocityContext() {
+ velocityContext = new VelocityContext();
+
+ velocityContext.put("email", this);
+ velocityContext.put("messageClass", messageClass);
+ velocityContext.put("StringUtils", StringUtils.class);
+ }
+
+ protected String velocify(String tpl) throws EmailException {
+ try {
+ StringWriter w = new StringWriter();
+ Velocity.evaluate(velocityContext, w, "OutgoingEmail", tpl);
+ return w.toString();
+ } catch(Exception e) {
+ throw new EmailException("Velocity template "+ tpl.toString(), e);
+ }
+ }
+
+ protected String velocifyFile(String name) throws EmailException {
+ try {
+ StringWriter w = new StringWriter();
+ Velocity.mergeTemplate(name, velocityContext, w);
+ return w.toString();
+ } catch(ResourceNotFoundException e) {
+ try {
+ StringWriter w = new StringWriter();
+ String pkg = "com/google/gerrit/server/mail/";
+ Velocity.mergeTemplate(pkg + name, velocityContext, w);
+ return w.toString();
+ } catch(Exception e2) {
+ throw new EmailException("Velocity WAR template" + name + ".\n", e2);
+ }
+ } catch(Exception e) {
+ throw new EmailException("Velocity template " + name + ".\n", e);
+ }
+ }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/RegisterNewEmailSender.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/RegisterNewEmailSender.java
index 9b201fd4..2c779994 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/RegisterNewEmailSender.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/RegisterNewEmailSender.java
@@ -40,7 +40,7 @@ public class RegisterNewEmailSender extends OutgoingEmail {
}
@Override
- protected void init() {
+ protected void init() throws EmailException {
super.init();
setHeader("Subject", "[Gerrit Code Review] Email Verification");
add(RecipientType.TO, new Address(addr));
@@ -52,39 +52,8 @@ public class RegisterNewEmailSender extends OutgoingEmail {
}
@Override
- protected void format() {
- final StringBuilder url = new StringBuilder();
- url.append(getGerritUrl());
- url.append("#VE,");
- url.append(getEmailRegistrationToken());
-
- appendText("Welcome to Gerrit Code Review at ");
- appendText(getGerritHost());
- appendText(".\n");
-
- appendText("\n");
- appendText("To add a verified email address to your user account, please\n");
- appendText("click on the following link:\n");
- appendText("\n");
- appendText(url.toString());
- appendText("\n");
-
- appendText("\n");
- appendText("If you have received this mail in error,"
- + " you do not need to take any\n");
- appendText("action to cancel the account."
- + " The account will not be activated, and\n");
- appendText("you will not receive any further emails.\n");
-
- appendText("\n");
- appendText("If clicking the link above does not work,"
- + " copy and paste the URL in a\n");
- appendText("new browser window instead.\n");
-
- appendText("\n");
- appendText("This is a send-only email address."
- + " Replies to this message will not\n");
- appendText("be read or answered.\n");
+ protected void format() throws EmailException {
+ appendText(velocifyFile("RegisterNewEmail.vm"));
}
public String getEmailRegistrationToken() {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/ReplacePatchSetSender.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/ReplacePatchSetSender.java
index 841aa355..0c8ca9ae 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/ReplacePatchSetSender.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/ReplacePatchSetSender.java
@@ -22,6 +22,7 @@ import com.google.inject.assistedinject.Assisted;
import com.jcraft.jsch.HostKey;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
@@ -53,7 +54,7 @@ public class ReplacePatchSetSender extends ReplyToChangeSender {
}
@Override
- protected void init() {
+ protected void init() throws EmailException {
super.init();
if (fromId != null) {
@@ -67,77 +68,19 @@ public class ReplacePatchSetSender extends ReplyToChangeSender {
}
@Override
- protected void formatChange() {
- formatSalutation();
- formatChangeDetail();
-
- appendText("\n");
- appendText(" " + getPullUrl() + "\n");
+ protected void formatChange() throws EmailException {
+ appendText(velocifyFile("ReplacePatchSet.vm"));
}
- private void formatSalutation() {
- final String changeUrl = getChangeUrl();
-
+ public List<String> getReviewerNames() {
if (reviewers.isEmpty()) {
- formatDest();
- if (changeUrl != null) {
- appendText("\n");
- appendText(" " + changeUrl + "\n");
- appendText("\n");
- }
- appendText("\n");
-
- } else {
- appendText("Hello");
- for (final Iterator<Account.Id> i = reviewers.iterator(); i.hasNext();) {
- appendText(" ");
- appendText(getNameFor(i.next()));
- appendText(",");
- }
- appendText("\n");
- appendText("\n");
-
- appendText("I'd like you to reexamine change "
- + change.getKey().abbreviate() + ".");
- if (changeUrl != null) {
- appendText(" Please visit\n");
- appendText("\n");
- appendText(" " + changeUrl + "\n");
- appendText("\n");
- appendText("to look at patch set " + patchSet.getPatchSetId());
- appendText(":\n");
- }
- appendText("\n");
-
- formatDest();
- appendText("\n");
+ return null;
}
- }
-
- private void formatDest() {
- appendText("Change " + change.getKey().abbreviate());
- appendText(" (patch set " + patchSet.getPatchSetId() + ")");
- appendText(" for ");
- appendText(change.getDest().getShortName());
- appendText(" in ");
- appendText(projectName);
- appendText(":\n");
- }
-
- private String getPullUrl() {
- final String host = getSshHost();
- if (host == null) {
- return "";
+ List<String> names = new ArrayList<String>();
+ for (Account.Id id : reviewers) {
+ names.add(getNameFor(id));
}
-
- final StringBuilder r = new StringBuilder();
- r.append("git pull ssh://");
- r.append(host);
- r.append("/");
- r.append(projectName);
- r.append(" ");
- r.append(patchSet.getRefName());
- return r.toString();
+ return names;
}
public String getSshHost() {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/ReplyToChangeSender.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/ReplyToChangeSender.java
index 05d2753d..4c3ed764 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/ReplyToChangeSender.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/ReplyToChangeSender.java
@@ -23,7 +23,7 @@ public abstract class ReplyToChangeSender extends ChangeEmail {
}
@Override
- protected void init() {
+ protected void init() throws EmailException {
super.init();
final String threadId = getChangeMessageThreadId();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_103.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_103.java
index 46c34341..54746381 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_103.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_103.java
@@ -33,7 +33,7 @@ public class Schema_103 extends SchemaVersion {
private static final int MAX_SCAN_SIZE = 1000;
@Inject
- Schema_103(Provider<Schema_40> prior) {
+ Schema_103(Provider<Schema_41> prior) {
super(prior);
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_41.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_41.java
new file mode 100644
index 00000000..508db436
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_41.java
@@ -0,0 +1,25 @@
+// Copyright (C) 2010 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_41 extends SchemaVersion {
+ @Inject
+ Schema_41(Provider<Schema_40> prior) {
+ super(prior);
+ }
+}
diff --git a/gerrit-server/src/main/resources/com/google/gerrit/server/mail/Abandoned.vm b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/Abandoned.vm
new file mode 100644
index 00000000..557ee608
--- /dev/null
+++ b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/Abandoned.vm
@@ -0,0 +1,40 @@
+## Copyright (C) 2010 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.
+##
+##
+## Template Type:
+## -------------
+## This is a velocity mail template, see: http://velocity.apache.org and the
+## gerrit-docs:config-mail.txt for more info on modifying gerrit mail templates.
+##
+## Template File Names and extensions:
+## ----------------------------------
+## Gerrit will use templates ending in ".vm" but will ignore templates ending
+## in ".vm.example". If a .vm template does not exist, the default internal
+## gerrit template which is the same as the .vm.example will be used. If you
+## want to override the default template, copy the .vm.exmaple file to a .vm
+## file and edit it appropriately.
+##
+## This Template:
+## --------------
+## The Abandoned.vm template will determine the contents of the email related
+## to a change being abandoned. It is a ChangeEmail: see ChangeSubject.vm and
+## ChangeFooter.vm.
+##
+$fromName has abandoned change $changeId.abbreviate():
+
+#if ($coverLetter)
+$coverLetter
+
+#end
diff --git a/gerrit-server/src/main/resources/com/google/gerrit/server/mail/ChangeFooter.vm b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/ChangeFooter.vm
new file mode 100644
index 00000000..c15d6efb
--- /dev/null
+++ b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/ChangeFooter.vm
@@ -0,0 +1,49 @@
+## Copyright (C) 2010 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.
+##
+##
+## Template Type:
+## -------------
+## This is a velocity mail template, see: http://velocity.apache.org and the
+## gerrit-docs:config-mail.txt for more info on modifying gerrit mail templates.
+##
+## Template File Names and extensions:
+## ----------------------------------
+## Gerrit will use templates ending in ".vm" but will ignore templates ending
+## in ".vm.example". If a .vm template does not exist, the default internal
+## gerrit template which is the same as the .vm.example will be used. If you
+## want to override the default template, copy the .vm.exmaple file to a .vm
+## file and edit it appropriately.
+##
+## This Template:
+## --------------
+## The ChangeFooter.vm template will determine the contents of the footer
+## text that will be appended to ALL emails related to changes.
+##
+--
+#if ($email.changeUrl)
+To view, visit $email.changeUrl
+#set ($notblank = 1)
+#end
+#if ($email.settingsUrl)
+To unsubscribe, visit $email.settingsUrl
+#set ($notblank = 1)
+#end
+#if ($notblank == 1)
+
+#end
+Gerrit-MessageType: $messageClass
+Gerrit-Project: $projectName
+Gerrit-Branch: $branch.shortName
+Gerrit-Owner: $email.getNameEmailFor($change.owner)
diff --git a/gerrit-server/src/main/resources/com/google/gerrit/server/mail/ChangeSubject.vm b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/ChangeSubject.vm
new file mode 100644
index 00000000..2132c635
--- /dev/null
+++ b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/ChangeSubject.vm
@@ -0,0 +1,37 @@
+## Copyright (C) 2010 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.
+##
+##
+## Template Type:
+## -------------
+## This is a velocity mail template, see: http://velocity.apache.org and the
+## gerrit-docs:config-mail.txt for more info on modifying gerrit mail templates.
+##
+## Template File Names and extensions:
+## ----------------------------------
+## Gerrit will use templates ending in ".vm" but will ignore templates ending
+## in ".vm.example". If a .vm template does not exist, the default internal
+## gerrit template which is the same as the .vm.example will be used. If you
+## want to override the default template, copy the .vm.exmaple file to a .vm
+## file and edit it appropriately.
+##
+## This Template:
+## --------------
+## The ChangeSubject.vm template will determine the contents of the email
+## subject line for ALL emails related to changes.
+##
+#macro(elipses $length $str)
+#if($str.length() > $length)${str.substring(0,$length)}...#else$str#end
+#end
+[$branch.shortName] Change $changeId.abbreviate(): ($projectName) #elipses(60, $change.subject)
diff --git a/gerrit-server/src/main/resources/com/google/gerrit/server/mail/Comment.vm b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/Comment.vm
new file mode 100644
index 00000000..b7ba89e2
--- /dev/null
+++ b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/Comment.vm
@@ -0,0 +1,47 @@
+## Copyright (C) 2010 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.
+##
+##
+## Template Type:
+## -------------
+## This is a velocity mail template, see: http://velocity.apache.org and the
+## gerrit-docs:config-mail.txt for more info on modifying gerrit mail templates.
+##
+## Template File Names and extensions:
+## ----------------------------------
+## Gerrit will use templates ending in ".vm" but will ignore templates ending
+## in ".vm.example". If a .vm template does not exist, the default internal
+## gerrit template which is the same as the .vm.example will be used. If you
+## want to override the default template, copy the .vm.exmaple file to a .vm
+## file and edit it appropriately.
+##
+## This Template:
+## --------------
+## The Comment.vm template will determine the contents of the email related to
+## a user submitting comments on changes. It is a ChangeEmail: see
+## ChangeSubject.vm and ChangeFooter.vm.
+##
+#if ($email.coverLetter || $email.inlineComments)
+Comments on Patch Set $patchSet.patchSetId:
+
+#if ($email.coverLetter)
+$email.coverLetter
+
+#end
+#if($email.inlineComments)$email.inlineComments#end
+#if ($email.changeUrl)
+To respond, visit $email.changeUrl
+
+#end
+#end
diff --git a/gerrit-server/src/main/resources/com/google/gerrit/server/mail/MergeFail.vm b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/MergeFail.vm
new file mode 100644
index 00000000..17036a1b
--- /dev/null
+++ b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/MergeFail.vm
@@ -0,0 +1,41 @@
+## Copyright (C) 2010 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.
+##
+##
+## Template Type:
+## -------------
+## This is a velocity mail template, see: http://velocity.apache.org and the
+## gerrit-docs:config-mail.txt for more info on modifying gerrit mail templates.
+##
+## Template File Names and extensions:
+## ----------------------------------
+## Gerrit will use templates ending in ".vm" but will ignore templates ending
+## in ".vm.example". If a .vm template does not exist, the default internal
+## gerrit template which is the same as the .vm.example will be used. If you
+## want to override the default template, copy the .vm.exmaple file to a .vm
+## file and edit it appropriately.
+##
+## This Template:
+## --------------
+## The MergeFail.vm template will determine the contents of the email related
+## to a failure upon attempting to merge a change to the head. It is a
+## ChangeEmail: see ChangeSubject.vm and ChangeFooter.vm.
+##
+Change $change.key.abbreviate()#if ($patchSetInfo.author.name)
+ by $patchSetInfo.author.name#end FAILED to submit to ${change.dest.shortName}.
+
+#if ($email.coverLetter)
+$email.coverLetter
+
+#end
diff --git a/gerrit-server/src/main/resources/com/google/gerrit/server/mail/Merged.vm b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/Merged.vm
new file mode 100644
index 00000000..c459c169
--- /dev/null
+++ b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/Merged.vm
@@ -0,0 +1,38 @@
+## Copyright (C) 2010 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.
+##
+##
+## Template Type:
+## -------------
+## This is a velocity mail template, see: http://velocity.apache.org and the
+## gerrit-docs:config-mail.txt for more info on modifying gerrit mail templates.
+##
+## Template File Names and extensions:
+## ----------------------------------
+## Gerrit will use templates ending in ".vm" but will ignore templates ending
+## in ".vm.example". If a .vm template does not exist, the default internal
+## gerrit template which is the same as the .vm.example will be used. If you
+## want to override the default template, copy the .vm.exmaple file to a .vm
+## file and edit it appropriately.
+##
+## This Template:
+## --------------
+## The Merged.vm template will determine the contents of the email related to
+## a change successfully merged to the head. It is a ChangeEmail: see
+## ChangeSubject.vm and ChangeFooter.vm.
+##
+Change $changeId.abbreviate()#if ($patchSetInfo.author.name)
+ by $patchSetInfo.author.name#end submitted to $change.dest.shortName:
+
+$email.changeDetail$email.approvals
diff --git a/gerrit-server/src/main/resources/com/google/gerrit/server/mail/NewChange.vm b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/NewChange.vm
new file mode 100644
index 00000000..7f610391
--- /dev/null
+++ b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/NewChange.vm
@@ -0,0 +1,57 @@
+## Copyright (C) 2010 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.
+##
+##
+## Template Type:
+## -------------
+## This is a velocity mail template, see: http://velocity.apache.org and the
+## gerrit-docs:config-mail.txt for more info on modifying gerrit mail templates.
+##
+## Template File Names and extensions:
+## ----------------------------------
+## Gerrit will use templates ending in ".vm" but will ignore templates ending
+## in ".vm.example". If a .vm template does not exist, the default internal
+## gerrit template which is the same as the .vm.example will be used. If you
+## want to override the default template, copy the .vm.exmaple file to a .vm
+## file and edit it appropriately.
+##
+## This Template:
+## --------------
+## The NewChange.vm template will determine the contents of the email related
+## to a user submitting a new change for review. It is a ChangeEmail: see
+## ChangeSubject.vm and ChangeFooter.vm.
+##
+#set ($destination = "Change $changeId.abbreviate() for $branch.shortName in $projectName:")
+#if($email.reviewerNames)
+Hello $StringUtils.join($email.reviewerNames, ' ,'),
+
+I'd like you to do a code review.#if($email.changeUrl) Please visit
+
+ $email.changeUrl
+
+to review the following change:
+#end
+
+$destination
+#else
+$destination
+#if($email.changeUrl)
+
+ $email.changeUrl
+
+#end
+#end
+
+$email.changeDetail
+ git pull ssh://$email.sshHost/$projectName $patchSet.refName
diff --git a/gerrit-server/src/main/resources/com/google/gerrit/server/mail/RegisterNewEmail.vm b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/RegisterNewEmail.vm
new file mode 100644
index 00000000..c1de87e6
--- /dev/null
+++ b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/RegisterNewEmail.vm
@@ -0,0 +1,49 @@
+## Copyright (C) 2010 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.
+##
+##
+## Template Type:
+## -------------
+## This is a velocity mail template, see: http://velocity.apache.org and the
+## gerrit-docs:config-mail.txt for more info on modifying gerrit mail templates.
+##
+## Template File Names and extensions:
+## ----------------------------------
+## Gerrit will use templates ending in ".vm" but will ignore templates ending
+## in ".vm.example". If a .vm template does not exist, the default internal
+## gerrit template which is the same as the .vm.example will be used. If you
+## want to override the default template, copy the .vm.exmaple file to a .vm
+## file and edit it appropriately.
+##
+## This Template:
+## --------------
+## The RegisterNewEmail.vm template will determine the contents of the email
+## related to registering new email accounts.
+##
+Welcome to Gerrit Code Review at ${email.gerritHost}.
+
+To add a verified email address to your user account, please
+click on the following link:
+
+$email.gerritUrl#VE,$email.emailRegistrationToken
+
+If you have received this mail in error, you do not need to take any
+action to cancel the account. The account will not be activated, and
+you will not receive any further emails.
+
+If clicking the link above does not work, copy and paste the URL in a
+new browser window instead.
+
+This is a send-only email address. Replies to this message will not
+be read or answered.
diff --git a/gerrit-server/src/main/resources/com/google/gerrit/server/mail/ReplacePatchSet.vm b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/ReplacePatchSet.vm
new file mode 100644
index 00000000..d13b6aff
--- /dev/null
+++ b/gerrit-server/src/main/resources/com/google/gerrit/server/mail/ReplacePatchSet.vm
@@ -0,0 +1,57 @@
+## Copyright (C) 2010 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.
+##
+##
+## Template Type:
+## -------------
+## This is a velocity mail template, see: http://velocity.apache.org and the
+## gerrit-docs:config-mail.txt for more info on modifying gerrit mail templates.
+##
+## Template File Names and extensions:
+## ----------------------------------
+## Gerrit will use templates ending in ".vm" but will ignore templates ending
+## in ".vm.example". If a .vm template does not exist, the default internal
+## gerrit template which is the same as the .vm.example will be used. If you
+## want to override the default template, copy the .vm.exmaple file to a .vm
+## file and edit it appropriately.
+##
+## This Template:
+## --------------
+## The ReplacePatchSet.vm template will determine the contents of the email
+## related to a user submitting a new patchset for a change. It is a
+## ChangeEmail: see ChangeSubject.vm and ChangeFooter.vm.
+##
+#set ($destination = "Change $changeId.abbreviate() (patch set $patchSet.patchSetId) for $branch.shortName in $projectName:")
+#if($email.reviewerNames)
+Hello $StringUtils.join($email.reviewerNames, ' ,'),
+
+I'd like you to reexamine change ${changeId.abbreviate()}.#if($email.changeUrl) Please visit
+
+ $email.changeUrl
+
+to look at patch set $patchSet.patchSetId
+#end
+
+$destination
+#else
+$destination
+#if($email.changeUrl)
+
+ $email.changeUrl
+
+#end
+#end
+
+$email.changeDetail
+ git pull ssh://$email.sshHost/$projectName $patchSet.refName
diff --git a/gerrit-sshd/pom.xml b/gerrit-sshd/pom.xml
index d1adb77f..d48972f6 100644
--- a/gerrit-sshd/pom.xml
+++ b/gerrit-sshd/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
</parent>
<artifactId>gerrit-sshd</artifactId>
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java
index ee6a72a9..e2a37f59 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java
@@ -135,6 +135,11 @@ class DatabasePubKeyAuth implements PublickeyAuthenticator {
}
}
+ if (!createUser(sd, key).getAccount().isActive()) {
+ sd.authenticationError(username, "inactive-account");
+ return false;
+ }
+
return success(username, session, sd, createUser(sd, key));
}
diff --git a/gerrit-util-cli/pom.xml b/gerrit-util-cli/pom.xml
index 20f28e10..6db5241a 100644
--- a/gerrit-util-cli/pom.xml
+++ b/gerrit-util-cli/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
</parent>
<artifactId>gerrit-util-cli</artifactId>
diff --git a/gerrit-util-ssl/pom.xml b/gerrit-util-ssl/pom.xml
index 220ae479..39d3ce09 100644
--- a/gerrit-util-ssl/pom.xml
+++ b/gerrit-util-ssl/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
</parent>
<artifactId>gerrit-util-ssl</artifactId>
diff --git a/gerrit-war/pom.xml b/gerrit-war/pom.xml
index 4bfa17e2..87cfaa5f 100644
--- a/gerrit-war/pom.xml
+++ b/gerrit-war/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<parent>
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
</parent>
<artifactId>gerrit-war</artifactId>
diff --git a/pom.xml b/pom.xml
index d6b4cdbf..93ee2be6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
<groupId>com.google.gerrit</groupId>
<artifactId>gerrit-parent</artifactId>
<packaging>pom</packaging>
- <version>2.1.4-SNAPSHOT</version>
+ <version>2.1-SNAPSHOT</version>
<name>Gerrit Code Review - Parent</name>
<url>http://code.google.com/p/gerrit/</url>
@@ -483,6 +483,12 @@ limitations under the License.
</dependency>
<dependency>
+ <groupId>org.apache.velocity</groupId>
+ <artifactId>velocity</artifactId>
+ <version>1.6.4</version>
+ </dependency>
+
+ <dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>1.7.2</version>