Skip to content

Commit

Permalink
Feat/validate tags with format version (#52)
Browse files Browse the repository at this point in the history
* Rename TagValidators to TagValueValidators

* Add error for unsupported tags in version 1.0.0 and 1.1.0

* Add error if duplicate tags have inconsistent values
  • Loading branch information
Nianna authored Oct 3, 2024
1 parent 0135fe1 commit 638379d
Show file tree
Hide file tree
Showing 20 changed files with 340 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.github.nianna.karedi.song.Song;
import com.github.nianna.karedi.song.SongTrack;
import com.github.nianna.karedi.song.tag.TagKey;
import com.github.nianna.karedi.song.tag.TagValidators;
import com.github.nianna.karedi.song.tag.TagValueValidators;
import com.github.nianna.karedi.util.Converter;

import java.util.logging.Logger;
Expand Down Expand Up @@ -55,15 +55,15 @@ private void setDefaultGap(Song song) {

private void validateBpm(Song song) {
String value = song.getTagValue(TagKey.BPM).orElseThrow();
if (TagValidators.hasValidationErrors(TagKey.BPM, value)) {
if (TagValueValidators.hasValidationErrors(TagKey.BPM, value)) {
LOGGER.severe(I18N.get("normalizer.bpm.invalid", value, Song.DEFAULT_BPM));
song.getBeatMillisConverter().setBpm(Song.DEFAULT_BPM);
}
}

private void validateGap(Song song) {
String value = song.getTagValue(TagKey.GAP).orElseThrow();
if (TagValidators.hasValidationErrors(TagKey.GAP, value)) {
if (TagValueValidators.hasValidationErrors(TagKey.GAP, value)) {
LOGGER.severe(I18N.get("normalizer.gap.invalid", value, Song.DEFAULT_GAP));
song.getBeatMillisConverter().setGap(Song.DEFAULT_GAP);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import com.github.nianna.karedi.song.Song;
import com.github.nianna.karedi.song.tag.Tag;
import com.github.nianna.karedi.song.tag.TagKey;
import com.github.nianna.karedi.song.tag.TagValidators;
import com.github.nianna.karedi.song.tag.TagValueValidators;
import com.github.nianna.karedi.util.ContextMenuBuilder;
import com.github.nianna.karedi.util.Converter;
import com.github.nianna.karedi.util.MathUtils;
Expand Down Expand Up @@ -78,7 +78,7 @@ private void initialize() {
keyColumn.setCellValueFactory(cell -> new SimpleStringProperty(cell.getValue().getKey()));
valueColumn.setCellValueFactory(cell -> cell.getValue().valueProperty());
valueColumn.setCellFactory(
params -> new TagValueTableCell(tag -> TagValidators.forKey(tag.getKey())));
params -> new TagValueTableCell(tag -> TagValueValidators.forKey(tag.getKey())));
}

@Override
Expand Down Expand Up @@ -216,7 +216,7 @@ private void handleRemove(Tag tag) {
}

private void changeTagValueIfValid(TagKey key, String value) {
if (!TagValidators.hasValidationErrors(key, value)) {
if (!TagValueValidators.hasValidationErrors(key, value)) {
commandContext.execute(new ChangeTagValueCommand(activeSongContext.getSong(), key, value));
}
}
Expand Down Expand Up @@ -290,7 +290,7 @@ public void startEdit() {
setPadding(new Insets(5));

validator = validatorSupplier.apply(tag);
TagValidators.forbiddenCharacterRegex(tag.getKey()).ifPresent(regex -> {
TagValueValidators.forbiddenCharacterRegex(tag.getKey()).ifPresent(regex -> {
textField.setForbiddenCharacterRegex(regex);
});
textField.setText(getText());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import com.github.nianna.karedi.control.NonNegativeIntegerTextField;
import com.github.nianna.karedi.song.tag.Tag;
import com.github.nianna.karedi.song.tag.TagKey;
import com.github.nianna.karedi.song.tag.TagValidators;
import com.github.nianna.karedi.song.tag.TagValueValidators;
import com.github.nianna.karedi.util.Language;
import com.github.nianna.karedi.util.NumericNodeUtils;

Expand Down Expand Up @@ -77,12 +77,12 @@ private void initialize() {
}

private void registerValidators() {
validationSupport.registerValidator(gapField, TagValidators.forKey(TagKey.GAP));
validationSupport.registerValidator(yearField, TagValidators.forKey(TagKey.YEAR));
validationSupport.registerValidator(languageField, TagValidators.forKey(TagKey.LANGUAGE));
validationSupport.registerValidator(creatorField, TagValidators.forKey(TagKey.CREATOR));
validationSupport.registerValidator(genreField, TagValidators.forKey(TagKey.GENRE));
validationSupport.registerValidator(editionField, TagValidators.forKey(TagKey.EDITION));
validationSupport.registerValidator(gapField, TagValueValidators.forKey(TagKey.GAP));
validationSupport.registerValidator(yearField, TagValueValidators.forKey(TagKey.YEAR));
validationSupport.registerValidator(languageField, TagValueValidators.forKey(TagKey.LANGUAGE));
validationSupport.registerValidator(creatorField, TagValueValidators.forKey(TagKey.CREATOR));
validationSupport.registerValidator(genreField, TagValueValidators.forKey(TagKey.GENRE));
validationSupport.registerValidator(editionField, TagValueValidators.forKey(TagKey.EDITION));
}

private List<Tag> generateListOfValidTags() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import com.github.nianna.karedi.control.RestrictedTextField;
import com.github.nianna.karedi.dialog.EditFilenamesDialog.FilenamesEditResult;
import com.github.nianna.karedi.song.tag.TagKey;
import com.github.nianna.karedi.song.tag.TagValidators;
import com.github.nianna.karedi.song.tag.TagValueValidators;
import com.github.nianna.karedi.util.Utils;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
Expand Down Expand Up @@ -129,9 +129,9 @@ public void initialize() {
backgroundExtensionField.setText(DEFAULT_IMAGE_EXTENSION);

Platform.runLater(() -> {
validationSupport.registerValidator(titleField, TagValidators.forKey(TagKey.TITLE));
validationSupport.registerValidator(artistField, TagValidators.forKey(TagKey.ARTIST));
validationSupport.registerValidator(coverExtensionField, TagValidators.defaultValidator());
validationSupport.registerValidator(titleField, TagValueValidators.forKey(TagKey.TITLE));
validationSupport.registerValidator(artistField, TagValueValidators.forKey(TagKey.ARTIST));
validationSupport.registerValidator(coverExtensionField, TagValueValidators.defaultValidator());
validationSupport.initInitialDecoration();
includeBackgroundCheckBox.setSelected(!hideBackground);
includeVideoCheckBox.setSelected(!hideVideo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import com.github.nianna.karedi.control.NonNegativeIntegerTextField;
import com.github.nianna.karedi.song.Song.Medley;
import com.github.nianna.karedi.song.tag.TagKey;
import com.github.nianna.karedi.song.tag.TagValidators;
import com.github.nianna.karedi.song.tag.TagValueValidators;
import com.github.nianna.karedi.util.NumericNodeUtils;

public class EditMedleyDialog extends ValidatedDialog<Medley> {
Expand Down Expand Up @@ -44,7 +44,7 @@ private void initialize() {
}

private void configureTagTextField(NonNegativeIntegerTextField textField, TagKey tagKey) {
validationSupport.registerValidator(textField, TagValidators.forKey(tagKey));
validationSupport.registerValidator(textField, TagValueValidators.forKey(tagKey));
textField.setOnScroll(NumericNodeUtils.createUpdateIntValueOnScrollHandler(
textField::getValue, textField::setValueIfLegal));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import com.github.nianna.karedi.control.RestrictedTextField;
import com.github.nianna.karedi.song.tag.Tag;
import com.github.nianna.karedi.song.tag.TagKey;
import com.github.nianna.karedi.song.tag.TagValidators;
import com.github.nianna.karedi.song.tag.TagValueValidators;
import com.github.nianna.karedi.util.ValidationUtils;

public class EditTagDialog extends Dialog<Tag> {
Expand All @@ -27,7 +27,7 @@ public class EditTagDialog extends Dialog<Tag> {

private ValidationDecoration valueDecoration = new GraphicValidationDecoration();
private ValidationDecoration keyDecoration = new GraphicValidationDecoration();
private Validator<String> valueValidator = TagValidators.defaultValidator();
private Validator<String> valueValidator = TagValueValidators.defaultValidator();
private Validator<String> keyValidator = Validator
.createEmptyValidator(I18N.get("dialog.tag.key_required"));

Expand Down Expand Up @@ -66,10 +66,10 @@ public void initialize() {
}

private void onKeyFieldTextChanged() {
TagValidators.forbiddenCharacterRegex(keyField.getText()).ifPresent(regex -> {
TagValueValidators.forbiddenCharacterRegex(keyField.getText()).ifPresent(regex -> {
valueField.setForbiddenCharacterRegex(regex);
});
valueValidator = TagValidators.forKey(keyField.getText());
valueValidator = TagValueValidators.forKey(keyField.getText());
refreshValueFieldDecoration();
refreshKeyFieldDecoration();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import com.github.nianna.karedi.control.NonNegativeDoubleTextField;
import com.github.nianna.karedi.dialog.ModifyBpmDialog.BpmEditResult;
import com.github.nianna.karedi.song.tag.TagKey;
import com.github.nianna.karedi.song.tag.TagValidators;
import com.github.nianna.karedi.song.tag.TagValueValidators;
import com.github.nianna.karedi.util.NumericNodeUtils;

public abstract class ModifyBpmDialog extends ValidatedDialog<BpmEditResult> {
Expand All @@ -35,7 +35,7 @@ private void initialize() {
.addListener(this::refreshScalingButtonsDisable);

Platform.runLater(() -> {
validationSupport.registerValidator(bpmField, TagValidators.forKey(TagKey.BPM));
validationSupport.registerValidator(bpmField, TagValueValidators.forKey(TagKey.BPM));
validationSupport.initInitialDecoration();
bpmField.requestFocus();
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.github.nianna.karedi.problem;

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

public class InconsistentTagsProblem extends TagProblem {

public InconsistentTagsProblem(TagKey key, TagKey otherKey) {
super(Severity.ERROR, I18N.get("problem.tag.inconsistent.title", key, otherKey), key, otherKey);
setDescription(I18N.get("problem.tag.inconsistent.description"));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,21 @@
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

import com.github.nianna.karedi.region.IntBounded;
import com.github.nianna.karedi.song.SongTrack;
import com.github.nianna.karedi.song.tag.TagKey;

public abstract class TagProblem extends Problem {
private TagKey[] keys;
private String[] keys;

public TagProblem(Severity severity, String title, TagKey... keys) {
super(severity, title);
this.keys = Stream.of(keys).map(TagKey::toString).toArray(String[]::new);
}

public TagProblem(Severity severity, String title, String... keys) {
super(severity, title);
this.keys = keys;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.github.nianna.karedi.problem;

import com.github.nianna.karedi.I18N;

public class UnsupportedTagProblem extends TagProblem {

public UnsupportedTagProblem(String key) {
super(Severity.ERROR, I18N.get("problem.tag.unsupported.title", key), key);
}

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

import com.github.nianna.karedi.problem.InconsistentTagsProblem;
import com.github.nianna.karedi.problem.TagProblem;
import com.github.nianna.karedi.song.tag.TagKey;

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

import static java.util.Objects.nonNull;

public class DuplicatedTagsConsistencyValidator {

private static final Map<TagKey, TagKey> TAG_DUPLICATES = Map.of(
TagKey.MP3, TagKey.AUDIO,
TagKey.AUDIO, TagKey.MP3,
TagKey.P1, TagKey.DUETSINGERP1,
TagKey.DUETSINGERP1, TagKey.P1,
TagKey.P2, TagKey.DUETSINGERP2,
TagKey.DUETSINGERP2, TagKey.P2
);

private DuplicatedTagsConsistencyValidator() {

}

public static Optional<TagProblem> validate(Song song, TagKey key) {
if (TAG_DUPLICATES.containsKey(key)) {
String tagValue = song.getTagValue(key).orElseThrow();
String similarTagValue = song.getTagValue(TAG_DUPLICATES.get(key)).orElse(null);
if (nonNull(similarTagValue) && !tagValue.equals(similarTagValue)) {
return Optional.of(new InconsistentTagsProblem(key, TAG_DUPLICATES.get(key)));
}
}
return Optional.empty();
}

}
Loading

0 comments on commit 638379d

Please sign in to comment.