適用於Communities元件的OSGi事件
- 主題:
- 社群
建立對象:
- 管理員
概觀
當成員與Communities功能互動時,會傳送可觸發非同步接聽程式的OSGi事件,例如通知或遊戲化(評分和徽章)。
元件的SocialEvent執行個體會將事件記錄為topic
發生的actions
。 SocialEvent包含傳回與動作相關聯之verb
的方法。 actions
與verbs
之間有 n-1 關係。
針對發行版本中傳遞的Communities元件,下表說明針對每個topic
定義的verbs
可供使用。
主題和動詞
行事曆元件
社交活動topic
= com/adobe/cq/social/calendar
動詞 | 說明 |
---|---|
POST | 成員建立行事曆事件 |
新增 | 行事曆事件的成員註解 |
更新 | 編輯成員的行事曆事件或註解 |
刪除 | 成員的行事曆事件或註解已刪除 |
註解元件
SocialEvent topic
= com/adobe/cq/social/comment
動詞 | 說明 |
---|---|
POST | 成員建立註解 |
新增 | 成員回複評論 |
更新 | 已編輯成員的註解 |
刪除 | 已刪除成員的註解 |
檔案庫元件
SocialEvent topic
= com/adobe/cq/social/fileLibrary
動詞 | 說明 |
---|---|
POST | 成員建立資料夾 |
附加 | 成員上傳檔案 |
更新 | 成員更新資料夾或檔案 |
刪除 | 成員刪除資料夾或檔案 |
論壇元件
SocialEvent topic
= com/adobe/cq/social/forum
動詞 | 說明 |
---|---|
POST | 成員建立論壇主題 |
新增 | 成員對論壇主題的回覆 |
更新 | 成員的論壇主題或回覆已編輯 |
刪除 | 已刪除成員的論壇主題或回覆 |
日誌元件
SocialEvent topic
= com/adobe/cq/social/journal
動詞 | 說明 |
---|---|
POST | 成員建立部落格 |
新增 | 部落格上的成員評論 |
更新 | 編輯成員的部落格或評論 |
刪除 | 成員的部落格或評論已刪除 |
QnA元件
SocialEvent topic
= com/adobe/cq/social/qna
動詞 | 說明 |
---|---|
POST | 成員建立QnA問題 |
新增 | 成員建立QnA答案 |
更新 | 編輯成員的QnA問題或答案 |
選取 | 已選取成員的答案 |
取消選取 | 已取消選取成員的答案 |
刪除 | 已刪除成員的QnA問題或答案 |
檢閱元件
SocialEvent topic
= com/adobe/cq/social/review
動詞 | 說明 |
---|---|
POST | 成員建立稽核 |
更新 | 成員的稽核已編輯 |
刪除 | 已刪除成員的評論 |
評等元件
SocialEvent topic
= com/adobe/cq/social/tally
動詞 | 說明 |
---|---|
新增評等 | 已對成員內容進行升級 |
移除評等 | 成員的內容已降級 |
投票元件
SocialEvent topic
= com/adobe/cq/social/tally
動詞 | 說明 |
---|---|
新增投票 | 成員內容已投贊成票 |
移除投票 | 成員內容已被投票否決 |
啟用仲裁的元件
SocialEvent topic
= com/adobe/cq/social/moderation
動詞 | 說明 |
---|---|
拒絕 | 成員內容遭拒 |
如有不當情形,加註旗標 | 成員內容已標幟 |
如有不當情形,取消標幟 | 成員的內容未標幟 |
ACCEPT | 仲裁者已核准成員的內容 |
關閉 | 成員關閉評論以進行編輯和回覆 |
開啟 | 成員重新開啟註解 |
自訂元件的事件
對於自訂元件,SocialEvent抽象類別必須延伸d,以將元件的事件記錄為topic
發生的actions
。
自訂事件會覆寫方法getVerb()
,以便為每個action
傳回適當的verb
。 針對動作傳回的verb
可以是常用的(例如POST
)或專用於元件的(例如ADD RATING
)。 actions
與verbs
之間有 n-1 關係。
自訂元件事件的偽程式碼
org.osgi.service.event.Event;
com.adobe.cq.social.scf.core.SocialEvent;
com.adobe.granite.activitystreams.ObjectTypes;
com.adobe.granite.activitystreams.Verbs;
package com.mycompany.recipe;
import org.osgi.service.event.Event;
import com.adobe.cq.social.scf.core.SocialEvent;
import com.adobe.granite.activitystreams.ObjectTypes;
import com.adobe.granite.activitystreams.Verbs;
/*
* The Recipe type, passed to RecipeEvent(), would be a custom Recipe class
* that extends either
* com.adobe.cq.social.scf.SocialComponent
* or
* com.adobe.cq.social.scf.SocialCollectionComponent
* See https://docs.adobe.com/docs/en/aem/6-2/develop/communities/scf/server-customize.html
*/
/**
* Defines events that are triggered on a custom component, "Recipe".
*/
public class RecipeEvent extends SocialEvent<RecipeEvent.RecipeActions> {
private static final long serialVersionUID = 1L;
protected static final String PARENT_PATH = "PARENT_PATH";
/**
* The event topic suffix for Recipe events
*/
public static final String RECIPE_TOPIC = "recipe";
/**
* @param recipe - the recipe resource on which the event was triggered
* @param userId - the user id of the user who triggered the action
* @param action - the recipe action that triggered this event
*/
public RecipeEvent(final Recipe recipe, final String userId, final RecipeEvent.RecipeActions action) {
String recipePath = recipe.getResource().getPath();
String parentPath = (recipe.getParentComponent() != null) ?
recipe.getParentComponent().getResource().getPath() :
recipe.getSourceComponentId();
this(recipePath, userId, parentPath, action);
}
/**
* @param recipePath - the path to the recipe resource (jcr node) on which the event was triggered
* @param userId - the user id of the user who triggered the action
* @param parentPath - the path to the parent node of the recipe resource
* @param action - the recipe action that triggered this event
*/
public RecipeEvent(final String recipePath, final String userId, final String parentPath) {
super(RECIPE_TOPIC, recipePath, userId, action,
new BaseEventObject(recipePath, ObjectTypes.ARTICLE),
new BaseEventObject(parentPath, ObjectTypes.COLLECTION),
new HashMap<String, Object>(1) {
private static final long serialVersionUID = 1L;
{
if (parentPath != null) {
this.put(PARENT_PATH, parentPath);
}
}
});
}
private RecipeEvent (final Event event) {
super(event);
}
/**
* List of available recipe actions that can trigger a recipe event.
*/
public static enum RecipeActions implements SocialEvent.SocialActions {
RecipeAdded,
RecipeModified,
RecipeDeleted;
@Override
public String getVerb() {
switch (this) {
case RecipeAdded:
return Verbs.POST;
case RecipeModified:
return Verbs.UPDATE;
case RecipeDeleted:
return Verbs.DELETE;
default:
throw new IllegalArgumentException("Unsupported action");
}
}
}
}
用於篩選活動資料流的EventListener範例
您可以監聽事件,以修改活動資料流中顯示的內容。
下列偽程式碼範例將從活動資料流中移除Comments元件的DELETE事件。
EventListener的偽程式碼
需要最新的功能套件。
package my.company.comments;
import java.util.Collections;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Modified;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.osgi.service.component.ComponentContext;
import com.adobe.cq.social.activitystreams.listener.api.ActivityStreamProviderExtension;
import com.adobe.cq.social.commons.events.CommentEvent.CommentActions;
import com.adobe.cq.social.scf.core.SocialEvent;
@Service
@Component(metatype = true, label = "My Comment Delete Event Filter",
description = "Prevents comment DELETE events from showing up in activity streams")
public class CommentDeleteEventActivityFilter implements ActivityStreamProviderExtension {
@Property(name = "ranking", intValue = 10)
protected int ranking;
@Activate
public void activate(final ComponentContext ctx) {
ranking = PropertiesUtil.toInteger(ctx.getProperties().get("ranking"), 10);
}
@Modified
public void update(final Map<String, Object> props) {
ranking = PropertiesUtil.toInteger(props.get("ranking"), 10);
}
@Override
public boolean evaluate(final SocialEvent<?> evt, final Resource resource) {
if (evt.getAction() != null && evt.getAction() instanceof SocialEvent.SocialActions) {
final SocialEvent.SocialActions action = evt.getAction();
if (StringUtils.equals(action.getVerb(), CommentActions.DELETED.getVerb())) {
return false;
}
}
return true;
}
@Override
public Map<String, ? extends Object> getActivityProperties(final SocialEvent<?> arg0, final Resource arg1) {
return Collections.<String, Object>emptyMap();
}
@Override
public Map<String, ? extends Object> getActorProperties(final SocialEvent<?> arg0, final Resource arg1) {
return Collections.<String, Object>emptyMap();
}
@Override
public String getName() {
return "My Comment Delete Event Filter";
}
@Override
public Map<String, ? extends Object> getObjectProperties(final SocialEvent<?> arg0, final Resource arg1) {
return Collections.<String, Object>emptyMap();
}
/* Ensure a custom extension is registered with a ranking lower than any existing implementation in the product. */
@Override
public int getRanking() {
return this.ranking;
}
@Override
public Map<String, ? extends Object> getTargetProperties(final SocialEvent<?> arg0, final Resource arg1) {
return Collections.<String, Object>emptyMap();
}
@Override
public String[] getStreamProviderPid() {
return new String[]{"*"};
}
}