Skip to content

Add quality checker for journal abbrevs#13190

Closed
aaspst wants to merge 37 commits into
JabRef:mainfrom
aaspst:fix-for-issue-149
Closed

Add quality checker for journal abbrevs#13190
aaspst wants to merge 37 commits into
JabRef:mainfrom
aaspst:fix-for-issue-149

Conversation

@aaspst

@aaspst aaspst commented May 30, 2025

Copy link
Copy Markdown

Closes JabRef/abbrv.jabref.org#149
Describe the changes you have made here: what, where, why, ...

Changes made

###Testing

  • Added 32 JUnit tests in JournalAbbreviationValidatorTest covering:
    • All validation rules
    • Edge cases (special chars, long inputs, empty values)
    • Allowed exceptions (e.g., Acta Phys. Polon.)

Mandatory checks

  • I own the copyright of the code submitted and I license it under the MIT license
  • [/] Change in CHANGELOG.md described in a way that is understandable for the average user (if change is visible to the user)
  • Tests created for changes (if applicable)
  • Manually tested changed features in running JabRef (always required)
  • [/] Screenshots added in PR description (if change is visible to the user)
  • Checked developer's documentation: Is the information available and up to date? If not, I outlined it in this pull request.
  • Checked documentation: Is the information available and up to date? If not, I created an issue at https://github.com/JabRef/user-documentation/issues or, even better, I submitted a pull request to the documentation repository.

@koppor

koppor commented May 30, 2025

Copy link
Copy Markdown
Member

This PR fixes JabRef/abbrv.jabref.org#149.

Update: I think, it is OK to have in here - and therefore in JabKit. But then, it should be wired into JabKit!


Old text:

It should be a pull request to https://github.com/JabRef/abbrv.jabref.org/.

I like that it is implemented in Java.

It can be implemented using JBang as wrapper. You can also use gradle or bld as build tool.

@koppor koppor marked this pull request as draft May 30, 2025 16:07
@Siedlerchr Siedlerchr changed the title Fix for issue 149 Add quality checker for journal abbrevs Jun 2, 2025
@aaspst

aaspst commented Jun 2, 2025

Copy link
Copy Markdown
Author

This PR fixes JabRef/abbrv.jabref.org#149.

Update: I think, it is OK to have in here - and therefore in JabKit. But then, it should be wired into JabKit!

Old text:

It should be a pull request to https://github.com/JabRef/abbrv.jabref.org/.

I like that it is implemented in Java.

It can be implemented using JBang as wrapper. You can also use gradle or bld as build tool.

@koppor Hi! I was thinking of adding a Runtime validation for when abbreviations are added dynamically and a CI bulk validation (via JabKit) to check all existing abbreviation files. Do you think it would be okay to do it that way?

@koppor

koppor commented Jun 3, 2025

Copy link
Copy Markdown
Member

@koppor Hi! I was thinking of adding a Runtime validation for when abbreviations are added dynamically and a CI bulk validation (via JabKit) to check all existing abbreviation files. Do you think it would be okay to do it that way?

Yes. Also enable checking in the dialog (if possible) -> the lists can be modified eternally.

Comment thread src/main/java/org/jabref/cli/ArgumentProcessor.java
@aaspst aaspst marked this pull request as ready for review June 3, 2025 22:54
if (viewModel.validateAbbreviationsProperty().get()) {
AbbreviationViewModel item = event.getRowValue();
String newValue = event.getNewValue();
List<ValidationResult> results = viewModel.validateAbbreviation(item.getName(), newValue, item.getAbbreviation());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code duplicates the validation logic across multiple columns. This violates the DRY principle and could be refactored to a single method to improve maintainability.

@aaspst aaspst force-pushed the fix-for-issue-149 branch from 9181df0 to 096f556 Compare June 4, 2025 19:43
@aaspst aaspst force-pushed the fix-for-issue-149 branch from 096f556 to 3c285e7 Compare June 4, 2025 20:57
return uiCommands;
}

private void validateJournalAbbreviations() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method validateJournalAbbreviations does not follow the Single-responsibility principle as it both loads the repository and prints validation results. These should be separate responsibilities.


