diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessDataTab.java b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessDataTab.java index 7d1cc00922f..4f9a05aee34 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessDataTab.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessDataTab.java @@ -12,19 +12,29 @@ package org.kitodo.production.forms.createprocess; import java.io.IOException; +import java.util.Collection; import java.util.List; import java.util.Objects; +import java.util.Optional; import javax.faces.model.SelectItem; +import org.apache.commons.lang.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.kitodo.api.MdSec; +import org.kitodo.api.Metadata; +import org.kitodo.api.MetadataEntry; import org.kitodo.api.dataeditor.rulesetmanagement.StructuralElementViewInterface; import org.kitodo.data.database.beans.Process; import org.kitodo.exceptions.DoctypeMissingException; import org.kitodo.exceptions.ProcessGenerationException; import org.kitodo.production.helper.Helper; +import org.kitodo.production.helper.TempProcess; +import org.kitodo.production.helper.metadata.legacytypeimplementations.LegacyMetsModsDigitalDocumentHelper; +import org.kitodo.production.process.TitleGenerator; import org.kitodo.production.services.ServiceManager; +import org.kitodo.production.services.data.ImportService; import org.kitodo.production.services.data.ProcessService; import org.omnifaces.util.Ajax; @@ -35,7 +45,6 @@ public class ProcessDataTab { private List allDocTypes; private final CreateProcessForm createProcessForm; private String docType; - private String atstsl = ""; private String tiffHeaderImageDescription = ""; private String tiffHeaderDocumentName = ""; private int guessedImages = 0; @@ -192,23 +201,91 @@ public void generateProcessTitleAndTiffHeader() { Process process = this.createProcessForm.getMainProcess(); try { StructuralElementViewInterface docTypeView = createProcessForm.getRulesetManagement().getStructuralElementView( - docType, createProcessForm.getAcquisitionStage(), createProcessForm.getPriorityList()); + docType, createProcessForm.getAcquisitionStage(), createProcessForm.getPriorityList()); String processTitle = docTypeView.getProcessTitle().orElse(""); if (processTitle.isEmpty()) { Helper.setErrorMessage("newProcess.titleGeneration.creationRuleNotFound", new Object[] {getDocTypeLabel(docType), process.getRuleset().getTitle() }); } - this.atstsl = ProcessService.generateProcessTitle(this.atstsl, processDetails, - processTitle, process); + + String currentTitle = TitleGenerator.getValueOfMetadataID(TitleGenerator.TITLE_DOC_MAIN, processDetails); + + if (StringUtils.isBlank(currentTitle)) { + Process parentProcess = createProcessForm.getTitleRecordLinkTab().getTitleRecordProcess(); + if (Objects.nonNull(parentProcess)) { + currentTitle = getTitleFromLogicalStructure(parentProcess); + } else { + currentTitle = getTitleFromAncestors(); + } + } + + String atstsl = ProcessService.generateProcessTitleAndGetAtstsl(processDetails, processTitle, process, + currentTitle); + // document name is generally equal to process title this.tiffHeaderDocumentName = process.getTitle(); - this.tiffHeaderImageDescription = ProcessService.generateTiffHeader( - processDetails, this.atstsl, ServiceManager.getImportService().getTiffDefinition(), this.docType); + this.tiffHeaderImageDescription = ProcessService.generateTiffHeader(processDetails, atstsl, + ServiceManager.getImportService().getTiffDefinition(), this.docType); } catch (ProcessGenerationException e) { Helper.setErrorMessage(e.getLocalizedMessage(), logger, e); } Ajax.update("editForm:processFromTemplateTabView:processDataEditGrid", - "editForm:processFromTemplateTabView:processMetadata"); + "editForm:processFromTemplateTabView:processMetadata"); + } + + private String getTitleFromLogicalStructure(Process process) { + try { + LegacyMetsModsDigitalDocumentHelper metsModsDigitalDocumentHelper = ServiceManager.getProcessService() + .readMetadataFile(process); + return getTitleFromMetadata(metsModsDigitalDocumentHelper.getWorkpiece().getLogicalStructure().getMetadata()); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + return StringUtils.EMPTY; + } + + private String getTitleFromAncestors() { + int processesSize = createProcessForm.getProcesses().size(); + + if (processesSize <= 1) { + return StringUtils.EMPTY; + } + + List ancestors = createProcessForm.getProcesses().subList(1, processesSize); + + // get title of ancestors where TitleDocMain exists when several processes were + // imported + for (TempProcess tempProcess : ancestors) { + ProcessFieldedMetadata processFieldedMetadata = initializeTempProcessDetails(tempProcess); + String title = getTitleFromMetadata(processFieldedMetadata.getChildMetadata()); + if (StringUtils.isNotBlank(title)) { + return title; + } + } + return StringUtils.EMPTY; + } + + private String getTitleFromMetadata(Collection metadata) { + Optional metadataOptional = metadata.parallelStream() + .filter(metadataItem -> TitleGenerator.TITLE_DOC_MAIN.equals(metadataItem.getKey())).findFirst(); + if (metadataOptional.isPresent() && metadataOptional.get() instanceof MetadataEntry) { + return ((MetadataEntry) metadataOptional.get()).getValue(); + } + return StringUtils.EMPTY; + } + + /** + * initialize process details table. + * + * @param tempProcess + * whose metadata should be queried + */ + private ProcessFieldedMetadata initializeTempProcessDetails(TempProcess tempProcess) { + ProcessFieldedMetadata metadata = ImportService.initializeProcessDetails(tempProcess.getWorkpiece().getLogicalStructure(), + createProcessForm.getRulesetManagement(), createProcessForm.getAcquisitionStage(), + createProcessForm.getPriorityList()); + metadata.setMetadata(ImportService.importMetadata(tempProcess.getMetadataNodes(), MdSec.DMD_SEC)); + return metadata; } private String getDocTypeLabel(String docType) { diff --git a/Kitodo/src/main/java/org/kitodo/production/process/TitleGenerator.java b/Kitodo/src/main/java/org/kitodo/production/process/TitleGenerator.java index 18f2ea78544..1e05d5d5726 100644 --- a/Kitodo/src/main/java/org/kitodo/production/process/TitleGenerator.java +++ b/Kitodo/src/main/java/org/kitodo/production/process/TitleGenerator.java @@ -23,7 +23,10 @@ public class TitleGenerator extends Generator { - private static final String TITLE_DOC_MAIN = "TitleDocMain"; + /** + * Metadata identifier for title doc main. + */ + public static final String TITLE_DOC_MAIN = "TitleDocMain"; /** * Constructor for TitleGenerator. @@ -44,9 +47,21 @@ public TitleGenerator(String atstsl, List processDetailsList) { */ public String generateTitle(String titleDefinition, Map genericFields) throws ProcessGenerationException { - String currentAuthors = ImportService.getListOfCreators(this.processDetailsList); - String currentTitle = getCurrentValue(TITLE_DOC_MAIN); + return generateTitle(titleDefinition, genericFields, getValueOfMetadataID(TITLE_DOC_MAIN, processDetailsList)); + } + /** + * Generate title for process. + * + * @param titleDefinition + * definition for title to generation + * @param genericFields + * Map of Strings + * @return String + */ + public String generateTitle(String titleDefinition, Map genericFields, String title) + throws ProcessGenerationException { + String currentAuthors = ImportService.getListOfCreators(this.processDetailsList); StringBuilder newTitle = new StringBuilder(); StringTokenizer tokenizer = new StringTokenizer(titleDefinition, "+"); @@ -65,7 +80,7 @@ public String generateTitle(String titleDefinition, Map genericF } } } else { - newTitle.append(evaluateAdditionalDetailsRows(currentTitle, currentAuthors, token)); + newTitle.append(evaluateAdditionalDetailsRows(title, currentAuthors, token)); } } @@ -130,22 +145,23 @@ public static String createAtstsl(String title, String author) { return result.toString().replaceAll("[\\W]", ""); // delete umlauts etc. } - private String getCurrentValue(String metadataTag) { - //int counter = 0; - for (ProcessDetail row : this.processDetailsList) { - // TODO: check how to set "autogenerated" flag for metadata in ruleset! - /* if (row.isAutogenerated() && metadataValue.isEmpty()) { - row.setValue(String.valueOf(System.currentTimeMillis() + counter)); - ProcessMetadataTab.setAdditionalDetailsRow(row, - String.valueOf(System.currentTimeMillis() + counter)); - counter++; - }*/ + /** + * Get the value of metadata identifier from process details list. + * + * @param metadataID + * The metadata identifier + * @param processDetailsList + * The process detail list that contains the potential value + * @return The value of metadata identifier or null + */ + public static String getValueOfMetadataID(String metadataID, List processDetailsList) { + for (ProcessDetail row : processDetailsList) { String metadata = row.getMetadataID(); - if (Objects.nonNull(metadata) && metadata.equals(metadataTag)) { + if (Objects.nonNull(metadata) && metadata.equals(metadataID)) { return ImportService.getProcessDetailValue(row); } } - return ""; + return StringUtils.EMPTY; } private String evaluateAdditionalDetailsRows(String currentTitle, String currentAuthors, String token) diff --git a/Kitodo/src/main/java/org/kitodo/production/services/data/ImportService.java b/Kitodo/src/main/java/org/kitodo/production/services/data/ImportService.java index 6246a9bd927..42df13d0625 100644 --- a/Kitodo/src/main/java/org/kitodo/production/services/data/ImportService.java +++ b/Kitodo/src/main/java/org/kitodo/production/services/data/ImportService.java @@ -979,7 +979,7 @@ public static void createProcessTitle(TempProcess tempProcess, StructuralElementViewInterface docTypeView = rulesetManagementInterface .getStructuralElementView(docType, acquisitionStage, priorityList); String processTitle = docTypeView.getProcessTitle().orElse(""); - ProcessService.generateProcessTitle("", processDetails, + ProcessService.generateProcessTitle(processDetails, processTitle, tempProcess.getProcess()); } diff --git a/Kitodo/src/main/java/org/kitodo/production/services/data/ProcessService.java b/Kitodo/src/main/java/org/kitodo/production/services/data/ProcessService.java index 27bbc27448e..d6840fe5268 100644 --- a/Kitodo/src/main/java/org/kitodo/production/services/data/ProcessService.java +++ b/Kitodo/src/main/java/org/kitodo/production/services/data/ProcessService.java @@ -18,14 +18,6 @@ import static org.kitodo.data.database.enums.CorrectionComments.NO_OPEN_CORRECTION_COMMENTS; import static org.kitodo.data.database.enums.CorrectionComments.OPEN_CORRECTION_COMMENTS; -import com.itextpdf.text.Document; -import com.itextpdf.text.DocumentException; -import com.itextpdf.text.PageSize; -import com.itextpdf.text.Paragraph; -import com.itextpdf.text.Rectangle; -import com.itextpdf.text.pdf.PdfPTable; -import com.itextpdf.text.pdf.PdfWriter; - import java.io.File; import java.io.FileInputStream; import java.io.FilenameFilter; @@ -62,6 +54,13 @@ import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.io.IOUtils; @@ -149,6 +148,7 @@ import org.kitodo.production.services.data.base.ProjectSearchService; import org.kitodo.production.services.file.FileService; import org.kitodo.production.services.workflow.WorkflowControllerService; +import org.kitodo.production.workflow.KitodoNamespaceContext; import org.kitodo.serviceloader.KitodoServiceLoader; import org.primefaces.model.charts.ChartData; import org.primefaces.model.charts.axes.cartesian.linear.CartesianLinearAxes; @@ -158,6 +158,17 @@ import org.primefaces.model.charts.optionconfig.tooltip.Tooltip; import org.primefaces.model.charts.pie.PieChartDataSet; import org.primefaces.model.charts.pie.PieChartModel; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import com.itextpdf.text.Document; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.PageSize; +import com.itextpdf.text.Paragraph; +import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.PdfPTable; +import com.itextpdf.text.pdf.PdfWriter; + public class ProcessService extends ProjectSearchService { private final FileService fileService = ServiceManager.getFileService(); @@ -2280,12 +2291,26 @@ private HashSet getProcessesLinkedInLogicalDivision( } /** - * Generate process title. + * Generate and set the title to process. */ - public static String generateProcessTitle(String atstsl, List processDetails, String titleDefinition, - Process process) throws ProcessGenerationException { - TitleGenerator titleGenerator = new TitleGenerator(atstsl, processDetails); - String newTitle = titleGenerator.generateTitle(titleDefinition, null); + public static void generateProcessTitle(List processDetails, String titleDefinition, Process process) + throws ProcessGenerationException { + generateProcessTitleAndGetAtstsl(processDetails, titleDefinition, process, + TitleGenerator.getValueOfMetadataID(TitleGenerator.TITLE_DOC_MAIN, processDetails)); + } + + /** + * Generate and set the title to process using current title parameter and gets + * the atstsl. + * + * @param title + * of the work to generate atstsl + * @return String atstsl + */ + public static String generateProcessTitleAndGetAtstsl(List processDetails, String titleDefinition, + Process process, String title) throws ProcessGenerationException { + TitleGenerator titleGenerator = new TitleGenerator(null, processDetails); + String newTitle = titleGenerator.generateTitle(titleDefinition, null, title); process.setTitle(newTitle); // atstsl is created in title generator and next used in tiff header generator return titleGenerator.getAtstsl(); @@ -2407,6 +2432,31 @@ public static void deleteSymlinksFromUserHomes(Task task) { } } + /** + * Get the node list from metadata file by the xpath. + * + * @param process + * The process for which the metadata file is searched for + * @param xpath + * The xpath to get to the node list + * @return The node list of process by the of xpath + */ + public NodeList getNodeListFromMetadataFile(Process process, String xpath) throws IOException { + try (InputStream fileInputStream = ServiceManager.getFileService().readMetadataFile(process)) { + DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); + builderFactory.setNamespaceAware(true); + DocumentBuilder builder = builderFactory.newDocumentBuilder(); + org.w3c.dom.Document xmlDocument = builder.parse(fileInputStream); + + XPath xPath = XPathFactory.newInstance().newXPath(); + xPath.setNamespaceContext(new KitodoNamespaceContext()); + return (NodeList) xPath.compile(xpath).evaluate(xmlDocument, XPathConstants.NODESET); + } catch (ParserConfigurationException | SAXException | XPathExpressionException e) { + logger.error(e.getMessage(), e); + throw new IOException(e); + } + } + /** * Export Mets. * @@ -2704,8 +2754,11 @@ public HorizontalBarChartModel getBarChartModel(List processes) { HorizontalBarChartModel horizontalBarChartModel = new HorizontalBarChartModel(); horizontalBarChartModel.setData(data); + horizontalBarChartModel.setOptions(getBarChartOptions()); + return horizontalBarChartModel; + } - // Options + private BarChartOptions getBarChartOptions() { CartesianLinearAxes linearAxes = new CartesianLinearAxes(); linearAxes.setStacked(true); BarChartOptions options = new BarChartOptions(); @@ -2714,9 +2767,7 @@ public HorizontalBarChartModel getBarChartModel(List processes) { tooltip.setMode("index"); tooltip.setIntersect(false); options.setTooltip(tooltip); - - horizontalBarChartModel.setOptions(options); - return horizontalBarChartModel; + return options; } /** diff --git a/Kitodo/src/main/java/org/kitodo/production/services/workflow/WorkflowControllerService.java b/Kitodo/src/main/java/org/kitodo/production/services/workflow/WorkflowControllerService.java index 751962d8920..11ff3043f11 100644 --- a/Kitodo/src/main/java/org/kitodo/production/services/workflow/WorkflowControllerService.java +++ b/Kitodo/src/main/java/org/kitodo/production/services/workflow/WorkflowControllerService.java @@ -13,7 +13,6 @@ import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.net.URI; import java.nio.file.Paths; import java.util.ArrayList; @@ -24,14 +23,6 @@ import java.util.Objects; import java.util.concurrent.locks.ReentrantLock; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.kitodo.api.command.CommandResult; @@ -62,10 +53,6 @@ import org.kitodo.production.services.ServiceManager; import org.kitodo.production.services.data.TaskService; import org.kitodo.production.thread.TaskScriptThread; -import org.kitodo.production.workflow.KitodoNamespaceContext; -import org.w3c.dom.Document; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; public class WorkflowControllerService { @@ -685,20 +672,7 @@ private boolean runScriptCondition(String script, Process process) throws IOExce } private boolean runXPathCondition(Process process, String xpath) throws IOException { - try (InputStream fileInputStream = ServiceManager.getFileService().readMetadataFile(process)) { - DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); - builderFactory.setNamespaceAware(true); - DocumentBuilder builder = builderFactory.newDocumentBuilder(); - Document xmlDocument = builder.parse(fileInputStream); - - XPath xPath = XPathFactory.newInstance().newXPath(); - xPath.setNamespaceContext(new KitodoNamespaceContext()); - NodeList nodeList = (NodeList) xPath.compile(xpath).evaluate(xmlDocument, XPathConstants.NODESET); - return nodeList.getLength() > 0; - } catch (ParserConfigurationException | SAXException | XPathExpressionException e) { - logger.error(e.getMessage(), e); - throw new IOException(e); - } + return ServiceManager.getProcessService().getNodeListFromMetadataFile(process, xpath).getLength() > 0; } private void verifyTask(Task task) {