Skip to content

Commit

Permalink
[kbss-cvut/termit-ui#581] Modify REST API to support term translation…
Browse files Browse the repository at this point in the history
…s import.
  • Loading branch information
ledsoft committed Nov 29, 2024
1 parent 2c9568a commit 469e13b
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 20 deletions.
36 changes: 24 additions & 12 deletions src/main/java/cz/cvut/kbss/termit/rest/VocabularyController.java
Original file line number Diff line number Diff line change
Expand Up @@ -235,12 +235,22 @@ public ResponseEntity<Void> createVocabulary(
example = ApiDoc.ID_NAMESPACE_EXAMPLE)
@RequestParam(name = QueryParams.NAMESPACE,
required = false) Optional<String> namespace,
@Parameter(description = "File containing a SKOS glossary in RDF.")
@RequestParam(name = "file") MultipartFile file) {
@Parameter(
description = "File containing a SKOS glossary in RDF or an Excel file with supported structure.")
@RequestParam(name = "file") MultipartFile file,
@Parameter(description = "Whether to import only translations of existing terms from the vocabulary.")
@RequestParam(name = "translationsOnly", required = false,
defaultValue = "false") boolean translationsOnly) {
final URI vocabularyIri = resolveVocabularyUri(localName, namespace);
final Vocabulary vocabulary = vocabularyService.importVocabulary(vocabularyIri, file);
LOG.debug("Vocabulary {} re-imported.", vocabulary);
return ResponseEntity.created(locationWithout(generateLocation(vocabulary.getUri()), "/import/" + localName))
final Vocabulary result;
if (translationsOnly) {
result = vocabularyService.importTermTranslations(vocabularyIri, file);
LOG.debug("Translations of terms in vocabulary {} imported.", result);
} else {
result = vocabularyService.importVocabulary(vocabularyIri, file);
LOG.debug("Vocabulary {} re-imported.", result);
}
return ResponseEntity.created(locationWithout(generateLocation(result.getUri()), "/import/" + localName))
.build();
}

Expand Down Expand Up @@ -310,13 +320,14 @@ public List<AbstractChangeRecord> getDetailedHistoryOfContent(
example = ApiDoc.ID_NAMESPACE_EXAMPLE) @RequestParam(name = QueryParams.NAMESPACE,
required = false) Optional<String> namespace,
@Parameter(description = ChangeRecordFilterDto.ApiDoc.TERM_NAME_DESCRIPTION) @RequestParam(name = "term",
required = false,
defaultValue = "") String termName,
required = false,
defaultValue = "") String termName,
@Parameter(description = ChangeRecordFilterDto.ApiDoc.CHANGE_TYPE_DESCRIPTION) @RequestParam(name = "type",
required = false) URI changeType,
@Parameter(description = ChangeRecordFilterDto.ApiDoc.AUTHOR_NAME_DESCRIPTION) @RequestParam(name = "author",
required = false,
defaultValue = "") String authorName,
required = false) URI changeType,
@Parameter(description = ChangeRecordFilterDto.ApiDoc.AUTHOR_NAME_DESCRIPTION) @RequestParam(
name = "author",
required = false,
defaultValue = "") String authorName,
@Parameter(description = ChangeRecordFilterDto.ApiDoc.CHANGED_ATTRIBUTE_DESCRIPTION) @RequestParam(
name = "attribute", required = false, defaultValue = "") String changedAttributeName,

