New event listeners and new event types

This is a first step towards moving ChangeHooks into a plugin.  The
listeners[1] are now invoked from all places where corresponding
hooks are invoked.  Invocation of hooks is not removed in this change.
This will happen when we make sure that they are invoked from a new
event listener.

[1] All listeners under:
gerrit-extension-api/src/main/java/com/google/gerrit/extensions/events/

Change-Id: I6e5356edb2c326d2d7a0133b84509ad6071140d0
This commit is contained in:
Saša Živkov
2015-11-11 14:50:46 -08:00
committed by David Pursehouse
parent 32c126204b
commit 59cdd227a9
29 changed files with 1251 additions and 10 deletions

View File

@@ -27,6 +27,7 @@ public interface CommentAddedListener {
AccountInfo getAuthor();
String getComment();
Map<String, ApprovalInfo> getApprovals();
Map<String, ApprovalInfo> getOldApprovals();
}
void onCommentAdded(Event event);

View File

@@ -33,6 +33,7 @@ import com.google.gerrit.server.account.AccountByEmailCache;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.account.Realm;
import com.google.gerrit.server.extensions.events.AgreementSignup;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gwtjsonrpc.common.AsyncCallback;
import com.google.gwtjsonrpc.common.VoidResult;
@@ -58,6 +59,7 @@ class AccountSecurityImpl extends BaseServiceImplementation implements
private final ChangeHooks hooks;
private final GroupCache groupCache;
private final AuditService auditService;
private final AgreementSignup agreementSignup;
@Inject
AccountSecurityImpl(final Provider<ReviewDb> schema,
@@ -68,7 +70,8 @@ class AccountSecurityImpl extends BaseServiceImplementation implements
final DeleteExternalIds.Factory deleteExternalIdsFactory,
final ExternalIdDetailFactory.Factory externalIdDetailFactory,
final ChangeHooks hooks, final GroupCache groupCache,
final AuditService auditService) {
final AuditService auditService,
AgreementSignup agreementSignup) {
super(schema, currentUser);
realm = r;
user = u;
@@ -80,6 +83,7 @@ class AccountSecurityImpl extends BaseServiceImplementation implements
this.externalIdDetailFactory = externalIdDetailFactory;
this.hooks = hooks;
this.groupCache = groupCache;
this.agreementSignup = agreementSignup;
}
@Override
@@ -153,6 +157,7 @@ class AccountSecurityImpl extends BaseServiceImplementation implements
}
Account account = user.get().getAccount();
agreementSignup.fire(account, ca.getName());
hooks.doClaSignupHook(account, ca.getName());
final AccountGroupMember.Key key =

View File

