package org.exoplatform.wiki.service.jcrext;
import java.util.List;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import org.apache.commons.chain.Context;
import org.exoplatform.container.ExoContainer;
import org.exoplatform.services.command.action.Action;
import org.exoplatform.services.ext.action.InvocationContext;
import org.exoplatform.services.jcr.observation.ExtendedEvent;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.wiki.mow.api.WikiNodeType;
import org.exoplatform.wiki.service.WikiService;
import org.exoplatform.wiki.service.listener.PageWikiListener;
import org.exoplatform.wiki.utils.Utils;
/**
* the class for executing {@link PageWikiListener} when having a trigger from jcr node.
* <br>
* The listeners will be invoked for adding page when property 'text' of {@link WikiNodeType#WIKI_CONTENT_ITEM} is added.
* <br>
* The listeners will be invoked for updating page when property 'text' of {@link WikiNodeType#WIKI_CONTENT_ITEM} is updated.
* @author exo
*
*/
public class PageListenersInAction implements Action {
private static final Log log = ExoLogger.getLogger(PageListenersInAction.class);
private static final String SIGN = "executedListeners";
public enum PageEvent {PAGE_ADDED, PAGE_EDITED}
@Override
public boolean execute(Context context) throws Exception {
if (context.containsKey(SIGN)) return false;
Object currentItemObj = context.get(InvocationContext.CURRENT_ITEM);
Object eventObj = context.get(InvocationContext.EVENT);
boolean result;
if ((currentItemObj instanceof Node) && Integer.parseInt(eventObj.toString()) == ExtendedEvent.NODE_ADDED) {
result = processAddNode(context);
} else if ((currentItemObj instanceof Property) && Integer.parseInt(eventObj.toString()) == ExtendedEvent.PROPERTY_CHANGED) {
result = processChangeProperty(context);
} else {
throw new IllegalStateException("The listener is not configured properly!");
}
context.put(SIGN, true);
return result;
}
private Node getPageNode(Node descendant) throws RepositoryException {
Node pageNode = null;
if (descendant.isNodeType(WikiNodeType.WIKI_PAGE)) {
pageNode = descendant;
}
if (WikiNodeType.Definition.CONTENT.equals(descendant.getName())) {
pageNode = descendant.getParent();
}
if (descendant.isNodeType("nt:resource")) {
pageNode = (Node) descendant.getAncestor(descendant.getDepth() - 2);
if (pageNode != null && !pageNode.isNodeType(WikiNodeType.WIKI_PAGE)) {
// descendant is another resource but not content of wiki page.
return null;
}
}
if (pageNode == null) throw new IllegalStateException(String.format("Can not get wiki:page node from [%s]", descendant.getPath()));
return pageNode;
}
private boolean executeListeners(Context context, Node pageNode, PageEvent event) throws RepositoryException {
ExoContainer container = (ExoContainer) context.get(InvocationContext.EXO_CONTAINER);
WikiService wikiService = (WikiService) container.getComponentInstanceOfType(WikiService.class);
String pageJcrPath = pageNode.getPath();
String wikiType, owner, pageId;
try {
wikiType = Utils.getWikiType(pageJcrPath);
owner = Utils.getSpaceIdByJcrPath(pageJcrPath);
pageId = pageNode.getName();
} catch (IllegalArgumentException ie) {
if (log.isWarnEnabled()) {
log.warn(String.format("can not get wikiType and owner from [%s]", pageJcrPath), ie);
}
return false;
}
List<PageWikiListener> listeners = wikiService.getPageListeners();
for (PageWikiListener l : listeners) {
try {
if (event == PageEvent.PAGE_ADDED)
l.postAddPage(wikiType, owner, pageId, Utils.makeSimplePage(pageNode));
else if (event == PageEvent.PAGE_EDITED)
l.postUpdatePage(wikiType, owner, pageId, Utils.makeSimplePage(pageNode));
} catch (Exception e) {
if (log.isWarnEnabled()) {
log.warn(String.format("executing listener [%s] on [%s] failed", l.toString(), pageNode.getPath()), e);
}
}
}
return false;
}
private boolean processAddNode(Context context) throws RepositoryException {
Object currentItemObj = context.get(InvocationContext.CURRENT_ITEM);
Node currentNode = (Node) currentItemObj;
Node pageNode = getPageNode(currentNode);
if (pageNode == null) return false;
return executeListeners(context, pageNode, PageEvent.PAGE_ADDED);
}
private boolean processChangeProperty(Context context) throws RepositoryException {
Object currentItemObj = context.get(InvocationContext.CURRENT_ITEM);
Property currentProperty = (Property) currentItemObj;
Node pageNode = getPageNode(currentProperty.getParent());
if (pageNode == null) return false;
pageNode.getVersionHistory().getAllVersions().getSize();
return executeListeners(context, pageNode, PageEvent.PAGE_EDITED);
}
}