Skip to content

Commit

Permalink
Validate mandatory tags (#70)
Browse files Browse the repository at this point in the history
* Add util method for joining 2 sets

* Add error if any of the mandatory tags is missing
  • Loading branch information
Nianna authored Oct 13, 2024
1 parent bcfb8cc commit c28cd60
Show file tree
Hide file tree
Showing 11 changed files with 147 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.github.nianna.karedi.problem;

import com.github.nianna.karedi.I18N;
import com.github.nianna.karedi.song.tag.TagKey;

public class MandatoryTagMissingProblem extends TagProblem {

public MandatoryTagMissingProblem(TagKey key) {
super(Severity.ERROR, I18N.get("problem.tag.mandatory_missing.title", key), key);
}

}
21 changes: 20 additions & 1 deletion src/main/java/com/github/nianna/karedi/song/SongChecker.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.github.nianna.karedi.problem.DuetTagNotForDuetProblem;
import com.github.nianna.karedi.problem.InvalidMedleyBeatRangeProblem;
import com.github.nianna.karedi.problem.InvalidMedleyLengthProblem;
import com.github.nianna.karedi.problem.MandatoryTagMissingProblem;
import com.github.nianna.karedi.problem.MedleyMissingProblem;
import com.github.nianna.karedi.problem.NonZeroFirstBeatProblem;
import com.github.nianna.karedi.problem.NotesAfterEndProblem;
Expand All @@ -26,6 +27,7 @@
import javafx.collections.ObservableList;
import org.controlsfx.validation.ValidationResult;

import java.util.Comparator;
import java.util.Optional;

public class SongChecker implements Problematic {
Expand All @@ -39,7 +41,7 @@ public SongChecker(Song song) {
song.getTracks().addListener(ListenersUtils.createListChangeListener(this::refreshTrack,
this::refreshTrack, this::onTrackAdded, this::onTrackRemoved));
song.getTags().addListener(ListenersUtils.createListChangeListener(ListenersUtils::pass,
this::refreshTag, this::refreshTag, this::onTagRemoved));
this::refreshTag, this::onTagAdded, this::onTagRemoved));

song.getBeatMillisConverter().addListener(obs -> {
checkStart();
Expand Down Expand Up @@ -111,6 +113,12 @@ private void doValidateTag(Tag tag) {

private void onTagRemoved(Tag tag) {
removeTagProblems(tag);
revalidateMandatoryTags();
}

private void onTagAdded(Tag tag) {
refreshTag(tag);
revalidateMandatoryTags();
}

private void validateTagKey(String tagKey) {
Expand Down Expand Up @@ -153,6 +161,7 @@ private void revalidateAllTagsOnVersionChange() {
song.getTags().stream()
.filter(tag -> !TagKey.isKey(tag.getKey(), TagKey.VERSION))
.forEach(this::refreshTag);
revalidateMandatoryTags();
}

private void revalidateAllMultiplayerTags() {
Expand All @@ -161,6 +170,16 @@ private void revalidateAllMultiplayerTags() {
.forEach(this::refreshTag);
}

private void revalidateMandatoryTags() {
combiner.removeIf(problem -> problem instanceof MandatoryTagMissingProblem);

FormatSpecification.mandatoryTags(song.getFormatSpecificationVersion()).stream()
.sorted(Comparator.comparing(Enum::toString))
.filter(key -> !song.hasTag(key))
.map(MandatoryTagMissingProblem::new)
.forEach(combiner::add);
}

private void validateValue(TagKey key, String value) {
ValidationResult result = TagValueValidators.validate(key, value);
if (!result.getErrors().isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.Arrays;
import java.util.Optional;
import java.util.Set;

public enum FormatSpecification {
V_1_0_0("1.0.0"),
Expand Down Expand Up @@ -33,6 +34,10 @@ public static boolean supports(FormatSpecification formatSpecification, TagKey t
return FormatSpecificationSupportedTags.isSupported(formatSpecification, tagKey);
}

public static Set<TagKey> mandatoryTags(FormatSpecification formatSpecification) {
return FormatSpecificationMandatoryTags.forFormat(formatSpecification);
}

@Override
public String toString() {
return version;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.github.nianna.karedi.song.tag;

import com.github.nianna.karedi.util.CollectionsUtils;

import java.util.Map;
import java.util.Optional;
import java.util.Set;

class FormatSpecificationMandatoryTags {

private static final Set<TagKey> COMMON_MANDATORY_KEYS = Set.of(
TagKey.ARTIST,
TagKey.TITLE,
TagKey.BPM,
TagKey.MP3
);

private static final Set<TagKey> V_1_0_0_MANDATORY_KEYS = CollectionsUtils.join(
COMMON_MANDATORY_KEYS, Set.of(TagKey.VERSION)
);

private static final Set<TagKey> V_1_1_0_MANDATORY_KEYS = CollectionsUtils.join(
V_1_0_0_MANDATORY_KEYS,
Set.of(TagKey.AUDIO)
);

private static final Map<FormatSpecification, Set<TagKey>> MANDATORY_KEYS = Map.of(
FormatSpecification.V_1_0_0, V_1_0_0_MANDATORY_KEYS,
FormatSpecification.V_1_1_0, V_1_1_0_MANDATORY_KEYS
);


private FormatSpecificationMandatoryTags() {

}

public static Set<TagKey> forFormat(FormatSpecification formatSpecification) {
return Optional.ofNullable(formatSpecification)
.map(MANDATORY_KEYS::get)
.orElse(COMMON_MANDATORY_KEYS);
}


}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.github.nianna.karedi.song.tag;

import java.util.List;
import java.util.Set;

class FormatSpecificationMultiValuedTags {

private static final List<TagKey> MULTI_VALUED_KEYS = List.of(
private static final Set<TagKey> MULTI_VALUED_KEYS = Set.of(
TagKey.CREATOR,
TagKey.EDITION,
TagKey.GENRE,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.github.nianna.karedi.song.tag;

import java.util.List;
import com.github.nianna.karedi.util.CollectionsUtils;

import java.util.Map;
import java.util.stream.Stream;
import java.util.Set;

class FormatSpecificationSupportedTags {

private static final List<TagKey> V_1_0_0_SUPPORTED_KEYS = List.of(
private static final Set<TagKey> V_1_0_0_SUPPORTED_KEYS = Set.of(
TagKey.VERSION,
TagKey.TITLE,
TagKey.ARTIST,
Expand All @@ -33,12 +34,12 @@ class FormatSpecificationSupportedTags {
TagKey.COMMENT
);

private static final List<TagKey> V_1_1_0_SUPPORTED_KEYS = Stream.concat(
V_1_0_0_SUPPORTED_KEYS.stream(),
Stream.of(TagKey.AUDIO, TagKey.VOCALS, TagKey.INSTRUMENTAL, TagKey.TAGS, TagKey.PROVIDEDBY)
).toList();
private static final Set<TagKey> V_1_1_0_SUPPORTED_KEYS = CollectionsUtils.join(
V_1_0_0_SUPPORTED_KEYS,
Set.of(TagKey.AUDIO, TagKey.VOCALS, TagKey.INSTRUMENTAL, TagKey.TAGS, TagKey.PROVIDEDBY)
);

private static final Map<FormatSpecification, List<TagKey>> SUPPORTED_KEYS = Map.of(
private static final Map<FormatSpecification, Set<TagKey>> SUPPORTED_KEYS = Map.of(
FormatSpecification.V_1_0_0, V_1_0_0_SUPPORTED_KEYS,
FormatSpecification.V_1_1_0, V_1_1_0_SUPPORTED_KEYS
);
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/com/github/nianna/karedi/util/CollectionsUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.github.nianna.karedi.util;

import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public final class CollectionsUtils {

private CollectionsUtils() {

}

public static <T> Set<T> join(Set<T> first, Set<T> second) {
return Stream.of(first, second)
.flatMap(Collection::stream)
.collect(Collectors.toUnmodifiableSet());
}
}
1 change: 1 addition & 0 deletions src/main/resources/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ problem.line.overlapping.description=Lines should not overlap
problem.tag.validation_fail.title=Tag validation failed
problem.tag.validation_fail.full_title=Tag validation failed #{0}
problem.tag.unsupported.title=Unsupported tag #{0}
problem.tag.mandatory_missing.title=Mandatory tag #{0} is missing
problem.tag.nonexistent_track.title=Tag #{0} defines name for nonexistent track
problem.tag.duet_not_for_duet.title=Tag #{0} defined not for duet song
problem.tag.inconsistent.title=Tags #{0} and #{1} are inconsistent
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/messages_en_GB.properties
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ problem.line.overlapping.description=Lines should not overlap
problem.tag.validation_fail.title=Tag validation failed
problem.tag.validation_fail.full_title=Tag validation failed #{0}
problem.tag.unsupported.title=Unsupported tag #{0}
problem.tag.mandatory_missing.title=Mandatory tag #{0} is missing
problem.tag.nonexistent_track.title=Tag #{0} defines name for nonexistent track
problem.tag.duet_not_for_duet.title=Tag #{0} defined not for duet song
problem.tag.inconsistent.title=Tags #{0} and #{1} are inconsistent
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/messages_pl_PL.properties
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ problem.tag.validation_fail.full_title=Niepoprawna warto\u015B\u0107 tagu #{0}
problem.tag.inconsistent.title=Tagi #{0} i #{1} s\u0105 niespójne
problem.tag.inconsistent.description=Te tagi maj\u0105 t\u0105 sam\u0105 funkcj\u0119, usu\u0144 jeden z nich lub ustaw t\u0105 sam\u0105 warto\u015B\u0107
problem.tag.unsupported.title=Niewspierany tag #{0}
problem.tag.mandatory_missing.title=Tag #{0} jest wymagany
problem.tag.nonexistent_track.title=Tag #{0} definiuje nazw\u0119 dla nieistniej\u0105cej \u015Bcie\u017Cki
problem.tag.duet_not_for_duet.title=Tag #{0} u\u017Cyty nie w duecie
problem.uncommon_golden_bonus.title=Niepoprawny bonus za z\u0142ote nuty
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.github.nianna.karedi.song.tag;

import org.junit.jupiter.api.Test;

import java.util.Set;

import static org.junit.jupiter.api.Assertions.*;

class FormatSpecificationMandatoryTagsTest {

@Test
void shouldReturnMandatoryKeysForNullFormat() {
Set<TagKey> result = FormatSpecificationMandatoryTags.forFormat(null);
assertEquals(4, result.size());
assertTrue(result.containsAll(Set.of(TagKey.ARTIST, TagKey.TITLE, TagKey.BPM, TagKey.MP3)));
}

@Test
void shouldReturnMandatoryKeysForV1_0_0Format() {
Set<TagKey> result = FormatSpecificationMandatoryTags.forFormat(FormatSpecification.V_1_0_0);
assertEquals(5, result.size());
assertTrue(result.containsAll(Set.of(TagKey.ARTIST, TagKey.TITLE, TagKey.BPM, TagKey.MP3, TagKey.VERSION)));
}

@Test
void shouldReturnMandatoryKeysForV1_1_0Format() {
Set<TagKey> result = FormatSpecificationMandatoryTags.forFormat(FormatSpecification.V_1_1_0);
assertEquals(6, result.size());
assertTrue(result.containsAll(Set.of(TagKey.ARTIST, TagKey.TITLE, TagKey.BPM, TagKey.MP3, TagKey.VERSION,
TagKey.AUDIO)));
}

}

0 comments on commit c28cd60

Please sign in to comment.