Skip to content

Commit cb6693f

Browse files
authored
Merge pull request #6471 from effective-webwork/validate-new-process
Preserve metadata in collapsed metadata group panels during process creation
2 parents b77a41d + 36ddf07 commit cb6693f

12 files changed

Lines changed: 293 additions & 30 deletions

File tree

Kitodo-Validation/src/main/java/org/kitodo/validation/metadata/MetadataValidation.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,8 +335,10 @@ private static ValidationResult checkForDetailsInTheMetadata(
335335
String location, Map<String, String> translations, LinkedList<Map<MetadataEntry, Boolean>> surroundingMetadata) {
336336
boolean error = false;
337337
Collection<String> messages = new HashSet<>();
338-
surroundingMetadata.addLast(containedMetadata.parallelStream().filter(MetadataEntry.class::isInstance)
339-
.map(MetadataEntry.class::cast).collect(Collectors.toMap(Function.identity(), all -> Boolean.FALSE)));
338+
surroundingMetadata.addLast(containedMetadata.parallelStream()
339+
.filter(MetadataEntry.class::isInstance)
340+
.map(MetadataEntry.class::cast)
341+
.collect(Collectors.toMap(Function.identity(), each -> Boolean.FALSE, (firstValue, secondValue) -> firstValue)));
340342
List<MetadataViewWithValuesInterface> metadataViewsWithValues = containingMetadataView
341343
.getSortedVisibleMetadata(containedMetadata, Collections.emptyList());
342344
for (MetadataViewWithValuesInterface metadataViewWithValues : metadataViewsWithValues) {

Kitodo/src/main/java/org/kitodo/production/forms/createprocess/CatalogImportDialog.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,17 @@ importConfiguration, projectId, templateId, getImportDepth(),
203203
if (!createProcessForm.getProcesses().isEmpty() && additionalImport) {
204204
extendsMetadataTableOfMetadataTab(processes);
205205
} else {
206+
for (TempProcess tempProcess : createProcessForm.getChildProcesses()) {
207+
createProcessForm.fillCreateProcessForm(tempProcess);
208+
}
206209
createProcessForm.setProcesses(processes);
207-
TempProcess currentTempProcess = processes.getFirst();
208-
createProcessForm.fillCreateProcessForm(currentTempProcess);
209-
attachToExistingParentAndGenerateAtstslIfNotExist(currentTempProcess);
210+
for (int i = processes.size() - 1; i >= 0; i--) {
211+
TempProcess currentTempProcess = processes.get(i);
212+
if (i == 0) {
213+
attachToExistingParentAndGenerateAtstslIfNotExist(currentTempProcess);
214+
}
215+
createProcessForm.fillCreateProcessForm(currentTempProcess);
216+
}
210217
showMessageAndRecord(importConfiguration, processes);
211218
}
212219

Kitodo/src/main/java/org/kitodo/production/forms/createprocess/CreateProcessForm.java

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
package org.kitodo.production.forms.createprocess;
1313

14+
import static org.kitodo.api.validation.State.ERROR;
1415
import static org.kitodo.constants.StringConstants.CREATE;
1516

1617
import java.io.IOException;
@@ -19,6 +20,7 @@
1920
import java.util.Arrays;
2021
import java.util.Collection;
2122
import java.util.Collections;
23+
import java.util.HashMap;
2224
import java.util.LinkedList;
2325
import java.util.List;
2426
import java.util.Locale;
@@ -43,6 +45,7 @@
4345
import org.kitodo.api.dataformat.Workpiece;
4446
import org.kitodo.api.externaldatamanagement.ImportConfigurationType;
4547
import org.kitodo.api.schemaconverter.MetadataFormat;
48+
import org.kitodo.api.validation.ValidationResult;
4649
import org.kitodo.constants.StringConstants;
4750
import org.kitodo.data.database.beans.Client;
4851
import org.kitodo.data.database.beans.ImportConfiguration;
@@ -114,6 +117,7 @@ public class CreateProcessForm extends BaseForm implements MetadataTreeTableInte
114117
private String xmlString;
115118
private String filename;
116119
protected int numberOfEadElements;
120+
private HashMap<String, ValidationResult> validationResultHashMap = new HashMap<>();
117121

118122
public CreateProcessForm() {
119123
priorityList = ServiceManager.getUserService().getCurrentMetadataLanguage();
@@ -367,6 +371,8 @@ public String createNewProcess() {
367371
Helper.setErrorMessage("rulesetNotFound", new Object[] {rulesetFile }, logger, e);
368372
} catch (IOException | ProcessGenerationException e) {
369373
logger.error(e.getLocalizedMessage(), e);
374+
} catch (DAOException e) {
375+
Helper.setErrorMessage("Error validating process metadata", e);
370376
}
371377
return this.stayOnCurrentPage;
372378
}
@@ -378,7 +384,7 @@ public String createNewProcess() {
378384
*/
379385
public String createNewProcessAndContinue() {
380386
String destination = createNewProcess();
381-
if (!destination.equals(processListPath)) {
387+
if (!processListPath.equals(destination)) {
382388
return destination;
383389
}
384390
Process parentProcess = titleRecordLinkTab.getTitleRecordProcess();
@@ -390,7 +396,8 @@ public String createNewProcessAndContinue() {
390396
+ "&faces-redirect=true";
391397
}
392398

393-
private boolean canCreateProcess() throws IOException {
399+
private boolean canCreateProcess() throws IOException, DAOException {
400+
validationResultHashMap = new HashMap<>();
394401
if (Objects.nonNull(titleRecordLinkTab.getTitleRecordProcess())) {
395402
if ((Objects.isNull(titleRecordLinkTab.getSelectedInsertionPosition())
396403
|| titleRecordLinkTab.getSelectedInsertionPosition().isEmpty())) {
@@ -404,9 +411,60 @@ private boolean canCreateProcess() throws IOException {
404411
return false;
405412
}
406413
}
414+
// validate process and potential ancestors
415+
for (TempProcess tempProcess : processes) {
416+
ValidationResult result = ServiceManager.getMetadataValidationService().validate(
417+
tempProcess.getWorkpiece(), rulesetManagement, false);
418+
if (ERROR.equals(result.getState())) {
419+
validationResultHashMap.put(getCatalogId(tempProcess), result);
420+
}
421+
}
422+
// validate potential process children
423+
for (TempProcess tempProcess : childProcesses) {
424+
ValidationResult result = ServiceManager.getMetadataValidationService().validate(
425+
tempProcess.getWorkpiece(), rulesetManagement, false);
426+
if (ERROR.equals(result.getState())) {
427+
validationResultHashMap.put(getCatalogId(tempProcess), result);
428+
}
429+
}
430+
if (!validationResultHashMap.isEmpty()) {
431+
Helper.setErrorMessage("dataEditor.validation.state.error");
432+
for (Map.Entry<String, ValidationResult> resultEntry : validationResultHashMap.entrySet()) {
433+
if (processes.size() > 1 || childProcesses.size() > 1) {
434+
Helper.setErrorMessage(Helper.getTranslation("process") + ": " + resultEntry.getKey());
435+
}
436+
for (String message : resultEntry.getValue().getResultMessages()) {
437+
Helper.setErrorMessage(" - " + message);
438+
}
439+
}
440+
PrimeFaces.current().ajax().update("editForm:processFromTemplateTabView:processHierarchyContent");
441+
return false;
442+
}
407443
return true;
408444
}
409445

446+
/**
447+
* Get CSS style classes for UI button representing given TempProcess "process"
448+
* in import masks "Process hierarchy" panel as whitespace separated string of class names.
449+
* Always contains class name 'carousel-button'.
450+
* Also contains class name
451+
* - 'selected' if given process is currently selected in the import mask
452+
* - 'validation-error' if ruleset based metadata validation failed for given process
453+
* @param process TempProcess for which CSS style classes are returned
454+
* @return String containing style classes, separated by whitespaces, for given process
455+
*/
456+
public String getProcessButtonStyleClass(TempProcess process) {
457+
String styleClass = "carousel-button";
458+
if (currentProcess.equals(process)) {
459+
styleClass = styleClass + " selected";
460+
}
461+
String catalogId = getCatalogId(process);
462+
if (!validationResultHashMap.isEmpty() && validationResultHashMap.containsKey(catalogId)) {
463+
styleClass = styleClass + " validation-error";
464+
}
465+
return styleClass;
466+
}
467+
410468
private String parentTypeIfForbidden() throws IOException {
411469
URI metadataFileUri = ServiceManager.getProcessService()
412470
.getMetadataFileUri(titleRecordLinkTab.getTitleRecordProcess());

Kitodo/src/main/java/org/kitodo/production/forms/createprocess/ProcessDataTab.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import org.apache.logging.log4j.Logger;
2424
import org.kitodo.data.database.beans.Process;
2525
import org.kitodo.exceptions.DoctypeMissingException;
26+
import org.kitodo.exceptions.InvalidMetadataValueException;
27+
import org.kitodo.exceptions.NoSuchMetadataFieldException;
2628
import org.kitodo.exceptions.ProcessGenerationException;
2729
import org.kitodo.production.helper.Helper;
2830
import org.kitodo.production.helper.ProcessHelper;
@@ -67,20 +69,24 @@ public void setDocType(String docType) {
6769
* Update process metadata of currently selected process.
6870
*/
6971
public void updateProcessMetadata() {
70-
if (Objects.nonNull(docType) && Objects.nonNull(createProcessForm.getCurrentProcess()) && Objects.nonNull(
71-
createProcessForm.getCurrentProcess().getWorkpiece())) {
72-
createProcessForm.getCurrentProcess().getWorkpiece().getLogicalStructure().setType(this.docType);
73-
if (this.docType.isEmpty()) {
74-
createProcessForm.getProcessMetadata().setProcessDetails(ProcessFieldedMetadata.EMPTY);
75-
} else {
76-
createProcessForm.getProcessMetadata().initializeProcessDetails(
77-
createProcessForm.getCurrentProcess().getWorkpiece().getLogicalStructure(), createProcessForm);
78-
overwriteProcessMetadata();
72+
try {
73+
if (Objects.nonNull(docType) && Objects.nonNull(createProcessForm.getCurrentProcess()) && Objects.nonNull(
74+
createProcessForm.getCurrentProcess().getWorkpiece())) {
75+
createProcessForm.getCurrentProcess().getWorkpiece().getLogicalStructure().setType(this.docType);
76+
if (this.docType.isEmpty()) {
77+
createProcessForm.getProcessMetadata().setProcessDetails(ProcessFieldedMetadata.EMPTY);
78+
} else {
79+
createProcessForm.getProcessMetadata().initializeProcessDetails(
80+
createProcessForm.getCurrentProcess().getWorkpiece().getLogicalStructure(), createProcessForm);
81+
overwriteProcessMetadata();
82+
}
7983
}
84+
} catch (InvalidMetadataValueException | NoSuchMetadataFieldException e) {
85+
Helper.setErrorMessage(e.getMessage());
8086
}
8187
}
8288

83-
private void overwriteProcessMetadata() {
89+
private void overwriteProcessMetadata() throws InvalidMetadataValueException, NoSuchMetadataFieldException {
8490
TempProcess currentProcess = createProcessForm.getCurrentProcess();
8591
if (StringUtils.isNotBlank(currentProcess.getAtstsl())) {
8692
for (ProcessDetail processDetail : currentProcess.getProcessMetadata().getProcessDetailsElements()) {
@@ -89,6 +95,7 @@ private void overwriteProcessMetadata() {
8995
ProcessTextMetadata processTextMetadata = (ProcessTextMetadata) processDetail;
9096
if (StringUtils.isBlank(processTextMetadata.getValue())) {
9197
processTextMetadata.setValue(currentProcess.getAtstsl());
98+
processTextMetadata.preserve();
9299
}
93100
}
94101
}

Kitodo/src/main/webapp/WEB-INF/resources/css/kitodo.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,6 +1686,14 @@ Import form
16861686
background: var(--blue);
16871687
}
16881688

1689+
#editForm\:processFromTemplateTabView\:processHierarchyContent .ui-widget-content .ui-button.validation-error {
1690+
background: var(--orange);
1691+
}
1692+
1693+
#editForm\:processFromTemplateTabView\:processHierarchyContent .ui-widget-content .selected.validation-error {
1694+
background: var(--focused-orange);
1695+
}
1696+
16891697
#editForm\:processFromTemplateTabView\:processChildren {
16901698
margin: auto;
16911699
}

Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataTreeTable.xhtml

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@
4343
styleClass="no-header"
4444
widgetVar="metadataTable"
4545
id="metadataTable">
46-
<p:ajax event="collapse"
47-
onstart="return #{request.requestURI.contains('metadataEditor')};"/>
46+
<p:ajax event="collapse"/>
4847
<p:column>
4948
<span class="input-wrapper">
5049
<!-- field label
@@ -67,7 +66,6 @@
6766
label="#{item.label}"
6867
value="#{item.value}"
6968
disabled="#{not item.editable or readOnly}"
70-
required="#{item.required and (not empty param['editForm:save'] or not empty param['editForm:saveContinue'])}"
7169
styleClass="#{not item.editable or readOnly ? 'read-only disabled' : ''}"
7270
onkeydown="metadataEditor.metadataTree.handleKeyDown(event, this)">
7371
<p:ajax event="blur"
@@ -86,7 +84,6 @@
8684
value="#{item.value}"
8785
rows="2"
8886
disabled="#{not item.editable or readOnly}"
89-
required="#{item.required and (not empty param['editForm:save'] or not empty param['editForm:saveContinue'])}"
9087
styleClass="#{not item.editable or readOnly ? 'read-only disabled' : ''}">
9188
<p:ajax event="keyup"
9289
delay="300"
@@ -101,7 +98,6 @@
10198
label="#{item.label}"
10299
value="#{item.value}"
103100
disabled="#{not item.editable or readOnly}"
104-
required="#{item.required and (not empty param['editForm:save'] or not empty param['editForm:saveContinue'])}"
105101
styleClass="#{not item.editable or readOnly ? 'read-only disabled' : ''}">
106102
<p:ajax event="change"
107103
oncomplete="preserveMetadata(); #{item.leading ? (request.requestURI.contains('metadataEditor') ? 'updateTitleMetadataWithTable();' : 'updateProcessMetadata();') : (request.requestURI.contains('metadataEditor') ? 'updateTitleMetadata();' : '')}"/>
@@ -116,7 +112,6 @@
116112
pattern="yyyy-MM-dd"
117113
styleClass="input-with-button #{not item.editable or readOnly ? 'read-only disabled' : ''}"
118114
showOn="button"
119-
required="#{item.required and (not empty param['editForm:save'] or not empty param['editForm:saveContinue'])}"
120115
disabled="#{not item.editable or readOnly}">
121116
<p:ajax event="dateSelect"
122117
oncomplete="preserveMetadata(); #{item.leading ? (request.requestURI.contains('metadataEditor') ? 'updateTitleMetadataWithTable();' : 'updateProcessMetadata();') : (request.requestURI.contains('metadataEditor') ? 'updateTitleMetadata();' : '')}"/>
@@ -131,7 +126,6 @@
131126
readonly="#{not item.editable}"
132127
styleClass="#{not item.editable or readOnly ? 'read-only disabled' : ''}"
133128
disabled="#{not item.editable or readOnly}"
134-
required="#{item.required and (not empty param['editForm:save'] or not empty param['editForm:saveContinue'])}"
135129
showCheckbox="true"
136130
filter="#{item.filterable}"
137131
filterMatchMode="contains">
@@ -150,7 +144,6 @@
150144
readonly="#{not item.editable}"
151145
autoWidth="false"
152146
disabled="#{not item.editable or readOnly}"
153-
required="#{item.required and (not empty param['editForm:save'] or not empty param['editForm:saveContinue'])}"
154147
styleClass="#{readOnly ? 'read-only' : ''}"
155148
filter="#{item.filterable}"
156149
filterMatchMode="contains">
@@ -170,7 +163,6 @@
170163
label="#{item.label}"
171164
value="#{item.selectedItem}"
172165
readonly="#{not item.editable}"
173-
required="#{item.required and (not empty param['editForm:save'] or not empty param['editForm:saveContinue'])}"
174166
disabled="#{not item.editable or readOnly}"
175167
styleClass="#{not item.editable or readOnly ? 'read-only disabled' : ''}"
176168
layout="grid"
@@ -186,7 +178,6 @@
186178
<p:selectBooleanCheckbox id="toggleSwitch"
187179
label="#{item.label}"
188180
disabled="#{not item.editable or readOnly}"
189-
required="#{item.required and (not empty param['editForm:save'] or not empty param['editForm:saveContinue'])}"
190181
value="#{item.active}">
191182
<p:ajax event="change"
192183
oncomplete="preserveMetadata(); #{item.leading ? (request.requestURI.contains('metadataEditor') ? 'updateTitleMetadataWithTable();' : 'updateProcessMetadata();') : (request.requestURI.contains('metadataEditor') ? 'updateTitleMetadata();' : '')}"/>

Kitodo/src/main/webapp/WEB-INF/templates/includes/processFromTemplate/dataEdit.xhtml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
<p:commandButton action="#{CreateProcessForm.fillCreateProcessForm(processAncestor)}"
3434
actionListener="#{CreateProcessForm.processMetadata.preserve()}"
3535
process="@this"
36-
styleClass="carousel-button #{CreateProcessForm.currentProcess.equals(processAncestor) ? 'selected' : ''}"
36+
styleClass="#{CreateProcessForm.getProcessButtonStyleClass(processAncestor)}"
3737
value="#{CreateProcessForm.getCatalogId(processAncestor)}"
3838
update="editForm:processFromTemplateTabView:processData
3939
@(.carousel-button)"/>
@@ -49,7 +49,7 @@
4949
<p:commandButton action="#{CreateProcessForm.fillCreateProcessForm(childProcess)}"
5050
actionListener="#{CreateProcessForm.processMetadata.preserve()}"
5151
process="@this"
52-
styleClass="carousel-button #{CreateProcessForm.currentProcess.equals(childProcess) ? 'selected' : ''}"
52+
styleClass="#{CreateProcessForm.getProcessButtonStyleClass(childProcess)}"
5353
value="#{CreateProcessForm.getCatalogId(childProcess)}"
5454
update="editForm:processFromTemplateTabView:processData
5555
@(.carousel-button)"/>

0 commit comments

Comments
 (0)