Java tutorial
/* * (c) Kitodo. Key to digital objects e. V. <contact@kitodo.org> * * This file is part of the Kitodo project. * * It is licensed under GNU General Public License version 3 or later. * * For the full copyright and license information, please read the * GPL3-License.txt file that was distributed with this source code. */ package org.kitodo.production.services.command; import java.io.File; import java.io.IOException; import java.net.URI; import java.nio.file.Files; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import org.apache.commons.lang.text.StrTokenizer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.kitodo.data.database.beans.Process; import org.kitodo.data.database.beans.Role; import org.kitodo.data.database.beans.Ruleset; import org.kitodo.data.database.beans.Task; import org.kitodo.data.database.enums.TaskStatus; import org.kitodo.data.exceptions.DataException; import org.kitodo.export.ExportDms; import org.kitodo.production.helper.Helper; import org.kitodo.production.helper.metadata.legacytypeimplementations.LegacyMetsModsDigitalDocumentHelper; import org.kitodo.production.services.ServiceManager; import org.kitodo.production.services.file.FileService; public class KitodoScriptService { private Map<String, String> parameters; private static final Logger logger = LogManager.getLogger(KitodoScriptService.class); private final FileService fileService = ServiceManager.getFileService(); private static final String KITODO_SCRIPT_FIELD = "kitodoScriptfield"; private static final String RULESET = "ruleset"; private static final String SCRIPT = "script"; private static final String SOURCE_FOLDER = "sourcefolder"; private static final String STATUS = "status"; private static final String TASK_TITLE = "steptitle"; private static final String ROLE = "role"; /** * Start the script execution. * * @param processes * list of Process objects * @param script * from frontend passed as String */ public void execute(List<Process> processes, String script) throws DataException { this.parameters = new HashMap<>(); // decompose and capture all script parameters StrTokenizer tokenizer = new StrTokenizer(script, ' ', '\"'); while (tokenizer.hasNext()) { String tok = tokenizer.nextToken(); if (Objects.isNull(tok) || !tok.contains(":")) { Helper.setErrorMessage(KITODO_SCRIPT_FIELD, "missing delimiter / unknown parameter: ", tok); } else { String key = tok.substring(0, tok.indexOf(':')); String value = tok.substring(tok.indexOf(':') + 1); this.parameters.put(key, value); } } // pass the appropriate method with the correct parameters if (Objects.isNull(this.parameters.get("action"))) { Helper.setErrorMessage(KITODO_SCRIPT_FIELD, "missing action", " - possible: 'action:addRole, action:setTaskProperty, action:setStepStatus, " + "action:swapprozessesout, action:swapprozessesin, action:deleteTiffHeaderFile, " + "action:importFromFileSystem'"); return; } if (executeScript(processes)) { Helper.setMessage(KITODO_SCRIPT_FIELD, "", "kitodoScript finished"); } } private boolean executeScript(List<Process> processes) throws DataException { // call the correct method via the parameter switch (this.parameters.get("action")) { case "importFromFileSystem": importFromFileSystem(processes); break; case "addRole": addRole(processes); break; case "setTaskProperty": setTaskProperty(processes); break; case "setStepStatus": setTaskStatus(processes); break; case "addShellScriptToStep": addShellScriptToStep(processes); break; case "updateContentFiles": updateContentFiles(processes); break; case "deleteTiffHeaderFile": deleteTiffHeaderFile(processes); break; case "setRuleset": setRuleset(processes); break; case "exportDms": case "export": exportDms(processes, this.parameters.get("exportImages")); break; case "doit": case "doit2": exportDms(processes, String.valueOf(Boolean.FALSE)); break; case "runscript": String taskName = this.parameters.get("stepname"); String scriptName = this.parameters.get(SCRIPT); if (Objects.isNull(scriptName)) { Helper.setErrorMessage(KITODO_SCRIPT_FIELD, "", "Missing parameter"); return false; } else { runScript(processes, taskName, scriptName); } break; case "deleteProcess": String value = parameters.get("contentOnly"); boolean contentOnly = true; if (Objects.nonNull(value) && value.equalsIgnoreCase("false")) { contentOnly = false; } deleteProcess(processes, contentOnly); break; default: Helper.setErrorMessage(KITODO_SCRIPT_FIELD, "Unknown action", " - use: 'action:addRole, action:setTaskProperty, action:setStepStatus, " + "action:swapprozessesout, action:swapprozessesin, action:deleteTiffHeaderFile, " + "action:importFromFileSystem'"); return false; } return true; } private void updateContentFiles(List<Process> processes) { for (Process process : processes) { try { LegacyMetsModsDigitalDocumentHelper rdf = ServiceManager.getProcessService() .readMetadataFile(process); rdf.getDigitalDocument().addAllContentFiles(); fileService.writeMetadataFile(rdf, process); Helper.setMessage(KITODO_SCRIPT_FIELD, "ContentFiles updated: ", process.getTitle()); } catch (IOException | RuntimeException e) { Helper.setErrorMessage(KITODO_SCRIPT_FIELD, "Error while updating content files", logger, e); } } Helper.setMessage(KITODO_SCRIPT_FIELD, "", "updateContentFiles finished"); } private void deleteProcess(List<Process> processes, boolean contentOnly) { for (Process process : processes) { String title = process.getTitle(); if (contentOnly) { try { URI ocr = fileService.getOcrDirectory(process); if (fileService.fileExist(ocr)) { fileService.delete(ocr); } URI images = fileService.getImagesDirectory(process); if (fileService.fileExist(images)) { fileService.delete(images); } Helper.setMessage("Content deleted for " + title); } catch (IOException | RuntimeException e) { Helper.setErrorMessage("errorDeleting", new Object[] { "content for " + title }, logger, e); } } else { try { deleteMetadataDirectory(process); ServiceManager.getProcessService().remove(process); Helper.setMessage("Process " + title + " deleted."); } catch (DataException | IOException e) { Helper.setErrorMessage("errorDeleting", new Object[] { Helper.getTranslation("process") + " " + title }, logger, e); } } } } private void deleteMetadataDirectory(Process process) throws IOException { fileService.deleteProcessContent(process); } private void runScript(List<Process> processes, String taskName, String scriptName) throws DataException { for (Process process : processes) { for (Task task : process.getTasks()) { if (task.getTitle().equalsIgnoreCase(taskName)) { if (Objects.nonNull(scriptName)) { if (task.getScriptName().equals(scriptName)) { String path = task.getScriptPath(); ServiceManager.getTaskService().executeScript(task, path, false); } } else { ServiceManager.getTaskService().executeScript(task, false); } } } } } /** * Import the data from a directories of the given processes. * * @param processes * list of Process objects */ private void importFromFileSystem(List<Process> processes) { if (isActionParameterInvalid(SOURCE_FOLDER)) { return; } URI sourceFolder = new File(this.parameters.get(SOURCE_FOLDER)).toURI(); try { if (!fileService.isDirectory(sourceFolder)) { Helper.setErrorMessage(KITODO_SCRIPT_FIELD, "Directory " + this.parameters.get(SOURCE_FOLDER) + " does not exisist"); return; } for (Process process : processes) { Integer processId = process.getId(); String processTitle = process.getTitle(); URI imagesFolder = ServiceManager.getProcessService().getImagesOriginDirectory(false, process); if (!fileService.getSubUris(imagesFolder).isEmpty()) { Helper.setErrorMessage(KITODO_SCRIPT_FIELD, "", "The process " + processTitle + " [" + processId + "] has already data in image folder"); } else { URI sourceFolderProcess = fileService.createResource(sourceFolder, processTitle); if (!fileService.isDirectory(sourceFolder)) { Helper.setErrorMessage(KITODO_SCRIPT_FIELD, "", "The directory for process " + processTitle + " [" + processId + "] is not existing"); } else { fileService.copyDirectory(sourceFolderProcess, imagesFolder); Helper.setMessage(KITODO_SCRIPT_FIELD, "", "The directory for process " + processTitle + " [" + processId + "] is copied"); } Helper.setMessage(KITODO_SCRIPT_FIELD, "", "The process " + processTitle + " [" + processId + "] is copied"); } } } catch (IOException e) { Helper.setErrorMessage(e.getLocalizedMessage(), logger, e); } } /** * Set ruleset. * * @param processes * list of Process objects */ private void setRuleset(List<Process> processes) { if (isActionParameterInvalid(RULESET)) { return; } try { List<Ruleset> rulesets = ServiceManager.getRulesetService() .getByQuery("from Ruleset where title='" + this.parameters.get(RULESET) + "'"); if (rulesets.isEmpty()) { Helper.setErrorMessage(KITODO_SCRIPT_FIELD, "Could not find ruleset: ", RULESET); return; } Ruleset ruleset = rulesets.get(0); for (Process process : processes) { process.setRuleset(ruleset); ServiceManager.getProcessService().save(process); } } catch (DataException | RuntimeException e) { Helper.setErrorMessage(e); logger.error(e.getMessage(), e); } } /** * Add ShellScript to task of the given processes. * * @param processes * list of Process objects */ private void addShellScriptToStep(List<Process> processes) { if (isActionParameterInvalid(TASK_TITLE) || isActionParameterInvalid("label") || isActionParameterInvalid(SCRIPT)) { return; } executeActionForAddShellToScript(processes); Helper.setMessage(KITODO_SCRIPT_FIELD, "", "addShellScriptToStep finished: "); } private void executeActionForAddShellToScript(List<Process> processes) { for (Process process : processes) { for (Task task : process.getTasks()) { if (task.getTitle().equals(this.parameters.get(TASK_TITLE))) { task.setScriptPath(this.parameters.get(SCRIPT)); task.setScriptName(this.parameters.get("label")); saveProcess(process); Helper.setMessage(KITODO_SCRIPT_FIELD, "Added script to step: ", process.getTitle()); break; } } } } /** * Flag von Schritten setzen. * * @param processes * list of Process objects */ private void setTaskProperty(List<Process> processes) { if (isActionParameterInvalid(TASK_TITLE) || isActionParameterInvalid("property") || isActionParameterInvalid("value")) { return; } String property = this.parameters.get("property"); String value = this.parameters.get("value"); if (!property.equals("metadata") && !property.equals("readimages") && !property.equals("writeimages") && !property.equals("validate") && !property.equals("exportdms") && !property.equals("batch") && !property.equals("automatic")) { Helper.setErrorMessage(KITODO_SCRIPT_FIELD, "", "wrong parameter 'property'; possible values: metadata, readimages, writeimages, " + "validate, exportdms"); return; } if (!value.equals("true") && !value.equalsIgnoreCase(String.valueOf(Boolean.FALSE))) { Helper.setErrorMessage(KITODO_SCRIPT_FIELD, "wrong parameter 'value'; possible " + "values: true, false"); return; } executeActionForSetTaskProperty(processes, property, value); Helper.setMessage(KITODO_SCRIPT_FIELD, "", "setTaskProperty abgeschlossen: "); } private void executeActionForSetTaskProperty(List<Process> processes, String property, String value) { for (Process process : processes) { for (Task task : process.getTasks()) { if (task.getTitle().equals(this.parameters.get(TASK_TITLE))) { switch (property) { case "metadata": task.setTypeMetadata(Boolean.parseBoolean(value)); break; case "automatic": task.setTypeAutomatic(Boolean.parseBoolean(value)); break; case "batch": task.setBatchStep(Boolean.parseBoolean(value)); break; case "readimages": task.setTypeImagesRead(Boolean.parseBoolean(value)); break; case "writeimages": task.setTypeImagesWrite(Boolean.parseBoolean(value)); break; case "validate": task.setTypeCloseVerify(Boolean.parseBoolean(value)); break; case "exportdms": task.setTypeExportDMS(Boolean.parseBoolean(value)); break; default: break; } saveProcess(process); Helper.setMessage(KITODO_SCRIPT_FIELD, "Error while saving process: ", process.getTitle()); break; } } } } /** * Set task status for the given processes. * * @param processes * list of Process objects */ private void setTaskStatus(List<Process> processes) { if (isActionParameterInvalid(TASK_TITLE) || isActionParameterInvalid(STATUS)) { return; } if (!this.parameters.get(STATUS).equals("0") && !this.parameters.get(STATUS).equals("1") && !this.parameters.get(STATUS).equals("2") && !this.parameters.get(STATUS).equals("3")) { Helper.setErrorMessage(KITODO_SCRIPT_FIELD, "Wrong status parameter: status ", "(possible: 0=closed, 1=open, 2=in work, 3=finished"); return; } executeActionForSetTaskStatus(processes); Helper.setMessage(KITODO_SCRIPT_FIELD, "", "setStepStatus finished: "); } private void executeActionForSetTaskStatus(List<Process> processes) { for (Process process : processes) { for (Task task : process.getTasks()) { if (task.getTitle().equals(this.parameters.get(TASK_TITLE))) { TaskStatus newTaskStatus = TaskStatus .getStatusFromValue(Integer.valueOf(this.parameters.get(STATUS))); task.setProcessingStatus(newTaskStatus); saveTask(process.getTitle(), task); Helper.setMessage(KITODO_SCRIPT_FIELD, "stepstatus set in process: ", process.getTitle()); break; } } } } /** * Add role to the task of given processes. * * @param processes * list of Process objects */ private void addRole(List<Process> processes) { if (isActionParameterInvalid(TASK_TITLE) || isActionParameterInvalid(ROLE)) { return; } // check if role exists Role role; List<Role> foundRoles = ServiceManager.getRoleService() .getByQuery("FROM Role WHERE title='" + this.parameters.get(ROLE) + "'"); if (!foundRoles.isEmpty()) { role = foundRoles.get(0); } else { Helper.setErrorMessage(KITODO_SCRIPT_FIELD, "Unknown role: ", this.parameters.get(ROLE)); return; } executeActionForAddRole(processes, role); Helper.setMessage(KITODO_SCRIPT_FIELD, "", "addRole finished"); } private void executeActionForAddRole(List<Process> processes, Role role) { for (Process process : processes) { for (Task task : process.getTasks()) { if (task.getTitle().equals(this.parameters.get(TASK_TITLE))) { List<Role> roles = task.getRoles(); if (!roles.contains(role)) { roles.add(role); saveTask(process.getTitle(), task); } } } Helper.setMessage(KITODO_SCRIPT_FIELD, "added role to task: ", process.getTitle()); } } /** * Delete TiffHeader file from given processes. * * @param processes * list of Process objects */ public void deleteTiffHeaderFile(List<Process> processes) { for (Process process : processes) { try { File tiffHeaderFile = new File(fileService.getImagesDirectory(process) + "tiffwriter.conf"); if (tiffHeaderFile.exists()) { Files.delete(tiffHeaderFile.toPath()); } Helper.setMessage(KITODO_SCRIPT_FIELD, "TiffHeaderFile deleted: ", process.getTitle()); } catch (IOException | RuntimeException e) { Helper.setErrorMessage(KITODO_SCRIPT_FIELD, "Error while deleting TiffHeader", logger, e); } } Helper.setMessage(KITODO_SCRIPT_FIELD, "", "deleteTiffHeaderFile finished"); } private void exportDms(List<Process> processes, String exportImages) { boolean withoutImages = Objects.nonNull(exportImages) && exportImages.equalsIgnoreCase("false"); for (Process process : processes) { try { ExportDms dms = new ExportDms(!withoutImages); dms.startExport(process); } catch (IOException e) { logger.error(e.getMessage(), e); } } } private boolean isActionParameterInvalid(String parameter) { if (Objects.isNull(this.parameters.get(parameter)) || Objects.equals(this.parameters.get(parameter), "")) { Helper.setErrorMessage(KITODO_SCRIPT_FIELD, "missing parameter: ", parameter); return true; } return false; } private void saveProcess(Process process) { try { ServiceManager.getProcessService().save(process); } catch (DataException e) { Helper.setErrorMessage(KITODO_SCRIPT_FIELD, "Error while saving process: " + process.getTitle(), logger, e); } } private void saveTask(String processTitle, Task task) { try { ServiceManager.getTaskService().save(task); } catch (DataException e) { Helper.setErrorMessage(KITODO_SCRIPT_FIELD, "Error while saving - " + processTitle, logger, e); } } }