package fr.acxio.tools.agia.alfresco;
/*
* Copyright 2014 Acxio
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.Date;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.ItemWriteListener;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import fr.acxio.tools.agia.alfresco.dao.NodeDao;
import fr.acxio.tools.agia.alfresco.dao.NodeDaoException;
import fr.acxio.tools.agia.alfresco.domain.Document;
import fr.acxio.tools.agia.alfresco.domain.Folder;
import fr.acxio.tools.agia.alfresco.domain.Node;
import fr.acxio.tools.agia.alfresco.domain.NodeList;
import fr.acxio.tools.agia.alfresco.domain.NodeStatus;
import fr.acxio.tools.agia.common.ProcessIndicatorItemWrapper;
/**
* <p>
* A specific {@link org.springframework.batch.item.ItemProcessor ItemProcessor}
* for the Hibernate store of {@link fr.acxio.tools.agia.alfresco.domain.Node
* Node}s that marks the nodes with a given lifecyle status (success or error).
* </p>
*
* <p>
* It follows the process indicator pattern.
* </p>
*
* @author pcollardez
*
*/
public class HibernateNodeProcessor implements ItemProcessor<ProcessIndicatorItemWrapper<Node>, NodeList>, ItemWriteListener<NodeList>, InitializingBean {
private static final Logger LOGGER = LoggerFactory.getLogger(HibernateNodeProcessor.class);
private NodeDao nodeDao;
private int nextStep = NodeStatus.DONE;
private int errorStep = NodeStatus.ERROR;
public void setNodeDao(NodeDao sNodeDao) {
nodeDao = sNodeDao;
}
public void setNextStep(int sNextStep) {
nextStep = sNextStep;
}
public void setErrorStep(int sErrorStep) {
errorStep = sErrorStep;
}
public void afterPropertiesSet() {
Assert.notNull(nodeDao, "You must provide a NodeDao.");
}
public NodeList process(ProcessIndicatorItemWrapper<Node> sWrapper) {
NodeList aNodeList = new NodeList();
Node aNode = sWrapper.getItem();
addAndMarkNodes(aNodeList, aNode);
return aNodeList;
}
private void addAndMarkNodes(NodeList sNodeList, Node sParentNode) {
sNodeList.add(sParentNode);
sParentNode.setInjectedTimestamp(new Date());
sParentNode.setJobStep(nextStep);
if (sParentNode instanceof Folder) {
Folder sFolder = (Folder) sParentNode;
for (Folder aFolder : sFolder.getFolders()) {
addAndMarkNodes(sNodeList, aFolder);
}
for (Document aDocument : sFolder.getDocuments()) {
addAndMarkNodes(sNodeList, aDocument);
}
}
}
public void beforeWrite(List<? extends NodeList> sItems) {
// Nothing to do
}
public void afterWrite(List<? extends NodeList> sItems) {
try {
for (NodeList aNodeList : sItems) {
for (Node aNode : aNodeList) {
if (aNode.getParent() == null) {
nodeDao.saveOrUpdate(aNode);
}
}
}
} catch (NodeDaoException e) {
LOGGER.error("Cannot update nodes", e);
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void onWriteError(Exception sException, List<? extends NodeList> sItems) {
LOGGER.info("Write error occured");
for (NodeList aNodeList : sItems) {
for (Node aNode : aNodeList) {
try {
nodeDao.markError(aNode.getId(), errorStep);
} catch (Exception e) {
LOGGER.error("Unable to mark node on error with id " + aNode.getId(), e);
}
}
}
}
}