Expand All @@ -327,7 +338,8 @@ public List<AbstractChangeRecord> getDetailedHistoryOfContent(
name = Constants.QueryParams.PAGE, required = false, defaultValue = DEFAULT_PAGE) Integer pageNo) {
final Pageable pageReq = createPageRequest(pageSize, pageNo);
final Vocabulary vocabulary = vocabularyService.getReference(resolveVocabularyUri(localName, namespace));
final ChangeRecordFilterDto filter = new ChangeRecordFilterDto(termName, changedAttributeName, authorName, changeType);
final ChangeRecordFilterDto filter = new ChangeRecordFilterDto(termName, changedAttributeName, authorName,
changeType);
return vocabularyService.getDetailedHistoryOfContent(vocabulary, filter, pageReq);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,19 @@ public Vocabulary importVocabulary(URI vocabularyIri, MultipartFile file) {
return repositoryService.importVocabulary(vocabularyIri, file);
}

/**
* Imports translations of terms in the specified vocabulary from the specified file.
* @param vocabularyIri IRI of vocabulary for whose terms to import translations
* @param file File from which to import the translations
* @return The imported vocabulary metadata
* @throws cz.cvut.kbss.termit.exception.importing.VocabularyImportException If the import fails
*/
@PreAuthorize("@vocabularyAuthorizationService.canModify(#vocabularyIri)")
public Vocabulary importTermTranslations(URI vocabularyIri, MultipartFile file) {
// TODO
return null;
}

/**
* Gets an Excel template file that can be used to import terms into TermIt.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;

/**
* Base class for resolving term occurrences in an annotated document.
Expand All @@ -50,7 +49,7 @@ protected TermOccurrenceResolver(TermRepositoryService termService) {
* Parses the specified input into some abstract representation from which new terms and term occurrences can be
* extracted.
* <p>
* Note that this method has to be called before calling {@link #findTermOccurrences(Consumer)}.
* Note that this method has to be called before calling {@link #findTermOccurrences(OccurrenceConsumer)}.
*
* @param input The input to parse
* @param source Original source of the input. Used for term occurrence generation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@ public boolean canRead(VocabularyDto dto) {
return canRead(new Vocabulary(dto.getUri()));
}

public boolean canModify(URI vocabularyIri) {
Objects.requireNonNull(vocabularyIri);
final Vocabulary vocabulary = new Vocabulary(vocabularyIri);
return canModify(vocabulary);
}

@Override
public boolean canModify(Vocabulary asset) {
Objects.requireNonNull(asset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ void getHistoryReturnsListOfChangeRecordsForSpecifiedVocabulary() throws Excepti
});
assertNotNull(result);
assertEquals(records, result);
verify(serviceMock).getChanges(vocabulary,emptyFilter);
verify(serviceMock).getChanges(vocabulary, emptyFilter);
}

@Test
Expand Down Expand Up @@ -653,15 +653,18 @@ void getDetailedHistoryOfContentReturnsListOfChangeRecordsWhenNoFilterIsSpecifie
final int pageSize = Integer.parseInt(VocabularyController.DEFAULT_PAGE_SIZE);
final Vocabulary vocabulary = generateVocabularyAndInitReferenceResolution();
final Term term = Generator.generateTermWithId();
final List<AbstractChangeRecord> changeRecords = IntStream.range(0, 5).mapToObj(i -> Generator.generateChangeRecords(term, user)).flatMap(List::stream).toList();
final List<AbstractChangeRecord> changeRecords = IntStream.range(0, 5).mapToObj(
i -> Generator.generateChangeRecords(term, user)).flatMap(List::stream).toList();
final ChangeRecordFilterDto filter = new ChangeRecordFilterDto();
final Pageable pageable = Pageable.ofSize(pageSize);

doReturn(changeRecords).when(serviceMock).getDetailedHistoryOfContent(vocabulary, filter, pageable);

final MvcResult mvcResult = mockMvc.perform(get(PATH + "/" + FRAGMENT + "/history-of-content/detail")).andExpect(status().isOk()).andReturn();
final MvcResult mvcResult = mockMvc.perform(get(PATH + "/" + FRAGMENT + "/history-of-content/detail"))
.andExpect(status().isOk()).andReturn();
final List<AbstractChangeRecord> result =
readValue(mvcResult, new TypeReference<List<AbstractChangeRecord>>() {});
readValue(mvcResult, new TypeReference<>() {
});
assertNotNull(result);
assertEquals(changeRecords, result);
verify(serviceMock).getDetailedHistoryOfContent(vocabulary, filter, pageable);
Expand All @@ -673,9 +676,33 @@ void getLanguagesRetrievesAndReturnsListOfLanguagesUsedInVocabulary() throws Exc
final List<String> languages = List.of(Environment.LANGUAGE, "cs", "de");
when(serviceMock.getLanguages(VOCABULARY_URI)).thenReturn(languages);

final MvcResult mvcResult = mockMvc.perform(get(PATH + "/" + FRAGMENT + "/languages").queryParam(QueryParams.NAMESPACE, NAMESPACE)).andReturn();
final List<String> result = readValue(mvcResult, new TypeReference<List<String>>() {});
final MvcResult mvcResult = mockMvc.perform(
get(PATH + "/" + FRAGMENT + "/languages").queryParam(QueryParams.NAMESPACE, NAMESPACE)).andReturn();
final List<String> result = readValue(mvcResult, new TypeReference<>() {
});
assertEquals(languages, result);
verify(serviceMock).getLanguages(VOCABULARY_URI);
}

@Test
void reImportVocabularyRunsTermTranslationsImportForUploadedFileWhenTranslationsOnlyIsSpecified() throws Exception {
when(configMock.getNamespace().getVocabulary()).thenReturn(NAMESPACE);
final Vocabulary vocabulary = Generator.generateVocabulary();
vocabulary.setUri(URI.create(NAMESPACE + FRAGMENT));
when(idResolverMock.resolveIdentifier(NAMESPACE, FRAGMENT)).thenReturn(vocabulary.getUri());
when(serviceMock.importTermTranslations(any(URI.class), any())).thenReturn(vocabulary);
final MockMultipartFile upload = new MockMultipartFile("file", "vocabulary.xlsx",
Constants.MediaType.EXCEL,
Environment.loadFile("data/import-simple-en-cs.xlsx"));
final MvcResult mvcResult = mockMvc.perform(multipart(PATH + "/" + FRAGMENT + "/import").file(upload)
.queryParam(
"translationsOnly",
"true"))
.andExpect(status().isCreated())
.andReturn();
verifyLocationEquals(PATH + "/" + FRAGMENT, mvcResult);
assertThat(mvcResult.getResponse().getHeader(HttpHeaders.LOCATION),
containsString(QueryParams.NAMESPACE + "=" + NAMESPACE));
verify(serviceMock).importTermTranslations(vocabulary.getUri(), upload);
}
}

0 comments on commit 469e13b

Please sign in to comment.