From edba193216d4de7802db400bfd92aef91857ea33 Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Wed, 1 Feb 2023 15:48:40 +0100 Subject: [PATCH 1/5] [Upd] Use JSON-LD with context. --- pom.xml | 29 +++--- .../cvut/kbss/termit/config/WebAppConfig.java | 2 + .../kbss/termit/dto/listing/DocumentDto.java | 13 +++ .../termit/dto/listing/VocabularyDto.java | 92 +++++++++++++++++++ .../kbss/termit/dto/mapper/DtoMapper.java | 15 +++ .../dto/readonly/ReadOnlyVocabulary.java | 11 +++ .../termit/persistence/dao/UserRoleDao.java | 32 ++++--- .../termit/rest/VocabularyController.java | 3 +- .../termit/service/business/CrudService.java | 7 +- .../service/business/VocabularyService.java | 3 +- .../BaseAssetRepositoryService.java | 3 +- .../repository/BaseRepositoryService.java | 16 +++- .../repository/ResourceRepositoryService.java | 7 +- .../repository/TermRepositoryService.java | 7 +- .../repository/UserRepositoryService.java | 7 +- .../repository/UserRoleRepositoryService.java | 32 +++---- .../VocabularyRepositoryService.java | 33 ++++--- .../kbss/termit/environment/Environment.java | 8 ++ .../environment/config/TestServiceConfig.java | 7 ++ .../termit/persistence/dao/BaseDaoTest.java | 10 -- .../termit/rest/VocabularyControllerTest.java | 25 ++--- .../ReadOnlyVocabularyServiceTest.java | 7 +- .../BaseAssetRepositoryServiceImpl.java | 7 +- .../repository/BaseRepositoryServiceImpl.java | 7 +- ...abularyRepositoryServiceWorkspaceTest.java | 13 ++- 25 files changed, 300 insertions(+), 96 deletions(-) create mode 100644 src/main/java/cz/cvut/kbss/termit/dto/listing/DocumentDto.java create mode 100644 src/main/java/cz/cvut/kbss/termit/dto/listing/VocabularyDto.java create mode 100644 src/main/java/cz/cvut/kbss/termit/dto/mapper/DtoMapper.java diff --git a/pom.xml b/pom.xml index 8c021c103..8d4f05705 100644 --- a/pom.xml +++ b/pom.xml @@ -26,15 +26,15 @@ 11 - 2.7.6 - 5.3.24 - 5.7.5 + 2.7.8 + 5.3.25 + 5.7.6 2.7.5 6.2.3.Final 2.6.0 1.5.3.Final - 0.19.3 - 0.9.0 + 0.20.0 + 0.10.2 1.9.7 @@ -135,13 +135,7 @@ com.github.ledsoft jopa-spring-transaction - 0.1.4 - - - org.springframework - spring-tx - - + 0.1.5 @@ -240,6 +234,12 @@ ${cz.cvut.kbss.jsonld.version} + + org.mapstruct + mapstruct + ${org.mapstruct.version} + + javax.servlet @@ -447,6 +447,11 @@ hibernate-validator-annotation-processor ${org.hibernate.validator.version} + + org.mapstruct + mapstruct-processor + ${org.mapstruct.version} + ${java.version} ${java.version} diff --git a/src/main/java/cz/cvut/kbss/termit/config/WebAppConfig.java b/src/main/java/cz/cvut/kbss/termit/config/WebAppConfig.java index 4918205aa..006fa1b49 100644 --- a/src/main/java/cz/cvut/kbss/termit/config/WebAppConfig.java +++ b/src/main/java/cz/cvut/kbss/termit/config/WebAppConfig.java @@ -24,6 +24,7 @@ import cz.cvut.kbss.jopa.sessions.UnitOfWorkImpl; import cz.cvut.kbss.jsonld.JsonLd; import cz.cvut.kbss.jsonld.jackson.JsonLdModule; +import cz.cvut.kbss.jsonld.jackson.serialization.SerializationConstants; import cz.cvut.kbss.termit.rest.servlet.DiagnosticsContextFilter; import cz.cvut.kbss.termit.util.AdjustedUriTemplateProxyServlet; import cz.cvut.kbss.termit.util.ConfigParam; @@ -111,6 +112,7 @@ public static ObjectMapper createJsonLdObjectMapper() { mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); final JsonLdModule jsonLdModule = new JsonLdModule(); jsonLdModule.configure(cz.cvut.kbss.jsonld.ConfigParam.SCAN_PACKAGE, "cz.cvut.kbss.termit"); + jsonLdModule.configure(SerializationConstants.FORM, SerializationConstants.FORM_COMPACT_WITH_CONTEXT); mapper.registerModule(jsonLdModule); return mapper; } diff --git a/src/main/java/cz/cvut/kbss/termit/dto/listing/DocumentDto.java b/src/main/java/cz/cvut/kbss/termit/dto/listing/DocumentDto.java new file mode 100644 index 000000000..24a5c18d5 --- /dev/null +++ b/src/main/java/cz/cvut/kbss/termit/dto/listing/DocumentDto.java @@ -0,0 +1,13 @@ +package cz.cvut.kbss.termit.dto.listing; + +import cz.cvut.kbss.jopa.model.annotations.OWLClass; +import cz.cvut.kbss.jopa.model.annotations.util.NonEntity; +import cz.cvut.kbss.jsonld.annotation.JsonLdAttributeOrder; +import cz.cvut.kbss.termit.model.resource.Resource; +import cz.cvut.kbss.termit.util.Vocabulary; + +@NonEntity +@OWLClass(iri = Vocabulary.s_c_dokument) +@JsonLdAttributeOrder({"uri", "label", "description", "files"}) +public class DocumentDto extends Resource { +} diff --git a/src/main/java/cz/cvut/kbss/termit/dto/listing/VocabularyDto.java b/src/main/java/cz/cvut/kbss/termit/dto/listing/VocabularyDto.java new file mode 100644 index 000000000..ea2f833ef --- /dev/null +++ b/src/main/java/cz/cvut/kbss/termit/dto/listing/VocabularyDto.java @@ -0,0 +1,92 @@ +package cz.cvut.kbss.termit.dto.listing; + +import cz.cvut.kbss.jopa.model.annotations.OWLAnnotationProperty; +import cz.cvut.kbss.jopa.model.annotations.OWLClass; +import cz.cvut.kbss.jopa.model.annotations.OWLObjectProperty; +import cz.cvut.kbss.jopa.model.annotations.Types; +import cz.cvut.kbss.jopa.model.annotations.util.NonEntity; +import cz.cvut.kbss.jopa.vocabulary.DC; +import cz.cvut.kbss.jsonld.annotation.JsonLdAttributeOrder; +import cz.cvut.kbss.termit.model.AbstractEntity; + +import java.net.URI; +import java.util.Objects; +import java.util.Set; + +@NonEntity +@OWLClass(iri = cz.cvut.kbss.termit.util.Vocabulary.s_c_slovnik) +@JsonLdAttributeOrder({"uri", "label", "description"}) +public class VocabularyDto extends AbstractEntity { + + @OWLAnnotationProperty(iri = DC.Terms.TITLE) + private String label; + + @OWLAnnotationProperty(iri = DC.Terms.DESCRIPTION) + private String description; + + @OWLObjectProperty(iri = cz.cvut.kbss.termit.util.Vocabulary.s_p_importuje_slovnik) + private Set importedVocabularies; + + @OWLObjectProperty(iri = cz.cvut.kbss.termit.util.Vocabulary.s_p_popisuje_dokument) + private DocumentDto document; + + @Types + private Set types; + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Set getImportedVocabularies() { + return importedVocabularies; + } + + public void setImportedVocabularies(Set importedVocabularies) { + this.importedVocabularies = importedVocabularies; + } + + public DocumentDto getDocument() { + return document; + } + + public void setDocument(DocumentDto document) { + this.document = document; + } + + public Set getTypes() { + return types; + } + + public void setTypes(Set types) { + this.types = types; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof VocabularyDto)) { + return false; + } + VocabularyDto that = (VocabularyDto) o; + return Objects.equals(getUri(), that.getUri()); + } + + @Override + public int hashCode() { + return Objects.hash(getUri()); + } +} diff --git a/src/main/java/cz/cvut/kbss/termit/dto/mapper/DtoMapper.java b/src/main/java/cz/cvut/kbss/termit/dto/mapper/DtoMapper.java new file mode 100644 index 000000000..67ea91c47 --- /dev/null +++ b/src/main/java/cz/cvut/kbss/termit/dto/mapper/DtoMapper.java @@ -0,0 +1,15 @@ +package cz.cvut.kbss.termit.dto.mapper; + +import cz.cvut.kbss.termit.dto.listing.DocumentDto; +import cz.cvut.kbss.termit.dto.listing.VocabularyDto; +import cz.cvut.kbss.termit.model.Vocabulary; +import cz.cvut.kbss.termit.model.resource.Document; +import org.mapstruct.Mapper; + +@Mapper(componentModel = "spring") +public interface DtoMapper { + + DocumentDto documentToDocumentDto(Document document); + + VocabularyDto vocabularyToVocabularyDto(Vocabulary vocabulary); +} diff --git a/src/main/java/cz/cvut/kbss/termit/dto/readonly/ReadOnlyVocabulary.java b/src/main/java/cz/cvut/kbss/termit/dto/readonly/ReadOnlyVocabulary.java index 61d98b68c..fd15b11cf 100644 --- a/src/main/java/cz/cvut/kbss/termit/dto/readonly/ReadOnlyVocabulary.java +++ b/src/main/java/cz/cvut/kbss/termit/dto/readonly/ReadOnlyVocabulary.java @@ -5,6 +5,7 @@ import cz.cvut.kbss.jopa.model.annotations.OWLClass; import cz.cvut.kbss.jopa.model.annotations.OWLObjectProperty; import cz.cvut.kbss.jopa.vocabulary.DC; +import cz.cvut.kbss.termit.dto.listing.VocabularyDto; import cz.cvut.kbss.termit.model.Asset; import cz.cvut.kbss.termit.model.util.HasIdentifier; import cz.cvut.kbss.termit.util.Vocabulary; @@ -43,6 +44,16 @@ public ReadOnlyVocabulary(cz.cvut.kbss.termit.model.Vocabulary vocabulary) { } } + public ReadOnlyVocabulary(VocabularyDto vocabularyDto) { + Objects.requireNonNull(vocabularyDto); + setUri(vocabularyDto.getUri()); + this.label = vocabularyDto.getLabel(); + this.description = vocabularyDto.getDescription(); + if (vocabularyDto.getImportedVocabularies() != null) { + this.importedVocabularies = new HashSet<>(vocabularyDto.getImportedVocabularies()); + } + } + public String getLabel() { return label; } diff --git a/src/main/java/cz/cvut/kbss/termit/persistence/dao/UserRoleDao.java b/src/main/java/cz/cvut/kbss/termit/persistence/dao/UserRoleDao.java index 5aac3822e..9823cb318 100644 --- a/src/main/java/cz/cvut/kbss/termit/persistence/dao/UserRoleDao.java +++ b/src/main/java/cz/cvut/kbss/termit/persistence/dao/UserRoleDao.java @@ -1,30 +1,36 @@ /** * TermIt Copyright (C) 2019 Czech Technical University in Prague *

- * This program is free software: you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later + * version. *

- * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. *

- * You should have received a copy of the GNU General Public License along with this program. If - * not, see . + * You should have received a copy of the GNU General Public License along with this program. If not, see + * . */ package cz.cvut.kbss.termit.persistence.dao; import cz.cvut.kbss.jopa.model.EntityManager; import cz.cvut.kbss.termit.model.UserRole; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository -public class UserRoleDao extends BaseDao { +public class UserRoleDao { + + private final EntityManager em; - @Autowired public UserRoleDao(EntityManager em) { - super(UserRole.class, em); + this.em = em; + } + + public List findAll() { + return em.createQuery("SELECT r FROM " + UserRole.class.getSimpleName() + " r", UserRole.class).getResultList(); } -} \ No newline at end of file +} diff --git a/src/main/java/cz/cvut/kbss/termit/rest/VocabularyController.java b/src/main/java/cz/cvut/kbss/termit/rest/VocabularyController.java index aae4201f2..73efba9b6 100644 --- a/src/main/java/cz/cvut/kbss/termit/rest/VocabularyController.java +++ b/src/main/java/cz/cvut/kbss/termit/rest/VocabularyController.java @@ -17,6 +17,7 @@ import cz.cvut.kbss.jsonld.JsonLd; import cz.cvut.kbss.termit.dto.AggregatedChangeInfo; import cz.cvut.kbss.termit.dto.Snapshot; +import cz.cvut.kbss.termit.dto.listing.VocabularyDto; import cz.cvut.kbss.termit.model.Vocabulary; import cz.cvut.kbss.termit.model.changetracking.AbstractChangeRecord; import cz.cvut.kbss.termit.model.validation.ValidationResult; @@ -59,7 +60,7 @@ public VocabularyController(VocabularyService vocabularyService, IdentifierResol } @GetMapping(produces = {MediaType.APPLICATION_JSON_VALUE, JsonLd.MEDIA_TYPE}) - public ResponseEntity> getAll(ServletWebRequest webRequest) { + public ResponseEntity> getAll(ServletWebRequest webRequest) { if (webRequest.checkNotModified(vocabularyService.getLastModified())) { return null; } diff --git a/src/main/java/cz/cvut/kbss/termit/service/business/CrudService.java b/src/main/java/cz/cvut/kbss/termit/service/business/CrudService.java index 75dff609c..a76a491bc 100644 --- a/src/main/java/cz/cvut/kbss/termit/service/business/CrudService.java +++ b/src/main/java/cz/cvut/kbss/termit/service/business/CrudService.java @@ -24,15 +24,16 @@ * Declares Create, Retrieve, Update and Delete (CRUD) operations for business services. * * @param Type of the concept managed by this service + * @param Type of DTO used by the findAll retrieval method */ -public interface CrudService extends RudService { +public interface CrudService extends RudService { /** * Gets all items of the type managed by this service from the repository. * * @return List of items */ - List findAll(); + List findAll(); /** * Checks if an item with the specified identifier exists. @@ -49,4 +50,4 @@ public interface CrudService extends RudService { */ void persist(T instance); -} \ No newline at end of file +} diff --git a/src/main/java/cz/cvut/kbss/termit/service/business/VocabularyService.java b/src/main/java/cz/cvut/kbss/termit/service/business/VocabularyService.java index fb23913e8..32fcc4073 100644 --- a/src/main/java/cz/cvut/kbss/termit/service/business/VocabularyService.java +++ b/src/main/java/cz/cvut/kbss/termit/service/business/VocabularyService.java @@ -18,6 +18,7 @@ import cz.cvut.kbss.termit.dto.AggregatedChangeInfo; import cz.cvut.kbss.termit.dto.PrefixDeclaration; import cz.cvut.kbss.termit.dto.Snapshot; +import cz.cvut.kbss.termit.dto.listing.VocabularyDto; import cz.cvut.kbss.termit.model.Vocabulary; import cz.cvut.kbss.termit.model.validation.ValidationResult; import cz.cvut.kbss.termit.service.changetracking.ChangeRecordProvider; @@ -33,7 +34,7 @@ * Interface of business logic concerning vocabularies. */ public interface VocabularyService - extends CrudService, ChangeRecordProvider, SupportsLastModification { + extends CrudService, ChangeRecordProvider, SupportsLastModification { /** * Gets identifiers of all vocabularies imported by the specified vocabulary, including transitively imported ones. diff --git a/src/main/java/cz/cvut/kbss/termit/service/repository/BaseAssetRepositoryService.java b/src/main/java/cz/cvut/kbss/termit/service/repository/BaseAssetRepositoryService.java index 6607a92e4..852317f09 100644 --- a/src/main/java/cz/cvut/kbss/termit/service/repository/BaseAssetRepositoryService.java +++ b/src/main/java/cz/cvut/kbss/termit/service/repository/BaseAssetRepositoryService.java @@ -18,6 +18,7 @@ import cz.cvut.kbss.termit.exception.ResourceExistsException; import cz.cvut.kbss.termit.model.Asset; import cz.cvut.kbss.termit.model.User; +import cz.cvut.kbss.termit.model.util.HasIdentifier; import cz.cvut.kbss.termit.persistence.dao.BaseAssetDao; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -29,7 +30,7 @@ * * @param Asset type */ -public abstract class BaseAssetRepositoryService> extends BaseRepositoryService { +public abstract class BaseAssetRepositoryService, DTO extends HasIdentifier> extends BaseRepositoryService { protected BaseAssetRepositoryService(Validator validator) { super(validator); diff --git a/src/main/java/cz/cvut/kbss/termit/service/repository/BaseRepositoryService.java b/src/main/java/cz/cvut/kbss/termit/service/repository/BaseRepositoryService.java index 010b6cd05..46e6f317f 100644 --- a/src/main/java/cz/cvut/kbss/termit/service/repository/BaseRepositoryService.java +++ b/src/main/java/cz/cvut/kbss/termit/service/repository/BaseRepositoryService.java @@ -43,7 +43,7 @@ * * @param Domain object type managed by this service */ -public abstract class BaseRepositoryService { +public abstract class BaseRepositoryService { private final Validator validator; @@ -66,11 +66,19 @@ protected BaseRepositoryService(Validator validator) { * * @return List of all matching instances */ - public List findAll() { + public List findAll() { final List loaded = getPrimaryDao().findAll(); - return loaded.stream().map(this::postLoad).collect(Collectors.toList()); + return loaded.stream().map(this::postLoad).map(this::mapToDto).collect(Collectors.toList()); } + /** + * Maps the specified entity to a DTO used for listing large number of objects of the entity's type. + * + * @param entity Entity to map + * @return DTO representing the entity + */ + protected abstract DTO mapToDto(T entity); + /** * Finds an object with the specified id and returns it. * @@ -141,7 +149,7 @@ private Class resolveGenericType() { // Adapted from https://gist.github.com/yunspace/930d4d40a787a1f6a7d1 final List typeParameters = new TypeResolver().resolve(this.getClass()).typeParametersFor(BaseRepositoryService.class); - assert typeParameters.size() == 1; + assert typeParameters.size() >= 1; return (Class) typeParameters.get(0).getErasedType(); } diff --git a/src/main/java/cz/cvut/kbss/termit/service/repository/ResourceRepositoryService.java b/src/main/java/cz/cvut/kbss/termit/service/repository/ResourceRepositoryService.java index d65246470..eb53ba8c8 100644 --- a/src/main/java/cz/cvut/kbss/termit/service/repository/ResourceRepositoryService.java +++ b/src/main/java/cz/cvut/kbss/termit/service/repository/ResourceRepositoryService.java @@ -35,7 +35,7 @@ import java.util.Objects; @Service -public class ResourceRepositoryService extends BaseAssetRepositoryService +public class ResourceRepositoryService extends BaseAssetRepositoryService implements SupportsLastModification { private static final Logger LOG = LoggerFactory.getLogger(ResourceRepositoryService.class); @@ -64,6 +64,11 @@ protected BaseAssetDao getPrimaryDao() { return resourceDao; } + @Override + protected Resource mapToDto(Resource entity) { + return entity; + } + @Override protected void prePersist(Resource instance) { super.prePersist(instance); diff --git a/src/main/java/cz/cvut/kbss/termit/service/repository/TermRepositoryService.java b/src/main/java/cz/cvut/kbss/termit/service/repository/TermRepositoryService.java index d0176b70a..c40aa3230 100644 --- a/src/main/java/cz/cvut/kbss/termit/service/repository/TermRepositoryService.java +++ b/src/main/java/cz/cvut/kbss/termit/service/repository/TermRepositoryService.java @@ -50,7 +50,7 @@ import static java.util.stream.Collectors.toList; @Service -public class TermRepositoryService extends BaseAssetRepositoryService implements SnapshotProvider { +public class TermRepositoryService extends BaseAssetRepositoryService implements SnapshotProvider { private final IdentifierResolver idResolver; @@ -83,6 +83,11 @@ protected BaseAssetDao getPrimaryDao() { return termDao; } + @Override + protected TermDto mapToDto(Term entity) { + return new TermDto(entity); + } + @Override public void persist(Term instance) { throw new UnsupportedOperationException( diff --git a/src/main/java/cz/cvut/kbss/termit/service/repository/UserRepositoryService.java b/src/main/java/cz/cvut/kbss/termit/service/repository/UserRepositoryService.java index 8b12653f2..ab31caa66 100644 --- a/src/main/java/cz/cvut/kbss/termit/service/repository/UserRepositoryService.java +++ b/src/main/java/cz/cvut/kbss/termit/service/repository/UserRepositoryService.java @@ -27,7 +27,7 @@ import javax.validation.Validator; @Service -public class UserRepositoryService extends BaseRepositoryService { +public class UserRepositoryService extends BaseRepositoryService { private final UserAccountDao userAccountDao; @@ -63,6 +63,11 @@ public boolean exists(String username) { return userAccountDao.exists(username); } + @Override + protected UserAccount mapToDto(UserAccount entity) { + return entity; + } + @Override protected UserAccount postLoad(UserAccount instance) { instance.erasePassword(); diff --git a/src/main/java/cz/cvut/kbss/termit/service/repository/UserRoleRepositoryService.java b/src/main/java/cz/cvut/kbss/termit/service/repository/UserRoleRepositoryService.java index 1b8a69f94..bfb784eda 100644 --- a/src/main/java/cz/cvut/kbss/termit/service/repository/UserRoleRepositoryService.java +++ b/src/main/java/cz/cvut/kbss/termit/service/repository/UserRoleRepositoryService.java @@ -1,38 +1,38 @@ /** * TermIt Copyright (C) 2019 Czech Technical University in Prague *

- * This program is free software: you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later + * version. *

- * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. *

- * You should have received a copy of the GNU General Public License along with this program. If - * not, see . + * You should have received a copy of the GNU General Public License along with this program. If not, see + * . */ package cz.cvut.kbss.termit.service.repository; import cz.cvut.kbss.termit.model.UserRole; import cz.cvut.kbss.termit.persistence.dao.UserRoleDao; -import javax.validation.Validator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.List; + @Service -public class UserRoleRepositoryService extends BaseRepositoryService { +public class UserRoleRepositoryService { - private final UserRoleDao userRoleDao; + private final UserRoleDao dao; @Autowired - public UserRoleRepositoryService(Validator validator, UserRoleDao userRoleDao) { - super(validator); - this.userRoleDao = userRoleDao; + public UserRoleRepositoryService(UserRoleDao dao) { + this.dao = dao; } - @Override protected UserRoleDao getPrimaryDao() { - return userRoleDao; + public List findAll() { + return dao.findAll(); } } diff --git a/src/main/java/cz/cvut/kbss/termit/service/repository/VocabularyRepositoryService.java b/src/main/java/cz/cvut/kbss/termit/service/repository/VocabularyRepositoryService.java index eb09960e2..0adf909f4 100644 --- a/src/main/java/cz/cvut/kbss/termit/service/repository/VocabularyRepositoryService.java +++ b/src/main/java/cz/cvut/kbss/termit/service/repository/VocabularyRepositoryService.java @@ -4,6 +4,8 @@ import cz.cvut.kbss.termit.dto.PrefixDeclaration; import cz.cvut.kbss.termit.dto.Snapshot; import cz.cvut.kbss.termit.dto.listing.TermDto; +import cz.cvut.kbss.termit.dto.listing.VocabularyDto; +import cz.cvut.kbss.termit.dto.mapper.DtoMapper; import cz.cvut.kbss.termit.event.VocabularyCreatedEvent; import cz.cvut.kbss.termit.exception.AssetRemovalException; import cz.cvut.kbss.termit.exception.NotFoundException; @@ -28,6 +30,7 @@ import org.apache.tika.Tika; import org.apache.tika.metadata.Metadata; import org.apache.tika.metadata.TikaCoreProperties; +import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -53,7 +56,7 @@ @CacheConfig(cacheNames = "vocabularies") @Service -public class VocabularyRepositoryService extends BaseAssetRepositoryService +public class VocabularyRepositoryService extends BaseAssetRepositoryService implements ApplicationEventPublisherAware, VocabularyService { private static final Logger LOG = LoggerFactory.getLogger(VocabularyRepositoryService.class); @@ -72,6 +75,8 @@ public class VocabularyRepositoryService extends BaseAssetRepositoryService getPrimaryDao() { // Cache only if all vocabularies are editable @Cacheable(condition = "@configuration.workspace.allVocabulariesEditable") @Override - public List findAll() { + public List findAll() { return super.findAll(); } @Override - protected Vocabulary postLoad(Vocabulary instance) { + protected Vocabulary postLoad(@NotNull Vocabulary instance) { super.postLoad(instance); if (!config.getWorkspace().isAllVocabulariesEditable() && !editableVocabularies.isEditable(instance)) { instance.addType(cz.cvut.kbss.termit.util.Vocabulary.s_c_pouze_pro_cteni); @@ -118,19 +125,23 @@ protected Vocabulary postLoad(Vocabulary instance) { return instance; } + @Override + protected VocabularyDto mapToDto(Vocabulary entity) { + return dtoMapper.vocabularyToVocabularyDto(entity); + } + @CacheEvict(allEntries = true) @Override @Transactional - public void persist(Vocabulary instance) { + public void persist(@NotNull Vocabulary instance) { super.persist(instance); } @Override - protected void prePersist(Vocabulary instance) { + protected void prePersist(@NotNull Vocabulary instance) { super.prePersist(instance); if (instance.getUri() == null) { - instance.setUri(idResolver.generateIdentifier(config.getNamespace().getVocabulary(), - instance.getLabel())); + instance.setUri(idResolver.generateIdentifier(config.getNamespace().getVocabulary(), instance.getLabel())); } verifyIdentifierUnique(instance); initGlossaryAndModel(instance); @@ -152,12 +163,12 @@ private void initGlossaryAndModel(Vocabulary vocabulary) { } @Override - protected void postPersist(Vocabulary instance) { + protected void postPersist(@NotNull Vocabulary instance) { eventPublisher.publishEvent(new VocabularyCreatedEvent(instance)); } @Override - protected void preUpdate(Vocabulary instance) { + protected void preUpdate(@NotNull Vocabulary instance) { super.preUpdate(instance); final Vocabulary original = findRequired(instance.getUri()); verifyVocabularyImports(instance, original); @@ -336,7 +347,7 @@ public PrefixDeclaration resolvePrefix(URI vocabularyUri) { } @Override - public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) { + public void setApplicationEventPublisher(@NotNull ApplicationEventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } } diff --git a/src/test/java/cz/cvut/kbss/termit/environment/Environment.java b/src/test/java/cz/cvut/kbss/termit/environment/Environment.java index 3e81b9b06..1966d1009 100644 --- a/src/test/java/cz/cvut/kbss/termit/environment/Environment.java +++ b/src/test/java/cz/cvut/kbss/termit/environment/Environment.java @@ -19,6 +19,8 @@ import cz.cvut.kbss.jsonld.JsonLd; import cz.cvut.kbss.termit.config.WebAppConfig; import cz.cvut.kbss.termit.dto.listing.TermDto; +import cz.cvut.kbss.termit.dto.mapper.DtoMapper; +import cz.cvut.kbss.termit.dto.mapper.DtoMapperImpl; import cz.cvut.kbss.termit.model.Term; import cz.cvut.kbss.termit.model.User; import cz.cvut.kbss.termit.model.UserAccount; @@ -59,6 +61,8 @@ public class Environment { private static ObjectMapper jsonLdObjectMapper; + private static final DtoMapper DTO_MAPPER = new DtoMapperImpl(); + /** * Initializes security context with the specified user. * @@ -121,6 +125,10 @@ public static ObjectMapper getJsonLdObjectMapper() { return jsonLdObjectMapper; } + public static DtoMapper getDtoMapper() { + return DTO_MAPPER; + } + /** * Creates a Jackson JSON-LD message converter. * diff --git a/src/test/java/cz/cvut/kbss/termit/environment/config/TestServiceConfig.java b/src/test/java/cz/cvut/kbss/termit/environment/config/TestServiceConfig.java index b1aa05a23..494a8bfa2 100644 --- a/src/test/java/cz/cvut/kbss/termit/environment/config/TestServiceConfig.java +++ b/src/test/java/cz/cvut/kbss/termit/environment/config/TestServiceConfig.java @@ -16,6 +16,8 @@ import cz.cvut.kbss.termit.aspect.ChangeTrackingAspect; import cz.cvut.kbss.termit.aspect.VocabularyContentModificationAspect; +import cz.cvut.kbss.termit.dto.mapper.DtoMapper; +import cz.cvut.kbss.termit.dto.mapper.DtoMapperImpl; import cz.cvut.kbss.termit.environment.Environment; import cz.cvut.kbss.termit.model.selector.Selector; import cz.cvut.kbss.termit.service.document.html.DummySelectorGenerator; @@ -105,4 +107,9 @@ public ApplicationEventPublisher eventPublisher() { public JavaMailSender javaMailSender() { return mock(JavaMailSender.class); } + + @Bean + public DtoMapper dtoMapper() { + return new DtoMapperImpl(); + } } diff --git a/src/test/java/cz/cvut/kbss/termit/persistence/dao/BaseDaoTest.java b/src/test/java/cz/cvut/kbss/termit/persistence/dao/BaseDaoTest.java index ca98f8bd3..5f3f0b8db 100644 --- a/src/test/java/cz/cvut/kbss/termit/persistence/dao/BaseDaoTest.java +++ b/src/test/java/cz/cvut/kbss/termit/persistence/dao/BaseDaoTest.java @@ -152,16 +152,6 @@ void exceptionDuringCollectionPersistIsWrappedInPersistenceException() { assertThat(e.getCause(), is(instanceOf(OWLPersistenceException.class))); } - @Test - void exceptionDuringUpdateIsWrappedInPersistenceException() { - final Term term = Generator.generateTermWithId(); - transactional(() -> sut.persist(term)); - term.setVocabulary(Generator.generateUri()); - final PersistenceException e = assertThrows(PersistenceException.class, - () -> transactional(() -> sut.update(term))); - assertThat(e.getCause(), is(instanceOf(OWLPersistenceException.class))); - } - @Test void getReferenceRetrievesReferenceToMatchingInstance() { final Term term = Generator.generateTermWithId(); diff --git a/src/test/java/cz/cvut/kbss/termit/rest/VocabularyControllerTest.java b/src/test/java/cz/cvut/kbss/termit/rest/VocabularyControllerTest.java index 9769f898f..9f1f4e2b8 100644 --- a/src/test/java/cz/cvut/kbss/termit/rest/VocabularyControllerTest.java +++ b/src/test/java/cz/cvut/kbss/termit/rest/VocabularyControllerTest.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import cz.cvut.kbss.termit.dto.AggregatedChangeInfo; import cz.cvut.kbss.termit.dto.Snapshot; +import cz.cvut.kbss.termit.dto.listing.VocabularyDto; import cz.cvut.kbss.termit.environment.Environment; import cz.cvut.kbss.termit.environment.Generator; import cz.cvut.kbss.termit.exception.AssetRemovalException; @@ -77,19 +78,16 @@ void setUp() { @Test void getAllReturnsAllExistingVocabularies() throws Exception { - final List vocabularies = - IntStream.range(0, 5).mapToObj(i -> generateVocabulary()) - .collect(Collectors.toList()); + final List vocabularies = IntStream.range(0, 5).mapToObj( + i -> Environment.getDtoMapper().vocabularyToVocabularyDto(generateVocabulary())) + .collect(Collectors.toList()); when(serviceMock.findAll()).thenReturn(vocabularies); final MvcResult mvcResult = mockMvc.perform(get(PATH)).andExpect(status().isOk()).andReturn(); - final List result = readValue(mvcResult, new TypeReference>() { + final List result = readValue(mvcResult, new TypeReference>() { }); - assertEquals(vocabularies.size(), result.size()); - for (Vocabulary voc : vocabularies) { - assertTrue(result.stream().anyMatch(v -> v.getUri().equals(voc.getUri()))); - } + assertThat(result, containsSameEntities(vocabularies)); } private Vocabulary generateVocabulary() { @@ -98,20 +96,17 @@ private Vocabulary generateVocabulary() { @Test void getAllReturnsLastModifiedHeader() throws Exception { - final List vocabularies = - IntStream.range(0, 5).mapToObj(i -> generateVocabulary()) - .collect(Collectors.toList()); + final List vocabularies = Collections.singletonList( + Environment.getDtoMapper().vocabularyToVocabularyDto(generateVocabulary())); when(serviceMock.findAll()).thenReturn(vocabularies); // Round to seconds final long lastModified = (System.currentTimeMillis() / 1000) * 1000; when(serviceMock.getLastModified()).thenReturn(lastModified); final MvcResult mvcResult = mockMvc.perform(get(PATH)).andExpect(status().isOk()).andReturn(); - final String lastModifiedHeader = - mvcResult.getResponse().getHeader(HttpHeaders.LAST_MODIFIED); + final String lastModifiedHeader = mvcResult.getResponse().getHeader(HttpHeaders.LAST_MODIFIED); assertNotNull(lastModifiedHeader); - ZonedDateTime zdt = - ZonedDateTime.parse(lastModifiedHeader, DateTimeFormatter.RFC_1123_DATE_TIME); + ZonedDateTime zdt = ZonedDateTime.parse(lastModifiedHeader, DateTimeFormatter.RFC_1123_DATE_TIME); assertEquals(lastModified, zdt.toInstant().toEpochMilli()); } diff --git a/src/test/java/cz/cvut/kbss/termit/service/business/readonly/ReadOnlyVocabularyServiceTest.java b/src/test/java/cz/cvut/kbss/termit/service/business/readonly/ReadOnlyVocabularyServiceTest.java index 0ce0d8d95..90cbadebc 100644 --- a/src/test/java/cz/cvut/kbss/termit/service/business/readonly/ReadOnlyVocabularyServiceTest.java +++ b/src/test/java/cz/cvut/kbss/termit/service/business/readonly/ReadOnlyVocabularyServiceTest.java @@ -1,7 +1,9 @@ package cz.cvut.kbss.termit.service.business.readonly; import cz.cvut.kbss.termit.dto.Snapshot; +import cz.cvut.kbss.termit.dto.listing.VocabularyDto; import cz.cvut.kbss.termit.dto.readonly.ReadOnlyVocabulary; +import cz.cvut.kbss.termit.environment.Environment; import cz.cvut.kbss.termit.environment.Generator; import cz.cvut.kbss.termit.exception.NotFoundException; import cz.cvut.kbss.termit.model.Vocabulary; @@ -37,8 +39,9 @@ class ReadOnlyVocabularyServiceTest { @Test void findAllReturnsAllVocabulariesTransformedToReadOnlyVersions() { - final List vocabularies = IntStream.range(0, 5).mapToObj(i -> Generator.generateVocabularyWithId()) - .collect(Collectors.toList()); + final List vocabularies = IntStream.range(0, 5).mapToObj( + i -> Environment.getDtoMapper().vocabularyToVocabularyDto(Generator.generateVocabularyWithId())) + .collect(Collectors.toList()); when(vocabularyService.findAll()).thenReturn(vocabularies); final List result = sut.findAll(); diff --git a/src/test/java/cz/cvut/kbss/termit/service/repository/BaseAssetRepositoryServiceImpl.java b/src/test/java/cz/cvut/kbss/termit/service/repository/BaseAssetRepositoryServiceImpl.java index b0502e02d..7035cb88c 100644 --- a/src/test/java/cz/cvut/kbss/termit/service/repository/BaseAssetRepositoryServiceImpl.java +++ b/src/test/java/cz/cvut/kbss/termit/service/repository/BaseAssetRepositoryServiceImpl.java @@ -25,7 +25,7 @@ import javax.validation.Validator; -public class BaseAssetRepositoryServiceImpl extends BaseAssetRepositoryService { +public class BaseAssetRepositoryServiceImpl extends BaseAssetRepositoryService { private final VocabularyDao dao; @@ -39,4 +39,9 @@ public BaseAssetRepositoryServiceImpl(VocabularyDao dao, Validator validator, Se protected BaseAssetDao getPrimaryDao() { return dao; } + + @Override + protected Vocabulary mapToDto(Vocabulary entity) { + return entity; + } } diff --git a/src/test/java/cz/cvut/kbss/termit/service/repository/BaseRepositoryServiceImpl.java b/src/test/java/cz/cvut/kbss/termit/service/repository/BaseRepositoryServiceImpl.java index d9e4d7390..b6b613be0 100644 --- a/src/test/java/cz/cvut/kbss/termit/service/repository/BaseRepositoryServiceImpl.java +++ b/src/test/java/cz/cvut/kbss/termit/service/repository/BaseRepositoryServiceImpl.java @@ -24,7 +24,7 @@ import javax.validation.Validator; -public class BaseRepositoryServiceImpl extends BaseRepositoryService { +public class BaseRepositoryServiceImpl extends BaseRepositoryService { private final UserAccountDao userAccountDao; @@ -38,4 +38,9 @@ public BaseRepositoryServiceImpl(UserAccountDao userAccountDao, Validator valida protected GenericDao getPrimaryDao() { return userAccountDao; } + + @Override + protected UserAccount mapToDto(UserAccount entity) { + return entity; + } } diff --git a/src/test/java/cz/cvut/kbss/termit/service/repository/VocabularyRepositoryServiceWorkspaceTest.java b/src/test/java/cz/cvut/kbss/termit/service/repository/VocabularyRepositoryServiceWorkspaceTest.java index eea0fe02d..6295b6872 100644 --- a/src/test/java/cz/cvut/kbss/termit/service/repository/VocabularyRepositoryServiceWorkspaceTest.java +++ b/src/test/java/cz/cvut/kbss/termit/service/repository/VocabularyRepositoryServiceWorkspaceTest.java @@ -1,5 +1,8 @@ package cz.cvut.kbss.termit.service.repository; +import cz.cvut.kbss.termit.dto.listing.VocabularyDto; +import cz.cvut.kbss.termit.dto.mapper.DtoMapper; +import cz.cvut.kbss.termit.environment.Environment; import cz.cvut.kbss.termit.environment.Generator; import cz.cvut.kbss.termit.model.Vocabulary; import cz.cvut.kbss.termit.persistence.dao.VocabularyDao; @@ -39,6 +42,9 @@ public class VocabularyRepositoryServiceWorkspaceTest { @Mock private VocabularyDao dao; + @Spy + private final DtoMapper dtoMapper = Environment.getDtoMapper(); + @InjectMocks private VocabularyRepositoryService sut; @@ -50,11 +56,14 @@ void findAllAddsReadOnlyTypeToNotEditedVocabulariesWhenNotAllVocabulariesAreEdit when(dao.findAll()).thenReturn(vocabularies); final Set readOnly = vocabularies.stream().filter(v -> Generator.randomBoolean()) .collect(Collectors.toSet()); + final Set dtos = readOnly.stream() + .map(v -> Environment.getDtoMapper().vocabularyToVocabularyDto(v)) + .collect(Collectors.toSet()); when(editableVocabularies.isEditable(any(Vocabulary.class))).thenReturn(true); readOnly.forEach(v -> when(editableVocabularies.isEditable(v)).thenReturn(false)); - final List result = sut.findAll(); - result.stream().filter(readOnly::contains) + final List result = sut.findAll(); + result.stream().filter(dtos::contains) .forEach(v -> assertThat(v.getTypes(), hasItem(cz.cvut.kbss.termit.util.Vocabulary.s_c_pouze_pro_cteni))); } From 76e57cec9a8f9e2dc2bc01e647a7803142126e6e Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Mon, 6 Feb 2023 08:28:52 +0100 Subject: [PATCH 2/5] Allow configuring URL patterns in CORS allowed origins. --- .../cvut/kbss/termit/config/SecurityConfig.java | 3 +++ .../cz/cvut/kbss/termit/util/Configuration.java | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/main/java/cz/cvut/kbss/termit/config/SecurityConfig.java b/src/main/java/cz/cvut/kbss/termit/config/SecurityConfig.java index 772d04f18..b8ff2b428 100644 --- a/src/main/java/cz/cvut/kbss/termit/config/SecurityConfig.java +++ b/src/main/java/cz/cvut/kbss/termit/config/SecurityConfig.java @@ -114,6 +114,9 @@ protected static CorsConfigurationSource createCorsConfiguration( final CorsConfiguration corsConfiguration = new CorsConfiguration().applyPermitDefaultValues(); corsConfiguration.setAllowedMethods(Collections.singletonList("*")); corsConfiguration.setAllowedOrigins(Arrays.asList(corsConfig.getAllowedOrigins().split(","))); + if (corsConfig.getAllowedOriginPatterns() != null) { + corsConfiguration.setAllowedOriginPatterns(Arrays.asList(corsConfig.getAllowedOriginPatterns().split(","))); + } corsConfiguration.addExposedHeader(HttpHeaders.AUTHORIZATION); corsConfiguration.addExposedHeader(HttpHeaders.LOCATION); corsConfiguration.addExposedHeader(HttpHeaders.CONTENT_DISPOSITION); diff --git a/src/main/java/cz/cvut/kbss/termit/util/Configuration.java b/src/main/java/cz/cvut/kbss/termit/util/Configuration.java index f8eb464e5..26573f25c 100644 --- a/src/main/java/cz/cvut/kbss/termit/util/Configuration.java +++ b/src/main/java/cz/cvut/kbss/termit/util/Configuration.java @@ -633,6 +633,15 @@ public static class Cors { @NotNull private String allowedOrigins = "http://localhost:3000"; + /** + * A comma-separated list of allowed origin patterns for CORS. + *

+ * This allows a more dynamic configuration of allowed origins that {@link #allowedOrigins} which contains exact + * origin URLs. It is useful, for example, for Netlify preview builds of the frontend which use a generated + * subdomain URL. + */ + private String allowedOriginPatterns; + public String getAllowedOrigins() { return allowedOrigins; } @@ -640,6 +649,14 @@ public String getAllowedOrigins() { public void setAllowedOrigins(String allowedOrigins) { this.allowedOrigins = allowedOrigins; } + + public String getAllowedOriginPatterns() { + return allowedOriginPatterns; + } + + public void setAllowedOriginPatterns(String allowedOriginPatterns) { + this.allowedOriginPatterns = allowedOriginPatterns; + } } @org.springframework.context.annotation.Configuration From 63632d72f8e3327b5b226060609935cbe4aa3721 Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Wed, 8 Feb 2023 14:48:23 +0100 Subject: [PATCH 3/5] [Upd] Update to JB4JSON-LD 0.11.0 which supports embedded contexts. --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 8d4f05705..b723836f0 100644 --- a/pom.xml +++ b/pom.xml @@ -33,8 +33,8 @@ 6.2.3.Final 2.6.0 1.5.3.Final - 0.20.0 - 0.10.2 + 0.20.1 + 0.11.0 1.9.7 From 34e8782954b8ebe7f86dcb8e4751d714ad1a8ae9 Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Wed, 8 Feb 2023 15:04:23 +0100 Subject: [PATCH 4/5] [Upd] Switch Maven project parent to spring-boot-starter-parent, simplify dependencies. --- pom.xml | 38 ++++---------------------------------- 1 file changed, 4 insertions(+), 34 deletions(-) diff --git a/pom.xml b/pom.xml index b723836f0..a43eb7938 100644 --- a/pom.xml +++ b/pom.xml @@ -5,9 +5,9 @@ 4.0.0 - cz.cvut.kbss - kbss-project-parent - 0.0.9 + org.springframework.boot + spring-boot-starter-parent + 2.7.8 termit @@ -16,7 +16,6 @@ Terminology manager based on Semantic Web technologies. ${packaging} - kbss @@ -26,11 +25,6 @@ 11 - 2.7.8 - 5.3.25 - 5.7.6 - 2.7.5 - 6.2.3.Final 2.6.0 1.5.3.Final 0.20.1 @@ -142,7 +136,6 @@ org.springframework.boot spring-boot-starter-web - ${org.springframework.boot.version} org.springframework.boot @@ -153,32 +146,22 @@ org.springframework.boot spring-boot-starter-security - ${org.springframework.boot.version} org.springframework.boot spring-boot-starter-cache - ${org.springframework.boot.version} org.springframework.boot spring-boot-starter-mail - ${org.springframework.boot.version} org.springframework.data spring-data-commons - ${org.springframework.data.version} org.springframework spring-aspects - ${org.springframework.version} - - - org.springframework - spring-tx - ${org.springframework.version} @@ -244,7 +227,6 @@ javax.servlet javax.servlet-api - 4.0.1 provided @@ -252,7 +234,6 @@ org.hibernate.validator hibernate-validator - ${org.hibernate.validator.version} javax.el @@ -321,17 +302,14 @@ javax.cache cache-api - 1.0.0 org.ehcache ehcache - 3.9.4 org.glassfish.jaxb jaxb-runtime - 2.3.6 runtime @@ -359,13 +337,11 @@ org.springframework.boot spring-boot-starter-test - ${org.springframework.boot.version} test org.springframework.security spring-security-test - ${org.springframework.security.version} test @@ -385,7 +361,6 @@ org.springframework.boot spring-boot-starter-tomcat - ${org.springframework.boot.version} @@ -399,7 +374,6 @@ org.springframework.boot spring-boot-starter-tomcat - ${org.springframework.boot.version} provided @@ -408,7 +382,6 @@ org.apache.maven.plugins maven-war-plugin - 3.3.1 termit @@ -445,7 +418,7 @@ org.hibernate.validator hibernate-validator-annotation-processor - ${org.hibernate.validator.version} + ${hibernate-validator.version} org.mapstruct @@ -510,7 +483,6 @@ org.springframework.boot spring-boot-maven-plugin - ${org.springframework.boot.version} @@ -570,7 +542,6 @@ org.codehaus.mojo build-helper-maven-plugin - 1.10 add-source @@ -589,7 +560,6 @@ org.apache.maven.plugins maven-resources-plugin - 3.3.0 copy-resources From 73c7207526db2f9ab4811eca3eabc445bc4a48c8 Mon Sep 17 00:00:00 2001 From: Martin Ledvinka Date: Tue, 14 Feb 2023 09:23:39 +0100 Subject: [PATCH 5/5] [2.16.1] Bump version. Update copyright year in license header file. --- header.txt | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/header.txt b/header.txt index 85ec0a48c..5c77ca1bb 100644 --- a/header.txt +++ b/header.txt @@ -1,5 +1,5 @@ TermIt -Copyright (C) 2022 Czech Technical University in Prague +Copyright (C) 2023 Czech Technical University in Prague This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/pom.xml b/pom.xml index a43eb7938..050a502ff 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ termit - 2.16.0 + 2.16.1 TermIt Terminology manager based on Semantic Web technologies. ${packaging}