/**
* Copyright (C) 2009 fgrilli <federico.grilli@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.google.code.mgnlgroovy.scheduler.manager;
import info.magnolia.cms.beans.config.ContentRepository;
import info.magnolia.cms.core.Content;
import info.magnolia.cms.core.HierarchyManager;
import info.magnolia.cms.core.ItemType;
import info.magnolia.cms.core.NodeData;
import info.magnolia.cms.core.search.Query;
import info.magnolia.cms.core.search.QueryManager;
import info.magnolia.cms.core.search.QueryResult;
import info.magnolia.cms.security.AccessDeniedException;
import info.magnolia.cms.util.ContentUtil;
import info.magnolia.cms.util.ExclusiveWrite;
import info.magnolia.cms.util.NodeDataUtil;
import info.magnolia.content2bean.Content2BeanException;
import info.magnolia.content2bean.Content2BeanUtil;
import info.magnolia.context.MgnlContext;
import com.google.code.mgnlgroovy.scheduler.JobDefinition;
import com.google.code.mgnlgroovy.scheduler.SchedulerConsts;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.jcr.ItemExistsException;
import javax.jcr.ItemNotFoundException;
import javax.jcr.RepositoryException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author fgrilli
* @version $Id: DefaultJobDefinitionManager.java 39 2009-04-20 16:30:54Z federico.grilli $
*/
public class DefaultJobDefinitionManager implements JobDefinitionManager
{
protected static final String SCHEDULER_CONFIG_JOBS_XPATH_QUERY = "//scheduler//config//jobs/*[jcr:primaryType='mgnl:contentNode']";
protected static final Logger log = LoggerFactory.getLogger(DefaultJobDefinitionManager.class);
@SuppressWarnings("unchecked")
public Collection<Content> findAllJobDefinitions() throws RepositoryException
{
QueryManager qm = MgnlContext.getQueryManager(ContentRepository.CONFIG);
try
{
Query q = qm.createQuery(SCHEDULER_CONFIG_JOBS_XPATH_QUERY, Query.XPATH);
QueryResult qr = q.execute();
return qr.getContent("mgnl:contentNode");
}
catch (RepositoryException e)
{
log.error(e.getMessage());
throw e;
}
}
public void removeJobDefinition(String uuid) throws RepositoryException, ItemNotFoundException
{
Content jobNode = ContentUtil.getContentByUUID(ContentRepository.CONFIG, uuid);
if (jobNode == null)
{
String msg = "could not find node to remove with uuid " + uuid;
log.error(msg);
throw new ItemNotFoundException(msg);
}
try
{
Content parent = jobNode.getParent();
log.info("Trying to delete job {}...", jobNode.getName());
jobNode.delete();
parent.save();
log.info("Job deleted successfully");
}
catch (RepositoryException e)
{
log.error(e.getMessage());
throw e;
}
}
@SuppressWarnings("unchecked")
public String saveOrUpdateJobDefinition(JobDefinition definition) throws ItemExistsException
{
if (definition == null)
{
log.warn("JobDefinition is null, returning without doing anything.");
return null;
}
synchronized (ExclusiveWrite.getInstance())
{
HierarchyManager hm = MgnlContext.getSystemContext().getHierarchyManager(ContentRepository.CONFIG);
try
{
Content root = hm.getContent(SchedulerConsts.ROOT_PATH_FOR_JOBS);
Content jobNode = ContentUtil.getOrCreateContent(root, definition.getName(), ItemType.CONTENTNODE);
NodeDataUtil.getOrCreateAndSet(jobNode, "active", definition.isActive());
if (StringUtils.isNotBlank(definition.getCatalog()))
NodeDataUtil.getOrCreateAndSet(jobNode, "catalog", definition.getCatalog());
if (StringUtils.isNotBlank(definition.getCommand()))
NodeDataUtil.getOrCreateAndSet(jobNode, "command", definition.getCommand());
if (StringUtils.isNotBlank(definition.getGroovyScript()))
NodeDataUtil.getOrCreateAndSet(jobNode, "groovyScript", definition.getGroovyScript());
NodeDataUtil.getOrCreateAndSet(jobNode, "cron", definition.getCron());
if (definition.getStartTime() != 0)
NodeDataUtil.getOrCreateAndSet(jobNode, "startTime", definition.getStartTime());
if (definition.getEndTime() != 0)
NodeDataUtil.getOrCreateAndSet(jobNode, "endTime", definition.getEndTime());
if (definition.getLastFireTime() != 0)
NodeDataUtil.getOrCreateAndSet(jobNode, "lastFireTime", definition.getLastFireTime());
if (definition.getNextFireTime() != 0
&& (definition.getEndTime() == 0 || (definition.getEndTime() != 0 && definition.getNextFireTime() < definition
.getEndTime())))
NodeDataUtil.getOrCreateAndSet(jobNode, "nextFireTime", definition.getNextFireTime());
NodeDataUtil.getOrCreateAndSet(jobNode, "terminatedWithError", definition.isTerminatedWithError());
if (StringUtils.isNotBlank(definition.getDescription()))
NodeDataUtil.getOrCreateAndSet(jobNode, "description", definition.getDescription());
if (definition.getParams() != null && !definition.getParams().isEmpty())
{
Content paramNode = ContentUtil.getOrCreateContent(jobNode, "params", ItemType.CONTENTNODE);
Iterator children = paramNode.getNodeDataCollection().iterator();
while (children.hasNext())
{
NodeData node = (NodeData) children.next();
log.debug("deleting node {}", node.getHandle());
node.delete();
}
Iterator it = definition.getParams().entrySet().iterator();
while (it.hasNext())
{
Map.Entry pairs = (Map.Entry) it.next();
NodeDataUtil.getOrCreateAndSet(paramNode, (String) pairs.getKey(), pairs.getValue());
}
}
root.save();
jobNode = ContentUtil.getOrCreateContent(root, definition.getName(), ItemType.CONTENTNODE);
log.debug("saved job UUID is {}", jobNode.getUUID());
return jobNode.getUUID();
}
catch (AccessDeniedException e)
{
log.error(e.getMessage());
throw new RuntimeException("can't add job: ", e);
}
catch (RepositoryException e)
{
log.error(e.getMessage());
throw new RuntimeException("can't add job: ", e);
}
}
}
protected List<JobDefinition> node2JobDefinitionList(Collection<Content> results, boolean recursive,
Class<JobDefinition> clazz)
{
List<JobDefinition> list = new ArrayList<JobDefinition>();
long start = System.currentTimeMillis();
for (Content node : results)
{
try
{
JobDefinition jd = clazz.cast(Content2BeanUtil.toBean(node, true, clazz));
list.add(jd);
}
catch (Content2BeanException e)
{
log.error(e.getMessage());
throw new RuntimeException(e);
}
}
long stop = System.currentTimeMillis();
log.debug("Content2Bean on result set took {} ms", stop - start);
return list;
}
public JobDefinition getJobDefinitionByName(String jobName) throws RepositoryException
{
HierarchyManager hm = MgnlContext.getSystemContext().getHierarchyManager(ContentRepository.CONFIG);
Content root = hm.getContent(SchedulerConsts.ROOT_PATH_FOR_JOBS);
Content jobNode = ContentUtil.getOrCreateContent(root, jobName, ItemType.CONTENTNODE);
try
{
JobDefinition retVal = (JobDefinition) Content2BeanUtil.toBean(jobNode, true, JobDefinition.class);
if (retVal != null)
return retVal;
throw new ItemNotFoundException();
}
catch (Content2BeanException e)
{
log.error(e.getMessage());
throw new RuntimeException(e);
}
}
public JobDefinition getJobDefinitionByUUID(String uuid) throws RepositoryException
{
Content jobNode = ContentUtil.getContentByUUID(ContentRepository.CONFIG, uuid);
try
{
JobDefinition retVal = (JobDefinition) Content2BeanUtil.toBean(jobNode, true, JobDefinition.class);
if (retVal != null)
return retVal;
throw new ItemNotFoundException();
}
catch (Content2BeanException e)
{
log.error(e.getMessage());
throw new RuntimeException(e);
}
}
public boolean sameJobNameExists(String jobName)
{
HierarchyManager hm = MgnlContext.getSystemContext().getHierarchyManager(ContentRepository.CONFIG);
return hm.isExist(SchedulerConsts.ROOT_PATH_FOR_JOBS + "/" + jobName);
}
}