Skip to content

Commit

Permalink
Merge pull request #255 from kbss-cvut/bug#254-import-does-not-create…
Browse files Browse the repository at this point in the history
…-document

[Bug #254] Ensure document is generated for new vocabulary when it is not provided
  • Loading branch information
ledsoft authored Feb 12, 2024
2 parents 25b2edf + 80c0232 commit fac0003
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 5 deletions.
48 changes: 48 additions & 0 deletions src/main/java/cz/cvut/kbss/termit/service/MessageFormatter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package cz.cvut.kbss.termit.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.NonNull;

import java.text.MessageFormat;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.Objects;
import java.util.ResourceBundle;

/**
* Formats internationalized messages.
* <p>
* The message bundles should be located in {@code src/main/resources/i18n} and be called {@code messages}.
*/
public class MessageFormatter {

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

private final ResourceBundle messages;

public MessageFormatter(@NonNull String lang) {
Objects.requireNonNull(lang);
final Locale locale = new Locale(lang);
this.messages = ResourceBundle.getBundle("i18n/messages", locale);
LOG.info("Loaded message bundle '{}_{}'.", messages.getBaseBundleName(), locale);
}

/**
* Formats message with the specified identifier using the specified parameters.
*
* @param messageId Message identifier
* @param params Parameters to substitute into the message string
* @return Formatted message
*/
public String formatMessage(@NonNull String messageId, Object... params) {
Objects.requireNonNull(messageId);
try {
final MessageFormat formatter = new MessageFormat(messages.getString(messageId));
return formatter.format(params);
} catch (MissingResourceException e) {
LOG.error("No message found for message id '{}'. Returning the message id.", messageId, e);
return messageId;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,19 @@
import cz.cvut.kbss.termit.model.Glossary;
import cz.cvut.kbss.termit.model.Model;
import cz.cvut.kbss.termit.model.Vocabulary;
import cz.cvut.kbss.termit.model.resource.Document;
import cz.cvut.kbss.termit.model.validation.ValidationResult;
import cz.cvut.kbss.termit.persistence.dao.BaseAssetDao;
import cz.cvut.kbss.termit.persistence.dao.VocabularyDao;
import cz.cvut.kbss.termit.persistence.dao.skos.SKOSImporter;
import cz.cvut.kbss.termit.service.IdentifierResolver;
import cz.cvut.kbss.termit.service.MessageFormatter;
import cz.cvut.kbss.termit.service.snapshot.SnapshotProvider;
import cz.cvut.kbss.termit.util.Configuration;
import cz.cvut.kbss.termit.util.Constants;
import cz.cvut.kbss.termit.util.Utils;
import cz.cvut.kbss.termit.workspace.EditableVocabularies;
import jakarta.validation.Validator;
import org.apache.tika.Tika;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.metadata.TikaCoreProperties;
Expand All @@ -52,11 +55,14 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import jakarta.validation.Validator;
import java.io.IOException;
import java.net.URI;
import java.time.Instant;
import java.util.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@CacheConfig(cacheNames = "vocabularies")
Expand Down Expand Up @@ -137,6 +143,7 @@ protected void prePersist(@NotNull Vocabulary instance) {
}
verifyIdentifierUnique(instance);
initGlossaryAndModel(instance);
initDocument(instance);
if (instance.getDocument() != null) {
instance.getDocument().setVocabulary(null);
}
Expand All @@ -154,6 +161,19 @@ private void initGlossaryAndModel(Vocabulary vocabulary) {
}
}

private void initDocument(Vocabulary vocabulary) {
if (vocabulary.getDocument() != null) {
return;
}
final Document doc = new Document();
doc.setUri(idResolver.generateIdentifier(vocabulary.getUri().toString(),
Constants.DEFAULT_DOCUMENT_IRI_COMPONENT));
doc.setLabel(
new MessageFormatter(config.getPersistence().getLanguage()).formatMessage("vocabulary.document.label",
vocabulary.getLabel()));
vocabulary.setDocument(doc);
}

@Override
protected void preUpdate(@NotNull Vocabulary instance) {
super.preUpdate(instance);
Expand Down
13 changes: 10 additions & 3 deletions src/main/java/cz/cvut/kbss/termit/util/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ public class Constants {
/**
* Path to directory containing queries used by the system.
* <p>
* The path should be relative to the classpath, so that queries from it can be loaded using {@link
* ClassLoader#getResourceAsStream(String)}.
* The path should be relative to the classpath, so that queries from it can be loaded using
* {@link ClassLoader#getResourceAsStream(String)}.
*/
public static final String QUERY_DIRECTORY = "query";

Expand All @@ -88,9 +88,16 @@ public class Constants {
*/
public static final String DEFAULT_MODEL_IRI_COMPONENT = "model";

/**
* Default identifier component for {@link cz.cvut.kbss.termit.model.resource.Document}.
* <p>
* This component is appended to the containing vocabulary identifier to form the document identifier.
*/
public static final String DEFAULT_DOCUMENT_IRI_COMPONENT = "document";

/**
* Default language when none is specified in configuration.
*
* <p>
* Used mainly for resolving internationalized templates.
*/
public static final String DEFAULT_LANGUAGE = "en";
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/i18n/messages_cs.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
vocabulary.document.label=Dokument pro {0}
1 change: 1 addition & 0 deletions src/main/resources/i18n/messages_en.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
vocabulary.document.label=Document for {0}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package cz.cvut.kbss.termit.service;

import cz.cvut.kbss.termit.environment.Environment;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;

class MessageFormatterTest {

@ParameterizedTest
@MethodSource("i18nFormattingValues")
void formatsMessageWithSpecifiedIdUsingSpecifiedValues(String language, String expectedMessage) {
final MessageFormatter sut = new MessageFormatter(language);
final String vocabularyLabel = "Test";
assertEquals(expectedMessage, sut.formatMessage("vocabulary.document.label", vocabularyLabel));
}

static Stream<Arguments> i18nFormattingValues() {
return Stream.of(
Arguments.of("en", "Document for Test"),
Arguments.of("cs", "Dokument pro Test")
);
}

@Test
void formatMessageReturnsMessageIdAndLogsErrorWhenMessageIsNotFound() {
final String unknownMessageId = "unknownMessage";
final MessageFormatter sut = new MessageFormatter(Environment.LANGUAGE);
assertDoesNotThrow(() -> {
final String result = sut.formatMessage(unknownMessageId, "12345");
assertEquals(unknownMessageId, result);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import cz.cvut.kbss.termit.model.UserAccount;
import cz.cvut.kbss.termit.model.Vocabulary;
import cz.cvut.kbss.termit.model.changetracking.PersistChangeRecord;
import cz.cvut.kbss.termit.model.resource.Document;
import cz.cvut.kbss.termit.persistence.context.DescriptorFactory;
import cz.cvut.kbss.termit.service.BaseServiceTestRunner;
import cz.cvut.kbss.termit.service.IdentifierResolver;
Expand Down Expand Up @@ -383,4 +384,26 @@ void updateEnsuresReferenceToAccessControlListIsPreserved() {
assertEquals(update.getLabel(), result.getLabel());
assertEquals(vocabulary.getAcl(), result.getAcl());
}

@Test
void importCreatesDocumentAssociatedWithVocabulary() {
final String skos =
"@prefix skos : <http://www.w3.org/2004/02/skos/core#> . " +
"@prefix dc : <http://purl.org/dc/terms/> . " +
"<https://example.org/cs> a skos:ConceptScheme ; dc:title \"Test\"@en . " +
"<https://example.org/pojem/a> a skos:Concept ; skos:inScheme <https://example.org/cs> . ";


final MultipartFile mf = new MockMultipartFile(
"file",
"thesaurus",
"text/turtle",
skos.getBytes(StandardCharsets.UTF_8)
);

final Vocabulary v = sut.importVocabulary(true, mf);
assertNotNull(v.getDocument());
assertNotNull(em.find(Document.class, v.getDocument().getUri()));
assertEquals("Document for " + v.getLabel(), v.getDocument().getLabel());
}
}

0 comments on commit fac0003

Please sign in to comment.