package com.constellio.model.services.batch.xml.list; import com.constellio.model.entities.batchprocess.BatchProcess; import com.constellio.model.entities.batchprocess.BatchProcessAction; import com.constellio.model.utils.ParametrizedInstanceUtils; import org.apache.commons.collections.IteratorUtils; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.filter.Filter; import org.jdom2.filter.Filters; import org.jdom2.util.IteratorIterable; import org.joda.time.LocalDateTime; import java.util.ArrayList; import java.util.List; public class BatchProcessListWriter { private static final String ID = "id"; private static final String RECORDS = "records"; private static final String QUERY = "query"; private static final String ERRORS = "errors"; private static final String REQUEST_DATE_TIME = "requestDateTime"; private static final String ACTION = "action"; private static final String RECORDS_COUNT = "recordsCount"; private static final String PROGRESSION = "progression"; private static final String COLLECTION = "collection"; private static final String USERNAME = "username"; private static final String TITLE = "title"; private static final String BATCH_PROCESS = "batchProcess"; private static final String STANDBY_BATCH_PROCESSES = "standbyBatchProcesses"; private static final String PENDING_BATCH_PROCESSES = "pendingBatchProcesses"; private static final String CURRENT_BATCH_PROCESS = "currentBatchProcess"; private static final String PREVIOUS_BATCH_PROCESSES = "previousBatchProcesses"; private final Document document; public BatchProcessListWriter(Document document) { this.document = document; } public void createEmptyProcessList() { document.setRootElement(new Element("root")); document.getRootElement().addContent(new Element(STANDBY_BATCH_PROCESSES)); document.getRootElement().addContent(new Element(PREVIOUS_BATCH_PROCESSES)); document.getRootElement().addContent(new Element(CURRENT_BATCH_PROCESS)); document.getRootElement().addContent(new Element(PENDING_BATCH_PROCESSES)); } public void addBatchProcess(String id, String query, String collection, LocalDateTime requestDateTime, int recordsCount, BatchProcessAction batchProcessAction) { Element actionElement = newParametrizedInstanceUtils().toElement(batchProcessAction, ACTION); Element requestDateTimeElement = new Element(REQUEST_DATE_TIME).setText(requestDateTime.toString()); Element recordsCountElement = new Element(RECORDS_COUNT).setText(String.valueOf(recordsCount)); Element collectionElement = new Element(COLLECTION).setText(collection); Element queryElement = new Element(QUERY).setText(query); Element batchProcess = new Element(BATCH_PROCESS).setAttribute(ID, id); batchProcess.addContent(requestDateTimeElement); batchProcess.addContent(recordsCountElement); batchProcess.addContent(actionElement); batchProcess.addContent(queryElement); batchProcess.addContent(collectionElement); Element pendingBatchProcessesElement = document.getRootElement().getChild(STANDBY_BATCH_PROCESSES).detach(); pendingBatchProcessesElement.addContent(batchProcess); document.getRootElement().addContent(pendingBatchProcessesElement); } public void addBatchProcess(String id, String query, String collection, LocalDateTime requestDateTime, int recordsCount, BatchProcessAction batchProcessAction, String username, String title) { Element actionElement = newParametrizedInstanceUtils().toElement(batchProcessAction, ACTION); Element requestDateTimeElement = new Element(REQUEST_DATE_TIME).setText(requestDateTime.toString()); Element recordsCountElement = new Element(RECORDS_COUNT).setText(String.valueOf(recordsCount)); Element collectionElement = new Element(COLLECTION).setText(collection); Element queryElement = new Element(QUERY).setText(query); Element batchProcess = new Element(BATCH_PROCESS).setAttribute(ID, id); Element usernameElement = new Element(USERNAME).setText(username); Element titleElement = new Element(TITLE).setText(title); batchProcess.addContent(requestDateTimeElement); batchProcess.addContent(recordsCountElement); batchProcess.addContent(actionElement); batchProcess.addContent(queryElement); batchProcess.addContent(collectionElement); batchProcess.addContent(usernameElement); batchProcess.addContent(titleElement); Element pendingBatchProcessesElement = document.getRootElement().getChild(STANDBY_BATCH_PROCESSES).detach(); pendingBatchProcessesElement.addContent(batchProcess); document.getRootElement().addContent(pendingBatchProcessesElement); } public void addBatchProcess(String id, List<String> records, String collection, LocalDateTime requestDateTime, int recordsCount, BatchProcessAction batchProcessAction, String username, String title) { Element actionElement = newParametrizedInstanceUtils().toElement(batchProcessAction, ACTION); Element requestDateTimeElement = new Element(REQUEST_DATE_TIME).setText(requestDateTime.toString()); Element recordsCountElement = new Element(RECORDS_COUNT).setText(String.valueOf(recordsCount)); Element collectionElement = new Element(COLLECTION).setText(collection); Element queryElement = new Element(RECORDS).setText(records.toString()); Element batchProcess = new Element(BATCH_PROCESS).setAttribute(ID, id); Element usernameElement = new Element(USERNAME).setText(username); Element titleElement = new Element(TITLE).setText(title); batchProcess.addContent(requestDateTimeElement); batchProcess.addContent(recordsCountElement); batchProcess.addContent(actionElement); batchProcess.addContent(queryElement); batchProcess.addContent(collectionElement); batchProcess.addContent(usernameElement); batchProcess.addContent(titleElement); Element pendingBatchProcessesElement = document.getRootElement().getChild(STANDBY_BATCH_PROCESSES).detach(); pendingBatchProcessesElement.addContent(batchProcess); document.getRootElement().addContent(pendingBatchProcessesElement); } @SuppressWarnings("unchecked") public void markBatchProcessAsFinished(BatchProcess batchProcess, int errors) { boolean found = false; Filter<Element> filters = Filters.element(BATCH_PROCESS); IteratorIterable<Element> batchProcesses = document.getRootElement().getDescendants(filters); List<Element> copyBatchProcesses = IteratorUtils.toList(batchProcesses); for (Element nextBatchProcess : copyBatchProcesses) { if (found = markBatchProcessAsFinished(batchProcess, errors, nextBatchProcess)) { break; } } if (!found) { throw new BatchProcessListWriterRuntimeException.BatchProcessNotFound(batchProcess.getId()); } } @SuppressWarnings("unchecked") private Element getBatchProcessElementWithId(String id) { Filter<Element> filters = Filters.element(BATCH_PROCESS); IteratorIterable<Element> batchProcesses = document.getRootElement().getChild(CURRENT_BATCH_PROCESS) .getDescendants(filters); List<Element> copyBatchProcesses = IteratorUtils.toList(batchProcesses); for (Element nextBatchProcess : copyBatchProcesses) { if (nextBatchProcess.getAttributeValue(ID).equals(id)) { return nextBatchProcess; } } throw new BatchProcessListWriterRuntimeException.BatchProcessNotFound(id); } public void incrementProgression(BatchProcess batchProcess, int progressionIncrement, int errorsIncrement) { String recordsCount = null; Element batchProcessElement = getBatchProcessElementWithId(batchProcess.getId()); recordsCount = batchProcessElement.getChild(RECORDS_COUNT).getText(); int progressionCount = incrementCounter(PROGRESSION, progressionIncrement, batchProcessElement); int errorsCount = incrementCounter(ERRORS, errorsIncrement, batchProcessElement); if (recordsCount != null && progressionCount == Integer.parseInt(recordsCount)) { markBatchProcessAsFinished(batchProcess, errorsCount); } else { batchProcessElement.detach(); document.getRootElement().getChild(CURRENT_BATCH_PROCESS).addContent(batchProcessElement); } } private int incrementCounter(String tagName, int increment, Element batchProcessElement) { int count; Element counterElement = batchProcessElement.getChild(tagName); if (counterElement == null) { count = increment; counterElement = new Element(tagName).setText(String.valueOf(count)); } else { counterElement = counterElement.detach(); count = Integer.parseInt(counterElement.getText()) + increment; counterElement.setText(String.valueOf(count)); } batchProcessElement.addContent(counterElement); return count; } public void startNextBatchProcess(LocalDateTime startDate) { Element nextBatchProcesses = document.getRootElement().getChild(PENDING_BATCH_PROCESSES).getChild(BATCH_PROCESS); if (nextBatchProcesses != null) { nextBatchProcesses = nextBatchProcesses.detach(); Element startDateTime = new Element("startDateTime").setText(startDate.toString()); nextBatchProcesses.addContent(startDateTime); Element currentBatchProcess = document.getRootElement().getChild(CURRENT_BATCH_PROCESS).detach(); if (currentBatchProcess.getChildren().size() == 0) { currentBatchProcess.addContent(nextBatchProcesses); document.getRootElement().addContent(currentBatchProcess); } else { document.getRootElement().addContent(currentBatchProcess); document.getRootElement().getChild(PENDING_BATCH_PROCESSES).addContent(nextBatchProcesses); throw new BatchProcessListWriterRuntimeException.CannotHaveTwoBatchProcessInCurrentBatchProcessList(); } } else { throw new BatchProcessListWriterRuntimeException.NoPendingBatchProcessesInList(); } } private boolean markBatchProcessAsFinished(BatchProcess batchProcess, int errors, Element nextBatchProcess) { if (nextBatchProcess.getAttributeValue(ID).equals(batchProcess.getId()) && nextBatchProcess.getParentElement().getName().equals(PREVIOUS_BATCH_PROCESSES)) { throw new BatchProcessListWriterRuntimeException.BatchProcessAlreadyFinished(); } else if (nextBatchProcess.getAttributeValue(ID).equals(batchProcess.getId())) { Element errorsElement = setErrorsElementValue(errors, nextBatchProcess); nextBatchProcess.addContent(errorsElement); nextBatchProcess.detach(); document.getRootElement().getChild(PREVIOUS_BATCH_PROCESSES).addContent(nextBatchProcess); return true; } return false; } private Element setErrorsElementValue(int errors, Element nextBatchProcess) { Element errorsElement = nextBatchProcess.getChild(ERRORS); if (errorsElement == null) { errorsElement = new Element(ERRORS).setText(String.valueOf(errors)); } else { errorsElement = errorsElement.detach(); errorsElement.setText(String.valueOf(errors)); } return errorsElement; } public ParametrizedInstanceUtils newParametrizedInstanceUtils() { return new ParametrizedInstanceUtils(); } public void markBatchProcessAsPending(String batchProcessId) { List<Element> standbyBatchProcesses = document.getRootElement().getChild(STANDBY_BATCH_PROCESSES) .getChildren(BATCH_PROCESS); for (Element standbyBatchProcess : standbyBatchProcesses) { if (standbyBatchProcess.getAttributeValue(ID).equals(batchProcessId)) { standbyBatchProcess.detach(); document.getRootElement().getChild(PENDING_BATCH_PROCESSES).addContent(standbyBatchProcess); break; } } } public void cancelStandByBatchProcess(String batchProcessId) { List<Element> standbyBatchProcesses = document.getRootElement().getChild(STANDBY_BATCH_PROCESSES) .getChildren(BATCH_PROCESS); for (Element standbyBatchProcess : standbyBatchProcesses) { if (standbyBatchProcess.getAttributeValue(ID).equals(batchProcessId)) { standbyBatchProcess.detach(); break; } } } public void markAllBatchProcessAsPending() { Element standbyListElement = document.getRootElement().getChild(STANDBY_BATCH_PROCESSES); List<Element> standbyBatchProcesses = new ArrayList<>(standbyListElement.getChildren(BATCH_PROCESS)); for (Element standbyBatchProcess : standbyBatchProcesses) { standbyBatchProcess.detach(); document.getRootElement().getChild(PENDING_BATCH_PROCESSES).addContent(standbyBatchProcess); } } public void deleteBatchProcessesAlteration(List<String> ids) { Element finishedBatchProcessesElement = document.getRootElement().getChild(PREVIOUS_BATCH_PROCESSES); List<Element> elementsToDelete = new ArrayList<>(); for (Element batchProcessElement : finishedBatchProcessesElement.getChildren(BATCH_PROCESS)) { String batchProcessId = batchProcessElement.getAttributeValue(ID); if (ids.contains(batchProcessId)) { elementsToDelete.add(batchProcessElement); } } for (Element element : elementsToDelete) { element.detach(); } } }