Skip to content

Commit

Permalink
[kbss-cvut/termit-ui#449] Handle languages other than Czech and Engli…
Browse files Browse the repository at this point in the history
…sh when importing Excel sheet.
  • Loading branch information
ledsoft committed Jul 29, 2024
1 parent 7f186d6 commit fe32cbe
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -38,6 +39,8 @@ class LocalizedSheetImporter {

private static final Logger LOG = LoggerFactory.getLogger(LocalizedSheetImporter.class);

private static final String FALLBACK_LANGUAGE = "en";

private final List<Term> existingTerms;

private Map<String, Integer> attributeToColumn;
Expand Down Expand Up @@ -72,11 +75,8 @@ List<Term> resolveTermsFromSheet(Sheet sheet) {
LOG.trace("Sheet '{}' mapped to language tag '{}'.", sheet.getSheetName(), langTag);
final Properties attributeMapping = new Properties();
this.labelToTerm = new LinkedHashMap<>();
// TODO How to handle languages for which we do not have column names (attribute mapping)?
// Use English as backup
try {
attributeMapping.load(
getClass().getClassLoader().getResourceAsStream("attributes/" + langTag + ".properties"));
attributeMapping.load(resolveColumnMappingFile());
final Row attributes = sheet.getRow(0);
this.attributeToColumn = resolveAttributeColumns(attributes, attributeMapping);
} catch (IOException e) {
Expand All @@ -91,6 +91,16 @@ List<Term> resolveTermsFromSheet(Sheet sheet) {
return new ArrayList<>(labelToTerm.values());
}

private InputStream resolveColumnMappingFile() {
if (getClass().getClassLoader().getResource("attributes/" + langTag + ".properties") != null) {
LOG.trace("Loading attribute mapping for language tag '{}'.", langTag);
return getClass().getClassLoader().getResourceAsStream("attributes/" + langTag + ".properties");
} else {
LOG.trace("No attribute mapping found for language tag '{}', falling back to '{}'.", langTag, FALLBACK_LANGUAGE);
return getClass().getClassLoader().getResourceAsStream("attributes/" + FALLBACK_LANGUAGE + ".properties");
}
}

/**
* First map terms to labels.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ void importThrowsVocabularyDoesNotExistExceptionWhenVocabularyIsNotFound() {
void importCreatesRootTermsWithBasicAttributesFromEnglishSheet() {
when(vocabularyDao.exists(vocabulary.getUri())).thenReturn(true);
when(vocabularyDao.find(vocabulary.getUri())).thenReturn(Optional.of(vocabulary));
initIdentifierGenerator(false);
initIdentifierGenerator(Constants.DEFAULT_LANGUAGE, false);

final Vocabulary result = sut.importVocabulary(
new VocabularyImporter.ImportConfiguration(false, vocabulary.getUri(), prePersist),
Expand All @@ -125,18 +125,18 @@ void importCreatesRootTermsWithBasicAttributesFromEnglishSheet() {
assertEquals("The process of building a building", construction.get().getDefinition().get("en"));
}

private void initIdentifierGenerator(boolean forChild) {
private void initIdentifierGenerator(String lang, boolean forChild) {
doAnswer(inv -> {
final Term t = inv.getArgument(0);
t.setUri(URI.create(vocabulary.getUri().toString() + "/" + IdentifierResolver.normalize(
t.getLabel().get(Constants.DEFAULT_LANGUAGE))));
t.getLabel().get(lang))));
return null;
}).when(termService).addRootTermToVocabulary(any(Term.class), eq(vocabulary));
if (forChild) {
doAnswer(inv -> {
final Term t = inv.getArgument(0);
t.setUri(URI.create(vocabulary.getUri().toString() + "/" + IdentifierResolver.normalize(
t.getLabel().get(Constants.DEFAULT_LANGUAGE))));
t.getLabel().get(lang))));
return null;
}).when(termService).addChildTerm(any(Term.class), any(Term.class));
}
Expand All @@ -146,7 +146,7 @@ private void initIdentifierGenerator(boolean forChild) {
void importCreatesRootTermsWithPluralBasicAttributesFromEnglishSheet() {
when(vocabularyDao.exists(vocabulary.getUri())).thenReturn(true);
when(vocabularyDao.find(vocabulary.getUri())).thenReturn(Optional.of(vocabulary));
initIdentifierGenerator(false);
initIdentifierGenerator(Constants.DEFAULT_LANGUAGE, false);

final Vocabulary result = sut.importVocabulary(
new VocabularyImporter.ImportConfiguration(false, vocabulary.getUri(), prePersist),
Expand Down Expand Up @@ -181,7 +181,7 @@ void importCreatesRootTermsWithPluralBasicAttributesFromEnglishSheet() {
void importCreatesRootTermsWithBasicAttributesFromMultipleTranslationSheets() {
when(vocabularyDao.exists(vocabulary.getUri())).thenReturn(true);
when(vocabularyDao.find(vocabulary.getUri())).thenReturn(Optional.of(vocabulary));
initIdentifierGenerator(false);
initIdentifierGenerator(Constants.DEFAULT_LANGUAGE, false);

final Vocabulary result = sut.importVocabulary(
new VocabularyImporter.ImportConfiguration(false, vocabulary.getUri(), prePersist),
Expand Down Expand Up @@ -212,7 +212,7 @@ void importCreatesRootTermsWithBasicAttributesFromMultipleTranslationSheets() {
void importCreatesRootTermsWithPluralBasicAttributesFromMultipleTranslationSheets() {
when(vocabularyDao.exists(vocabulary.getUri())).thenReturn(true);
when(vocabularyDao.find(vocabulary.getUri())).thenReturn(Optional.of(vocabulary));
initIdentifierGenerator(false);
initIdentifierGenerator(Constants.DEFAULT_LANGUAGE, false);

final Vocabulary result = sut.importVocabulary(
new VocabularyImporter.ImportConfiguration(false, vocabulary.getUri(), prePersist),
Expand Down Expand Up @@ -249,7 +249,7 @@ void importCreatesRootTermsWithPluralBasicAttributesFromMultipleTranslationSheet
void importCreatesTermHierarchy() {
when(vocabularyDao.exists(vocabulary.getUri())).thenReturn(true);
when(vocabularyDao.find(vocabulary.getUri())).thenReturn(Optional.of(vocabulary));
initIdentifierGenerator(true);
initIdentifierGenerator(Constants.DEFAULT_LANGUAGE, true);

final Vocabulary result = sut.importVocabulary(
new VocabularyImporter.ImportConfiguration(false, vocabulary.getUri(), prePersist),
Expand All @@ -273,7 +273,7 @@ void importCreatesTermHierarchy() {
void importSavesRelationshipsBetweenTerms() {
when(vocabularyDao.exists(vocabulary.getUri())).thenReturn(true);
when(vocabularyDao.find(vocabulary.getUri())).thenReturn(Optional.of(vocabulary));
initIdentifierGenerator(false);
initIdentifierGenerator(Constants.DEFAULT_LANGUAGE, false);

final Vocabulary result = sut.importVocabulary(
new VocabularyImporter.ImportConfiguration(false, vocabulary.getUri(), prePersist),
Expand All @@ -294,7 +294,7 @@ void importSavesRelationshipsBetweenTerms() {
void importImportsTermsWhenAnotherLanguageSheetIsEmpty() {
when(vocabularyDao.exists(vocabulary.getUri())).thenReturn(true);
when(vocabularyDao.find(vocabulary.getUri())).thenReturn(Optional.of(vocabulary));
initIdentifierGenerator(false);
initIdentifierGenerator(Constants.DEFAULT_LANGUAGE,false);

final Vocabulary result = sut.importVocabulary(
new VocabularyImporter.ImportConfiguration(false, vocabulary.getUri(), prePersist),
Expand All @@ -315,4 +315,29 @@ void importImportsTermsWhenAnotherLanguageSheetIsEmpty() {
assertTrue(construction.isPresent());
assertEquals("The process of building a building", construction.get().getDefinition().get("en"));
}

@Test
void importFallsBackToEnglishColumnLabelsForUnknownLanguages() {
when(vocabularyDao.exists(vocabulary.getUri())).thenReturn(true);
when(vocabularyDao.find(vocabulary.getUri())).thenReturn(Optional.of(vocabulary));
initIdentifierGenerator("de", false);

final Vocabulary result = sut.importVocabulary(
new VocabularyImporter.ImportConfiguration(false, vocabulary.getUri(), prePersist),
new VocabularyImporter.ImportInput(Constants.MediaType.EXCEL,
Environment.loadFile(
"data/import-simple-de.xlsx")));
assertEquals(vocabulary, result);
final ArgumentCaptor<Term> captor = ArgumentCaptor.forClass(Term.class);
verify(termService, times(2)).addRootTermToVocabulary(captor.capture(), eq(vocabulary));
assertEquals(2, captor.getAllValues().size());
final Optional<Term> building = captor.getAllValues().stream()
.filter(t -> "Gebäude".equals(t.getLabel().get("de"))).findAny();
assertTrue(building.isPresent());
assertEquals("Definition für ein Gebäude", building.get().getDefinition().get("de"));
final Optional<Term> construction = captor.getAllValues().stream()
.filter(t -> "Bau".equals(t.getLabel().get("de"))).findAny();
assertTrue(construction.isPresent());
assertEquals("Ein Prozess", construction.get().getDefinition().get("de"));
}
}
Binary file added src/test/resources/data/import-simple-de.xlsx
Binary file not shown.

0 comments on commit fe32cbe

Please sign in to comment.