@@ -33,6 +33,7 @@ import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.extensions.events.ChangeAbandoned;
import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.git.BatchUpdate.ChangeContext;
import com.google.gerrit.server.git.BatchUpdate.Context;
@@ -61,6 +62,7 @@ public class Abandon implements RestModifyView<ChangeResource, AbandonInput>,
private final ChangeMessagesUtil cmUtil;
private final PatchSetUtil psUtil;
private final BatchUpdate.Factory batchUpdateFactory;
private final ChangeAbandoned changeAbandoned;
@Inject
Abandon(ChangeHooks hooks,
@@ -69,7 +71,8 @@ public class Abandon implements RestModifyView<ChangeResource, AbandonInput>,
ChangeJson.Factory json,
ChangeMessagesUtil cmUtil,
PatchSetUtil psUtil,
BatchUpdate.Factory batchUpdateFactory) {
BatchUpdate.Factory batchUpdateFactory,
ChangeAbandoned changeAbandoned) {
this.hooks = hooks;
this.abandonedSenderFactory = abandonedSenderFactory;
this.dbProvider = dbProvider;
@@ -77,6 +80,7 @@ public class Abandon implements RestModifyView<ChangeResource, AbandonInput>,
this.cmUtil = cmUtil;
this.psUtil = psUtil;
this.batchUpdateFactory = batchUpdateFactory;
this.changeAbandoned = changeAbandoned;
}
@Override
@@ -171,6 +175,7 @@ public class Abandon implements RestModifyView<ChangeResource, AbandonInput>,
} catch (Exception e) {
log.error("Cannot email update for change " + change.getId(), e);
}
changeAbandoned.fire(change, patchSet, account, msgTxt);
hooks.doChangeAbandonedHook(change,
account,
patchSet,

View File

@@ -37,6 +37,8 @@ import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.events.CommitReceivedEvent;
import com.google.gerrit.server.extensions.events.CommentAdded;
import com.google.gerrit.server.extensions.events.RevisionCreated;
import com.google.gerrit.server.git.BanCommit;
import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.git.BatchUpdate.ChangeContext;
@@ -94,6 +96,8 @@ public class ChangeInserter extends BatchUpdate.InsertChangeOp {
private final CreateChangeSender.Factory createChangeSenderFactory;
private final ExecutorService sendEmailExecutor;
private final CommitValidators.Factory commitValidatorsFactory;
private final RevisionCreated revisionCreated;
private final CommentAdded commentAdded;
private final Change.Id changeId;
private final PatchSet.Id psId;
@@ -134,6 +138,8 @@ public class ChangeInserter extends BatchUpdate.InsertChangeOp {
CreateChangeSender.Factory createChangeSenderFactory,
@SendEmailExecutor ExecutorService sendEmailExecutor,
CommitValidators.Factory commitValidatorsFactory,
CommentAdded commentAdded,
RevisionCreated revisionCreated,
@Assisted Change.Id changeId,
@Assisted RevCommit commit,
@Assisted String refName) {
@@ -147,6 +153,8 @@ public class ChangeInserter extends BatchUpdate.InsertChangeOp {
this.createChangeSenderFactory = createChangeSenderFactory;
this.sendEmailExecutor = sendEmailExecutor;
this.commitValidatorsFactory = commitValidatorsFactory;
this.revisionCreated = revisionCreated;
this.commentAdded = commentAdded;
this.changeId = changeId;
this.psId = new PatchSet.Id(changeId, INITIAL_PATCH_SET_ID);
@@ -397,6 +405,7 @@ public class ChangeInserter extends BatchUpdate.InsertChangeOp {
* show a transition from an oldValue of 0 to the new value.
*/
if (runHooks) {
revisionCreated.fire(change, patchSet, ctx.getUser().getAccountId());
ReviewDb db = ctx.getDb();
hooks.doPatchsetCreatedHook(change, patchSet, db);
if (approvals != null && !approvals.isEmpty()) {
@@ -415,6 +424,9 @@ public class ChangeInserter extends BatchUpdate.InsertChangeOp {
oldApprovals.put(entry.getKey(), (short) 0);
}
}
commentAdded.fire(change, patchSet,
ctx.getUser().asIdentifiedUser().getAccount(), null,
allApprovals, oldApprovals, ctx.getWhen());
hooks.doCommentAddedHook(change,
ctx.getUser().asIdentifiedUser().getAccount(), patchSet, null,
allApprovals, oldApprovals, db);

View File

@@ -754,11 +754,17 @@ public class ChangeJson {
private ApprovalInfo approvalInfo(Account.Id id, Integer value, String tag,
Timestamp date) {
ApprovalInfo ai = getApprovalInfo(id, value, tag, date);
accountLoader.put(ai);
return ai;
}
public static ApprovalInfo getApprovalInfo(
Account.Id id, Integer value, String tag, Timestamp date) {
ApprovalInfo ai = new ApprovalInfo(id.get());
ai.value = value;
ai.date = date;
ai.tag = tag;
accountLoader.put(ai);
return ai;
}
@@ -923,6 +929,15 @@ public class ChangeJson {
return map;
}
public RevisionInfo getRevisionInfo(ChangeControl ctl, PatchSet in)
throws PatchListNotAvailableException, GpgException, OrmException,
IOException {
accountLoader = accountLoaderFactory.create(has(DETAILED_ACCOUNTS));
RevisionInfo rev = toRevisionInfo(ctl, in);
accountLoader.fill();
return rev;
}
private RevisionInfo toRevisionInfo(ChangeControl ctl, PatchSet in)
throws PatchListNotAvailableException, GpgException, OrmException,
IOException {

View File

@@ -33,6 +33,7 @@ import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.ReviewerSet;
import com.google.gerrit.server.events.CommitReceivedEvent;
import com.google.gerrit.server.extensions.events.RevisionCreated;
import com.google.gerrit.server.git.BanCommit;
import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.git.BatchUpdate.ChangeContext;
@@ -76,6 +77,7 @@ public class PatchSetInserter extends BatchUpdate.Op {
private final ReviewDb db;
private final CommitValidators.Factory commitValidatorsFactory;
private final ReplacePatchSetSender.Factory replacePatchSetFactory;
private final RevisionCreated revisionCreated;
private final ApprovalsUtil approvalsUtil;
private final ApprovalCopier approvalCopier;
private final ChangeMessagesUtil cmUtil;
@@ -118,6 +120,7 @@ public class PatchSetInserter extends BatchUpdate.Op {
CommitValidators.Factory commitValidatorsFactory,
ReplacePatchSetSender.Factory replacePatchSetFactory,
PatchSetUtil psUtil,
RevisionCreated revisionCreated,
@Assisted ChangeControl ctl,
@Assisted PatchSet.Id psId,
@Assisted RevCommit commit) {
@@ -130,6 +133,7 @@ public class PatchSetInserter extends BatchUpdate.Op {
this.commitValidatorsFactory = commitValidatorsFactory;
this.replacePatchSetFactory = replacePatchSetFactory;
this.psUtil = psUtil;
this.revisionCreated = revisionCreated;
this.origCtl = ctl;
this.psId = psId;
@@ -274,6 +278,7 @@ public class PatchSetInserter extends BatchUpdate.Op {
}
if (runHooks) {
revisionCreated.fire(change, patchSet, ctx.getUser().getAccountId());
hooks.doPatchsetCreatedHook(change, patchSet, ctx.getDb());
}
}

View File

@@ -61,6 +61,7 @@ import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.PatchLineCommentsUtil;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.account.AccountsCollection;
import com.google.gerrit.server.extensions.events.CommentAdded;
import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.git.BatchUpdate.ChangeContext;
import com.google.gerrit.server.git.BatchUpdate.Context;
@@ -110,6 +111,7 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
private final AccountsCollection accounts;
private final EmailReviewComments.Factory email;
private final ChangeHooks hooks;
private final CommentAdded commentAdded;
@Inject
PostReview(Provider<ReviewDb> db,
@@ -123,7 +125,8 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
PatchListCache patchListCache,
AccountsCollection accounts,
EmailReviewComments.Factory email,
ChangeHooks hooks) {
ChangeHooks hooks,
CommentAdded commentAdded) {
this.db = db;
this.batchUpdateFactory = batchUpdateFactory;
this.changes = changes;
@@ -136,6 +139,7 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
this.accounts = accounts;
this.email = email;
this.hooks = hooks;
this.commentAdded = commentAdded;
}
@Override
@@ -384,6 +388,9 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
comments).sendAsync();
}
try {
commentAdded.fire(
notes.getChange(), ps, user.getAccount(), message.getMessage(),
approvals, oldApprovals, ctx.getWhen());
hooks.doCommentAddedHook(notes.getChange(), user.getAccount(), ps,
message.getMessage(), approvals, oldApprovals, ctx.getDb());
} catch (OrmException e) {

View File

@@ -46,6 +46,7 @@ import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.git.BatchUpdate.ChangeContext;
import com.google.gerrit.server.git.BatchUpdate.Context;
import com.google.gerrit.server.git.UpdateException;
import com.google.gerrit.server.extensions.events.ReviewerAdded;
import com.google.gerrit.server.group.GroupsCollection;
import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.mail.AddReviewerSender;
@@ -91,6 +92,7 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer
private final ChangeHooks hooks;
private final AccountCache accountCache;
private final ReviewerJson json;
private final ReviewerAdded reviewerAdded;
@Inject
PostReviewers(AccountsCollection accounts,
@@ -108,7 +110,8 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer
@GerritServerConfig Config cfg,
ChangeHooks hooks,
AccountCache accountCache,
ReviewerJson json) {
ReviewerJson json,
ReviewerAdded reviewerAdded) {
this.accounts = accounts;
this.reviewerFactory = reviewerFactory;
this.approvalsUtil = approvalsUtil;
@@ -125,6 +128,7 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer
this.hooks = hooks;
this.accountCache = accountCache;
this.json = json;
this.reviewerAdded = reviewerAdded;
}
@Override
@@ -289,6 +293,7 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer
if (!added.isEmpty()) {
for (PatchSetApproval psa : added) {
Account account = accountCache.get(psa.getAccountId()).getAccount();
reviewerAdded.fire(rsrc.getChange(), patchSet, account);
hooks.doReviewerAddedHook(
rsrc.getChange(), account, patchSet, dbProvider.get());
}

View File

@@ -40,6 +40,7 @@ import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.account.AccountResolver;
import com.google.gerrit.server.change.PublishDraftPatchSet.Input;
import com.google.gerrit.server.extensions.events.DraftPublished;
import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.git.BatchUpdate.ChangeContext;
import com.google.gerrit.server.git.BatchUpdate.Context;
@@ -82,6 +83,7 @@ public class PublishDraftPatchSet implements RestModifyView<RevisionResource, In
private final PatchSetUtil psUtil;
private final Provider<ReviewDb> dbProvider;
private final ReplacePatchSetSender.Factory replacePatchSetFactory;
private final DraftPublished draftPublished;
@Inject
public PublishDraftPatchSet(
@@ -93,7 +95,8 @@ public class PublishDraftPatchSet implements RestModifyView<RevisionResource, In
PatchSetInfoFactory patchSetInfoFactory,
PatchSetUtil psUtil,
Provider<ReviewDb> dbProvider,
ReplacePatchSetSender.Factory replacePatchSetFactory) {
ReplacePatchSetSender.Factory replacePatchSetFactory,
DraftPublished draftPublished) {
this.accountResolver = accountResolver;
this.approvalsUtil = approvalsUtil;
this.updateFactory = updateFactory;
@@ -103,6 +106,7 @@ public class PublishDraftPatchSet implements RestModifyView<RevisionResource, In
this.psUtil = psUtil;
this.dbProvider = dbProvider;
this.replacePatchSetFactory = replacePatchSetFactory;
this.draftPublished = draftPublished;
}
@Override
@@ -223,6 +227,7 @@ public class PublishDraftPatchSet implements RestModifyView<RevisionResource, In
@Override
public void postUpdate(Context ctx) throws OrmException {
draftPublished.fire(change, patchSet, ctx.getUser().getAccountId());
hooks.doDraftPublishedHook(change, patchSet, ctx.getDb());
if (patchSet.isDraft() && change.getStatus() == Change.Status.DRAFT) {
// Skip emails if the patch set is still a draft.

View File

@@ -29,6 +29,7 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.change.PutTopic.Input;
import com.google.gerrit.server.extensions.events.TopicEdited;
import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.git.BatchUpdate.ChangeContext;
import com.google.gerrit.server.git.BatchUpdate.Context;
@@ -47,6 +48,7 @@ public class PutTopic implements RestModifyView<ChangeResource, Input>,
private final ChangeHooks hooks;
private final ChangeMessagesUtil cmUtil;
private final BatchUpdate.Factory batchUpdateFactory;
private final TopicEdited topicEdited;
public static class Input {
@DefaultInput
@@ -57,11 +59,13 @@ public class PutTopic implements RestModifyView<ChangeResource, Input>,
PutTopic(Provider<ReviewDb> dbProvider,
ChangeHooks hooks,
ChangeMessagesUtil cmUtil,
BatchUpdate.Factory batchUpdateFactory) {
BatchUpdate.Factory batchUpdateFactory,
TopicEdited topicEdited) {
this.dbProvider = dbProvider;
this.hooks = hooks;
this.cmUtil = cmUtil;
this.batchUpdateFactory = batchUpdateFactory;
this.topicEdited = topicEdited;
}
@Override
@@ -129,6 +133,9 @@ public class PutTopic implements RestModifyView<ChangeResource, Input>,
@Override
public void postUpdate(Context ctx) throws OrmException {
if (change != null) {
topicEdited.fire(change,
ctx.getUser().asIdentifiedUser().getAccount(),
oldTopicName);
hooks.doTopicChangedHook(
change,
ctx.getUser().asIdentifiedUser().getAccount(),

View File

@@ -32,6 +32,7 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.extensions.events.ChangeRestored;
import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.git.BatchUpdate.ChangeContext;
import com.google.gerrit.server.git.BatchUpdate.Context;
@@ -60,6 +61,7 @@ public class Restore implements RestModifyView<ChangeResource, RestoreInput>,
private final ChangeMessagesUtil cmUtil;
private final PatchSetUtil psUtil;
private final BatchUpdate.Factory batchUpdateFactory;
private final ChangeRestored changeRestored;
@Inject
Restore(ChangeHooks hooks,
@@ -68,7 +70,8 @@ public class Restore implements RestModifyView<ChangeResource, RestoreInput>,
ChangeJson.Factory json,
ChangeMessagesUtil cmUtil,
PatchSetUtil psUtil,
BatchUpdate.Factory batchUpdateFactory) {
BatchUpdate.Factory batchUpdateFactory,
ChangeRestored changeRestored) {
this.hooks = hooks;
this.restoredSenderFactory = restoredSenderFactory;
this.dbProvider = dbProvider;
@@ -76,6 +79,7 @@ public class Restore implements RestModifyView<ChangeResource, RestoreInput>,
this.cmUtil = cmUtil;
this.psUtil = psUtil;
this.batchUpdateFactory = batchUpdateFactory;
this.changeRestored = changeRestored;
}
@Override
@@ -154,6 +158,9 @@ public class Restore implements RestModifyView<ChangeResource, RestoreInput>,
} catch (Exception e) {
log.error("Cannot email update for change " + change.getId(), e);
}
changeRestored.fire(change, patchSet,
ctx.getUser().asIdentifiedUser().getAccount(),
Strings.emptyToNull(input.message));
hooks.doChangeRestoredHook(change,
ctx.getUser().asIdentifiedUser().getAccount(),
patchSet,

View File

@@ -30,6 +30,7 @@ import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.ChangeMessage;
import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.extensions.events.HashtagsEdited;
import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.git.BatchUpdate.ChangeContext;
import com.google.gerrit.server.git.BatchUpdate.Context;
@@ -56,6 +57,7 @@ public class SetHashtagsOp extends BatchUpdate.Op {
private final ChangeMessagesUtil cmUtil;
private final ChangeHooks hooks;
private final DynamicSet<HashtagValidationListener> validationListeners;
private final HashtagsEdited hashtagsEdited;
private final HashtagsInput input;
private boolean runHooks = true;
@@ -71,11 +73,13 @@ public class SetHashtagsOp extends BatchUpdate.Op {
ChangeMessagesUtil cmUtil,
ChangeHooks hooks,
DynamicSet<HashtagValidationListener> validationListeners,
HashtagsEdited hashtagsEdited,
@Assisted @Nullable HashtagsInput input) {
this.notesMigration = notesMigration;
this.cmUtil = cmUtil;
this.hooks = hooks;
this.validationListeners = validationListeners;
this.hashtagsEdited = hashtagsEdited;
this.input = input;
}
@@ -166,6 +170,8 @@ public class SetHashtagsOp extends BatchUpdate.Op {
@Override
public void postUpdate(Context ctx) throws OrmException {
if (updated() && runHooks) {
hashtagsEdited.fire(change, ctx.getUser().getAccountId(), updatedHashtags,
toAdd, toRemove);
hooks.doHashtagsChangedHook(
change, ctx.getUser().asIdentifiedUser().getAccount(),
toAdd, toRemove, updatedHashtags,

View File

@@ -29,12 +29,23 @@ import com.google.gerrit.extensions.config.DownloadCommand;
import com.google.gerrit.extensions.config.DownloadScheme;
import com.google.gerrit.extensions.config.ExternalIncludedIn;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.gerrit.extensions.events.AgreementSignupListener;
import com.google.gerrit.extensions.events.ChangeAbandonedListener;
import com.google.gerrit.extensions.events.ChangeMergedListener;
import com.google.gerrit.extensions.events.ChangeRestoredListener;
import com.google.gerrit.extensions.events.CommentAddedListener;
import com.google.gerrit.extensions.events.DraftPublishedListener;
import com.google.gerrit.extensions.events.GarbageCollectorListener;
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
import com.google.gerrit.extensions.events.HashtagsEditedListener;
import com.google.gerrit.extensions.events.HeadUpdatedListener;
import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.gerrit.extensions.events.NewProjectCreatedListener;
import com.google.gerrit.extensions.events.PluginEventListener;
import com.google.gerrit.extensions.events.ProjectDeletedListener;
import com.google.gerrit.extensions.events.ReviewerAddedListener;
import com.google.gerrit.extensions.events.RevisionCreatedListener;
import com.google.gerrit.extensions.events.TopicEditedListener;
import com.google.gerrit.extensions.events.UsageDataPublishedListener;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.extensions.registration.DynamicMap;
@@ -283,6 +294,17 @@ public class GerritGlobalModule extends FactoryModule {
DynamicSet.setOf(binder(), CacheRemovalListener.class);
DynamicMap.mapOf(binder(), CapabilityDefinition.class);
DynamicSet.setOf(binder(), GitReferenceUpdatedListener.class);
DynamicSet.setOf(binder(), ChangeAbandonedListener.class);
DynamicSet.setOf(binder(), CommentAddedListener.class);
DynamicSet.setOf(binder(), DraftPublishedListener.class);
DynamicSet.setOf(binder(), HashtagsEditedListener.class);
DynamicSet.setOf(binder(), ChangeMergedListener.class);
DynamicSet.setOf(binder(), ChangeRestoredListener.class);
DynamicSet.setOf(binder(), ReviewerAddedListener.class);
DynamicSet.setOf(binder(), RevisionCreatedListener.class);
DynamicSet.setOf(binder(), TopicEditedListener.class);
DynamicSet.setOf(binder(), AgreementSignupListener.class);
DynamicSet.setOf(binder(), PluginEventListener.class);
DynamicSet.setOf(binder(), ReceivePackInitializer.class);
DynamicSet.setOf(binder(), PostReceiveHook.class);
DynamicSet.setOf(binder(), PreUploadHook.class);

View File

@@ -0,0 +1,31 @@
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.extensions.events;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.events.ChangeEvent;
public abstract class AbstractChangeEvent implements ChangeEvent {
private final ChangeInfo changeInfo;
protected AbstractChangeEvent(ChangeInfo change) {
this.changeInfo = change;
}
@Override
public ChangeInfo getChange() {
return changeInfo;
}
}

View File

@@ -0,0 +1,35 @@
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.extensions.events;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.extensions.events.RevisionEvent;
public abstract class AbstractRevisionEvent extends AbstractChangeEvent
implements RevisionEvent {
private final RevisionInfo revisionInfo;
protected AbstractRevisionEvent(ChangeInfo change, RevisionInfo revision) {
super(change);
revisionInfo = revision;
}
@Override
public RevisionInfo getRevision() {
return revisionInfo;
}
}

View File

@@ -0,0 +1,64 @@
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.extensions.events;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.events.AgreementSignupListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.reviewdb.client.Account;
import com.google.inject.Inject;
public class AgreementSignup {
private final DynamicSet<AgreementSignupListener> listeners;
private final EventUtil util;
@Inject
AgreementSignup(DynamicSet<AgreementSignupListener> listeners,
EventUtil util) {
this.listeners = listeners;
this.util = util;
}
public void fire(Account account, String agreementName) {
if (!listeners.iterator().hasNext()) {
return;
}
Event e = new Event(util.accountInfo(account), agreementName);
for (AgreementSignupListener l : listeners) {
l.onAgreementSignup(e);
}
}
private static class Event implements AgreementSignupListener.Event {
private final AccountInfo account;
private final String agreementName;
Event(AccountInfo account, String agreementName) {
this.account = account;
this.agreementName = agreementName;
}
@Override
public AccountInfo getAccount() {
return account;
}
@Override
public String getAgreementName() {
return agreementName;
}
}
}

View File

@@ -0,0 +1,97 @@
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.extensions.events;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.extensions.events.ChangeAbandonedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.GpgException;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
public class ChangeAbandoned {
private static final Logger log =
LoggerFactory.getLogger(ChangeAbandoned.class);
private final DynamicSet<ChangeAbandonedListener> listeners;
private final EventUtil util;
@Inject
ChangeAbandoned(DynamicSet<ChangeAbandonedListener> listeners,
EventUtil util) {
this.listeners = listeners;
this.util = util;
}
public void fire(ChangeInfo change, RevisionInfo revision,
AccountInfo abandoner, String reason) {
if (!listeners.iterator().hasNext()) {
return;
}
Event e = new Event(change, revision, abandoner, reason);
for (ChangeAbandonedListener l : listeners) {
l.onChangeAbandoned(e);
}
}
public void fire(Change change, PatchSet ps, Account abandoner, String reason) {
if (!listeners.iterator().hasNext()) {
return;
}
try {
fire(util.changeInfo(change),
util.revisionInfo(change.getProject(), ps),
util.accountInfo(abandoner),
reason);
} catch (PatchListNotAvailableException | GpgException | IOException
| OrmException e) {
log.error("Couldn't fire event", e);
}
}
private static class Event extends AbstractRevisionEvent
implements ChangeAbandonedListener.Event {
private final AccountInfo abandoner;
private final String reason;
Event(ChangeInfo change, RevisionInfo revision, AccountInfo abandoner,
String reason) {
super(change, revision);
this.abandoner = abandoner;
this.reason = reason;
}
@Override
public AccountInfo getAbandoner() {
return abandoner;
}
@Override
public String getReason() {
return reason;
}
}
}

View File

@@ -0,0 +1,98 @@
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.extensions.events;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.extensions.events.ChangeMergedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.GpgException;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
public class ChangeMerged {
private static final Logger log =
LoggerFactory.getLogger(ChangeAbandoned.class);
private final DynamicSet<ChangeMergedListener> listeners;
private final EventUtil util;
@Inject
ChangeMerged(DynamicSet<ChangeMergedListener> listeners,
EventUtil util) {
this.listeners = listeners;
this.util = util;
}
public void fire(ChangeInfo change, RevisionInfo revision,
AccountInfo merger, String newRevisionId) {
if (!listeners.iterator().hasNext()) {
return;
}
Event e = new Event(change, revision, merger, newRevisionId);
for (ChangeMergedListener l : listeners) {
l.onChangeMerged(e);
}
}
public void fire(Change change, PatchSet ps, Account merger,
String newRevisionId) {
if (!listeners.iterator().hasNext()) {
return;
}
try {
fire(util.changeInfo(change),
util.revisionInfo(change.getProject(), ps),
util.accountInfo(merger),
newRevisionId);
} catch (PatchListNotAvailableException | GpgException | IOException
| OrmException e) {
log.error("Couldn't fire event", e);
}
}
private static class Event extends AbstractRevisionEvent
implements ChangeMergedListener.Event {
private final AccountInfo merger;
private final String newRevisionId;
Event(ChangeInfo change, RevisionInfo revision, AccountInfo merger,
String newRevisionId) {
super(change, revision);
this.merger = merger;
this.newRevisionId = newRevisionId;
}
@Override
public AccountInfo getMerger() {
return merger;
}
@Override
public String getNewRevisionId() {
return newRevisionId;
}
}
}

View File

@@ -0,0 +1,98 @@
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.extensions.events;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.extensions.events.ChangeRestoredListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.GpgException;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ChangeRestored {
private static final Logger log =
LoggerFactory.getLogger(ChangeRestored.class);
private final DynamicSet<ChangeRestoredListener> listeners;
private final EventUtil util;
@Inject
ChangeRestored(DynamicSet<ChangeRestoredListener> listeners,
EventUtil util) {
this.listeners = listeners;
this.util = util;
}
public void fire(ChangeInfo change, RevisionInfo revision,
AccountInfo restorer, String reason) {
Event e = new Event(change, revision, restorer, reason);
if (!listeners.iterator().hasNext()) {
return;
}
for (ChangeRestoredListener l : listeners) {
l.onChangeRestored(e);
}
}
public void fire(Change change, PatchSet ps, Account restorer, String reason) {
if (!listeners.iterator().hasNext()) {
return;
}
try {
fire(util.changeInfo(change),
util.revisionInfo(change.getProject(), ps),
util.accountInfo(restorer),
reason);
} catch (PatchListNotAvailableException | GpgException | IOException
| OrmException e) {
log.error("Couldn't fire event", e);
}
}
private static class Event extends AbstractRevisionEvent
implements ChangeRestoredListener.Event {
private AccountInfo restorer;
private String reason;
Event(ChangeInfo change, RevisionInfo revision, AccountInfo restorer,
String reason) {
super(change, revision);
this.restorer = restorer;
this.reason = reason;
}
@Override
public AccountInfo getRestorer() {
return restorer;
}
@Override
public String getReason() {
return reason;
}
}
}

View File

@@ -0,0 +1,122 @@
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.extensions.events;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ApprovalInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.extensions.events.CommentAddedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.GpgException;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.Map;
public class CommentAdded {
private static final Logger log =
LoggerFactory.getLogger(CommentAdded.class);
private final DynamicSet<CommentAddedListener> listeners;
private final EventUtil util;
@Inject
CommentAdded(DynamicSet<CommentAddedListener> listeners,
EventUtil util) {
this.listeners = listeners;
this.util = util;
}
public void fire(ChangeInfo change, RevisionInfo revision, AccountInfo author,
String comment, Map<String, ApprovalInfo> approvals,
Map<String, ApprovalInfo> oldApprovals) {
if (!listeners.iterator().hasNext()) {
return;
}
Event e = new Event(
change, revision, author, comment, approvals, oldApprovals);
for (CommentAddedListener l : listeners) {
l.onCommentAdded(e);
}
}
public void fire(Change change, PatchSet ps, Account author,
String comment, Map<String, Short> approvals,
Map<String, Short> oldApprovals, Timestamp ts) {
if (!listeners.iterator().hasNext()) {
return;
}
try {
fire(util.changeInfo(change),
util.revisionInfo(change.getProject(), ps),
util.accountInfo(author),
comment,
util.approvals(author, approvals, ts),
util.approvals(author, oldApprovals, ts));
} catch (PatchListNotAvailableException | GpgException | IOException
| OrmException e) {
log.error("Couldn't fire event", e);
}
}
private static class Event extends AbstractRevisionEvent
implements CommentAddedListener.Event {
private final AccountInfo author;
private final String comment;
private final Map<String, ApprovalInfo> approvals;
private final Map<String, ApprovalInfo> oldApprovals;
Event(ChangeInfo change, RevisionInfo revision, AccountInfo author,
String comment, Map<String, ApprovalInfo> approvals,
Map<String, ApprovalInfo> oldApprovals) {
super(change, revision);
this.author = author;
this.comment = comment;
this.approvals = approvals;
this.oldApprovals = oldApprovals;
}
@Override
public AccountInfo getAuthor() {
return author;
}
@Override
public String getComment() {
return comment;
}
@Override
public Map<String, ApprovalInfo> getApprovals() {
return approvals;
}
@Override
public Map<String, ApprovalInfo> getOldApprovals() {
return oldApprovals;
}
}
}

View File

@@ -0,0 +1,85 @@
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.extensions.events;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.extensions.events.DraftPublishedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.GpgException;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
public class DraftPublished {
private static final Logger log =
LoggerFactory.getLogger(DraftPublished.class);
private final DynamicSet<DraftPublishedListener> listeners;
private final EventUtil util;
@Inject
public DraftPublished(DynamicSet<DraftPublishedListener> listeners,
EventUtil util) {
this.listeners = listeners;
this.util = util;
}
public void fire(ChangeInfo change, RevisionInfo revision,
AccountInfo publisher) {
if (!listeners.iterator().hasNext()) {
return;
}
Event e = new Event(change, revision, publisher);
for (DraftPublishedListener l : listeners) {
l.onDraftPublished(e);
}
}
public void fire(Change change, PatchSet patchSet, Account.Id accountId) {
try {
fire(util.changeInfo(change),
util.revisionInfo(change.getProject(), patchSet),
util.accountInfo(accountId));
} catch (PatchListNotAvailableException | GpgException | IOException
| OrmException e) {
log.error("Couldn't fire event", e);
}
}
private static class Event extends AbstractRevisionEvent
implements DraftPublishedListener.Event {
private final AccountInfo publisher;
Event(ChangeInfo change, RevisionInfo revision, AccountInfo publisher) {
super(change, revision);
this.publisher = publisher;
}
@Override
public AccountInfo getPublisher() {
return publisher;
}
}
}

View File

@@ -15,19 +15,66 @@
package com.google.gerrit.server.extensions.events;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ApprovalInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.server.GpgException;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.change.ChangeJson;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;
public class EventUtil {
private final ChangeData.Factory changeDataFactory;
private final Provider<ReviewDb> db;
private final ChangeJson changeJson;
private final AccountCache accountCache;
@Inject
EventUtil(AccountCache accountCache) {
EventUtil(ChangeJson.Factory changeJsonFactory,
ChangeData.Factory changeDataFactory,
Provider<ReviewDb> db,
AccountCache accountCache) {
this.changeDataFactory = changeDataFactory;
this.db = db;
this.changeJson = changeJsonFactory.create(ChangeJson.NO_OPTIONS);
this.accountCache = accountCache;
}
public ChangeInfo changeInfo(Change change) throws OrmException {
return changeJson.format(change);
}
public RevisionInfo revisionInfo(Project project, PatchSet ps)
throws OrmException, PatchListNotAvailableException, GpgException,
IOException {
return revisionInfo(project.getNameKey(), ps);
}
public RevisionInfo revisionInfo(Project.NameKey project, PatchSet ps)
throws OrmException, PatchListNotAvailableException, GpgException,
IOException {
ChangeData cd = changeDataFactory.create(db.get(),
project, ps.getId().getParentKey());
ChangeControl ctl = cd.changeControl();
return changeJson.getRevisionInfo(ctl, ps);
}
public AccountInfo accountInfo(Account a) {
if (a == null || a.getId() == null) {
return null;
@@ -42,4 +89,15 @@ public class EventUtil {
public AccountInfo accountInfo(Account.Id accountId) {
return accountInfo(accountCache.get(accountId).getAccount());
}
public Map<String, ApprovalInfo> approvals(Account a,
Map<String, Short> approvals, Timestamp ts) {
Map<String, ApprovalInfo> result = new HashMap<>();
for (Map.Entry<String, Short> e : approvals.entrySet()) {
Integer value = e.getValue() != null ? new Integer(e.getValue()) : null;
result.put(e.getKey(),
ChangeJson.getApprovalInfo(a.getId(), value, null, ts));
}
return result;
}
}

View File

@@ -115,6 +115,9 @@ public class GitReferenceUpdated {
public void fire(Project.NameKey project, BatchRefUpdate batchRefUpdate,
Account.Id updater) {
if (!listeners.iterator().hasNext()) {
return;
}
for (ReceiveCommand cmd : batchRefUpdate.getCommands()) {
if (cmd.getResult() == ReceiveCommand.Result.OK) {
fire(project, cmd, util.accountInfo(updater));
@@ -130,6 +133,9 @@ public class GitReferenceUpdated {
private void fire(Project.NameKey project, String ref, ObjectId oldObjectId,
ObjectId newObjectId, ReceiveCommand.Type type, AccountInfo updater) {
if (!listeners.iterator().hasNext()) {
return;
}
ObjectId o = oldObjectId != null ? oldObjectId : ObjectId.zeroId();
ObjectId n = newObjectId != null ? newObjectId : ObjectId.zeroId();
Event event = new Event(project, ref, o.name(), n.name(), type, updater);

View File

@@ -0,0 +1,110 @@
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.extensions.events;
import com.google.common.collect.ImmutableSortedSet;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.events.HashtagsEditedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.reviewdb.client.Account.Id;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.Set;
public class HashtagsEdited {
private static final Logger log =
LoggerFactory.getLogger(HashtagsEdited.class);
private final DynamicSet<HashtagsEditedListener> listeners;
private final EventUtil util;
@Inject
public HashtagsEdited(DynamicSet<HashtagsEditedListener> listeners,
EventUtil util) {
this.listeners = listeners;
this.util = util;
}
public void fire(ChangeInfo change, AccountInfo editor, Collection<String> hashtags,
Collection<String> added, Collection<String> removed) {
Event e = new Event(change, editor, hashtags, added, removed);
if (!listeners.iterator().hasNext()) {
return;
}
for (HashtagsEditedListener l : listeners) {
l.onHashtagsEdited(e);
}
}
public void fire(Change change, Id accountId,
ImmutableSortedSet<String> updatedHashtags, Set<String> toAdd,
Set<String> toRemove) {
if (!listeners.iterator().hasNext()) {
return;
}
try {
fire(util.changeInfo(change),
util.accountInfo(accountId),
updatedHashtags, toAdd, toRemove);
} catch (OrmException e) {
log.error("Couldn't fire event", e);
}
}
private static class Event extends AbstractChangeEvent
implements HashtagsEditedListener.Event {
private AccountInfo editor;
private Collection<String> updatedHashtags;
private Collection<String> addedHashtags;
private Collection<String> removedHashtags;
Event(ChangeInfo change, AccountInfo editor, Collection<String> updated,
Collection<String> added, Collection<String> removed) {
super(change);
this.editor = editor;
this.updatedHashtags = updated;
this.addedHashtags = added;
this.removedHashtags = removed;
}
@Override
public AccountInfo getEditor() {
return editor;
}
@Override
public Collection<String> getHashtags() {
return updatedHashtags;
}
@Override
public Collection<String> getAddedHashtags() {
return addedHashtags;
}
@Override
public Collection<String> getRemovedHashtags() {
return removedHashtags;
}
}
}

View File

@@ -0,0 +1,65 @@
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.extensions.events;
import com.google.gerrit.extensions.events.PluginEventListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.inject.Inject;
public class PluginEvent {
private final DynamicSet<PluginEventListener> listeners;
@Inject
PluginEvent(DynamicSet<PluginEventListener> listeners) {
this.listeners = listeners;
}
public void fire(String pluginName, String type, String data) {
if (!listeners.iterator().hasNext()) {
return;
}
Event e = new Event(pluginName, type, data);
for (PluginEventListener l : listeners) {
l.onPluginEvent(e);
}
}
private static class Event implements PluginEventListener.Event {
private final String pluginName;
private final String type;
private final String data;
Event(String pluginName, String type, String data) {
this.pluginName = pluginName;
this.type = type;
this.data = data;
}
@Override
public String pluginName() {
return pluginName;
}
@Override
public String getType() {
return type;
}
@Override
public String getData() {
return data;
}
}
}

View File

@@ -0,0 +1,88 @@
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.extensions.events;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.extensions.events.ReviewerAddedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.GpgException;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
public class ReviewerAdded {
private static final Logger log =
LoggerFactory.getLogger(ReviewerAdded.class);
private final DynamicSet<ReviewerAddedListener> listeners;
private final EventUtil util;
@Inject
ReviewerAdded(DynamicSet<ReviewerAddedListener> listeners,
EventUtil util) {
this.listeners = listeners;
this.util = util;
}
public void fire(ChangeInfo change, RevisionInfo revision,
AccountInfo reviewer) {
if (!listeners.iterator().hasNext()) {
return;
}
Event e = new Event(change, revision, reviewer);
for (ReviewerAddedListener l : listeners) {
l.onReviewerAdded(e);
}
}
public void fire(Change change, PatchSet patchSet, Account account) {
if (!listeners.iterator().hasNext()) {
return;
}
try {
fire(util.changeInfo(change),
util.revisionInfo(change.getProject(), patchSet),
util.accountInfo(account));
} catch (PatchListNotAvailableException | GpgException | IOException
| OrmException e) {
log.error("Couldn't fire event", e);
}
}
private static class Event extends AbstractRevisionEvent
implements ReviewerAddedListener.Event {
private final AccountInfo reviewer;
Event(ChangeInfo change, RevisionInfo revision, AccountInfo reviewer) {
super(change, revision);
this.reviewer = reviewer;
}
@Override
public AccountInfo getReviewer() {
return reviewer;
}
}
}

View File

@@ -0,0 +1,88 @@
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.extensions.events;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.extensions.events.RevisionCreatedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.GpgException;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
public class RevisionCreated {
private static final Logger log =
LoggerFactory.getLogger(RevisionCreated.class);
private final DynamicSet<RevisionCreatedListener> listeners;
private final EventUtil util;
@Inject
RevisionCreated(DynamicSet<RevisionCreatedListener> listeners,
EventUtil util) {
this.listeners = listeners;
this.util = util;
}
public void fire(ChangeInfo change, RevisionInfo revision,
AccountInfo uploader) {
if (!listeners.iterator().hasNext()) {
return;
}
Event e = new Event(change, revision, uploader);
for (RevisionCreatedListener l : listeners) {
l.onRevisionCreated(e);
}
}
public void fire(Change change, PatchSet patchSet, Account.Id uploader) {
if (!listeners.iterator().hasNext()) {
return;
}
try {
fire(util.changeInfo(change),
util.revisionInfo(change.getProject(), patchSet),
util.accountInfo(uploader));
} catch ( PatchListNotAvailableException | GpgException | IOException
| OrmException e) {
log.error("Couldn't fire event", e);
}
}
private static class Event extends AbstractRevisionEvent
implements RevisionCreatedListener.Event {
private final AccountInfo uploader;
Event(ChangeInfo change, RevisionInfo revision, AccountInfo uploader) {
super(change, revision);
this.uploader = uploader;
}
@Override
public AccountInfo getUploader() {
return uploader;
}
}
}

View File

@@ -0,0 +1,87 @@
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.extensions.events;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.events.TopicEditedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TopicEdited {
private static final Logger log =
LoggerFactory.getLogger(TopicEdited.class);
private final DynamicSet<TopicEditedListener> listeners;
private final EventUtil util;
@Inject
TopicEdited(DynamicSet<TopicEditedListener> listeners,
EventUtil util) {
this.listeners = listeners;
this.util = util;
}
public void fire(ChangeInfo change, AccountInfo editor, String oldTopic) {
if (!listeners.iterator().hasNext()) {
return;
}
Event e = new Event(change, editor, oldTopic);
for (TopicEditedListener l : listeners) {
l.onTopicEdited(e);
}
}
public void fire(Change change, Account account, String oldTopicName) {
if (!listeners.iterator().hasNext()) {
return;
}
try {
fire(util.changeInfo(change),
util.accountInfo(account),
oldTopicName);
} catch (OrmException e) {
log.error("Couldn't fire event", e);
}
}
private static class Event extends AbstractChangeEvent
implements TopicEditedListener.Event {
private final AccountInfo editor;
private final String oldTopic;
Event(ChangeInfo change, AccountInfo editor, String oldTopic) {
super(change);
this.editor = editor;
this.oldTopic = oldTopic;
}
@Override
public AccountInfo getEditor() {
return editor;
}
@Override
public String getOldTopic() {
return oldTopic;
}
}
}

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.server.git;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.ChangeMessage;
import com.google.gerrit.reviewdb.client.LabelId;
@@ -26,6 +27,7 @@ import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.extensions.events.ChangeMerged;
import com.google.gerrit.server.git.BatchUpdate.ChangeContext;
import com.google.gerrit.server.git.BatchUpdate.Context;
import com.google.gerrit.server.mail.MergedSender;
@@ -65,6 +67,7 @@ public class MergedByPushOp extends BatchUpdate.Op {
private final MergedSender.Factory mergedSenderFactory;
private final PatchSetUtil psUtil;
private final ExecutorService sendEmailExecutor;
private final ChangeMerged changeMerged;
private final PatchSet.Id psId;
private final String refName;
@@ -83,6 +86,7 @@ public class MergedByPushOp extends BatchUpdate.Op {
MergedSender.Factory mergedSenderFactory,
PatchSetUtil psUtil,
@SendEmailExecutor ExecutorService sendEmailExecutor,
ChangeMerged changeMerged,
@Assisted RequestScopePropagator requestScopePropagator,
@Assisted PatchSet.Id psId,
@Assisted String refName) {
@@ -92,6 +96,7 @@ public class MergedByPushOp extends BatchUpdate.Op {
this.mergedSenderFactory = mergedSenderFactory;
this.psUtil = psUtil;
this.sendEmailExecutor = sendEmailExecutor;
this.changeMerged = changeMerged;
this.requestScopePropagator = requestScopePropagator;
this.psId = psId;
this.refName = refName;
@@ -194,9 +199,11 @@ public class MergedByPushOp extends BatchUpdate.Op {
}
}));
Account account = ctx.getUser().asIdentifiedUser().getAccount();
hooks.doChangeMergedHook(
change, ctx.getUser().asIdentifiedUser().getAccount(), patchSet,
change, account, patchSet,
ctx.getDb(), patchSet.getRevision().get());
changeMerged.fire(change, patchSet, account, patchSet.getRevision().get());
}
private PatchSetInfo getPatchSetInfo(ChangeContext ctx) throws IOException {