private void printValidationResults(List<JournalAbbreviationValidator.ValidationResult> issues) {
if (issues.isEmpty()) {
System.out.println(Localization.lang("No validation issues found in journal abbreviations"));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string 'No validation issues found in journal abbreviations' should be localized using Localization.lang to ensure multilingual support.

try {
if (writeXMP) {
if (xmpPdfExporter.exportToAllFilesOfEntry(databaseContext, filePreferences, entry, List.of(entry), abbreviationRepository)) {
System.out.printf("Successfully written XMP metadata on at least one linked file of %s%n", citeKey);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string should be localized using Localization.lang to ensure multilingual support.

if (xmpPdfExporter.exportToAllFilesOfEntry(databaseContext, filePreferences, entry, List.of(entry), abbreviationRepository)) {
System.out.printf("Successfully written XMP metadata on at least one linked file of %s%n", citeKey);
} else {
System.err.printf("Cannot write XMP metadata on any linked files of %s. Make sure there is at least one linked file and the path is correct.%n", citeKey);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string should be localized using Localization.lang to ensure multilingual support.

}
if (embedBibfile) {
if (embeddedBibFilePdfExporter.exportToAllFilesOfEntry(databaseContext, filePreferences, entry, List.of(entry), abbreviationRepository)) {
System.out.printf("Successfully embedded metadata on at least one linked file of %s%n", citeKey);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string should be localized using Localization.lang to ensure multilingual support.

if (embeddedBibFilePdfExporter.exportToAllFilesOfEntry(databaseContext, filePreferences, entry, List.of(entry), abbreviationRepository)) {
System.out.printf("Successfully embedded metadata on at least one linked file of %s%n", citeKey);
} else {
System.out.printf("Cannot embed metadata on any linked files of %s. Make sure there is at least one linked file and the path is correct.%n", citeKey);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string should be localized using Localization.lang to ensure multilingual support.

for (String citeKey : citeKeys) {
List<BibEntry> bibEntryList = databaseContext.getDatabase().getEntriesByCitationKey(citeKey);
if (bibEntryList.isEmpty()) {
System.err.printf("Skipped - Cannot find %s in library.%n", citeKey);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string should be localized using Localization.lang to ensure multilingual support.

try {
if (writeXMP) {
if (xmpPdfExporter.exportToFileByPath(databaseContext, filePreferences, filePath, abbreviationRepository)) {
System.out.printf("Successfully written XMP metadata of at least one entry to %s%n", fileName);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string should be localized using Localization.lang to ensure multilingual support.

if (xmpPdfExporter.exportToFileByPath(databaseContext, filePreferences, filePath, abbreviationRepository)) {
System.out.printf("Successfully written XMP metadata of at least one entry to %s%n", fileName);
} else {
System.out.printf("File %s is not linked to any entry in database.%n", fileName);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string should be localized using Localization.lang to ensure multilingual support.

}
if (embeddBibfile) {
if (embeddedBibFilePdfExporter.exportToFileByPath(databaseContext, filePreferences, filePath, abbreviationRepository)) {
System.out.printf("Successfully embedded XMP metadata of at least one entry to %s%n", fileName);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string should be localized using Localization.lang to ensure multilingual support.

if (xmpPdfExporter.exportToFileByPath(databaseContext, filePreferences, filePath, abbreviationRepository)) {
System.out.printf("Successfully written XMP metadata of at least one entry to %s%n", fileName);
} else {
System.out.printf("File %s is not linked to any entry in database.%n", fileName);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string should be localized using Localization.lang to ensure multilingual support.

StringBuilder sb = new StringBuilder();

int maxLength = table.stream()
.mapToInt(pair -> Objects.requireNonNullElse(pair.getKey(), "").length())

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of Objects.requireNonNullElse is discouraged. Instead, use JSpecify @nonnull annotation to ensure non-null values.

String abbreviation = "Problemy Mat.";

var result = validator.checkWrongEscape(fullName, abbreviation, 1).orElseThrow();
assertEquals(false, result.isValid());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test uses assertEquals to check a boolean condition. It should directly assert the boolean value using assertFalse for better readability and adherence to best practices.

String abbreviation = "J. with \\r return and \\b backspace";

var result = validator.checkWrongEscape(fullName, abbreviation, 1).orElseThrow();
assertEquals(true, result.isValid());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test uses assertEquals to check a boolean condition. It should directly assert the boolean value using assertTrue for better readability and adherence to best practices.

@jabref-machine

Copy link
Copy Markdown
Collaborator

Your code currently does not meet JabRef's code guidelines. We use Checkstyle to identify issues. You can see which checks are failing by locating the box "Some checks were not successful" on the pull request page. To see the test output, locate "Tests / Checkstyle (pull_request)" and click on it.

In case of issues with the import order, double check that you activated Auto Import. You can trigger fixing imports by pressing Ctrl+Alt+O to trigger Optimize Imports.

Please carefully follow the setup guide for the codestyle. Afterwards, please run checkstyle locally and fix the issues, commit, and push.

@jabref-machine

Copy link
Copy Markdown
Collaborator

JUnit tests of jablib are failing. You can see which checks are failing by locating the box "Some checks were not successful" on the pull request page. To see the test output, locate "Tests / Unit tests (pull_request)" and click on it.

You can then run these tests in IntelliJ to reproduce the failing tests locally. We offer a quick test running howto in the section Final build system checks in our setup guide.

@trag-bot

trag-bot Bot commented Jul 7, 2025

Copy link
Copy Markdown

@trag-bot didn't find any issues in the code! ✅✨

@koppor

koppor commented Jul 7, 2025

Copy link
Copy Markdown
Member

@aaspst I see only red crosses here. Don't know why. Do you have time and motivatoin to continue working on this?

@koppor

koppor commented Jul 12, 2025

Copy link
Copy Markdown
Member

The PR contains ArgumentProcessor as new file. I think, this is broken.

Maybe, start from scratch. One PR: Basic testing infrastructure and then subsequent PRs for each test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add quality checkers DOI Lookup using CrossRef

3 participants