diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/MediaPartialForm.java b/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/MediaPartialForm.java index 39ed8d19b47..ad6e01a7126 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/MediaPartialForm.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/MediaPartialForm.java @@ -11,6 +11,15 @@ package org.kitodo.production.forms.dataeditor; +import static org.kitodo.production.forms.dataeditor.MediaPartialsPanel.convertFormattedTimeToMilliseconds; +import static org.kitodo.production.forms.dataeditor.MediaPartialsPanel.generateExtentAndSortMediaPartials; + +import java.io.Serializable; +import java.util.LinkedList; +import java.util.Map; +import java.util.Objects; +import java.util.regex.Pattern; + import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.kitodo.api.dataformat.LogicalDivision; @@ -22,15 +31,6 @@ import org.omnifaces.util.Ajax; import org.primefaces.PrimeFaces; -import java.io.Serializable; -import java.util.LinkedList; -import java.util.Map; -import java.util.Objects; -import java.util.regex.Pattern; - -import static org.kitodo.production.forms.dataeditor.MediaPartialsPanel.generateExtentAndSortMediaPartials; -import static org.kitodo.production.forms.dataeditor.MediaPartialsPanel.getMillisecondsOfFormattedTime; - public class MediaPartialForm implements Serializable { private final DataEditorForm dataEditor; @@ -39,12 +39,17 @@ public class MediaPartialForm implements Serializable { private String title; private String begin; private String type; - private String validationError; + private String validationErrorMessage; MediaPartialForm(DataEditorForm dataEditor) { this.dataEditor = dataEditor; } + /** + * Check if form is in edit mode. + * + * @return True if form is in edit mode. + */ public boolean isEdit() { return Objects.nonNull(mediaPartialDivision); } @@ -56,50 +61,26 @@ public void clean() { mediaPartialDivision = null; title = ""; begin = null; - validationError = ""; + validationErrorMessage = ""; Ajax.update("mediaPartialForm"); } - public boolean valid() { - validationError = ""; - if (Objects.isNull(getMediaSelection())) { - validationError = Helper.getTranslation("mediaPartialFormNoMedium"); - return false; - } - validationError = dataEditor.getGalleryPanel().getMediaPartialsPanel().validateDuration(); - if (Objects.nonNull(validationError)) { - return false; - } - if (StringUtils.isEmpty(getBegin())) { - validationError = Helper.getTranslation("mediaPartialFormStartEmpty"); - return false; - } - if (!Pattern.compile(MediaPartialsPanel.FORMATTED_TIME_REGEX).matcher(getBegin()).matches()) { - validationError = Helper.getTranslation("mediaPartialFormStartWrongTimeFormat"); - return false; - } - if (getMillisecondsOfFormattedTime(getBegin()) >= getMillisecondsOfFormattedTime(getDuration())) { - validationError = Helper.getTranslation("mediaPartialFormStartLessThanMediaDuration"); - return false; - } - if (!isEdit() || (isEdit() && !mediaPartialDivision.getValue().getBegin().equals(getBegin()))) { - boolean exists = getMediaSelection().getValue().getChildren().stream().anyMatch( - logicalDivision -> logicalDivision.getViews().getFirst().getPhysicalDivision().getMediaPartialView() - .getBegin().equals(getBegin())); - if (exists) { - validationError = Helper.getTranslation("mediaPartialFormStartExists"); - return false; - } - } - return true; - } - - public String getValidationError() { - return validationError; + /** + * Get the validation error message. + * + * @return The validation error message. + */ + public String getValidationErrorMessage() { + return validationErrorMessage; } - public boolean hasValidationError() { - return StringUtils.isNotEmpty(validationError); + /** + * Check if form has a validation error message. + * + * @return True if validation error is not empty. + */ + public boolean hasValidationErrorMessage() { + return StringUtils.isNotEmpty(validationErrorMessage); } /** @@ -138,7 +119,7 @@ public void save() { } generateExtentAndSortMediaPartials(getMediaSelection().getValue().getChildren(), - getMillisecondsOfFormattedTime(getDuration())); + convertFormattedTimeToMilliseconds(getMediaDuration())); try { dataEditor.refreshStructurePanel(); @@ -179,11 +160,46 @@ public void setType(String type) { this.type = type; } - private String getDuration() { - return dataEditor.getGalleryPanel().getMediaPartialsPanel().getDuration(); + private String getMediaDuration() { + return dataEditor.getGalleryPanel().getMediaPartialsPanel().getMediaDuration(); } private Pair getMediaSelection() { return dataEditor.getGalleryPanel().getMediaPartialsPanel().getMediaSelection(); } + + private boolean valid() { + validationErrorMessage = ""; + if (Objects.isNull(getMediaSelection())) { + validationErrorMessage = Helper.getTranslation("mediaPartialFormNoMedium"); + return false; + } + validationErrorMessage = dataEditor.getGalleryPanel().getMediaPartialsPanel().validateDuration(); + if (Objects.nonNull(validationErrorMessage)) { + return false; + } + if (StringUtils.isEmpty(getBegin())) { + validationErrorMessage = Helper.getTranslation("mediaPartialFormStartEmpty"); + return false; + } + if (!Pattern.compile(MediaPartialsPanel.FORMATTED_TIME_REGEX).matcher(getBegin()).matches()) { + validationErrorMessage = Helper.getTranslation("mediaPartialFormStartWrongTimeFormat"); + return false; + } + if (convertFormattedTimeToMilliseconds(getBegin()) >= convertFormattedTimeToMilliseconds(getMediaDuration())) { + validationErrorMessage = Helper.getTranslation("mediaPartialFormStartLessThanMediaDuration"); + return false; + } + if (!isEdit() || (isEdit() && !mediaPartialDivision.getValue().getBegin().equals(getBegin()))) { + boolean exists = getMediaSelection().getValue().getChildren().stream().anyMatch( + logicalDivision -> logicalDivision.getViews().getFirst().getPhysicalDivision().getMediaPartialView() + .getBegin().equals(getBegin())); + if (exists) { + validationErrorMessage = Helper.getTranslation("mediaPartialFormStartExists"); + return false; + } + } + return true; + } + } diff --git a/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/MediaPartialsPanel.java b/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/MediaPartialsPanel.java index 9ba909b244f..ce5a8e11a74 100644 --- a/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/MediaPartialsPanel.java +++ b/Kitodo/src/main/java/org/kitodo/production/forms/dataeditor/MediaPartialsPanel.java @@ -45,11 +45,11 @@ public class MediaPartialsPanel implements Serializable { - public static final String FORMATTED_TIME_REGEX = "(([0-1][0-9])|([2][0-3])):([0-5][0-9]):([0-5][0-9])"; - public static final String REQUEST_PARAMETER_DURATION = "duration"; + public static final String FORMATTED_TIME_REGEX = "([0-1]\\d|2[0-3]):[0-5]\\d:[0-5]\\d"; + public static final String REQUEST_PARAMETER_MEDIA_DURATION = "mediaDuration"; private MediaPartialForm mediaPartialForm; private DataEditorForm dataEditor; - private String duration; + private String mediaDuration; private Pair mediaSelection; MediaPartialsPanel(DataEditorForm dataEditor) { @@ -93,9 +93,9 @@ private static void getMediaPartialViewDivisions(Map logicalDivision.getViews().remove(); dataEditor.getStructurePanel().deleteLogicalDivision(logicalDivision); generateExtentAndSortMediaPartials(getMediaSelection().getValue().getChildren(), - getMillisecondsOfFormattedTime(getDuration())); + convertFormattedTimeToMilliseconds(getMediaDuration())); } } @@ -177,6 +177,11 @@ public MediaPartialForm getMediaPartialForm() { return mediaPartialForm; } + /** + * Get the media selection. + * + * @return The media selection + */ public Pair getMediaSelection() { return mediaSelection; } @@ -186,16 +191,24 @@ public Pair getMediaSelection() { */ public void setMembersByRequestParameter() { Map params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap(); - if (params.containsKey(REQUEST_PARAMETER_DURATION)) { - duration = params.get(REQUEST_PARAMETER_DURATION); + if (params.containsKey(REQUEST_PARAMETER_MEDIA_DURATION)) { + mediaDuration = params.get(REQUEST_PARAMETER_MEDIA_DURATION); } } - public static void generateExtentAndSortMediaPartials(List logicalDivisions, Long duration) { + /** + * Generate the extent field of every media partial and sort media partials by begin. + * + * @param logicalDivisions + * The logical divisions of media partials. + * @param mediaDuration + * The media duration. + */ + public static void generateExtentAndSortMediaPartials(List logicalDivisions, Long mediaDuration) { // sorting reverse to set extent starting from the last entry Collections.sort(logicalDivisions, getLogicalDivisionComparator().reversed()); - generateExtentForMediaPartials(logicalDivisions, duration); + generateExtentForMediaPartials(logicalDivisions, mediaDuration); Collections.sort(logicalDivisions, getLogicalDivisionComparator()); } @@ -211,19 +224,27 @@ private static void generateExtentForMediaPartials(List logical PhysicalDivision previousPhysicalDivision = previousLogicalDivision.getViews().getFirst() .getPhysicalDivision(); if (previousPhysicalDivision.hasMediaPartialView()) { - mediaPartialView.setExtent(getFormattedTimeOfMilliseconds(getMillisecondsOfFormattedTime( - previousPhysicalDivision.getMediaPartialView().getBegin()) - getMillisecondsOfFormattedTime( + mediaPartialView.setExtent(convertMillisecondsToFormattedTime(convertFormattedTimeToMilliseconds( + previousPhysicalDivision.getMediaPartialView() + .getBegin()) - convertFormattedTimeToMilliseconds( mediaPartialView.getBegin()))); } } else { - mediaPartialView.setExtent(getFormattedTimeOfMilliseconds( - duration - getMillisecondsOfFormattedTime(mediaPartialView.getBegin()))); + mediaPartialView.setExtent(convertMillisecondsToFormattedTime( + duration - convertFormattedTimeToMilliseconds(mediaPartialView.getBegin()))); } previousLogicalDivision = logicalDivision; } } - public static Long getMillisecondsOfFormattedTime(String formattedTime) { + /** + * Convert formatted time to milliseconds. + * + * @param formattedTime + * The formatted time in form of {@value #FORMATTED_TIME_REGEX} + * @return The milliseconds + */ + public static Long convertFormattedTimeToMilliseconds(String formattedTime) { if (formattedTime.contains(".")) { formattedTime = formattedTime.split(".")[0]; } @@ -232,28 +253,33 @@ public static Long getMillisecondsOfFormattedTime(String formattedTime) { Integer.valueOf(time[0]) * 3600 + Integer.valueOf(time[1]) * 60 + Integer.valueOf(time[2])) * 1000; } - private static String getFormattedTimeOfMilliseconds(Long milliseconds) { + private static String convertMillisecondsToFormattedTime(Long milliseconds) { return String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(milliseconds), TimeUnit.MILLISECONDS.toMinutes(milliseconds) % 60, TimeUnit.MILLISECONDS.toSeconds(milliseconds) % 60); } private static Comparator getLogicalDivisionComparator() { - return (logicalDivision1, logicalDivision2) -> { - View view1 = logicalDivision1.getViews().getFirst(); - View view2 = logicalDivision2.getViews().getFirst(); - if (Objects.nonNull(view1) && Objects.nonNull(view2)) { - PhysicalDivision physicalDivision1 = view1.getPhysicalDivision(); - PhysicalDivision physicalDivision2 = view2.getPhysicalDivision(); - if (physicalDivision1.hasMediaPartialView() && physicalDivision2.hasMediaPartialView()) { - return physicalDivision1.getMediaPartialView().getBegin() - .compareTo(physicalDivision2.getMediaPartialView().getBegin()); + return (logicalDivisionA, logicalDivisionB) -> { + View viewA = logicalDivisionA.getViews().getFirst(); + View viewB = logicalDivisionB.getViews().getFirst(); + if (Objects.nonNull(viewA) && Objects.nonNull(viewB)) { + PhysicalDivision physicalDivisionA = viewA.getPhysicalDivision(); + PhysicalDivision physicalDivisionB = viewB.getPhysicalDivision(); + if (physicalDivisionA.hasMediaPartialView() && physicalDivisionB.hasMediaPartialView()) { + return physicalDivisionA.getMediaPartialView().getBegin() + .compareTo(physicalDivisionB.getMediaPartialView().getBegin()); } } - return Integer.compare(logicalDivision1.getOrder(), logicalDivision2.getOrder()); + return Integer.compare(logicalDivisionA.getOrder(), logicalDivisionB.getOrder()); }; } - public String getDuration() { - return duration; + /** + * Get the media duration. + * + * @return The media duration + */ + public String getMediaDuration() { + return mediaDuration; } } diff --git a/Kitodo/src/main/webapp/WEB-INF/resources/js/metadata_editor.js b/Kitodo/src/main/webapp/WEB-INF/resources/js/metadata_editor.js index 2f2805d105e..9188bc7ca81 100644 --- a/Kitodo/src/main/webapp/WEB-INF/resources/js/metadata_editor.js +++ b/Kitodo/src/main/webapp/WEB-INF/resources/js/metadata_editor.js @@ -90,8 +90,8 @@ metadataEditor.gallery = { } }, setDuration() { - let duration = this.formatTime(document.querySelector('#imagePreviewForm\\:mediaDetailMediaContainer video, #imagePreviewForm\\:mediaDetailMediaContainer audio').duration) - setMediaPartialsViewsPanelMembers([{name: "duration", value: duration}]); + let mediaDuration = this.formatTime(document.querySelector('#imagePreviewForm\\:mediaDetailMediaContainer video, #imagePreviewForm\\:mediaDetailMediaContainer audio').duration) + remoteCommandSetMembersByRequestParameter([{name: "mediaDuration", value: mediaDuration}]); }, stopPlayEvent: new CustomEvent("mediaPartialStopPlay"), togglePlay(button, formattedTimeBegin, formattedTimeExtent) { diff --git a/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/dialogs/addMediaPartial.xhtml b/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/dialogs/addMediaPartial.xhtml index d534998e1ba..312cebdff9f 100644 --- a/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/dialogs/addMediaPartial.xhtml +++ b/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/dialogs/addMediaPartial.xhtml @@ -29,11 +29,11 @@

#{DataEditorForm.galleryPanel.mediaPartialsPanel.mediaPartialForm.isEdit() ? msgs.editMediaPartial : msgs.addMediaPartial}

+ rendered="#{DataEditorForm.galleryPanel.mediaPartialsPanel.mediaPartialForm.hasValidationErrorMessage()}"> + value="#{DataEditorForm.galleryPanel.mediaPartialsPanel.mediaPartialForm.validationErrorMessage}"/> diff --git a/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/partials/media-detail-media-partial-list.xhtml b/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/partials/media-detail-media-partial-list.xhtml index 1940a71197c..b7de69b8591 100644 --- a/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/partials/media-detail-media-partial-list.xhtml +++ b/Kitodo/src/main/webapp/WEB-INF/templates/includes/metadataEditor/partials/media-detail-media-partial-list.xhtml @@ -23,7 +23,7 @@ rendered="#{DataEditorForm.galleryPanel.mediaPartialsPanel.enabled}"> -