/***************************************************************************
* Copyright 2001-2009 The eXo Platform SARL All rights reserved. *
* Please look at license.txt in info directory for more license detail. *
**************************************************************************/
package org.exoplatform.services.ecm.publication.actions;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.observation.Event;
import javax.jcr.observation.EventIterator;
import org.exoplatform.services.cms.actions.ActionServiceContainer;
import org.exoplatform.services.cms.actions.impl.ECMEventListener;
import org.exoplatform.services.cms.templates.TemplateService;
import org.exoplatform.services.ecm.publication.PublicationService;
import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.security.Identity;
import org.exoplatform.services.security.IdentityConstants;
import org.exoplatform.services.security.IdentityRegistry;
import org.exoplatform.services.security.MembershipEntry;
import org.exoplatform.services.wcm.utils.WCMCoreUtils;
/**
* Created by The eXo Platform SARL
* Author : Ly Dinh Quang
* quang.ly@exoplatform.com
* xxx5669@gmail.com
* Jan 6, 2009
*/
public abstract class WorkflowActionLauncherListener implements ECMEventListener {
protected String actionName_;
protected String repository_ ;
protected String srcWorkspace_;
protected String srcPath_;
protected String executable_;
protected Map actionVariables_;
private static final String MIXIN_MOVE = "exo:move";
private static final String WORKFLOW = "Workflow";
private static final String VALIDATION_REQUEST = "validation request";
private static final String CURRENT_STATE = "publication:currentState";
private static final String DEST_WORKSPACE = "exo:destWorkspace";
private static final String DESTPATH = "exo:destPath";
private static final String BACUP_PATH = "publication:backupPath";
private static final String DOCUMENT_BACUPUP = "documentsBackupPath";
private static final Log LOG = ExoLogger.getLogger(WorkflowActionLauncherListener.class.getName());
public WorkflowActionLauncherListener(String actionName, String executable,
String repository, String srcWorkspace, String srcPath, Map actionVariables)
throws Exception {
actionName_ = actionName;
executable_ = executable;
repository_ = repository ;
srcWorkspace_ = srcWorkspace;
srcPath_ = srcPath;
actionVariables_ = actionVariables;
}
public String getSrcWorkspace() { return srcWorkspace_; }
public String getRepository() { return repository_; }
@SuppressWarnings("unchecked")
public void onEvent(EventIterator events) {
RepositoryService repositoryService = WCMCoreUtils.getService(RepositoryService.class);
ActionServiceContainer actionServiceContainer = WCMCoreUtils.getService(ActionServiceContainer.class);
IdentityRegistry identityRegistry = WCMCoreUtils.getService(IdentityRegistry.class);
TemplateService templateService = WCMCoreUtils.getService(TemplateService.class);
if (events.hasNext()) {
Event event = events.nextEvent();
Node node = null;
Session jcrSession = null;
try {
jcrSession = repositoryService.getCurrentRepository().getSystemSession(srcWorkspace_);
node = (Node) jcrSession.getItem(srcPath_);
String userId = event.getUserID();
Node actionNode = actionServiceContainer.getAction(node, actionName_);
Property rolesProp = actionNode.getProperty("exo:roles");
Value[] roles = rolesProp.getValues();
boolean hasPermission = checkExcetuteable(userId, roles, identityRegistry) ;
if (!hasPermission) {
jcrSession.logout();
return;
}
String path = event.getPath();
Map<String, String> variables = new HashMap<String, String>();
variables.put("initiator", userId);
variables.put("actionName", actionName_);
variables.put("nodePath", path);
variables.put("repository", repository_);
variables.put("srcWorkspace", srcWorkspace_);
variables.put("srcPath", srcPath_);
variables.putAll(actionVariables_);
if(event.getType() == Event.NODE_ADDED) {
node = (Node) jcrSession.getItem(path);
String nodeType = node.getPrimaryNodeType().getName();
if (templateService.getDocumentTemplates().contains(nodeType)) {
variables.put("document-type", nodeType);
triggerAction(userId, variables, repository_);
}
} else {
triggerAction(userId, variables, repository_);
}
jcrSession.logout();
if (node.canAddMixin(MIXIN_MOVE)) {
node.addMixin(MIXIN_MOVE);
node.getSession().save();
}
PublicationService publicationService = WCMCoreUtils.getService(PublicationService.class);
publicationService.enrollNodeInLifecycle(node, WORKFLOW);
node.getSession().save();
node.setProperty(CURRENT_STATE, VALIDATION_REQUEST);
String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(new Date());
String[] logs = { date, VALIDATION_REQUEST, node.getSession().getUserID(),
"PublicationService.WorkflowPublicationPlugin.nodeValidationRequest" };
publicationService.addLog(node, logs);
NodeHierarchyCreator hierarchyCreator = WCMCoreUtils.getService(NodeHierarchyCreator.class);
String documentBackup = hierarchyCreator.getJcrPath(DOCUMENT_BACUPUP);
node.setProperty(DEST_WORKSPACE, actionNode.getProperty
(DEST_WORKSPACE).getString());
node.setProperty(DESTPATH, actionNode.getProperty
(DESTPATH).getString());
node.setProperty(BACUP_PATH, documentBackup);
node.getSession().save();
} catch (Exception e) {
if(jcrSession != null) jcrSession.logout();
if (LOG.isErrorEnabled()) {
LOG.error("Unexpected error", e);
}
}
}
}
public abstract void triggerAction(String userId, Map variables, String repository)
throws Exception; {
}
private boolean checkExcetuteable(String userId, Value[] roles, IdentityRegistry identityRegistry) throws Exception {
if(IdentityConstants.SYSTEM.equalsIgnoreCase(userId)) {
return true ;
}
Identity identity = identityRegistry.getIdentity(userId);
if(identity == null) {
return false ;
}
for (int i = 0; i < roles.length; i++) {
String role = roles[i].getString();
if("*".equalsIgnoreCase(role)) return true ;
MembershipEntry membershipEntry = MembershipEntry.parse(role) ;
if(identity.isMemberOf(membershipEntry)) {
return true ;
}
}
return false ;
}
}