ChangeStateCronJobImpl.java
package org.exoplatform.services.wcm.extensions.scheduler.impl;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import org.exoplatform.services.ecm.publication.PublicationPlugin;
import org.exoplatform.services.ecm.publication.PublicationService;
import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.jcr.ext.common.SessionProvider;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.wcm.extensions.publication.lifecycle.authoring.AuthoringPublicationConstant;
import org.exoplatform.services.wcm.publication.PublicationDefaultStates;
import org.exoplatform.services.wcm.utils.WCMCoreUtils;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* Created by The eXo Platform MEA Author : haikel.thamri@exoplatform.com
*/
public class ChangeStateCronJobImpl implements Job {
private static final Log LOG = ExoLogger.getLogger(ChangeStateCronJobImpl.class.getName());
private static final String START_TIME_PROPERTY = "publication:startPublishedDate";
private static final String END_TIME_PROPERTY = "publication:endPublishedDate";
private static final int NORMAL_NODE = 0;
private static final int STAGED_NODE = 1;
private String fromState = null;
private String toState = null;
private String predefinedPath = null;
private String workspace = null;
private String contentPath = null;
public void execute(JobExecutionContext context) throws JobExecutionException {
SessionProvider sessionProvider = null;
try {
RuntimeMXBean mx = ManagementFactory.getRuntimeMXBean();
if (mx.getUptime()>120000) {
if (LOG.isDebugEnabled()) LOG.debug("Start Execute ChangeStateCronJob");
if (fromState == null) {
JobDataMap jdatamap = context.getJobDetail().getJobDataMap();
fromState = jdatamap.getString("fromState");
toState = jdatamap.getString("toState");
predefinedPath = jdatamap.getString("predefinedPath");
String[] pathTab = predefinedPath.split(":");
workspace = pathTab[0];
contentPath = pathTab[1];
}
if (LOG.isDebugEnabled()) LOG.debug("Start Execute ChangeStateCronJob: change the State from " + fromState + " to "
+ toState);
sessionProvider = SessionProvider.createSystemProvider();
String property = null;
if ("staged".equals(fromState) && "published".equals(toState)) {
property = START_TIME_PROPERTY;
} else if ("published".equals(fromState) && "unpublished".equals(toState)) {
property = END_TIME_PROPERTY;
}
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
Date now = Calendar.getInstance().getTime();
String currentTime = format.format(now);
if (property != null) {
// appends trailing / if missing
if (contentPath != null) {
if (!contentPath.endsWith("/")) {
contentPath += "/";
}
}
StringBuilder normalNodesStatement
= new StringBuilder().append("select * from nt:base where ").
append("(publication:currentState='").append(fromState).append("') ").
append(" and (").append(property).append(" IS NOT NULL )").
append(" and (").append(property).append(" < TIMESTAMP '").append(currentTime).append("') ").
append(" and (jcr:path like '").append(contentPath).append("%' )");
StringBuilder stagedNodesStatement
= new StringBuilder().append("select * from nt:base where ").
append("(publication:currentState='").append(fromState).append("') ").
append(" and (").append(property).append(" IS NULL ) ").
append(" and (jcr:path like '").append(contentPath).append("%' )");
long normalCount = changeStateForNodes(sessionProvider, property, NORMAL_NODE, normalNodesStatement.toString());
long stagedCount = (START_TIME_PROPERTY.equals(property)) ?
changeStateForNodes(sessionProvider, property, STAGED_NODE, stagedNodesStatement.toString()) : 0;
long numberOfItemsToChange = normalCount + stagedCount;
if (numberOfItemsToChange > 0) {
if (LOG.isDebugEnabled()) {
LOG.debug(numberOfItemsToChange + " '" + fromState + "' candidates for state '" + toState
+ "' found in " + predefinedPath);
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("no '" + fromState + "' content found in " + predefinedPath);
}
}
}
if (LOG.isDebugEnabled()) LOG.debug("End Execute ChangeStateCronJob");
}
} catch (RepositoryException ex) {
if (LOG.isErrorEnabled()) LOG.error("Repository not found. Ignoring : " + ex.getMessage(), ex);
} catch (Exception ex) {
if (LOG.isErrorEnabled()) LOG.error("error when changing the state of the content : " + ex.getMessage(), ex);
} finally {
if (sessionProvider != null)
sessionProvider.close();
}
}
private long changeStateForNodes(SessionProvider sessionProvider, String property, int nodeType, String statement)
throws Exception {
long ret = 0;
RepositoryService repositoryService_ = WCMCoreUtils.getService(RepositoryService.class);
PublicationService publicationService = WCMCoreUtils.getService(PublicationService.class);
PublicationPlugin publicationPlugin = publicationService.getPublicationPlugins()
.get(AuthoringPublicationConstant.LIFECYCLE_NAME);
HashMap<String, String> context_ = new HashMap<String, String>();
ManageableRepository manageableRepository = repositoryService_.getCurrentRepository();
if (manageableRepository == null) {
if (LOG.isDebugEnabled()) LOG.debug("Repository not found. Ignoring");
return 0;
}
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
Session session = sessionProvider.getSession(workspace, manageableRepository);
QueryManager queryManager = session.getWorkspace().getQueryManager();
Query query = queryManager.createQuery(statement, Query.SQL);
QueryResult queryResult = query.execute();
for (NodeIterator iter = queryResult.getNodes(); iter.hasNext();) {
Node node_ = iter.nextNode();
String path = node_.getPath();
if (!path.startsWith("/jcr:system")) {
if (NORMAL_NODE == nodeType) {
Date nodeDate = node_.getProperty(property).getDate().getTime();
if (LOG.isInfoEnabled()) LOG.info("'" + toState + "' " + node_.getPath() + " (" + property + "="
+ format.format(nodeDate) + ")");
if (PublicationDefaultStates.UNPUBLISHED.equals(toState)) {
if (node_.hasProperty(AuthoringPublicationConstant.LIVE_REVISION_PROP)) {
String liveRevisionProperty = node_.getProperty(AuthoringPublicationConstant.LIVE_REVISION_PROP)
.getString();
if (!"".equals(liveRevisionProperty)) {
Node liveRevision = session.getNodeByUUID(liveRevisionProperty);
if (liveRevision != null) {
context_.put(AuthoringPublicationConstant.CURRENT_REVISION_NAME,
liveRevision.getName());
}
}
}
}
publicationPlugin.changeState(node_, toState, context_);
ret ++;
} else {
if (LOG.isInfoEnabled()) LOG.info("'" + toState + "' " + node_.getPath());
publicationPlugin.changeState(node_, toState, context_);
}
if(START_TIME_PROPERTY.equals(property) && node_.hasProperty(START_TIME_PROPERTY)){
node_.getProperty(START_TIME_PROPERTY).remove();
node_.save();
}
if(END_TIME_PROPERTY.equals(property) && node_.hasProperty(END_TIME_PROPERTY)){
node_.getProperty(END_TIME_PROPERTY).remove();
node_.save();
}
}
}
return ret;
}
}