Coverage Summary for Class: MigrationService (org.kitodo.production.services.migration)
Class |
Class, %
|
Method, %
|
Line, %
|
MigrationService |
100%
(1/1)
|
90,9%
(10/11)
|
88,4%
(76/86)
|
/*
* (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.migration;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.kitodo.api.dataformat.Workpiece;
import org.kitodo.data.database.beans.Process;
import org.kitodo.data.database.beans.Project;
import org.kitodo.data.database.beans.Task;
import org.kitodo.data.database.beans.Template;
import org.kitodo.data.database.beans.Workflow;
import org.kitodo.data.database.exceptions.DAOException;
import org.kitodo.data.exceptions.DataException;
import org.kitodo.production.helper.Helper;
import org.kitodo.production.migration.TaskComparer;
import org.kitodo.production.migration.TemplateComparer;
import org.kitodo.production.services.ServiceManager;
import org.kitodo.production.services.file.FileService;
public class MigrationService {
private static final Logger logger = LogManager.getLogger(MigrationService.class);
public static final char SEPARATOR = 0x1F;
private static volatile MigrationService instance = null;
/**
* Return singleton variable of type MigrationService.
*
* @return unique instance of MigrationService
*/
public static MigrationService getInstance() {
MigrationService localReference = instance;
if (Objects.isNull(localReference)) {
synchronized (MigrationService.class) {
localReference = instance;
if (Objects.isNull(localReference)) {
localReference = new MigrationService();
instance = localReference;
}
}
}
return localReference;
}
/**
* Migrates the meta.xml to the new Kitodo format.
*
* @param process
* process whose meta.xml is to be migrated
* @throws DAOException
* when Database access fails
*/
public void migrateMetadata(Process process) throws DAOException {
FileService fileService = ServiceManager.getFileService();
URI metadataFilePath;
try {
metadataFilePath = fileService.getMetadataFilePath(process, true, true);
ServiceManager.getDataEditorService().readData(metadataFilePath);
Workpiece workpiece = ServiceManager.getMetsService().loadWorkpiece(metadataFilePath);
workpiece.setId(process.getId().toString());
ServiceManager.getMetsService().saveWorkpiece(workpiece, metadataFilePath);
} catch (IOException e) {
Helper.setErrorMessage(e.getLocalizedMessage(), logger, e);
}
}
/**
* Test if a list of processes is equal, concerning the TaskComparator.
* @param firstProcessTasks The first list of tasks
* @param secondProcessTasks the second list of tasks
* @return true, if the lists are equal, false otherwise.
*/
public boolean tasksAreEqual(List<Task> firstProcessTasks, List<Task> secondProcessTasks) {
TaskComparer taskComparer = new TaskComparer();
Iterator<Task> firstTaskIterator = firstProcessTasks.iterator();
Iterator<Task> secondTaskIterator = secondProcessTasks.iterator();
while (firstTaskIterator.hasNext() && secondTaskIterator.hasNext()) {
Task firstTask = firstTaskIterator.next();
Task secondTask = secondTaskIterator.next();
if (!taskComparer.isEqual(firstTask, secondTask)) {
return false;
}
}
return true;
}
/**
* Creates a String out of the tasks to identify different tasks orders.
* @param processTasks The List of tasks to generate a string from.
* @return A string identifying the tasks.
*/
public String createTaskString(List<Task> processTasks) {
processTasks.sort(Comparator.comparingInt(Task::getOrdering));
String taskString = processTasks.stream().map(Task::getTitle).collect(Collectors.joining(", "));
String hashCode = Integer.toHexString(processTasks.parallelStream().mapToInt(TaskComparer::hashCode).sum());
return taskString + SEPARATOR + hashCode;
}
/**
* Creates templates for a list of processes with a given workflow.
* @param processes The list of processes to create the templates for.
* @param workflowToUse the workflow to use for the template.
* @return A map with templates and the corresponding processes.
*/
public Map<Template, List<Process>> createTemplatesForProcesses(List<Process> processes, Workflow workflowToUse) {
Map<Template, List<Process>> newTemplates = new HashMap<>();
for (Process process : processes) {
if (!templateListContainsTemplate(newTemplates, process, workflowToUse)) {
Template template = new Template();
template.setDocket(process.getDocket());
template.setRuleset(process.getRuleset());
template.setWorkflow(workflowToUse);
template.setClient(process.getProject().getClient());
template.setProjects(new ArrayList<>(Collections.singletonList(process.getProject())));
newTemplates.put(template, new ArrayList<>(Collections.singletonList(process)));
}
}
return newTemplates;
}
private boolean templateListContainsTemplate(Map<Template, List<Process>> newTemplates, Process process, Workflow workflowToUse) {
for (Template template : newTemplates.keySet()) {
if (template.getRuleset().equals(process.getRuleset()) && template.getDocket().equals(process.getDocket())
&& template.getWorkflow().equals(workflowToUse)) {
newTemplates.get(template).add(process);
return true;
}
}
return false;
}
/**
* Matches templates from the database to a list of given templates.
* @param templates the templates to find matching templates in the database for.
* @return A Map with matching templates
* @throws DAOException is thrown if the database access fails
*/
public Map<Template, Template> getMatchingTemplates(Set<Template> templates) throws DAOException {
Map<Template, Template> matchingTemplates = new HashMap<>();
TemplateComparer templateComparer = new TemplateComparer();
List<Template> existingTemplates = ServiceManager.getTemplateService().getAll();
for (Template templateToCreate : templates) {
for (Template existingTemplate : existingTemplates) {
if (templateComparer.isEqual(templateToCreate, existingTemplate)) {
matchingTemplates.put(templateToCreate, existingTemplate);
}
}
}
return matchingTemplates;
}
/**
* Adds a list of processes to a given template.
* @param template The template to add the processes to.
* @param processesToAddToTemplate the processes to be added to the template
* @throws DataException is thrown if database access fails
*/
public void addProcessesToTemplate(Template template, List<Process> processesToAddToTemplate) throws DataException {
int numberOfProcesses = processesToAddToTemplate.size();
HashMap<Project,String> projects = new HashMap<>();
for (int currentProcess = 0; currentProcess < numberOfProcesses; currentProcess++) {
Process process = processesToAddToTemplate.get(currentProcess);
logger.trace("Assigning template \"{}\" to process \"{}\" ({}% complete)", template.getTitle(),
process.getTitle(), 100 * currentProcess / numberOfProcesses);
process.setTemplate(template);
projects.put(process.getProject(),"");
ServiceManager.getProcessService().save(process, true);
}
template.getProjects().addAll(projects.keySet());
ServiceManager.getTemplateService().save(template);
}
/**
* Checks if the template tile is already in use or is empty.
* @param template the template to check
* @return true, is title is valid, false if title is empty or already in use
*/
public boolean isTitleValid(Template template) {
String templateTitle = template.getTitle();
if (StringUtils.isNotBlank(templateTitle)) {
List<Template> templates = ServiceManager.getTemplateService().getTemplatesWithTitleAndClient(templateTitle,
template.getClient().getId());
int count = templates.size();
if (count != 0) {
Helper.setErrorMessage("templateTitleAlreadyInUse");
return false;
}
return true;
}
Helper.setErrorMessage("templateTitleEmpty");
return false;
}
}