Skip to content

Commit

Permalink
Merge pull request kitodo#5835 from markusweigelt/fix-phyiscaldivisio…
Browse files Browse the repository at this point in the history
…n-type-of-av-for-3.6

For 3.6.x - Use type track for audio and video MIME types instead of type page for physical division type
  • Loading branch information
solth authored Nov 16, 2023
2 parents b847655 + 1ea605e commit a17b3d2
Show file tree
Hide file tree
Showing 14 changed files with 264 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
package org.kitodo.api.dataformat;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Arrays;
import java.util.Comparator;
import java.util.GregorianCalendar;
import java.util.List;
Expand Down Expand Up @@ -180,15 +180,16 @@ public List<LogicalDivision> getAllLogicalDivisions() {

/**
* Returns all child physical divisions of the physical division of the workpiece with
* type "page" sorted by their {@code order} as a flat list. The root media
* type "page" or "track" sorted by their {@code order} as a flat list. The root media
* unit is not contained. The list isn’t backed by the physical divisions, which
* means that insertions and deletions in the list would not change the
* physical divisions. Therefore, a list that cannot be modified is returned.
*
* @return all physical divisions with type "page", sorted by their {@code order}
* @return all physical divisions with type "page" or "track", sorted by their {@code order}
*/
public List<PhysicalDivision> getAllPhysicalDivisionChildrenFilteredByTypePageAndSorted() {
return getAllPhysicalDivisionChildrenFilteredByTypes(Collections.singletonList(PhysicalDivision.TYPE_PAGE));
public List<PhysicalDivision> getAllPhysicalDivisionChildrenSortedFilteredByPageAndTrack() {
return getAllPhysicalDivisionChildrenFilteredByTypes(
Arrays.asList(PhysicalDivision.TYPE_PAGE, PhysicalDivision.TYPE_TRACK));
}

/**
Expand Down
94 changes: 94 additions & 0 deletions Kitodo-API/src/main/java/org/kitodo/utils/MediaUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* (c) Kitodo. Key to digital objects e. V. <[email protected]>
*
* 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.utils;

import java.util.Objects;

import org.kitodo.api.dataformat.PhysicalDivision;

public class MediaUtil {

public static final String MIME_TYPE_AUDIO_PREFIX = "audio";
public static final String MIME_TYPE_IMAGE_PREFIX = "image";
public static final String MIME_TYPE_VIDEO_PREFIX = "video";

/**
* Private constructor to hide the implicit public one.
*/
private MediaUtil() {

}

/**
* Check if mime type starts with {@link org.kitodo.utils.MediaUtil#MIME_TYPE_AUDIO_PREFIX} or
* {@link org.kitodo.utils.MediaUtil#MIME_TYPE_VIDEO_PREFIX}.
*
* @param mimeType
* The mime type to check
* @return True if mime type starts with {@link org.kitodo.utils.MediaUtil#MIME_TYPE_AUDIO_PREFIX} or
* {@link org.kitodo.utils.MediaUtil#MIME_TYPE_VIDEO_PREFIX}.
*/
public static boolean isAudioOrVideo(String mimeType) {
return isAudio(mimeType) || isVideo(mimeType);
}

/**
* Check if mime type starts with {@link org.kitodo.utils.MediaUtil#MIME_TYPE_AUDIO_PREFIX}.
*
* @param mimeType
* The mime type to check
* @return True if mime type starts with {@link org.kitodo.utils.MediaUtil#MIME_TYPE_AUDIO_PREFIX}
*/
public static boolean isAudio(String mimeType) {
return Objects.nonNull(mimeType) && mimeType.startsWith(MIME_TYPE_AUDIO_PREFIX);
}

/**
* Check if mime type starts with {@link org.kitodo.utils.MediaUtil#MIME_TYPE_IMAGE_PREFIX}.
*
* @param mimeType
* The mime type to check
* @return True if mime type starts with {@link org.kitodo.utils.MediaUtil#MIME_TYPE_IMAGE_PREFIX}
*/
public static boolean isImage(String mimeType) {
return Objects.nonNull(mimeType) && mimeType.startsWith(MIME_TYPE_IMAGE_PREFIX);
}

/**
* Check if mime type starts with {@link org.kitodo.utils.MediaUtil#MIME_TYPE_VIDEO_PREFIX}.
*
* @param mimeType
* The mime type to check
* @return True if mime type starts with {@link org.kitodo.utils.MediaUtil#MIME_TYPE_VIDEO_PREFIX}
*/
public static boolean isVideo(String mimeType) {
return Objects.nonNull(mimeType) && mimeType.startsWith(MIME_TYPE_VIDEO_PREFIX);
}

/**
* Get the type of {@link org.kitodo.api.dataformat.PhysicalDivision} by mime type.
*
* @param mimeType
* The mime type to get the physical division type for
* @return The type of the {@link org.kitodo.api.dataformat.PhysicalDivision}
*/
public static String getPhysicalDivisionTypeOfMimeType(String mimeType) {
if (isImage(mimeType)) {
return PhysicalDivision.TYPE_PAGE;
}
if (isAudioOrVideo(mimeType)) {
return PhysicalDivision.TYPE_TRACK;
}
return PhysicalDivision.TYPE_OTHER;
}

}
52 changes: 52 additions & 0 deletions Kitodo-API/src/test/java/org/kitodo/utils/MediaUtilTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* (c) Kitodo. Key to digital objects e. V. <[email protected]>
*
* 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.utils;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Test;
import org.kitodo.api.dataformat.PhysicalDivision;

public class MediaUtilTest {

/**
* Test detection of mime type.
*/
@Test
public void testMimeTypeDetection() {
assertTrue(MediaUtil.isAudio("audio/mp3"));
assertFalse(MediaUtil.isVideo("image/jpeg"));

assertTrue(MediaUtil.isImage("image/jpeg"));
assertFalse(MediaUtil.isImage("video/mp4"));

assertTrue(MediaUtil.isVideo("video/mp4"));
assertFalse(MediaUtil.isVideo("image/jpeg"));

assertTrue(MediaUtil.isAudioOrVideo("audio/mp3"));
assertTrue(MediaUtil.isAudioOrVideo("video/mp4"));
assertFalse(MediaUtil.isAudioOrVideo("image/jpeg"));
}

/**
* Test getting the type of the {@link org.kitodo.api.dataformat.PhysicalDivision}.
*/
@Test
public void testGettingPhysicalDivisionTypeByMimeType() {
assertEquals(PhysicalDivision.TYPE_PAGE, MediaUtil.getPhysicalDivisionTypeOfMimeType("image/jpeg"));
assertEquals(PhysicalDivision.TYPE_TRACK, MediaUtil.getPhysicalDivisionTypeOfMimeType("audio/mp3"));
assertEquals(PhysicalDivision.TYPE_TRACK, MediaUtil.getPhysicalDivisionTypeOfMimeType("video/mp4"));
assertEquals(PhysicalDivision.TYPE_OTHER, MediaUtil.getPhysicalDivisionTypeOfMimeType("application/pdf"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
import java.util.NoSuchElementException;
import java.util.Objects;

import org.kitodo.api.dataformat.PhysicalDivision;
import org.kitodo.config.KitodoConfig;
import org.kitodo.config.enums.ParameterDataEditor;
import org.kitodo.dataeditor.MetsKitodoObjectFactory;
import org.kitodo.dataformat.metskitodo.DivType;
import org.kitodo.dataformat.metskitodo.FileType;
import org.kitodo.dataformat.metskitodo.StructMapType;
import org.kitodo.utils.MediaUtil;

public class PhysicalStructMapType extends StructMapType {

Expand Down Expand Up @@ -63,7 +63,7 @@ private List<DivType> getDivTypesByFileTypes(List<FileType> fileTypes) {
div.setID("PHYS_" + String.format("%04d", counter));
div.setORDER(BigInteger.valueOf(counter));
div.setORDERLABEL(KitodoConfig.getParameter(ParameterDataEditor.METS_EDITOR_DEFAULT_PAGINATION));
div.setTYPE(getPhysicalDivTypeByFileType(file));
div.setTYPE(MediaUtil.getPhysicalDivisionTypeOfMimeType(file.getMIMETYPE()));
DivType.Fptr divTypeFptr = objectFactory.createDivTypeFptr();
divTypeFptr.setFILEID(file);
div.getFptr().add(divTypeFptr);
Expand All @@ -75,16 +75,6 @@ private List<DivType> getDivTypesByFileTypes(List<FileType> fileTypes) {
return divTypes;
}

private String getPhysicalDivTypeByFileType(FileType file) {
if (file.getMIMETYPE().contains("image")) {
return PhysicalDivision.TYPE_PAGE;
}
if (file.getMIMETYPE().contains("audio")) {
return PhysicalDivision.TYPE_TRACK;
}
return PhysicalDivision.TYPE_OTHER;
}

private DivType getDivById(String id) {
for (DivType div : this.getDiv().getDiv()) {
if (Objects.equals(div.getID(),id)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.kitodo.api.dataformat.PhysicalDivision;
import org.kitodo.dataeditor.enums.FileLocationType;
import org.kitodo.dataeditor.enums.PositionOfNewDiv;
import org.kitodo.dataformat.metskitodo.DivType;
Expand Down Expand Up @@ -202,22 +203,22 @@ public void shouldReadGoobiMetadataGroup()
}

@Test
public void shouldInsertFileGroup() throws IOException, DatatypeConfigurationException {
public void shouldInsertFileGroup() throws DatatypeConfigurationException, IOException {
Path path = Paths.get("images");
int numberOfFiles = 5;
List<MediaFile> mediaFiles = new ArrayList<>();
for (int i = 1; i <= numberOfFiles; i++) {
mediaFiles.add(
new MediaFile(Paths.get(path + "/0000" + i + ".tif").toUri(), FileLocationType.URL, "image/tiff"));
new MediaFile(Paths.get(path + "/0000" + i + ".tif").toUri(), FileLocationType.URL, "image/tiff"));
}

MetsKitodoWrapper metsKitodoWrapper = new MetsKitodoWrapper("Manuscript");
metsKitodoWrapper.insertMediaFiles(mediaFiles);

Assert.assertEquals("Wrong number of divs in physical structMap", numberOfFiles,
metsKitodoWrapper.getPhysicalStructMap().getDiv().getDiv().size());
Assert.assertEquals("Wrong number of fils in fileSec", numberOfFiles,
metsKitodoWrapper.getMets().getFileSec().getFileGrp().get(0).getFile().size());
metsKitodoWrapper.getPhysicalStructMap().getDiv().getDiv().size());
Assert.assertEquals("Wrong number of files in fileSec", numberOfFiles,
metsKitodoWrapper.getMets().getFileSec().getFileGrp().get(0).getFile().size());

DivType divType = metsKitodoWrapper.getPhysicalStructMap().getDiv().getDiv().get(1);

Expand All @@ -231,6 +232,28 @@ public void shouldInsertFileGroup() throws IOException, DatatypeConfigurationExc

}


@Test
public void testPhysicalDivisionType() throws IOException, DatatypeConfigurationException {
List<MediaFile> mediaFiles = new ArrayList<>();
mediaFiles.add(new MediaFile(Paths.get("image/jpeg/0001.jpeg").toUri(), FileLocationType.URL, "image/jpeg"));
mediaFiles.add(new MediaFile(Paths.get("audio/mpeg/0002.jpeg").toUri(), FileLocationType.URL, "audio/mpeg"));
mediaFiles.add(new MediaFile(Paths.get("video/mp4/0003.jpeg").toUri(), FileLocationType.URL, "video/mp4"));

MetsKitodoWrapper metsKitodoWrapper = new MetsKitodoWrapper("MultiMedia");
metsKitodoWrapper.insertMediaFiles(mediaFiles);

Assert.assertEquals("Wrong number of divs in physical structMap", 3,
metsKitodoWrapper.getPhysicalStructMap().getDiv().getDiv().size());
Assert.assertEquals("Wrong number of files in fileSec", 3,
metsKitodoWrapper.getMets().getFileSec().getFileGrp().get(0).getFile().size());

List<DivType> divTypes = metsKitodoWrapper.getPhysicalStructMap().getDiv().getDiv();
Assert.assertEquals(PhysicalDivision.TYPE_PAGE, divTypes.get(0).getTYPE());
Assert.assertEquals(PhysicalDivision.TYPE_TRACK, divTypes.get(1).getTYPE());
Assert.assertEquals(PhysicalDivision.TYPE_TRACK, divTypes.get(2).getTYPE());
}

@Rule
public ExpectedException expectedException = ExpectedException.none();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ public void prepareAddableMetadataForStructure(boolean currentElement) {
}

private void prepareSelectPageOnAddNodeItems() {
List<PhysicalDivision> physicalDivisions = dataEditor.getWorkpiece().getAllPhysicalDivisionChildrenFilteredByTypePageAndSorted();
List<PhysicalDivision> physicalDivisions = dataEditor.getWorkpiece().getAllPhysicalDivisionChildrenSortedFilteredByPageAndTrack();
selectPageOnAddNodeItems = new ArrayList<>(physicalDivisions.size());
for (int i = 0; i < physicalDivisions.size(); i++) {
View view = View.of(physicalDivisions.get(i));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ List<View> getViewsToAdd(int firstPage, int lastPage) {

private List<View> getViewsToAdd(List<Integer> pages) {
return pages.parallelStream()
.map(dataEditor.getWorkpiece().getAllPhysicalDivisionChildrenFilteredByTypePageAndSorted()::get)
.map(dataEditor.getWorkpiece().getAllPhysicalDivisionChildrenSortedFilteredByPageAndTrack()::get)
.map(MetadataEditor::getFirstViewForPhysicalDivision)
.collect(Collectors.toList());
}
Expand All @@ -232,7 +232,7 @@ void prepare() {
paginationSubSelectionItems = new ArrayList<>();
paginationSelectionItems = new ArrayList<>();

List<PhysicalDivision> physicalDivisions = dataEditor.getWorkpiece().getAllPhysicalDivisionChildrenFilteredByTypePageAndSorted();
List<PhysicalDivision> physicalDivisions = dataEditor.getWorkpiece().getAllPhysicalDivisionChildrenSortedFilteredByPageAndTrack();
int capacity = (int) Math.ceil(physicalDivisions.size() / .75);
Set<Integer> assigneds = new HashSet<>(capacity);
Set<Integer> unassigneds = new HashSet<>(capacity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import org.kitodo.production.model.Subfolder;
import org.kitodo.production.services.ServiceManager;
import org.kitodo.production.services.file.FileService;
import org.kitodo.utils.MediaUtil;
import org.primefaces.PrimeFaces;

/**
Expand Down Expand Up @@ -349,7 +350,7 @@ void show() {
Process process = dataEditor.getProcess();
Project project = process.getProject();
List<PhysicalDivision> physicalDivisions = dataEditor.getWorkpiece()
.getAllPhysicalDivisionChildrenFilteredByTypePageAndSorted();
.getAllPhysicalDivisionChildrenSortedFilteredByPageAndTrack();

mediaContentTypeVariants.clear();
mediaContentTypePreviewFolder.clear();
Expand Down Expand Up @@ -393,7 +394,7 @@ private void initMediaContentType(List<PhysicalDivision> physicalDivisions, Fold
*/
private void updateMedia() {
List<PhysicalDivision> physicalDivisions = dataEditor.getWorkpiece()
.getAllPhysicalDivisionChildrenFilteredByTypePageAndSorted();
.getAllPhysicalDivisionChildrenSortedFilteredByPageAndTrack();
medias = new ArrayList<>(physicalDivisions.size());
dataEditor.getMediaProvider().resetMediaResolverForProcess(dataEditor.getProcess().getId());
for (PhysicalDivision physicalDivision : physicalDivisions) {
Expand Down Expand Up @@ -799,7 +800,7 @@ public boolean isSelected(GalleryMediaContent galleryMediaContent, GalleryStripe
private void selectMedia(String physicalDivisionOrder, String stripeIndex, String selectionType) {
PhysicalDivision selectedPhysicalDivision = null;
for (PhysicalDivision physicalDivision : this.dataEditor.getWorkpiece()
.getAllPhysicalDivisionChildrenFilteredByTypePageAndSorted()) {
.getAllPhysicalDivisionChildrenSortedFilteredByPageAndTrack()) {
if (Objects.equals(physicalDivision.getOrder(), Integer.parseInt(physicalDivisionOrder))) {
selectedPhysicalDivision = physicalDivision;
break;
Expand Down Expand Up @@ -976,4 +977,32 @@ public int getSeveralAssignmentsIndex(GalleryMediaContent galleryMediaContent) {
public String getCachingUUID() {
return cachingUUID;
}

/**
* Check if media view has mime type prefix.
*
* @param mimeTypePrefix
* The mime type prefix
* @return True if media view has mime type prefix
*/
public boolean hasMediaViewMimeTypePrefix(String mimeTypePrefix) {
Pair<PhysicalDivision, LogicalDivision> lastSelection = getLastSelection();
if (Objects.nonNull(lastSelection)) {
GalleryMediaContent galleryMediaContent = getGalleryMediaContent(lastSelection.getKey());
if (Objects.nonNull(galleryMediaContent)) {
String mediaViewMimeType = galleryMediaContent.getMediaViewMimeType();
switch (mimeTypePrefix) {
case MediaUtil.MIME_TYPE_AUDIO_PREFIX:
return MediaUtil.isAudio(mediaViewMimeType);
case MediaUtil.MIME_TYPE_VIDEO_PREFIX:
return MediaUtil.isVideo(mediaViewMimeType);
case MediaUtil.MIME_TYPE_IMAGE_PREFIX:
return MediaUtil.isImage(mediaViewMimeType);
default:
}
}
}
return false;
}

}
Loading

0 comments on commit a17b3d2

Please sign in to comment.