org.springframework
diff --git a/src/main/java/cz/cvut/kbss/termit/aspect/ChangeTrackingAspect.java b/src/main/java/cz/cvut/kbss/termit/aspect/ChangeTrackingAspect.java
deleted file mode 100644
index 241b25f46..000000000
--- a/src/main/java/cz/cvut/kbss/termit/aspect/ChangeTrackingAspect.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * TermIt
- * 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
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package cz.cvut.kbss.termit.aspect;
-
-import cz.cvut.kbss.termit.model.Asset;
-import cz.cvut.kbss.termit.model.Term;
-import cz.cvut.kbss.termit.model.Vocabulary;
-import cz.cvut.kbss.termit.persistence.dao.changetracking.ChangeTrackingHelperDao;
-import cz.cvut.kbss.termit.service.changetracking.ChangeTracker;
-import org.aspectj.lang.annotation.After;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Before;
-import org.aspectj.lang.annotation.Pointcut;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import java.net.URI;
-
-/**
- * Records changes to assets based on modification operations.
- */
-@Aspect
-public class ChangeTrackingAspect {
-
- private static final Logger LOG = LoggerFactory.getLogger(ChangeTrackingAspect.class);
-
- @Autowired
- private ChangeTracker changeTracker;
-
- @Autowired
- private ChangeTrackingHelperDao helperDao;
-
- @Pointcut(value = "execution(public void persist(..)) && (target(cz.cvut.kbss.termit.persistence.dao.BaseAssetDao)) " +
- "&& @args(cz.cvut.kbss.termit.model.changetracking.Audited)")
- public void persistOperation() {
- }
-
- @Pointcut(value = "execution(public void persist(..)) && target(cz.cvut.kbss.termit.persistence.dao.TermDao) " +
- "&& @args(cz.cvut.kbss.termit.model.changetracking.Audited, *)")
- public void persistTermOperation() {
- }
-
- @Pointcut(value = "execution(public * update(..)) && target(cz.cvut.kbss.termit.persistence.dao.BaseAssetDao) " +
- "&& @args(cz.cvut.kbss.termit.model.changetracking.Audited)")
- public void updateOperation() {
- }
-
- @Pointcut(value = "execution(public void setState(..)) && target(cz.cvut.kbss.termit.persistence.dao.TermDao)" +
- "&& @args(cz.cvut.kbss.termit.model.changetracking.Audited, *)")
- public void termStateUpdateOperation() {
- }
-
- @After(value = "persistOperation() && args(asset)")
- public void recordAssetPersist(Asset> asset) {
- LOG.trace("Recording creation of asset {}.", asset);
- changeTracker.recordAddEvent(asset);
- }
-
- @After(value = "persistTermOperation() && args(asset, voc)", argNames = "asset,voc")
- public void recordTermPersist(Term asset, Vocabulary voc) {
- LOG.trace("Recording creation of term {}.", asset);
- changeTracker.recordAddEvent(asset);
- }
-
- @Before(value = "updateOperation() && args(asset)")
- public void recordAssetUpdate(Asset> asset) {
- LOG.trace("Recording update of asset {}.", asset);
- changeTracker.recordUpdateEvent(asset, helperDao.findStored(asset));
- }
-
- @Before(value = "termStateUpdateOperation() && args(asset, state)", argNames = "asset, state")
- public void recordTermStateUpdate(Term asset, URI state) {
- LOG.trace("Recording update of asset {}.", asset);
- final Term original = new Term();
- original.setUri(asset.getUri());
- original.setState(helperDao.findStored(asset).getState());
- final Term update = new Term();
- update.setUri(asset.getUri());
- update.setState(state);
- changeTracker.recordUpdateEvent(update, original);
- }
-}
diff --git a/src/main/java/cz/cvut/kbss/termit/aspect/RefreshLastModifiedAspect.java b/src/main/java/cz/cvut/kbss/termit/aspect/RefreshLastModifiedAspect.java
deleted file mode 100644
index a977d083b..000000000
--- a/src/main/java/cz/cvut/kbss/termit/aspect/RefreshLastModifiedAspect.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * TermIt
- * 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
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package cz.cvut.kbss.termit.aspect;
-
-import cz.cvut.kbss.termit.asset.provenance.SupportsLastModification;
-import org.aspectj.lang.annotation.After;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Pointcut;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Ensures corresponding last modified timestamp is refreshed when a data modifying operation is invoked for an asset.
- */
-@Aspect
-public class RefreshLastModifiedAspect {
-
- private static final Logger LOG = LoggerFactory.getLogger(RefreshLastModifiedAspect.class);
-
- @Pointcut(value = "@annotation(cz.cvut.kbss.termit.asset.provenance.ModifiesData) " +
- "&& target(cz.cvut.kbss.termit.asset.provenance.SupportsLastModification)")
- public void dataModificationOperation() {
- }
-
- @After(value = "dataModificationOperation() && target(bean)", argNames = "bean")
- public void refreshLastModified(SupportsLastModification bean) {
- LOG.trace("Refreshing last modified timestamp on bean {}.", bean);
- bean.refreshLastModified();
- }
-}
diff --git a/src/main/java/cz/cvut/kbss/termit/aspect/VocabularyContentModificationAspect.java b/src/main/java/cz/cvut/kbss/termit/aspect/VocabularyContentModificationAspect.java
deleted file mode 100644
index dae9c9304..000000000
--- a/src/main/java/cz/cvut/kbss/termit/aspect/VocabularyContentModificationAspect.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * TermIt
- * 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
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package cz.cvut.kbss.termit.aspect;
-
-import cz.cvut.kbss.termit.event.VocabularyContentModified;
-import org.aspectj.lang.annotation.After;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Pointcut;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationEventPublisher;
-
-@Aspect
-public class VocabularyContentModificationAspect {
-
- @Autowired
- private ApplicationEventPublisher eventPublisher;
-
- @Pointcut("@annotation(cz.cvut.kbss.termit.asset.provenance.ModifiesData) && target(cz.cvut.kbss.termit.persistence.dao.TermDao)")
- public void vocabularyContentModificationOperation() {
- }
-
- @After("vocabularyContentModificationOperation()")
- public void vocabularyContentModified() {
- eventPublisher.publishEvent(new VocabularyContentModified(this));
- }
-}
diff --git a/src/main/java/cz/cvut/kbss/termit/asset/provenance/ModifiesData.java b/src/main/java/cz/cvut/kbss/termit/asset/provenance/ModifiesData.java
index c623a42d1..6cd707854 100644
--- a/src/main/java/cz/cvut/kbss/termit/asset/provenance/ModifiesData.java
+++ b/src/main/java/cz/cvut/kbss/termit/asset/provenance/ModifiesData.java
@@ -17,8 +17,6 @@
*/
package cz.cvut.kbss.termit.asset.provenance;
-import cz.cvut.kbss.termit.aspect.RefreshLastModifiedAspect;
-
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -27,9 +25,7 @@
/**
* Designates methods which modify data and should thus refresh last modified date on completion.
*
- * This annotation should be used on methods of classes implementing {@link SupportsLastModification}. A corresponding
- * aspect defined in {@link RefreshLastModifiedAspect} refreshes the last modified timestamp when a method modifying
- * data is invoked.
+ * This annotation should be used on methods of classes implementing {@link SupportsLastModification}.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
diff --git a/src/main/java/cz/cvut/kbss/termit/config/ServiceConfig.java b/src/main/java/cz/cvut/kbss/termit/config/ServiceConfig.java
index 7f749d9ba..227406729 100644
--- a/src/main/java/cz/cvut/kbss/termit/config/ServiceConfig.java
+++ b/src/main/java/cz/cvut/kbss/termit/config/ServiceConfig.java
@@ -18,14 +18,11 @@
package cz.cvut.kbss.termit.config;
import com.fasterxml.jackson.databind.ObjectMapper;
-import cz.cvut.kbss.termit.aspect.ChangeTrackingAspect;
-import cz.cvut.kbss.termit.aspect.VocabularyContentModificationAspect;
import cz.cvut.kbss.termit.exception.ResourceNotFoundException;
import cz.cvut.kbss.termit.util.Utils;
import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.impl.DefaultRedirectStrategy;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
-import org.aspectj.lang.Aspects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -108,16 +105,4 @@ public Resource termStatesLanguageFile(cz.cvut.kbss.termit.util.Configuration co
}
return new ClassPathResource("languages/states.ttl");
}
-
- @Bean
- ChangeTrackingAspect changeTrackingAspect() {
- // Need to create the aspect as a bean, so that it can be injected into
- return Aspects.aspectOf(ChangeTrackingAspect.class);
- }
-
- @Bean
- VocabularyContentModificationAspect vocabularyContentModificationAspect() {
- // Need to create the aspect as a bean, so that it can be injected into
- return Aspects.aspectOf(VocabularyContentModificationAspect.class);
- }
}
diff --git a/src/main/java/cz/cvut/kbss/termit/dto/TextAnalysisInput.java b/src/main/java/cz/cvut/kbss/termit/dto/TextAnalysisInput.java
index 72537cad0..e0e8cf7c1 100644
--- a/src/main/java/cz/cvut/kbss/termit/dto/TextAnalysisInput.java
+++ b/src/main/java/cz/cvut/kbss/termit/dto/TextAnalysisInput.java
@@ -44,6 +44,16 @@ public class TextAnalysisInput {
*/
private URI vocabularyRepository;
+ /**
+ * Username to access the repository
+ */
+ private String vocabularyRepositoryUserName;
+
+ /**
+ * Password to access the repository
+ */
+ private String vocabularyRepositoryPassword;
+
/**
* URIs of contexts containing vocabularies whose terms are used in the text analysis. Optional.
*
@@ -84,6 +94,22 @@ public void setVocabularyRepository(URI vocabularyRepository) {
this.vocabularyRepository = vocabularyRepository;
}
+ public String getVocabularyRepositoryUserName() {
+ return vocabularyRepositoryUserName;
+ }
+
+ public void setVocabularyRepositoryUserName(String vocabularyRepositoryUserName) {
+ this.vocabularyRepositoryUserName = vocabularyRepositoryUserName;
+ }
+
+ public String getVocabularyRepositoryPassword() {
+ return vocabularyRepositoryPassword;
+ }
+
+ public void setVocabularyRepositoryPassword(String vocabularyRepositoryPassword) {
+ this.vocabularyRepositoryPassword = vocabularyRepositoryPassword;
+ }
+
public Set getVocabularyContexts() {
return vocabularyContexts;
}
diff --git a/src/main/java/cz/cvut/kbss/termit/event/AssetPersistEvent.java b/src/main/java/cz/cvut/kbss/termit/event/AssetPersistEvent.java
new file mode 100644
index 000000000..9451d6bb8
--- /dev/null
+++ b/src/main/java/cz/cvut/kbss/termit/event/AssetPersistEvent.java
@@ -0,0 +1,21 @@
+package cz.cvut.kbss.termit.event;
+
+import cz.cvut.kbss.termit.model.Asset;
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * Event published when an asset is persisted.
+ */
+public class AssetPersistEvent extends ApplicationEvent {
+
+ private final Asset> asset;
+
+ public AssetPersistEvent(Object source, Asset> asset) {
+ super(source);
+ this.asset = asset;
+ }
+
+ public Asset> getAsset() {
+ return asset;
+ }
+}
diff --git a/src/main/java/cz/cvut/kbss/termit/event/AssetUpdateEvent.java b/src/main/java/cz/cvut/kbss/termit/event/AssetUpdateEvent.java
new file mode 100644
index 000000000..cece65039
--- /dev/null
+++ b/src/main/java/cz/cvut/kbss/termit/event/AssetUpdateEvent.java
@@ -0,0 +1,21 @@
+package cz.cvut.kbss.termit.event;
+
+import cz.cvut.kbss.termit.model.Asset;
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * Event published when an asset is updated.
+ */
+public class AssetUpdateEvent extends ApplicationEvent {
+
+ private final Asset> asset;
+
+ public AssetUpdateEvent(Object source, Asset> asset) {
+ super(source);
+ this.asset = asset;
+ }
+
+ public Asset> getAsset() {
+ return asset;
+ }
+}
diff --git a/src/main/java/cz/cvut/kbss/termit/event/VocabularyContentModified.java b/src/main/java/cz/cvut/kbss/termit/event/VocabularyContentModified.java
index 01595d0fa..8eed780fd 100644
--- a/src/main/java/cz/cvut/kbss/termit/event/VocabularyContentModified.java
+++ b/src/main/java/cz/cvut/kbss/termit/event/VocabularyContentModified.java
@@ -19,6 +19,8 @@
import org.springframework.context.ApplicationEvent;
+import java.net.URI;
+
/**
* Represents an event of modification of the content of a vocabulary.
*
@@ -26,7 +28,14 @@
*/
public class VocabularyContentModified extends ApplicationEvent {
- public VocabularyContentModified(Object source) {
+ private final URI vocabularyIri;
+
+ public VocabularyContentModified(Object source, URI vocabularyIri) {
super(source);
+ this.vocabularyIri = vocabularyIri;
+ }
+
+ public URI getVocabularyIri() {
+ return vocabularyIri;
}
}
diff --git a/src/main/java/cz/cvut/kbss/termit/persistence/dao/BaseAssetDao.java b/src/main/java/cz/cvut/kbss/termit/persistence/dao/BaseAssetDao.java
index 31651ca6a..bb6e26400 100644
--- a/src/main/java/cz/cvut/kbss/termit/persistence/dao/BaseAssetDao.java
+++ b/src/main/java/cz/cvut/kbss/termit/persistence/dao/BaseAssetDao.java
@@ -19,6 +19,8 @@
import cz.cvut.kbss.jopa.model.EntityManager;
import cz.cvut.kbss.termit.dto.RecentlyCommentedAsset;
+import cz.cvut.kbss.termit.event.AssetPersistEvent;
+import cz.cvut.kbss.termit.event.AssetUpdateEvent;
import cz.cvut.kbss.termit.exception.PersistenceException;
import cz.cvut.kbss.termit.model.Asset;
import cz.cvut.kbss.termit.model.User;
@@ -51,6 +53,18 @@ public abstract class BaseAssetDao> extends BaseDao {
this.descriptorFactory = descriptorFactory;
}
+ @Override
+ public void persist(T entity) {
+ super.persist(entity);
+ eventPublisher.publishEvent(new AssetPersistEvent(this, entity));
+ }
+
+ @Override
+ public T update(T entity) {
+ eventPublisher.publishEvent(new AssetUpdateEvent(this, entity));
+ return super.update(entity);
+ }
+
/**
* Finds unique last commented assets.
*
diff --git a/src/main/java/cz/cvut/kbss/termit/persistence/dao/BaseDao.java b/src/main/java/cz/cvut/kbss/termit/persistence/dao/BaseDao.java
index a87fb845d..a4e495cc1 100644
--- a/src/main/java/cz/cvut/kbss/termit/persistence/dao/BaseDao.java
+++ b/src/main/java/cz/cvut/kbss/termit/persistence/dao/BaseDao.java
@@ -21,9 +21,13 @@
import cz.cvut.kbss.jopa.model.descriptors.Descriptor;
import cz.cvut.kbss.jopa.model.descriptors.EntityDescriptor;
import cz.cvut.kbss.termit.asset.provenance.ModifiesData;
+import cz.cvut.kbss.termit.event.RefreshLastModifiedEvent;
import cz.cvut.kbss.termit.exception.PersistenceException;
import cz.cvut.kbss.termit.model.util.EntityToOwlClassMapper;
import cz.cvut.kbss.termit.model.util.HasIdentifier;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.ApplicationEventPublisherAware;
import java.net.URI;
import java.util.Collection;
@@ -34,13 +38,15 @@
/**
* Base implementation of the generic DAO API.
*/
-public abstract class BaseDao implements GenericDao {
+public abstract class BaseDao implements GenericDao, ApplicationEventPublisherAware {
protected final Class type;
protected final URI typeUri;
protected final EntityManager em;
+ protected ApplicationEventPublisher eventPublisher;
+
protected BaseDao(Class type, EntityManager em) {
this.type = type;
this.typeUri = URI.create(EntityToOwlClassMapper.getOwlClassForEntity(type));
@@ -69,10 +75,10 @@ public Optional find(URI id) {
}
@Override
- public Optional getReference(URI id) {
+ public T getReference(URI id) {
Objects.requireNonNull(id);
try {
- return Optional.ofNullable(em.getReference(type, id, getDescriptor()));
+ return em.getReference(type, id, getDescriptor());
} catch (RuntimeException e) {
throw new PersistenceException(e);
}
@@ -93,6 +99,7 @@ public void persist(T entity) {
} catch (RuntimeException e) {
throw new PersistenceException(e);
}
+ eventPublisher.publishEvent(new RefreshLastModifiedEvent(this));
}
@ModifiesData
@@ -104,6 +111,7 @@ public void persist(Collection entities) {
} catch (RuntimeException e) {
throw new PersistenceException(e);
}
+ eventPublisher.publishEvent(new RefreshLastModifiedEvent(this));
}
@ModifiesData
@@ -111,7 +119,9 @@ public void persist(Collection entities) {
public T update(T entity) {
Objects.requireNonNull(entity);
try {
- return em.merge(entity, getDescriptor());
+ final T result = em.merge(entity, getDescriptor());
+ eventPublisher.publishEvent(new RefreshLastModifiedEvent(this));
+ return result;
} catch (RuntimeException e) {
throw new PersistenceException(e);
}
@@ -123,8 +133,11 @@ public void remove(T entity) {
Objects.requireNonNull(entity);
Objects.requireNonNull(entity.getUri());
try {
- final Optional reference = getReference(entity.getUri());
- reference.ifPresent(em::remove);
+ final Optional toRemove = find(entity.getUri());
+ toRemove.ifPresent(elem -> {
+ em.remove(elem);
+ eventPublisher.publishEvent(new RefreshLastModifiedEvent(this));
+ });
} catch (RuntimeException e) {
throw new PersistenceException(e);
}
@@ -144,4 +157,9 @@ public boolean exists(URI id) {
protected Descriptor getDescriptor() {
return new EntityDescriptor();
}
+
+ @Override
+ public void setApplicationEventPublisher(@NotNull ApplicationEventPublisher eventPublisher) {
+ this.eventPublisher = eventPublisher;
+ }
}
diff --git a/src/main/java/cz/cvut/kbss/termit/persistence/dao/GenericDao.java b/src/main/java/cz/cvut/kbss/termit/persistence/dao/GenericDao.java
index 376918051..82267ee72 100644
--- a/src/main/java/cz/cvut/kbss/termit/persistence/dao/GenericDao.java
+++ b/src/main/java/cz/cvut/kbss/termit/persistence/dao/GenericDao.java
@@ -55,10 +55,9 @@ public interface GenericDao {
* operations.
*
* @param id Identifier
- * @return {@code Optional} containing a reference to a matching instance or an empty {@code Optional }if no such
- * instance exists
+ * @return Reference to an entity with the specified identifier
*/
- Optional getReference(URI id);
+ T getReference(URI id);
/**
* Detaches the specified entity from the current persistence context.
diff --git a/src/main/java/cz/cvut/kbss/termit/persistence/dao/ResourceDao.java b/src/main/java/cz/cvut/kbss/termit/persistence/dao/ResourceDao.java
index 90717ade6..95ee66483 100644
--- a/src/main/java/cz/cvut/kbss/termit/persistence/dao/ResourceDao.java
+++ b/src/main/java/cz/cvut/kbss/termit/persistence/dao/ResourceDao.java
@@ -22,6 +22,7 @@
import cz.cvut.kbss.jopa.vocabulary.DC;
import cz.cvut.kbss.termit.asset.provenance.ModifiesData;
import cz.cvut.kbss.termit.asset.provenance.SupportsLastModification;
+import cz.cvut.kbss.termit.event.AssetUpdateEvent;
import cz.cvut.kbss.termit.event.RefreshLastModifiedEvent;
import cz.cvut.kbss.termit.exception.PersistenceException;
import cz.cvut.kbss.termit.model.resource.Document;
@@ -80,6 +81,7 @@ public void persist(Resource resource, cz.cvut.kbss.termit.model.Vocabulary voca
} catch (RuntimeException e) {
throw new PersistenceException(e);
}
+ refreshLastModified();
}
private Descriptor createDescriptor(Resource resource, URI vocabularyUri) {
@@ -98,26 +100,29 @@ private Descriptor createDescriptor(Resource resource, URI vocabularyUri) {
@ModifiesData
@Override
public Resource update(Resource entity) {
+ final Resource updated;
try {
final URI vocabularyId = resolveVocabularyId(entity);
if (vocabularyId != null) {
setDocumentOnFileIfNecessary(entity, vocabularyId);
// This evict is a bit overkill, but there are multiple relationships that would have to be evicted
em.getEntityManagerFactory().getCache().evict(vocabularyId);
- return em.merge(entity, createDescriptor(entity, vocabularyId));
+ updated = em.merge(entity, createDescriptor(entity, vocabularyId));
} else {
- return em.merge(entity);
+ updated = em.merge(entity);
}
} catch (RuntimeException e) {
throw new PersistenceException(e);
}
+ refreshLastModified();
+ eventPublisher.publishEvent(new AssetUpdateEvent(this, updated));
+ return updated;
}
private URI resolveVocabularyId(Resource resource) {
if (resource instanceof Document) {
return ((Document) resource).getVocabulary();
- } else if (resource instanceof File) {
- final File f = (File) resource;
+ } else if (resource instanceof File f) {
if (f.getDocument() != null) {
return f.getDocument().getVocabulary();
}
@@ -138,11 +143,11 @@ private void setDocumentOnFileIfNecessary(Resource file, URI vocabularyId) {
public List findAll() {
try {
return em.createNativeQuery("SELECT ?x WHERE {" +
- "?x a ?type ;" +
- "?hasLabel ?label ." +
- "FILTER NOT EXISTS { ?y ?hasFile ?x . } " +
- "FILTER NOT EXISTS { ?x a ?vocabulary . } " +
- "} ORDER BY LCASE(?label)", Resource.class)
+ "?x a ?type ;" +
+ "?hasLabel ?label ." +
+ "FILTER NOT EXISTS { ?y ?hasFile ?x . } " +
+ "FILTER NOT EXISTS { ?x a ?vocabulary . } " +
+ "} ORDER BY LCASE(?label)", Resource.class)
.setParameter("type", typeUri)
.setParameter("hasLabel", labelProperty())
.setParameter("hasFile", URI.create(Vocabulary.s_p_ma_soubor))
diff --git a/src/main/java/cz/cvut/kbss/termit/persistence/dao/TermDao.java b/src/main/java/cz/cvut/kbss/termit/persistence/dao/TermDao.java
index 3d12e1bed..07fae2fe1 100644
--- a/src/main/java/cz/cvut/kbss/termit/persistence/dao/TermDao.java
+++ b/src/main/java/cz/cvut/kbss/termit/persistence/dao/TermDao.java
@@ -24,7 +24,10 @@
import cz.cvut.kbss.termit.dto.Snapshot;
import cz.cvut.kbss.termit.dto.TermInfo;
import cz.cvut.kbss.termit.dto.listing.TermDto;
+import cz.cvut.kbss.termit.event.AssetPersistEvent;
+import cz.cvut.kbss.termit.event.AssetUpdateEvent;
import cz.cvut.kbss.termit.event.EvictCacheEvent;
+import cz.cvut.kbss.termit.event.VocabularyContentModified;
import cz.cvut.kbss.termit.exception.PersistenceException;
import cz.cvut.kbss.termit.model.AbstractTerm;
import cz.cvut.kbss.termit.model.Term;
@@ -170,6 +173,8 @@ public void persist(Term entity, Vocabulary vocabulary) {
entity.setVocabulary(null); // This is inferred
em.persist(entity, descriptorFactory.termDescriptor(vocabulary));
evictCachedSubTerms(Collections.emptySet(), entity.getParentTerms());
+ eventPublisher.publishEvent(new VocabularyContentModified(this, vocabulary.getUri()));
+ eventPublisher.publishEvent(new AssetPersistEvent(this, entity));
} catch (RuntimeException e) {
throw new PersistenceException(e);
}
@@ -185,8 +190,11 @@ public Term update(Term entity) {
evictPossiblyCachedReferences(entity);
final Term original = em.find(Term.class, entity.getUri(), descriptorFactory.termDescriptor(entity));
entity.setDefinitionSource(original.getDefinitionSource());
+ eventPublisher.publishEvent(new AssetUpdateEvent(this, entity));
evictCachedSubTerms(original.getParentTerms(), entity.getParentTerms());
- return em.merge(entity, descriptorFactory.termDescriptor(entity));
+ final Term result = em.merge(entity, descriptorFactory.termDescriptor(entity));
+ eventPublisher.publishEvent(new VocabularyContentModified(this, original.getVocabulary()));
+ return result;
} catch (RuntimeException e) {
throw new PersistenceException(e);
}
@@ -223,6 +231,8 @@ private void evictPossiblyCachedReferences(Term term) {
* @param state State to set
*/
public void setState(Term term, URI state) {
+ term.setState(state);
+ eventPublisher.publishEvent(new AssetUpdateEvent(this, term));
evictPossiblyCachedReferences(term);
em.createNativeQuery("DELETE {" +
"?t ?hasState ?oldState ." +
@@ -603,7 +613,6 @@ public List findAll(String searchString, Vocabulary vocabulary) {
public List findAll(String searchString) {
Objects.requireNonNull(searchString);
final TypedQuery query = em.createNativeQuery("SELECT DISTINCT ?term WHERE {" +
- "" +
"?term a ?type ; " +
" ?hasLabel ?label ; " +
"FILTER CONTAINS(LCASE(?label), LCASE(?searchString)) ." +
@@ -727,10 +736,12 @@ public List findAllUnused(Vocabulary vocabulary) {
.getResultList();
}
+ @ModifiesData
@Override
public void remove(Term entity) {
super.remove(entity);
evictCachedSubTerms(entity.getParentTerms(), Collections.emptySet());
+ eventPublisher.publishEvent(new VocabularyContentModified(this, entity.getVocabulary()));
}
@Override
@@ -751,7 +762,6 @@ public Optional findVersionValidAt(Term asset, Instant at) {
@EventListener
public void onEvictCache(EvictCacheEvent evt) {
-
subTermsCache.evictAll();
}
}
diff --git a/src/main/java/cz/cvut/kbss/termit/persistence/dao/TermOccurrenceDao.java b/src/main/java/cz/cvut/kbss/termit/persistence/dao/TermOccurrenceDao.java
index e3529e477..373991a1e 100644
--- a/src/main/java/cz/cvut/kbss/termit/persistence/dao/TermOccurrenceDao.java
+++ b/src/main/java/cz/cvut/kbss/termit/persistence/dao/TermOccurrenceDao.java
@@ -23,6 +23,7 @@
import cz.cvut.kbss.jopa.model.query.Query;
import cz.cvut.kbss.jopa.vocabulary.DC;
import cz.cvut.kbss.jopa.vocabulary.RDFS;
+import cz.cvut.kbss.jopa.vocabulary.SKOS;
import cz.cvut.kbss.termit.dto.assignment.TermOccurrences;
import cz.cvut.kbss.termit.exception.PersistenceException;
import cz.cvut.kbss.termit.model.Asset;
@@ -184,7 +185,7 @@ public List getOccurrenceInfo(Term term) {
.setParameter("isDocumentOf", URI.create(Vocabulary.s_p_ma_soubor))
.setParameter("fileType", URI.create(Vocabulary.s_c_soubor))
.setParameter("lang", config.getLanguage())
- .setParameter("termType", URI.create(Vocabulary.s_c_term))
+ .setParameter("termType", URI.create(SKOS.CONCEPT))
.setParameter("termDefOcc", URI.create(Vocabulary.s_c_definicni_vyskyt_termu))
.setParameter("fileOcc", URI.create(Vocabulary.s_c_souborovy_vyskyt_termu))
.setParameter("t", term.getUri()).getResultList();
diff --git a/src/main/java/cz/cvut/kbss/termit/persistence/dao/VocabularyDao.java b/src/main/java/cz/cvut/kbss/termit/persistence/dao/VocabularyDao.java
index d3e05dd12..535293e90 100644
--- a/src/main/java/cz/cvut/kbss/termit/persistence/dao/VocabularyDao.java
+++ b/src/main/java/cz/cvut/kbss/termit/persistence/dao/VocabularyDao.java
@@ -26,6 +26,8 @@
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.event.AssetPersistEvent;
+import cz.cvut.kbss.termit.event.AssetUpdateEvent;
import cz.cvut.kbss.termit.event.RefreshLastModifiedEvent;
import cz.cvut.kbss.termit.exception.PersistenceException;
import cz.cvut.kbss.termit.model.Glossary;
@@ -116,10 +118,10 @@ public Optional find(URI id) {
}
@Override
- public Optional getReference(URI id) {
+ public Vocabulary getReference(URI id) {
Objects.requireNonNull(id);
try {
- return Optional.ofNullable(em.getReference(type, id, descriptorFactory.vocabularyDescriptor(id)));
+ return em.getReference(type, id, descriptorFactory.vocabularyDescriptor(id));
} catch (RuntimeException e) {
throw new PersistenceException(e);
}
@@ -165,12 +167,15 @@ public List getImportingVocabularies(Vocabulary vocabulary) {
@ModifiesData
@Override
- public Vocabulary update(Vocabulary entity) {
+ public void persist(Vocabulary entity) {
Objects.requireNonNull(entity);
try {
- // Evict possibly cached instance loaded from default context
- em.getEntityManagerFactory().getCache().evict(Vocabulary.class, entity.getUri(), null);
- return em.merge(entity, descriptorFactory.vocabularyDescriptor(entity));
+ em.persist(entity, descriptorFactory.vocabularyDescriptor(entity));
+ if (entity.getDocument() != null && em.find(Document.class, entity.getDocument().getUri()) == null) {
+ em.persist(entity.getDocument(), descriptorFactory.documentDescriptor(entity));
+ }
+ refreshLastModified();
+ eventPublisher.publishEvent(new AssetPersistEvent(this, entity));
} catch (RuntimeException e) {
throw new PersistenceException(e);
}
@@ -178,13 +183,15 @@ public Vocabulary update(Vocabulary entity) {
@ModifiesData
@Override
- public void persist(Vocabulary entity) {
+ public Vocabulary update(Vocabulary entity) {
Objects.requireNonNull(entity);
try {
- em.persist(entity, descriptorFactory.vocabularyDescriptor(entity));
- if (entity.getDocument() != null && em.find(Document.class, entity.getDocument().getUri()) == null) {
- em.persist(entity.getDocument(), descriptorFactory.documentDescriptor(entity));
- }
+ eventPublisher.publishEvent(new AssetUpdateEvent(this, entity));
+ // Evict possibly cached instance loaded from default context
+ em.getEntityManagerFactory().getCache().evict(Vocabulary.class, entity.getUri(), null);
+ final Vocabulary result = em.merge(entity, descriptorFactory.vocabularyDescriptor(entity));
+ refreshLastModified();
+ return result;
} catch (RuntimeException e) {
throw new PersistenceException(e);
}
@@ -195,7 +202,10 @@ public void persist(Vocabulary entity) {
public void remove(Vocabulary entity) {
Objects.requireNonNull(entity);
try {
- find(entity.getUri()).ifPresent(em::remove);
+ find(entity.getUri()).ifPresent(elem -> {
+ em.remove(elem);
+ refreshLastModified();
+ });
} catch (RuntimeException e) {
throw new PersistenceException(e);
}
@@ -238,7 +248,9 @@ public void forceRemove(Vocabulary entity) {
*/
public Glossary updateGlossary(Vocabulary entity) {
Objects.requireNonNull(entity);
- return em.merge(entity.getGlossary(), descriptorFactory.glossaryDescriptor(entity));
+ final Glossary result = em.merge(entity.getGlossary(), descriptorFactory.glossaryDescriptor(entity));
+ refreshLastModified();
+ return result;
}
/**
@@ -408,15 +420,16 @@ public Set getRelatedVocabularies(Vocabulary rootVocabulary, Collection toAdd = new HashSet<>(em.createNativeQuery("SELECT DISTINCT ?v WHERE {\n" +
- " ?t a ?term ;\n" +
- " ?inVocabulary ?vocabulary ;\n" +
- " ?y ?z .\n" +
- " ?z a ?term ;\n" +
- " ?inVocabulary ?v .\n" +
- " FILTER (?v != ?vocabulary)\n" +
- " FILTER (?y IN (?cascadingRelationships))\n" +
- "}", URI.class)
+ final Set toAdd = new HashSet<>(em.createNativeQuery("""
+ SELECT DISTINCT ?v WHERE {
+ ?t a ?term ;
+ ?inVocabulary ?vocabulary ;
+ ?y ?z .
+ ?z a ?term ;
+ ?inVocabulary ?v .
+ FILTER (?v != ?vocabulary)
+ FILTER (?y IN (?cascadingRelationships))
+ }""", URI.class)
.setParameter("term", URI.create(SKOS.CONCEPT))
.setParameter("inVocabulary",
URI.create(
@@ -456,7 +469,7 @@ public PrefixDeclaration resolvePrefix(URI vocabularyUri) {
.setParameter("hasNamespace", URI.create(
cz.cvut.kbss.termit.util.Vocabulary.s_p_preferredNamespaceUri))
.getResultList();
- if (result.size() == 0) {
+ if (result.isEmpty()) {
return PrefixDeclaration.EMPTY_PREFIX;
}
assert result.get(0) instanceof Object[];
diff --git a/src/main/java/cz/cvut/kbss/termit/persistence/snapshot/CascadingVocabularySnapshotRemover.java b/src/main/java/cz/cvut/kbss/termit/persistence/snapshot/CascadingVocabularySnapshotRemover.java
index c192609a8..28536ecba 100644
--- a/src/main/java/cz/cvut/kbss/termit/persistence/snapshot/CascadingVocabularySnapshotRemover.java
+++ b/src/main/java/cz/cvut/kbss/termit/persistence/snapshot/CascadingVocabularySnapshotRemover.java
@@ -19,7 +19,6 @@
import cz.cvut.kbss.jopa.model.EntityManager;
import cz.cvut.kbss.termit.dto.Snapshot;
-import cz.cvut.kbss.termit.exception.NotFoundException;
import cz.cvut.kbss.termit.exception.UnsupportedAssetOperationException;
import cz.cvut.kbss.termit.exception.UnsupportedOperationException;
import cz.cvut.kbss.termit.model.Vocabulary;
@@ -48,8 +47,7 @@ public CascadingVocabularySnapshotRemover(VocabularyDao vocabularyDao, EntityMan
public void removeSnapshot(Snapshot snapshot) {
Objects.requireNonNull(snapshot);
ensureAssetType(snapshot);
- final Vocabulary toRemove = vocabularyDao.getReference(snapshot.getUri()).orElseThrow(
- () -> NotFoundException.create(Vocabulary.class, snapshot.getUri()));
+ final Vocabulary toRemove = vocabularyDao.getReference(snapshot.getUri());
if (!toRemove.isSnapshot()) {
throw new UnsupportedOperationException("Vocabulary " + toRemove + " is not a snapshot.");
}
diff --git a/src/main/java/cz/cvut/kbss/termit/rest/OidcUserController.java b/src/main/java/cz/cvut/kbss/termit/rest/OidcUserController.java
index cf26c8c56..2a5931b02 100644
--- a/src/main/java/cz/cvut/kbss/termit/rest/OidcUserController.java
+++ b/src/main/java/cz/cvut/kbss/termit/rest/OidcUserController.java
@@ -47,7 +47,7 @@
/**
* Controller for basic user-related operations that do not involve editing/adding/removing user accounts.
- *
+ *
* Enabled when OIDC security is used.
*/
@ConditionalOnProperty(prefix = "termit.security", name = "provider", havingValue = "oidc")
@@ -76,7 +76,8 @@ public List getAll() {
@Operation(security = {@SecurityRequirement(name = "bearer-key")},
description = "Gets the currently logged-in user.")
@ApiResponse(responseCode = "200", description = "Metadata of the current user's account.")
- @GetMapping(value = UserController.CURRENT_USER_PATH, produces = {MediaType.APPLICATION_JSON_VALUE, JsonLd.MEDIA_TYPE})
+ @GetMapping(value = UserController.CURRENT_USER_PATH,
+ produces = {MediaType.APPLICATION_JSON_VALUE, JsonLd.MEDIA_TYPE})
public UserAccount getCurrent() {
return userService.getCurrent();
}
@@ -89,14 +90,15 @@ public UserAccount getCurrent() {
})
@GetMapping(value = "/{localName}/managed-assets", produces = {MediaType.APPLICATION_JSON_VALUE, JsonLd.MEDIA_TYPE})
@PreAuthorize("hasRole('" + SecurityConstants.ROLE_ADMIN + "')")
- public List getManagedAssets(@Parameter(description = UserController.UserControllerDoc.ID_LOCAL_NAME_DESCRIPTION,
- example = UserController.UserControllerDoc.ID_LOCAL_NAME_EXAMPLE)
- @PathVariable String localName,
- @Parameter(description = UserController.UserControllerDoc.ID_NAMESPACE_DESCRIPTION,
- example = UserController.UserControllerDoc.ID_NAMESPACE_EXAMPLE)
- @RequestParam(name = Constants.QueryParams.NAMESPACE,
- required = false) Optional namespace) {
+ public List getManagedAssets(
+ @Parameter(description = UserController.UserControllerDoc.ID_LOCAL_NAME_DESCRIPTION,
+ example = UserController.UserControllerDoc.ID_LOCAL_NAME_EXAMPLE)
+ @PathVariable String localName,
+ @Parameter(description = UserController.UserControllerDoc.ID_NAMESPACE_DESCRIPTION,
+ example = UserController.UserControllerDoc.ID_NAMESPACE_EXAMPLE)
+ @RequestParam(name = Constants.QueryParams.NAMESPACE,
+ required = false) Optional namespace) {
final URI id = idResolver.resolveIdentifier(namespace.orElse(config.getNamespace().getUser()), localName);
- return userService.getManagedAssets(userService.getRequiredReference(id));
+ return userService.getManagedAssets(userService.getReference(id));
}
}
diff --git a/src/main/java/cz/cvut/kbss/termit/rest/ResourceController.java b/src/main/java/cz/cvut/kbss/termit/rest/ResourceController.java
index ef3c155c2..f389a328a 100644
--- a/src/main/java/cz/cvut/kbss/termit/rest/ResourceController.java
+++ b/src/main/java/cz/cvut/kbss/termit/rest/ResourceController.java
@@ -235,7 +235,7 @@ public List getFiles(@Parameter(description = ResourceControllerDoc.ID_LOC
@RequestParam(name = QueryParams.NAMESPACE,
required = false) Optional namespace) {
final URI identifier = resolveIdentifier(namespace.orElse(config.getNamespace().getResource()), localName);
- return resourceService.getFiles(resourceService.getRequiredReference(identifier));
+ return resourceService.getFiles(resourceService.getReference(identifier));
}
private String resourceNamespace(Optional namespace) {
@@ -359,7 +359,7 @@ public List getHistory(
@RequestParam(name = QueryParams.NAMESPACE,
required = false) Optional namespace) {
final Resource resource = resourceService
- .getRequiredReference(resolveIdentifier(resourceNamespace(namespace), localName));
+ .getReference(resolveIdentifier(resourceNamespace(namespace), localName));
return resourceService.getChanges(resource);
}
diff --git a/src/main/java/cz/cvut/kbss/termit/rest/TermController.java b/src/main/java/cz/cvut/kbss/termit/rest/TermController.java
index 834b69d36..beec58274 100644
--- a/src/main/java/cz/cvut/kbss/termit/rest/TermController.java
+++ b/src/main/java/cz/cvut/kbss/termit/rest/TermController.java
@@ -220,7 +220,7 @@ public ResponseEntity checkTerms(
@Parameter(description = "Language of the label.")
@RequestParam(name = "language", required = false) String language) {
final URI vocabularyUri = getVocabularyUri(namespace, localName);
- final Vocabulary vocabulary = termService.getRequiredVocabularyReference(vocabularyUri);
+ final Vocabulary vocabulary = termService.getVocabularyReference(vocabularyUri);
if (prefLabel != null) {
final boolean exists = termService.existsInVocabulary(prefLabel, vocabulary, language);
return new ResponseEntity<>(exists ? HttpStatus.OK : HttpStatus.NOT_FOUND);
diff --git a/src/main/java/cz/cvut/kbss/termit/rest/UserController.java b/src/main/java/cz/cvut/kbss/termit/rest/UserController.java
index f36881c0e..4f713eba8 100644
--- a/src/main/java/cz/cvut/kbss/termit/rest/UserController.java
+++ b/src/main/java/cz/cvut/kbss/termit/rest/UserController.java
@@ -220,7 +220,7 @@ public List getManagedAssets(@Parameter(description = UserControll
@RequestParam(name = Constants.QueryParams.NAMESPACE,
required = false) Optional namespace) {
final URI id = idResolver.resolveIdentifier(namespace.orElse(config.getNamespace().getUser()), localName);
- return userService.getManagedAssets(userService.getRequiredReference(id));
+ return userService.getManagedAssets(userService.getReference(id));
}
/**
diff --git a/src/main/java/cz/cvut/kbss/termit/rest/UserGroupController.java b/src/main/java/cz/cvut/kbss/termit/rest/UserGroupController.java
index fe27aeb7a..fa5df36c8 100644
--- a/src/main/java/cz/cvut/kbss/termit/rest/UserGroupController.java
+++ b/src/main/java/cz/cvut/kbss/termit/rest/UserGroupController.java
@@ -109,7 +109,7 @@ public void remove(@Parameter(description = UserGroupControllerDoc.ID_LOCAL_NAME
example = UserGroupControllerDoc.ID_LOCAL_NAME_EXAMPLE)
@PathVariable String fragment) {
final URI uri = resolveIdentifier(UserGroup.NAMESPACE, fragment);
- final UserGroup toRemove = groupService.getRequiredReference(uri);
+ final UserGroup toRemove = groupService.getReference(uri);
groupService.remove(toRemove);
LOG.debug("Group {} removed.", toRemove);
}
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 eeecfee63..c4286bcbc 100644
--- a/src/main/java/cz/cvut/kbss/termit/rest/VocabularyController.java
+++ b/src/main/java/cz/cvut/kbss/termit/rest/VocabularyController.java
@@ -47,7 +47,16 @@
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.server.ResponseStatusException;
@@ -60,9 +69,9 @@
/**
* Vocabulary management REST API.
- *
- * Note that most endpoints are now secured only by requiring the user to be authenticated, authorization is done
- * on service level based on ACL.
+ *
+ * Note that most endpoints are now secured only by requiring the user to be authenticated, authorization is done on
+ * service level based on ACL.
*/
@Tag(name = "Vocabularies", description = "Vocabulary management API")
@RestController
@@ -139,7 +148,7 @@ public Collection getImports(@Parameter(description = ApiDoc.ID_LOCAL_NAME_
example = ApiDoc.ID_NAMESPACE_EXAMPLE)
@RequestParam(name = QueryParams.NAMESPACE,
required = false) Optional namespace) {
- final Vocabulary vocabulary = vocabularyService.getRequiredReference(
+ final Vocabulary vocabulary = vocabularyService.getReference(
resolveVocabularyUri(localName, namespace));
return vocabularyService.getTransitivelyImportedVocabularies(vocabulary);
}
@@ -158,7 +167,7 @@ public Collection getRelated(@Parameter(description = ApiDoc.ID_LOCAL_NAME_
example = ApiDoc.ID_NAMESPACE_EXAMPLE)
@RequestParam(name = QueryParams.NAMESPACE,
required = false) Optional namespace) {
- final Vocabulary vocabulary = vocabularyService.getRequiredReference(
+ final Vocabulary vocabulary = vocabularyService.getReference(
resolveVocabularyUri(localName, namespace));
return vocabularyService.getRelatedVocabularies(vocabulary);
}
@@ -232,7 +241,7 @@ public List getHistory(
example = ApiDoc.ID_NAMESPACE_EXAMPLE)
@RequestParam(name = QueryParams.NAMESPACE,
required = false) Optional namespace) {
- final Vocabulary vocabulary = vocabularyService.getRequiredReference(
+ final Vocabulary vocabulary = vocabularyService.getReference(
resolveVocabularyUri(localName, namespace));
return vocabularyService.getChanges(vocabulary);
}
@@ -253,7 +262,7 @@ public List getHistoryOfContent(
example = ApiDoc.ID_NAMESPACE_EXAMPLE)
@RequestParam(name = QueryParams.NAMESPACE,
required = false) Optional namespace) {
- final Vocabulary vocabulary = vocabularyService.getRequiredReference(
+ final Vocabulary vocabulary = vocabularyService.getReference(
resolveVocabularyUri(localName, namespace));
return vocabularyService.getChangesOfContent(vocabulary);
}
@@ -342,7 +351,7 @@ public void removeVocabulary(@Parameter(description = ApiDoc.ID_LOCAL_NAME_DESCR
@RequestParam(name = QueryParams.NAMESPACE,
required = false) Optional namespace) {
final URI identifier = resolveIdentifier(namespace.orElse(config.getNamespace().getVocabulary()), localName);
- final Vocabulary toRemove = vocabularyService.getRequiredReference(identifier);
+ final Vocabulary toRemove = vocabularyService.getReference(identifier);
vocabularyService.remove(toRemove);
LOG.debug("Vocabulary {} removed.", toRemove);
}
@@ -364,7 +373,7 @@ public List validateVocabulary(
@RequestParam(name = QueryParams.NAMESPACE,
required = false) Optional namespace) {
final URI identifier = resolveIdentifier(namespace.orElse(config.getNamespace().getVocabulary()), localName);
- final Vocabulary vocabulary = vocabularyService.getRequiredReference(identifier);
+ final Vocabulary vocabulary = vocabularyService.getReference(identifier);
return vocabularyService.validateContents(vocabulary);
}
@@ -385,7 +394,7 @@ public ResponseEntity createSnapshot(
@RequestParam(name = QueryParams.NAMESPACE,
required = false) Optional namespace) {
final URI identifier = resolveIdentifier(namespace.orElse(config.getNamespace().getVocabulary()), localName);
- final Vocabulary vocabulary = vocabularyService.getRequiredReference(identifier);
+ final Vocabulary vocabulary = vocabularyService.getReference(identifier);
final Snapshot snapshot = vocabularyService.createSnapshot(vocabulary);
LOG.debug("Created snapshot of vocabulary {}.", vocabulary);
return ResponseEntity.created(
@@ -413,7 +422,7 @@ public ResponseEntity> getSnapshots(@Parameter(description = ApiDoc.ID_LOCAL_N
example = ApiDocConstants.DATETIME_EXAMPLE)
@RequestParam(name = "at", required = false) Optional at) {
final URI identifier = resolveIdentifier(namespace.orElse(config.getNamespace().getVocabulary()), localName);
- final Vocabulary vocabulary = vocabularyService.getRequiredReference(identifier);
+ final Vocabulary vocabulary = vocabularyService.getReference(identifier);
if (at.isPresent()) {
final Instant instant = RestUtils.parseTimestamp(at.get());
return ResponseEntity.ok(vocabularyService.findVersionValidAt(vocabulary, instant));
@@ -437,7 +446,7 @@ public AccessControlListDto getAccessControlList(
@RequestParam(name = QueryParams.NAMESPACE,
required = false) Optional namespace) {
final URI identifier = resolveIdentifier(namespace.orElse(config.getNamespace().getVocabulary()), localName);
- final Vocabulary vocabulary = vocabularyService.getRequiredReference(identifier);
+ final Vocabulary vocabulary = vocabularyService.getReference(identifier);
return vocabularyService.getAccessControlList(vocabulary);
}
@@ -459,7 +468,7 @@ public void addAccessControlRecord(@Parameter(description = ApiDoc.ID_LOCAL_NAME
@Parameter(description = "Access control record to add.")
@RequestBody AccessControlRecord> record) {
final URI identifier = resolveIdentifier(namespace.orElse(config.getNamespace().getVocabulary()), localName);
- final Vocabulary vocabulary = vocabularyService.getRequiredReference(identifier);
+ final Vocabulary vocabulary = vocabularyService.getReference(identifier);
vocabularyService.addAccessControlRecords(vocabulary, record);
LOG.debug("Added access control record to ACL of vocabulary {}.", vocabulary);
}
@@ -482,7 +491,7 @@ public void removeAccessControlRecord(@Parameter(description = ApiDoc.ID_LOCAL_N
@Parameter(description = "Access control record to remove.")
@RequestBody AccessControlRecord> record) {
final URI identifier = resolveIdentifier(namespace.orElse(config.getNamespace().getVocabulary()), localName);
- final Vocabulary vocabulary = vocabularyService.getRequiredReference(identifier);
+ final Vocabulary vocabulary = vocabularyService.getReference(identifier);
vocabularyService.removeAccessControlRecord(vocabulary, record);
LOG.debug("Removed access control record from ACL of vocabulary {}.", vocabulary);
}
@@ -512,7 +521,7 @@ public void updateAccessControlLevel(@Parameter(description = ApiDoc.ID_LOCAL_NA
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Change record identifier does not match URL.");
}
final URI identifier = resolveIdentifier(namespace.orElse(config.getNamespace().getVocabulary()), localName);
- final Vocabulary vocabulary = vocabularyService.getRequiredReference(identifier);
+ final Vocabulary vocabulary = vocabularyService.getReference(identifier);
vocabularyService.updateAccessControlLevel(vocabulary, record);
LOG.debug("Updated access control record {} from ACL of vocabulary {}.", record, vocabulary);
}
@@ -532,7 +541,7 @@ public AccessLevel getAccessLevel(@Parameter(description = ApiDoc.ID_LOCAL_NAME_
@RequestParam(name = QueryParams.NAMESPACE,
required = false) Optional namespace) {
final URI identifier = resolveIdentifier(namespace.orElse(config.getNamespace().getVocabulary()), localName);
- final Vocabulary vocabulary = vocabularyService.getRequiredReference(identifier);
+ final Vocabulary vocabulary = vocabularyService.getReference(identifier);
return vocabularyService.getAccessLevel(vocabulary);
}
diff --git a/src/main/java/cz/cvut/kbss/termit/rest/handler/RestExceptionHandler.java b/src/main/java/cz/cvut/kbss/termit/rest/handler/RestExceptionHandler.java
index b28baa022..5f26432bb 100644
--- a/src/main/java/cz/cvut/kbss/termit/rest/handler/RestExceptionHandler.java
+++ b/src/main/java/cz/cvut/kbss/termit/rest/handler/RestExceptionHandler.java
@@ -17,6 +17,7 @@
*/
package cz.cvut.kbss.termit.rest.handler;
+import cz.cvut.kbss.jopa.exceptions.EntityNotFoundException;
import cz.cvut.kbss.jopa.exceptions.OWLPersistenceException;
import cz.cvut.kbss.jsonld.exception.JsonLdException;
import cz.cvut.kbss.termit.exception.AnnotationGenerationException;
@@ -112,6 +113,11 @@ public ResponseEntity usernameNotFound(HttpServletRequest request, Us
return new ResponseEntity<>(errorInfo(request, e), HttpStatus.NOT_FOUND);
}
+ @ExceptionHandler(EntityNotFoundException.class)
+ public ResponseEntity entityNotFoundException(HttpServletRequest request, EntityNotFoundException e) {
+ logException(e, request);
+ return new ResponseEntity<>(errorInfo(request, e), HttpStatus.NOT_FOUND);
+ }
@ExceptionHandler(AuthorizationException.class)
public ResponseEntity authorizationException(HttpServletRequest request, AuthorizationException e) {
diff --git a/src/main/java/cz/cvut/kbss/termit/rest/readonly/ReadOnlyTermController.java b/src/main/java/cz/cvut/kbss/termit/rest/readonly/ReadOnlyTermController.java
index 56c37fc7e..75c0cfe9b 100644
--- a/src/main/java/cz/cvut/kbss/termit/rest/readonly/ReadOnlyTermController.java
+++ b/src/main/java/cz/cvut/kbss/termit/rest/readonly/ReadOnlyTermController.java
@@ -232,7 +232,7 @@ public List getComments(
@Parameter(description = "Datetime (ISO-formatted) of the latest comment to retrieve. Defaults to now.")
@RequestParam(name = "to", required = false) Optional to) {
final URI termUri = getTermUri(localName, termLocalName, namespace);
- return termService.getComments(termService.getRequiredReference(termUri),
+ return termService.getComments(termService.getReference(termUri),
from.map(RestUtils::parseTimestamp).orElse(Constants.EPOCH_TIMESTAMP),
to.map(RestUtils::parseTimestamp).orElse(Utils.timestamp()));
}
@@ -257,7 +257,7 @@ public List getDefinitionallyRelatedTermsOf(
example = TermController.ApiDoc.ID_NAMESPACE_EXAMPLE)
@RequestParam(name = Constants.QueryParams.NAMESPACE, required = false) Optional namespace) {
final URI termUri = getTermUri(localName, termLocalName, namespace);
- return termService.getDefinitionallyRelatedOf(termService.getRequiredReference(termUri));
+ return termService.getDefinitionallyRelatedOf(termService.getReference(termUri));
}
@Operation(
@@ -280,7 +280,7 @@ public List getDefinitionallyRelatedTermsTargeting(
example = TermController.ApiDoc.ID_NAMESPACE_EXAMPLE)
@RequestParam(name = Constants.QueryParams.NAMESPACE, required = false) Optional namespace) {
final URI termUri = getTermUri(localName, termLocalName, namespace);
- return termService.getDefinitionallyRelatedTargeting(termService.getRequiredReference(termUri));
+ return termService.getDefinitionallyRelatedTargeting(termService.getReference(termUri));
}
@Operation(description = "Gets a list of comments on the term with the specified identifier.")
@@ -304,7 +304,7 @@ public List getComments(
example = ApiDocConstants.DATETIME_EXAMPLE)
@RequestParam(name = "to", required = false) Optional to) {
final URI termUri = idResolver.resolveIdentifier(namespace, localName);
- return termService.getComments(termService.getRequiredReference(termUri),
+ return termService.getComments(termService.getReference(termUri),
from.map(RestUtils::parseTimestamp).orElse(Constants.EPOCH_TIMESTAMP),
to.map(RestUtils::parseTimestamp).orElse(Utils.timestamp()));
}
diff --git a/src/main/java/cz/cvut/kbss/termit/service/IdentifierResolver.java b/src/main/java/cz/cvut/kbss/termit/service/IdentifierResolver.java
index ff402eb06..1adb75184 100644
--- a/src/main/java/cz/cvut/kbss/termit/service/IdentifierResolver.java
+++ b/src/main/java/cz/cvut/kbss/termit/service/IdentifierResolver.java
@@ -98,7 +98,7 @@ public static String normalize(String value) {
return value.toLowerCase()
.trim()
.replaceAll("[\\s/\\\\]", Character.toString(REPLACEMENT_CHARACTER))
- .replaceAll("[(?&$#),]", "");
+ .replaceAll("[(?&$#§),]", "");
}
/**
diff --git a/src/main/java/cz/cvut/kbss/termit/service/business/AccessControlListService.java b/src/main/java/cz/cvut/kbss/termit/service/business/AccessControlListService.java
index 54073421a..783b54a33 100644
--- a/src/main/java/cz/cvut/kbss/termit/service/business/AccessControlListService.java
+++ b/src/main/java/cz/cvut/kbss/termit/service/business/AccessControlListService.java
@@ -52,7 +52,7 @@ public interface AccessControlListService {
* @return Reference to a matching ACL
* @throws cz.cvut.kbss.termit.exception.NotFoundException If no matching ACL exists
*/
- AccessControlList getRequiredReference(URI id);
+ AccessControlList getReference(URI id);
/**
* Finds an {@link AccessControlList} guarding access to the specified subject.
diff --git a/src/main/java/cz/cvut/kbss/termit/service/business/ResourceService.java b/src/main/java/cz/cvut/kbss/termit/service/business/ResourceService.java
index 1a11ba6d7..824892e4c 100644
--- a/src/main/java/cz/cvut/kbss/termit/service/business/ResourceService.java
+++ b/src/main/java/cz/cvut/kbss/termit/service/business/ResourceService.java
@@ -108,7 +108,7 @@ public void remove(Resource toRemove) {
throw new AssetRemovalException("Cannot remove non-empty document " + toRemove.getLabel() + "!");
}
// We need the reference managed, so that its name is available to document manager
- final Resource actualToRemove = getRequiredReference(toRemove.getUri());
+ final Resource actualToRemove = getReference(toRemove.getUri());
documentManager.remove(actualToRemove);
repositoryService.remove(actualToRemove);
}
@@ -224,12 +224,12 @@ public void addFileToDocument(Resource document, File file) {
}
doc.addFile(file);
if (doc.getVocabulary() != null) {
- final Vocabulary vocabulary = vocabularyService.getRequiredReference(doc.getVocabulary());
+ final Vocabulary vocabulary = vocabularyService.getReference(doc.getVocabulary());
repositoryService.persist(file, vocabulary);
} else {
repositoryService.persist(file);
}
- if (getReference(document.getUri()).isEmpty()) {
+ if (!repositoryService.exists(document.getUri())) {
repositoryService.persist(document);
} else {
update(doc);
@@ -251,7 +251,7 @@ public void removeFile(File file) {
throw new InvalidParameterException("File was not attached to a document.");
} else {
doc.removeFile(file);
- if (repositoryService.getReference(doc.getUri()).isPresent()) {
+ if (repositoryService.find(doc.getUri()).isPresent()) {
update(doc);
}
}
@@ -292,7 +292,7 @@ public void runTextAnalysis(Resource resource, Set vocabularies) {
private Set includeImportedVocabularies(Set providedVocabularies) {
final Set result = new HashSet<>(providedVocabularies);
providedVocabularies.forEach(uri -> {
- final Vocabulary ref = vocabularyService.getRequiredReference(uri);
+ final Vocabulary ref = vocabularyService.getReference(uri);
result.addAll(vocabularyService.getTransitivelyImportedVocabularies(ref));
});
return result;
@@ -314,14 +314,10 @@ public Resource findRequired(URI id) {
return repositoryService.findRequired(id);
}
- public Optional getReference(URI id) {
+ public Resource getReference(URI id) {
return repositoryService.getReference(id);
}
- public Resource getRequiredReference(URI id) {
- return repositoryService.getRequiredReference(id);
- }
-
@Transactional
@PreAuthorize("@resourceAuthorizationService.canModify(#instance)")
public Resource update(Resource instance) {
diff --git a/src/main/java/cz/cvut/kbss/termit/service/business/RudService.java b/src/main/java/cz/cvut/kbss/termit/service/business/RudService.java
index 7af6661e5..ecbb4e1eb 100644
--- a/src/main/java/cz/cvut/kbss/termit/service/business/RudService.java
+++ b/src/main/java/cz/cvut/kbss/termit/service/business/RudService.java
@@ -50,16 +50,7 @@ public interface RudService {
* @param id Item identifier
* @return Matching item reference wrapped in an {@code Optional}
*/
- Optional getReference(URI id);
-
- /**
- * Gets a reference to an item with the specified identifier (with empty attribute values).
- *
- * @param id Item identifier
- * @return Matching item reference
- * @throws cz.cvut.kbss.termit.exception.NotFoundException When no matching item is found
- */
- T getRequiredReference(URI id);
+ T getReference(URI id);
/**
* Updates the specified item.
diff --git a/src/main/java/cz/cvut/kbss/termit/service/business/TermOccurrenceService.java b/src/main/java/cz/cvut/kbss/termit/service/business/TermOccurrenceService.java
index f391608ea..5f40caace 100644
--- a/src/main/java/cz/cvut/kbss/termit/service/business/TermOccurrenceService.java
+++ b/src/main/java/cz/cvut/kbss/termit/service/business/TermOccurrenceService.java
@@ -26,17 +26,6 @@
*/
public interface TermOccurrenceService {
- /**
- * Gets a reference to a {@link TermOccurrence} with the specified identifier.
- *
- * The returned instance may be empty apart from its identifier.
- *
- * @param id Term occurrence identifier
- * @return Matching term occurrence
- * @throws cz.cvut.kbss.termit.exception.NotFoundException If there is no such term occurrence
- */
- TermOccurrence getRequiredReference(URI id);
-
/**
* Persists the specified term occurrence.
*
diff --git a/src/main/java/cz/cvut/kbss/termit/service/business/TermService.java b/src/main/java/cz/cvut/kbss/termit/service/business/TermService.java
index 073bf0e78..1a0fa5542 100644
--- a/src/main/java/cz/cvut/kbss/termit/service/business/TermService.java
+++ b/src/main/java/cz/cvut/kbss/termit/service/business/TermService.java
@@ -263,8 +263,8 @@ public Vocabulary findVocabularyRequired(URI id) {
* @throws NotFoundException When vocabulary with the specified identifier does not exist
*/
@PostAuthorize("@vocabularyAuthorizationService.canRead(returnObject)")
- public Vocabulary getRequiredVocabularyReference(URI id) {
- return vocabularyService.getRequiredReference(id);
+ public Vocabulary getVocabularyReference(URI id) {
+ return vocabularyService.getReference(id);
}
/**
@@ -303,30 +303,16 @@ public Term findRequired(URI id) {
/**
* Gets a reference to a Term with the specified identifier.
*
- * Note that this method is not protected by ACL-based authorization and should thus not be used in without some
+ * Note that this method is not protected by ACL-based authorization and should thus not be used without some
* other type of authorization.
*
* @param id Term identifier
* @return Matching Term reference wrapped in an {@code Optional}
*/
- public Optional getReference(URI id) {
+ public Term getReference(URI id) {
return repositoryService.getReference(id);
}
- /**
- * Gets a reference to a Term with the specified identifier.
- *
- * Note that this method is not protected by ACL-based authorization and should thus not be used in without some
- * other type of authorization.
- *
- * @param id Term identifier
- * @return Matching term reference
- * @throws NotFoundException When no matching term is found
- */
- public Term getRequiredReference(URI id) {
- return repositoryService.getRequiredReference(id);
- }
-
/**
* Gets child terms of the specified parent term.
*
@@ -400,7 +386,7 @@ public void persistChild(Term child, Term parent) {
languageService.getInitialTermState().ifPresent(is -> child.setState(is.getUri()));
repositoryService.addChildTerm(child, parent);
analyzeTermDefinition(child, parent.getVocabulary());
- vocabularyService.runTextAnalysisOnAllTerms(getRequiredVocabularyReference(parent.getVocabulary()));
+ vocabularyService.runTextAnalysisOnAllTerms(getVocabularyReference(parent.getVocabulary()));
}
/**
@@ -421,7 +407,7 @@ public Term update(Term term) {
analyzeTermDefinition(term, original.getVocabulary());
}
if (!Objects.equals(original.getLabel(), term.getLabel())) {
- vocabularyService.runTextAnalysisOnAllTerms(getRequiredVocabularyReference(original.getVocabulary()));
+ vocabularyService.runTextAnalysisOnAllTerms(getVocabularyReference(original.getVocabulary()));
}
return result;
}
diff --git a/src/main/java/cz/cvut/kbss/termit/service/business/UserService.java b/src/main/java/cz/cvut/kbss/termit/service/business/UserService.java
index 1d1808e4e..b947cfb2e 100644
--- a/src/main/java/cz/cvut/kbss/termit/service/business/UserService.java
+++ b/src/main/java/cz/cvut/kbss/termit/service/business/UserService.java
@@ -32,6 +32,7 @@
import cz.cvut.kbss.termit.service.security.SecurityUtils;
import cz.cvut.kbss.termit.util.Utils;
import cz.cvut.kbss.termit.util.Vocabulary;
+import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -110,8 +111,8 @@ public UserAccount findRequired(URI id) {
* @return Reference to the matching user account
* @throws NotFoundException When no matching account is found
*/
- public UserAccount getRequiredReference(URI id) {
- return repositoryService.getRequiredReference(id);
+ public UserAccount getReference(URI id) {
+ return repositoryService.getReference(id);
}
/**
@@ -168,6 +169,19 @@ public void persist(UserAccount account) {
public void updateCurrent(UserUpdateDto update) {
LOG.trace("Updating current user account.");
Objects.requireNonNull(update);
+ UserAccount currentUser = getCurrentUser(update);
+ if (!Objects.equals(currentUser.getTypes(), update.getTypes())) {
+ throw new ValidationException(
+ "User " + securityUtils.getCurrentUser() + " attempted to update their role.");
+ }
+ if (update.getPassword() != null) {
+ securityUtils.verifyCurrentUserPassword(update.getOriginalPassword());
+ }
+ repositoryService.update(update.asUserAccount());
+ }
+
+ @NotNull
+ private UserAccount getCurrentUser(UserUpdateDto update) {
UserAccount currentUser = securityUtils.getCurrentUser();
if (!currentUser.getUri().equals(update.getUri())) {
@@ -178,14 +192,7 @@ public void updateCurrent(UserUpdateDto update) {
throw new ValidationException(
"User " + securityUtils.getCurrentUser() + " attempted to update their username.");
}
- if (!Objects.equals(currentUser.getTypes(), update.getTypes())) {
- throw new ValidationException(
- "User " + securityUtils.getCurrentUser() + " attempted to update their role.");
- }
- if (update.getPassword() != null) {
- securityUtils.verifyCurrentUserPassword(update.getOriginalPassword());
- }
- repositoryService.update(update.asUserAccount());
+ return currentUser;
}
/**
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 ac55ce39a..e0374c4f8 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
@@ -137,16 +137,10 @@ public Vocabulary findRequired(URI id) {
@Override
@PostAuthorize("@vocabularyAuthorizationService.canRead(returnObject)")
- public Optional getReference(URI id) {
+ public Vocabulary getReference(URI id) {
return repositoryService.getReference(id);
}
- @Override
- @PostAuthorize("@vocabularyAuthorizationService.canRead(returnObject)")
- public Vocabulary getRequiredReference(URI id) {
- return repositoryService.getRequiredReference(id);
- }
-
@Override
@Transactional
@PreAuthorize("@vocabularyAuthorizationService.canCreate()")
@@ -255,7 +249,7 @@ public void runTextAnalysisOnAllTerms(Vocabulary vocabulary) {
SnapshotProvider.verifySnapshotNotModified(vocabulary);
final List allTerms = termService.findAll(vocabulary);
getTransitivelyImportedVocabularies(vocabulary).forEach(
- importedVocabulary -> allTerms.addAll(termService.findAll(getRequiredReference(importedVocabulary))));
+ importedVocabulary -> allTerms.addAll(termService.findAll(getReference(importedVocabulary))));
final Map termsToContexts = new HashMap<>(allTerms.size());
allTerms.forEach(t -> termsToContexts.put(t, contextMapper.getVocabularyContext(t.getVocabulary())));
termService.asyncAnalyzeTermDefinitions(termsToContexts);
diff --git a/src/main/java/cz/cvut/kbss/termit/service/business/readonly/ReadOnlyTermService.java b/src/main/java/cz/cvut/kbss/termit/service/business/readonly/ReadOnlyTermService.java
index 1e350ddc4..86d3782c6 100644
--- a/src/main/java/cz/cvut/kbss/termit/service/business/readonly/ReadOnlyTermService.java
+++ b/src/main/java/cz/cvut/kbss/termit/service/business/readonly/ReadOnlyTermService.java
@@ -113,8 +113,8 @@ public List getComments(Term term, Instant from, Instant to) {
return termService.getComments(term, from, to);
}
- public Term getRequiredReference(URI uri) {
- return termService.getRequiredReference(uri);
+ public Term getReference(URI uri) {
+ return termService.getReference(uri);
}
/**
diff --git a/src/main/java/cz/cvut/kbss/termit/service/changetracking/ChangeCalculator.java b/src/main/java/cz/cvut/kbss/termit/service/changetracking/ChangeCalculator.java
index cfa26c46a..76aaddbcf 100644
--- a/src/main/java/cz/cvut/kbss/termit/service/changetracking/ChangeCalculator.java
+++ b/src/main/java/cz/cvut/kbss/termit/service/changetracking/ChangeCalculator.java
@@ -25,7 +25,7 @@
/**
* Calculates changes made to an asset when compared to its original from the repository.
*/
-interface ChangeCalculator {
+public interface ChangeCalculator {
/**
* Calculates the set of changes made to the specified asset.
diff --git a/src/main/java/cz/cvut/kbss/termit/service/changetracking/ChangeTracker.java b/src/main/java/cz/cvut/kbss/termit/service/changetracking/ChangeTracker.java
index dbd6b9cc1..de0de54e0 100644
--- a/src/main/java/cz/cvut/kbss/termit/service/changetracking/ChangeTracker.java
+++ b/src/main/java/cz/cvut/kbss/termit/service/changetracking/ChangeTracker.java
@@ -17,23 +17,28 @@
*/
package cz.cvut.kbss.termit.service.changetracking;
+import cz.cvut.kbss.termit.event.AssetPersistEvent;
+import cz.cvut.kbss.termit.event.AssetUpdateEvent;
import cz.cvut.kbss.termit.model.Asset;
import cz.cvut.kbss.termit.model.User;
import cz.cvut.kbss.termit.model.changetracking.AbstractChangeRecord;
import cz.cvut.kbss.termit.model.changetracking.PersistChangeRecord;
import cz.cvut.kbss.termit.model.changetracking.UpdateChangeRecord;
+import cz.cvut.kbss.termit.model.resource.File;
import cz.cvut.kbss.termit.persistence.dao.changetracking.ChangeRecordDao;
+import cz.cvut.kbss.termit.persistence.dao.changetracking.ChangeTrackingHelperDao;
import cz.cvut.kbss.termit.service.security.SecurityUtils;
import cz.cvut.kbss.termit.util.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
+import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.Instant;
import java.util.Collection;
-import java.util.Objects;
import java.util.stream.Collectors;
/**
@@ -48,30 +53,19 @@ public class ChangeTracker {
private final ChangeRecordDao changeRecordDao;
+ private final ChangeTrackingHelperDao helperDao;
+
private final SecurityUtils securityUtils;
@Autowired
public ChangeTracker(ChangeCalculator changeCalculator, ChangeRecordDao changeRecordDao,
- SecurityUtils securityUtils) {
+ ChangeTrackingHelperDao helperDao, SecurityUtils securityUtils) {
this.changeCalculator = changeCalculator;
this.changeRecordDao = changeRecordDao;
+ this.helperDao = helperDao;
this.securityUtils = securityUtils;
}
- /**
- * Records an asset addition to the repository.
- *
- * @param added The added asset
- */
- @Transactional
- public void recordAddEvent(Asset> added) {
- Objects.requireNonNull(added);
- final AbstractChangeRecord changeRecord = new PersistChangeRecord(added);
- changeRecord.setAuthor(securityUtils.getCurrentUser().toUser());
- changeRecord.setTimestamp(Utils.timestamp());
- changeRecordDao.persist(changeRecord, added);
- }
-
/**
* Records an asset update.
*
@@ -81,20 +75,43 @@ public void recordAddEvent(Asset> added) {
* @param original The original version of the asset
*/
@Transactional
- public void recordUpdateEvent(Asset> update, Asset> original) {
- Objects.requireNonNull(update);
- Objects.requireNonNull(original);
+ @EventListener(AssetUpdateEvent.class)
+ public void onAssetUpdateEvent(AssetUpdateEvent event) {
+ final Asset> update = event.getAsset();
+ final Asset> original = helperDao.findStored(update);
final Instant now = Utils.timestamp();
final User user = securityUtils.getCurrentUser().toUser();
final Collection changes = changeCalculator.calculateChanges(update, original);
- if (!changes.isEmpty()) {
- LOG.trace("Found changes to attributes: " + changes.stream().map(ch -> ch.getChangedAttribute().toString())
- .collect(Collectors.joining(", ")));
+ if (changes.isEmpty()) {
+ return;
}
+ LOG.trace("Recording update of asset {}.", update);
+ LOG.trace("Found changes to attributes: {}", changes.stream().map(ch -> ch.getChangedAttribute().toString())
+ .collect(Collectors.joining(", ")));
changes.forEach(ch -> {
ch.setAuthor(user);
ch.setTimestamp(now);
changeRecordDao.persist(ch, update);
});
}
+
+ /**
+ * Records an asset addition to the repository.
+ *
+ * @param event Event representing the asset persist
+ */
+ @Transactional
+ @EventListener
+ public void onAssetPersistEvent(@NonNull AssetPersistEvent event) {
+ final Asset> added = event.getAsset();
+ if (added instanceof File) {
+ LOG.trace("Skipping recording of creation of file {}.", added);
+ return;
+ }
+ LOG.trace("Recording creation of asset {}.", added);
+ final AbstractChangeRecord changeRecord = new PersistChangeRecord(added);
+ changeRecord.setAuthor(securityUtils.getCurrentUser().toUser());
+ changeRecord.setTimestamp(Utils.timestamp());
+ changeRecordDao.persist(changeRecord, added);
+ }
}
diff --git a/src/main/java/cz/cvut/kbss/termit/service/document/TextAnalysisService.java b/src/main/java/cz/cvut/kbss/termit/service/document/TextAnalysisService.java
index c2c7ae3c2..c5f81ba36 100644
--- a/src/main/java/cz/cvut/kbss/termit/service/document/TextAnalysisService.java
+++ b/src/main/java/cz/cvut/kbss/termit/service/document/TextAnalysisService.java
@@ -93,6 +93,8 @@ private TextAnalysisInput createAnalysisInput(File file) {
);
input.setVocabularyRepository(repositoryUrl);
input.setLanguage(config.getPersistence().getLanguage());
+ input.setVocabularyRepositoryUserName(config.getRepository().getUsername());
+ input.setVocabularyRepositoryPassword(config.getRepository().getPassword());
return input;
}
@@ -124,7 +126,7 @@ private Optional invokeTextAnalysisService(TextAnalysisInput input) {
}
final HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_XML_VALUE);
- LOG.debug("Invoking text analysis service on input: {}", input);
+ LOG.debug("Invoking text analysis service at '{}' on input: {}", config.getTextAnalysis().getUrl(), input);
final ResponseEntity resp = restClient
.exchange(config.getTextAnalysis().getUrl(), HttpMethod.POST,
new HttpEntity<>(input, headers), Resource.class);
@@ -169,6 +171,8 @@ public void analyzeTermDefinition(AbstractTerm term, URI vocabularyContext) {
final TextAnalysisInput input = new TextAnalysisInput(term.getDefinition().get(language), language,
URI.create(config.getRepository().getUrl()));
input.addVocabularyContext(vocabularyContext);
+ input.setVocabularyRepositoryUserName(config.getRepository().getUsername());
+ input.setVocabularyRepositoryPassword(config.getRepository().getPassword());
invokeTextAnalysisOnTerm(term, input);
}
diff --git a/src/main/java/cz/cvut/kbss/termit/service/jmx/AppAdminBean.java b/src/main/java/cz/cvut/kbss/termit/service/jmx/AppAdminBean.java
index 0ccf0c68c..ae8019e24 100644
--- a/src/main/java/cz/cvut/kbss/termit/service/jmx/AppAdminBean.java
+++ b/src/main/java/cz/cvut/kbss/termit/service/jmx/AppAdminBean.java
@@ -24,6 +24,7 @@
import cz.cvut.kbss.termit.service.mail.Message;
import cz.cvut.kbss.termit.service.mail.Postman;
import cz.cvut.kbss.termit.util.Configuration;
+import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -65,7 +66,7 @@ public void invalidateCaches() {
eventPublisher.publishEvent(new EvictCacheEvent(this));
LOG.info("Refreshing last modified timestamps...");
eventPublisher.publishEvent(new RefreshLastModifiedEvent(this));
- eventPublisher.publishEvent(new VocabularyContentModified(this));
+ eventPublisher.publishEvent(new VocabularyContentModified(this, null));
}
@ManagedOperation(description = "Sends test email to the specified address.")
@@ -76,7 +77,7 @@ public void sendTestEmail(String address) {
}
@Override
- public ObjectName getObjectName() throws MalformedObjectNameException {
+ public @NotNull ObjectName getObjectName() throws MalformedObjectNameException {
return new ObjectName("bean:name=" + beanName);
}
@@ -84,7 +85,7 @@ public ObjectName getObjectName() throws MalformedObjectNameException {
* Gets health info of the application.
*
* This method provides basic info on the status of the system.
- *
+ *
* TODO Resolve status of services used by TermIt (repository, annotace, mail server - if configured)
*
* @return Health info object
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 ee983b752..a5015182d 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
@@ -103,10 +103,14 @@ public Optional find(URI id) {
* for the loaded instance.
*
* @param id Identifier of the object to load
- * @return {@link Optional} with the loaded reference or an empty one
+ * @return Entity reference
+ * @throws NotFoundException If no matching instance is found
*/
- public Optional getReference(URI id) {
- return getPrimaryDao().getReference(id);
+ public T getReference(URI id) {
+ if (exists(id)) {
+ return getPrimaryDao().getReference(id);
+ }
+ throw NotFoundException.create(resolveGenericType().getSimpleName(), id);
}
/**
@@ -124,25 +128,6 @@ public T findRequired(URI id) {
return find(id).orElseThrow(() -> NotFoundException.create(resolveGenericType().getSimpleName(), id));
}
- /**
- * Gets a reference to an object wih the specified identifier.
- *
- * In comparison to {@link #getReference(URI)}, this method guarantees to return a matching instance. If no such
- * object is found, a {@link NotFoundException} is thrown.
- *
- * Note that all attributes of the reference are loaded lazily and the corresponding persistence context must be
- * still open to load them.
- *
- * Also note that, in contrast to {@link #find(URI)}, this method does not invoke {@link #postLoad(HasIdentifier)}
- * for the loaded instance.
- *
- * @param id Identifier of the object to load
- * @return {@link Optional} with the loaded reference or an empty one
- */
- public T getRequiredReference(URI id) {
- return getReference(id).orElseThrow(() -> NotFoundException.create(resolveGenericType().getSimpleName(), id));
- }
-
/**
* Resolves the actual generic type of the implementation of {@link BaseRepositoryService}.
*
diff --git a/src/main/java/cz/cvut/kbss/termit/service/repository/RepositoryAccessControlListService.java b/src/main/java/cz/cvut/kbss/termit/service/repository/RepositoryAccessControlListService.java
index f52f9ced2..e05d05df2 100644
--- a/src/main/java/cz/cvut/kbss/termit/service/repository/RepositoryAccessControlListService.java
+++ b/src/main/java/cz/cvut/kbss/termit/service/repository/RepositoryAccessControlListService.java
@@ -82,7 +82,7 @@ public AccessControlList findRequired(URI id) {
}
@Override
- public AccessControlList getRequiredReference(URI id) {
+ public AccessControlList getReference(URI id) {
return dao.getReference(id).orElseThrow(() -> NotFoundException.create(AccessControlList.class, id));
}
diff --git a/src/main/java/cz/cvut/kbss/termit/service/repository/TermOccurrenceRepositoryService.java b/src/main/java/cz/cvut/kbss/termit/service/repository/TermOccurrenceRepositoryService.java
index 20c19851c..88940766e 100644
--- a/src/main/java/cz/cvut/kbss/termit/service/repository/TermOccurrenceRepositoryService.java
+++ b/src/main/java/cz/cvut/kbss/termit/service/repository/TermOccurrenceRepositoryService.java
@@ -58,11 +58,6 @@ public TermOccurrenceRepositoryService(TermOccurrenceDao termOccurrenceDao, Term
this.resourceService = resourceService;
}
- @Override
- public TermOccurrence getRequiredReference(URI id) {
- return termOccurrenceDao.getReference(id).orElseThrow(() -> NotFoundException.create(TermOccurrence.class, id));
- }
-
@Transactional
@Override
public void persist(TermOccurrence occurrence) {
@@ -118,7 +113,7 @@ public void approve(URI occurrenceId) {
public void remove(URI occurrenceId) {
Objects.requireNonNull(occurrenceId);
LOG.trace("Removing term occurrence {}.", occurrenceId);
- termOccurrenceDao.getReference(occurrenceId).ifPresent(termOccurrenceDao::remove);
+ termOccurrenceDao.find(occurrenceId).ifPresent(termOccurrenceDao::remove);
}
/**
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 f9b09a1b7..23d5e2171 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
@@ -126,7 +126,7 @@ private void pruneEmptyTranslations(Term instance) {
@Override
protected void postUpdate(@NotNull Term instance) {
- final Vocabulary vocabulary = vocabularyService.getRequiredReference(instance.getVocabulary());
+ final Vocabulary vocabulary = vocabularyService.getReference(instance.getVocabulary());
if (instance.hasParentInSameVocabulary()) {
vocabulary.getGlossary().removeRootTerm(instance);
} else {
@@ -170,7 +170,7 @@ private URI generateIdentifier(URI vocabularyUri, MultilingualString multilingua
private void addTermAsRootToGlossary(Term instance, URI vocabularyIri) {
// Load vocabulary so that it is managed and changes to it (resp. the glossary) are persisted on commit
- final Vocabulary toUpdate = vocabularyService.getRequiredReference(vocabularyIri);
+ final Vocabulary toUpdate = vocabularyService.getReference(vocabularyIri);
instance.setGlossary(toUpdate.getGlossary().getUri());
toUpdate.getGlossary().addRootTerm(instance);
}
@@ -185,7 +185,7 @@ public void addChildTerm(Term instance, Term parentTerm) {
instance.getVocabulary() != null ? instance.getVocabulary() : parentTerm.getVocabulary();
prepareTermForPersist(instance, vocabularyIri);
- final Vocabulary vocabulary = vocabularyService.getRequiredReference(vocabularyIri);
+ final Vocabulary vocabulary = vocabularyService.getReference(vocabularyIri);
instance.setGlossary(vocabulary.getGlossary().getUri());
instance.addParentTerm(parentTerm);
instance.splitExternalAndInternalParents();
diff --git a/src/test/java/cz/cvut/kbss/termit/environment/Transaction.java b/src/test/java/cz/cvut/kbss/termit/environment/Transaction.java
index 1c842871b..3ccb06545 100644
--- a/src/test/java/cz/cvut/kbss/termit/environment/Transaction.java
+++ b/src/test/java/cz/cvut/kbss/termit/environment/Transaction.java
@@ -17,6 +17,7 @@
*/
package cz.cvut.kbss.termit.environment;
+import org.jetbrains.annotations.NotNull;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
@@ -47,7 +48,26 @@ public static void execute(PlatformTransactionManager txManager, Runnable proced
new TransactionTemplate(txManager).execute(new TransactionCallbackWithoutResult() {
@Override
- protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
+ protected void doInTransactionWithoutResult(@NotNull TransactionStatus transactionStatus) {
+ procedure.run();
+ }
+ });
+ }
+
+ /**
+ * Helper method for executing the specified portion of code in a read-only transaction.
+ *
+ * This method allows executing transactional behavior in a read-only mode.
+ *
+ * @param txManager Transaction manager to use to run the transactional code
+ * @param procedure Code to execute
+ */
+ public static void executeReadOnly(PlatformTransactionManager txManager, Runnable procedure) {
+ final TransactionTemplate transaction = new TransactionTemplate(txManager);
+ transaction.setReadOnly(true);
+ new TransactionTemplate(txManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(@NotNull TransactionStatus transactionStatus) {
procedure.run();
}
});
diff --git a/src/test/java/cz/cvut/kbss/termit/environment/TransactionalTestRunner.java b/src/test/java/cz/cvut/kbss/termit/environment/TransactionalTestRunner.java
index 1427929a6..2428ca354 100644
--- a/src/test/java/cz/cvut/kbss/termit/environment/TransactionalTestRunner.java
+++ b/src/test/java/cz/cvut/kbss/termit/environment/TransactionalTestRunner.java
@@ -30,6 +30,10 @@ protected void transactional(Runnable procedure) {
Transaction.execute(txManager, procedure);
}
+ protected void readOnlyTransactional(Runnable procedure) {
+ Transaction.executeReadOnly(txManager, procedure);
+ }
+
protected void enableRdfsInference(EntityManager em) {
transactional(() -> Environment.addModelStructureForRdfsInference(em));
}
diff --git a/src/test/java/cz/cvut/kbss/termit/environment/config/TestPersistenceAspectsConfig.java b/src/test/java/cz/cvut/kbss/termit/environment/config/TestPersistenceAspectsConfig.java
deleted file mode 100644
index af49866f0..000000000
--- a/src/test/java/cz/cvut/kbss/termit/environment/config/TestPersistenceAspectsConfig.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * TermIt
- * 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
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package cz.cvut.kbss.termit.environment.config;
-
-import cz.cvut.kbss.termit.aspect.ChangeTrackingAspect;
-import cz.cvut.kbss.termit.aspect.VocabularyContentModificationAspect;
-import cz.cvut.kbss.termit.service.changetracking.ChangeTracker;
-import org.aspectj.lang.Aspects;
-import org.springframework.boot.test.context.TestConfiguration;
-import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Primary;
-
-import static org.mockito.Mockito.mock;
-
-@TestConfiguration
-public class TestPersistenceAspectsConfig {
-
- @Bean
- public ChangeTrackingAspect changeTrackingAspect() {
- return Aspects.aspectOf(ChangeTrackingAspect.class);
- }
-
- @Bean
- @Primary
- public ChangeTracker changeTracker() {
- return mock(ChangeTracker.class);
- }
-
- @Bean
- VocabularyContentModificationAspect vocabularyContentModificationAspect() {
- return Aspects.aspectOf(VocabularyContentModificationAspect.class);
- }
-
- @Bean
- public ApplicationEventPublisher eventPublisher() {
- return mock(ApplicationEventPublisher.class);
- }
-}
diff --git a/src/test/java/cz/cvut/kbss/termit/environment/config/TestPersistenceConfig.java b/src/test/java/cz/cvut/kbss/termit/environment/config/TestPersistenceConfig.java
index 1fc4e8c2b..0bc340493 100644
--- a/src/test/java/cz/cvut/kbss/termit/environment/config/TestPersistenceConfig.java
+++ b/src/test/java/cz/cvut/kbss/termit/environment/config/TestPersistenceConfig.java
@@ -24,12 +24,16 @@
import cz.cvut.kbss.termit.workspace.EditableVocabulariesHolder;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
+import org.springframework.context.annotation.Primary;
import org.springframework.transaction.annotation.EnableTransactionManagement;
+import static org.mockito.Mockito.spy;
+
@TestConfiguration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Import({TestPersistenceFactory.class, PersistenceConfig.class})
@@ -41,4 +45,10 @@ public class TestPersistenceConfig {
public EditableVocabularies editableVocabularies(Configuration config, ObjectProvider editableVocabulariesHolder) {
return new EditableVocabularies(config, editableVocabulariesHolder);
}
+
+ @Bean("spiedPublisher")
+ @Primary
+ public ApplicationEventPublisher eventPublisher(ApplicationEventPublisher eventPublisher) {
+ return spy(eventPublisher);
+ }
}
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 41874802e..973b1424f 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
@@ -17,8 +17,6 @@
*/
package cz.cvut.kbss.termit.environment.config;
-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;
@@ -26,10 +24,8 @@
import cz.cvut.kbss.termit.service.document.html.DummySelectorGenerator;
import cz.cvut.kbss.termit.service.document.html.HtmlSelectorGenerators;
import cz.cvut.kbss.termit.util.Configuration;
-import org.aspectj.lang.Aspects;
import org.jsoup.nodes.Element;
import org.springframework.boot.test.context.TestConfiguration;
-import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Primary;
@@ -96,22 +92,6 @@ public ClassPathResource termStatesLanguageFile() {
return new ClassPathResource("languages/states.ttl");
}
- @Bean
- ChangeTrackingAspect changeTrackingAspect() {
- return Aspects.aspectOf(ChangeTrackingAspect.class);
- }
-
- @Bean
- VocabularyContentModificationAspect vocabularyContentModificationAspect() {
- return Aspects.aspectOf(VocabularyContentModificationAspect.class);
- }
-
- @Bean
- @Primary
- public ApplicationEventPublisher eventPublisher() {
- return mock(ApplicationEventPublisher.class);
- }
-
@Bean
public JavaMailSender javaMailSender() {
return mock(JavaMailSender.class);
diff --git a/src/test/java/cz/cvut/kbss/termit/model/util/validation/WithoutQueryParametersValidatorTest.java b/src/test/java/cz/cvut/kbss/termit/model/util/validation/WithoutQueryParametersValidatorTest.java
index 5f5e1f676..acc33c0bc 100644
--- a/src/test/java/cz/cvut/kbss/termit/model/util/validation/WithoutQueryParametersValidatorTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/model/util/validation/WithoutQueryParametersValidatorTest.java
@@ -17,14 +17,14 @@
*/
package cz.cvut.kbss.termit.model.util.validation;
+import cz.cvut.kbss.jopa.vocabulary.SKOS;
import cz.cvut.kbss.termit.environment.Generator;
-import cz.cvut.kbss.termit.util.Vocabulary;
+import jakarta.validation.ConstraintValidatorContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
-import jakarta.validation.ConstraintValidatorContext;
import java.net.URI;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -40,7 +40,7 @@ class WithoutQueryParametersValidatorTest {
@Test
void isValidReturnsTrueForNormalUris() {
- final URI uri = URI.create(Vocabulary.s_c_term + Generator.randomInt(0, 1000000));
+ final URI uri = URI.create(SKOS.CONCEPT + Generator.randomInt(0, 1000000));
assertTrue(sut.isValid(uri, ctx));
}
diff --git a/src/test/java/cz/cvut/kbss/termit/persistence/dao/BaseAssetDaoTest.java b/src/test/java/cz/cvut/kbss/termit/persistence/dao/BaseAssetDaoTest.java
new file mode 100644
index 000000000..30f4284ad
--- /dev/null
+++ b/src/test/java/cz/cvut/kbss/termit/persistence/dao/BaseAssetDaoTest.java
@@ -0,0 +1,89 @@
+package cz.cvut.kbss.termit.persistence.dao;
+
+import cz.cvut.kbss.jopa.model.EntityManager;
+import cz.cvut.kbss.jopa.vocabulary.SKOS;
+import cz.cvut.kbss.termit.environment.Generator;
+import cz.cvut.kbss.termit.event.AssetPersistEvent;
+import cz.cvut.kbss.termit.event.AssetUpdateEvent;
+import cz.cvut.kbss.termit.model.Term;
+import cz.cvut.kbss.termit.persistence.context.DescriptorFactory;
+import cz.cvut.kbss.termit.util.Configuration;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationEventPublisher;
+
+import java.net.URI;
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.verify;
+
+class BaseAssetDaoTest extends BaseDaoTestRunner{
+
+ @Autowired
+ private EntityManager em;
+
+ @Autowired
+ private Configuration config;
+
+ @Autowired
+ private DescriptorFactory descriptorFactory;
+
+ @Autowired
+ private ApplicationEventPublisher eventPublisher;
+
+ private BaseDao sut;
+
+ @BeforeEach
+ void setUp() {
+ this.sut = new BaseAssetDaoImpl(em, config.getPersistence(), descriptorFactory);
+ sut.setApplicationEventPublisher(eventPublisher);
+ }
+
+ @Test
+ void persistPublishesAssetPersistEvent() {
+ final Term t = Generator.generateTermWithId();
+
+ transactional(() -> sut.persist(t));
+ final ArgumentCaptor captor = ArgumentCaptor.forClass(ApplicationEvent.class);
+ verify(eventPublisher, atLeastOnce()).publishEvent(captor.capture());
+ final Optional evt = captor.getAllValues().stream()
+ .filter(AssetPersistEvent.class::isInstance)
+ .map(AssetPersistEvent.class::cast).findFirst();
+ assertTrue(evt.isPresent());
+ assertEquals(t, evt.get().getAsset());
+ }
+
+ @Test
+ void updatePublishesAssetUpdateEvent() {
+ final Term t = Generator.generateTermWithId();
+ transactional(() -> em.persist(t));
+ t.setPrimaryLabel("Updated primary label");
+
+ transactional(() -> sut.update(t));
+
+ final ArgumentCaptor captor = ArgumentCaptor.forClass(ApplicationEvent.class);
+ verify(eventPublisher, atLeastOnce()).publishEvent(captor.capture());
+ final Optional evt = captor.getAllValues().stream()
+ .filter(AssetUpdateEvent.class::isInstance)
+ .map(AssetUpdateEvent.class::cast).findFirst();
+ assertTrue(evt.isPresent());
+ assertEquals(t, evt.get().getAsset());
+ }
+
+ private static class BaseAssetDaoImpl extends BaseAssetDao {
+
+ BaseAssetDaoImpl(EntityManager em, Configuration.Persistence config, DescriptorFactory descriptorFactory) {
+ super(Term.class, em, config, descriptorFactory);
+ }
+
+ @Override
+ protected URI labelProperty() {
+ return URI.create(SKOS.PREF_LABEL);
+ }
+ }
+}
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 f677393f3..b426920f0 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
@@ -26,6 +26,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
import java.util.Collections;
import java.util.List;
@@ -34,19 +35,30 @@
import java.util.stream.IntStream;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.*;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.hamcrest.Matchers.hasItems;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
class BaseDaoTest extends BaseDaoTestRunner {
@Autowired
private EntityManager em;
+ @Autowired
+ private ApplicationEventPublisher eventPublisher;
+
private BaseDao sut;
@BeforeEach
void setUp() {
this.sut = new BaseDaoImpl(em);
+ sut.setApplicationEventPublisher(eventPublisher);
}
@Test
@@ -59,7 +71,7 @@ void findAllRetrievesAllExistingInstances() {
}).collect(Collectors.toList());
transactional(() -> sut.persist(terms));
final List result = sut.findAll();
- assertThat(result, hasItems(terms.toArray(new Term[] {})));
+ assertThat(result, hasItems(terms.toArray(new Term[]{})));
}
@Test
@@ -151,7 +163,7 @@ void exceptionDuringCollectionPersistIsWrappedInPersistenceException() {
transactional(() -> sut.persist(terms));
final PersistenceException e = assertThrows(PersistenceException.class,
- () -> transactional(() -> sut.persist(terms)));
+ () -> transactional(() -> sut.persist(terms)));
assertThat(e.getCause(), is(instanceOf(OWLPersistenceException.class)));
}
@@ -159,16 +171,12 @@ void exceptionDuringCollectionPersistIsWrappedInPersistenceException() {
void getReferenceRetrievesReferenceToMatchingInstance() {
final Term term = Generator.generateTermWithId();
transactional(() -> sut.persist(term));
- final Optional result = sut.getReference(term.getUri());
- assertTrue(result.isPresent());
- assertEquals(term.getUri(), result.get().getUri());
- }
-
- @Test
- void getReferenceReturnsEmptyOptionalWhenNoMatchingInstanceExists() {
- final Optional result = sut.getReference(Generator.generateUri());
- assertNotNull(result);
- assertFalse(result.isPresent());
+ readOnlyTransactional(() -> {
+ final Term result = sut.getReference(term.getUri());
+ assertNotNull(result);
+ // This will trigger state loading
+ assertEquals(term, result);
+ });
}
@Test
diff --git a/src/test/java/cz/cvut/kbss/termit/persistence/dao/BaseDaoTestRunner.java b/src/test/java/cz/cvut/kbss/termit/persistence/dao/BaseDaoTestRunner.java
index 3b5e05d0c..ea352ec61 100644
--- a/src/test/java/cz/cvut/kbss/termit/persistence/dao/BaseDaoTestRunner.java
+++ b/src/test/java/cz/cvut/kbss/termit/persistence/dao/BaseDaoTestRunner.java
@@ -18,7 +18,6 @@
package cz.cvut.kbss.termit.persistence.dao;
import cz.cvut.kbss.termit.environment.TransactionalTestRunner;
-import cz.cvut.kbss.termit.environment.config.TestPersistenceAspectsConfig;
import cz.cvut.kbss.termit.environment.config.TestPersistenceConfig;
import cz.cvut.kbss.termit.util.Configuration;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -34,7 +33,8 @@
@ExtendWith(SpringExtension.class)
@EnableConfigurationProperties(Configuration.class)
@EnableSpringConfigured
-@ContextConfiguration(classes = {TestPersistenceConfig.class, TestPersistenceAspectsConfig.class}, initializers = {ConfigDataApplicationContextInitializer.class})
+@ContextConfiguration(classes = {TestPersistenceConfig.class},
+ initializers = {ConfigDataApplicationContextInitializer.class})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
@ActiveProfiles("test")
public abstract class BaseDaoTestRunner extends TransactionalTestRunner {
diff --git a/src/test/java/cz/cvut/kbss/termit/persistence/dao/DataDaoTest.java b/src/test/java/cz/cvut/kbss/termit/persistence/dao/DataDaoTest.java
index 3fe2db5c1..55e3325bb 100644
--- a/src/test/java/cz/cvut/kbss/termit/persistence/dao/DataDaoTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/persistence/dao/DataDaoTest.java
@@ -139,7 +139,7 @@ void getLabelReturnsLabelWithoutLanguageTagWhenMatchingLanguageTagDoesNotExist()
final Repository repo = em.unwrap(Repository.class);
final ValueFactory vf = repo.getValueFactory();
try (final RepositoryConnection connection = repo.getConnection()) {
- connection.add(vf.createIRI(term.getUri().toString()), RDF.TYPE, vf.createIRI(Vocabulary.s_c_term));
+ connection.add(vf.createIRI(term.getUri().toString()), RDF.TYPE, SKOS.CONCEPT);
connection.add(vf.createIRI(term.getUri().toString()), SKOS.PREF_LABEL,
vf.createLiteral(term.getPrimaryLabel()));
connection.commit();
@@ -170,7 +170,7 @@ void getLabelReturnsEmptyOptionalForIdentifierWithMultipleLabels() {
final Repository repo = em.unwrap(Repository.class);
final ValueFactory vf = repo.getValueFactory();
try (final RepositoryConnection connection = repo.getConnection()) {
- connection.add(vf.createIRI(term.getUri().toString()), RDF.TYPE, vf.createIRI(Vocabulary.s_c_term));
+ connection.add(vf.createIRI(term.getUri().toString()), RDF.TYPE,SKOS.CONCEPT);
connection.add(vf.createIRI(term.getUri().toString()), SKOS.PREF_LABEL,
vf.createLiteral(term.getPrimaryLabel()));
connection.add(vf.createIRI(term.getUri().toString()), SKOS.PREF_LABEL,
@@ -234,7 +234,7 @@ void exportDataToTurtleExportsContextWhenProvided() {
transactional(() -> {
final Repository repo = em.unwrap(Repository.class);
try (final RepositoryConnection connection = repo.getConnection()) {
- connection.add(vf.createIRI(Vocabulary.s_c_term), RDFS.LABEL, vf.createLiteral("Term"),
+ connection.add(SKOS.CONCEPT, RDFS.LABEL, vf.createLiteral("Term"),
vf.createIRI(context.toString()));
connection.commit();
}
@@ -242,7 +242,7 @@ void exportDataToTurtleExportsContextWhenProvided() {
transactional(() -> {
final TypeAwareResource result = sut.exportDataAsTurtle(context);
Model model = parseExportToModel(result);
- assertTrue(model.contains(vf.createIRI(Vocabulary.s_c_term), RDFS.LABEL, vf.createLiteral("Term")));
+ assertTrue(model.contains(SKOS.CONCEPT, RDFS.LABEL, vf.createLiteral("Term")));
assertFalse(model.contains(vf.createIRI(Vocabulary.s_p_ma_krestni_jmeno), null, null));
});
}
diff --git a/src/test/java/cz/cvut/kbss/termit/persistence/dao/ResourceDaoTest.java b/src/test/java/cz/cvut/kbss/termit/persistence/dao/ResourceDaoTest.java
index 4a96ae7c4..bda9eaf71 100644
--- a/src/test/java/cz/cvut/kbss/termit/persistence/dao/ResourceDaoTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/persistence/dao/ResourceDaoTest.java
@@ -20,6 +20,7 @@
import cz.cvut.kbss.jopa.model.EntityManager;
import cz.cvut.kbss.termit.environment.Environment;
import cz.cvut.kbss.termit.environment.Generator;
+import cz.cvut.kbss.termit.event.AssetUpdateEvent;
import cz.cvut.kbss.termit.event.RefreshLastModifiedEvent;
import cz.cvut.kbss.termit.model.User;
import cz.cvut.kbss.termit.model.Vocabulary;
@@ -33,7 +34,10 @@
import org.eclipse.rdf4j.repository.RepositoryConnection;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationEventPublisher;
import org.springframework.test.annotation.DirtiesContext;
import java.util.Comparator;
@@ -54,6 +58,8 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.verify;
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class ResourceDaoTest extends BaseDaoTestRunner {
@@ -61,6 +67,9 @@ class ResourceDaoTest extends BaseDaoTestRunner {
@Autowired
private EntityManager em;
+ @Autowired
+ private ApplicationEventPublisher eventPublisher;
+
@Autowired
private DescriptorFactory descriptorFactory;
@@ -74,6 +83,7 @@ void setUp() {
this.user = Generator.generateUserWithId();
transactional(() -> em.persist(user));
Environment.setCurrentUser(user);
+ sut.setApplicationEventPublisher(eventPublisher);
}
private Resource generateResource() {
@@ -330,6 +340,22 @@ void updateRefreshesLastModifiedValue() {
assertThat(after, greaterThan(before));
}
+ @Test
+ void updatePublishesAssetUpdateEvent() {
+ final Resource resource = generateResource();
+ final String newLabel = "New label";
+ resource.setLabel(newLabel);
+
+ transactional(() -> sut.update(resource));
+ final ArgumentCaptor captor = ArgumentCaptor.forClass(ApplicationEvent.class);
+ verify(eventPublisher, atLeastOnce()).publishEvent(captor.capture());
+ final Optional evt = captor.getAllValues().stream()
+ .filter(AssetUpdateEvent.class::isInstance)
+ .map(AssetUpdateEvent.class::cast).findFirst();
+ assertTrue(evt.isPresent());
+ assertEquals(resource, evt.get().getAsset());
+ }
+
@Test
void removeFileUpdatesParentDocumentInVocabularyContext() {
final Document document = Generator.generateDocumentWithId();
@@ -353,7 +379,7 @@ void removeFileUpdatesParentDocumentInVocabularyContext() {
});
transactional(() -> {
- final Resource toRemove = sut.getReference(file.getUri()).get();
+ final Resource toRemove = sut.getReference(file.getUri());
sut.remove(toRemove);
});
diff --git a/src/test/java/cz/cvut/kbss/termit/persistence/dao/TermDaoTest.java b/src/test/java/cz/cvut/kbss/termit/persistence/dao/TermDaoTest.java
index a9aa9b83f..9acc6a73f 100644
--- a/src/test/java/cz/cvut/kbss/termit/persistence/dao/TermDaoTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/persistence/dao/TermDaoTest.java
@@ -25,6 +25,9 @@
import cz.cvut.kbss.termit.dto.listing.TermDto;
import cz.cvut.kbss.termit.environment.Environment;
import cz.cvut.kbss.termit.environment.Generator;
+import cz.cvut.kbss.termit.event.AssetPersistEvent;
+import cz.cvut.kbss.termit.event.AssetUpdateEvent;
+import cz.cvut.kbss.termit.event.VocabularyContentModified;
import cz.cvut.kbss.termit.model.Asset;
import cz.cvut.kbss.termit.model.Term;
import cz.cvut.kbss.termit.model.Term_;
@@ -46,7 +49,10 @@
import org.eclipse.rdf4j.repository.RepositoryConnection;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.PageRequest;
import org.springframework.test.annotation.DirtiesContext;
@@ -78,9 +84,12 @@
import static org.hamcrest.Matchers.nullValue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.verify;
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class TermDaoTest extends BaseTermDaoTestRunner {
@@ -88,9 +97,13 @@ class TermDaoTest extends BaseTermDaoTestRunner {
@Autowired
private Configuration configuration;
+ @Autowired
+ private ApplicationEventPublisher eventPublisher;
+
@BeforeEach
void setUp() {
super.setUp();
+ sut.setApplicationEventPublisher(eventPublisher);
}
private static List toDtos(List terms) {
@@ -349,6 +362,34 @@ void persistEnsuresVocabularyAttributeIsEmptySoThatItCanBeInferred() {
assertNull(result.getVocabulary());
}
+ @Test
+ void persistPublishesVocabularyContentModifiedEvent() {
+ final Term term = Generator.generateTermWithId(vocabulary.getUri());
+ transactional(() -> sut.persist(term, vocabulary));
+
+ final ArgumentCaptor captor = ArgumentCaptor.forClass(ApplicationEvent.class);
+ verify(eventPublisher, atLeastOnce()).publishEvent(captor.capture());
+ final Optional evt = captor.getAllValues().stream()
+ .filter(VocabularyContentModified.class::isInstance)
+ .map(VocabularyContentModified.class::cast).findFirst();
+ assertTrue(evt.isPresent());
+ assertEquals(vocabulary.getUri(), evt.get().getVocabularyIri());
+ }
+
+ @Test
+ void persistPublishesAssetPersistEvent() {
+ final Term term = Generator.generateTermWithId(vocabulary.getUri());
+ transactional(() -> sut.persist(term, vocabulary));
+
+ final ArgumentCaptor captor = ArgumentCaptor.forClass(ApplicationEvent.class);
+ verify(eventPublisher, atLeastOnce()).publishEvent(captor.capture());
+ final Optional evt = captor.getAllValues().stream()
+ .filter(AssetPersistEvent.class::isInstance)
+ .map(AssetPersistEvent.class::cast).findFirst();
+ assertTrue(evt.isPresent());
+ assertEquals(term, evt.get().getAsset());
+ }
+
@Test
void updateUpdatesTermInVocabularyContext() {
final Term term = Generator.generateTermWithId(vocabulary.getUri());
@@ -373,6 +414,50 @@ void updateUpdatesTermInVocabularyContext() {
.setParameter("label", oldLabel, Environment.LANGUAGE).getSingleResult());
}
+ @Test
+ void updatePublishesVocabularyContentModifiedEvent() {
+ final Term term = Generator.generateTermWithId(vocabulary.getUri());
+ transactional(() -> {
+ vocabulary.getGlossary().addRootTerm(term);
+ term.setGlossary(vocabulary.getGlossary().getUri());
+ em.merge(vocabulary.getGlossary(), descriptorFactory.glossaryDescriptor(vocabulary));
+ em.persist(term, descriptorFactory.termDescriptor(vocabulary));
+ Generator.addTermInVocabularyRelationship(term, vocabulary.getUri(), em);
+ });
+
+ final String updatedLabel = "Updated label";
+ term.setPrimaryLabel(updatedLabel);
+ transactional(() -> sut.update(term));
+ final ArgumentCaptor captor = ArgumentCaptor.forClass(ApplicationEvent.class);
+ verify(eventPublisher, atLeastOnce()).publishEvent(captor.capture());
+ final Optional evt = captor.getAllValues().stream().filter(VocabularyContentModified.class::isInstance)
+ .map(VocabularyContentModified.class::cast).findFirst();
+ assertTrue(evt.isPresent());
+ assertEquals(vocabulary.getUri(), evt.get().getVocabularyIri());
+ }
+
+ @Test
+ void updatePublishesAssetUpdateEvent() {
+ final Term term = Generator.generateTermWithId(vocabulary.getUri());
+ transactional(() -> {
+ vocabulary.getGlossary().addRootTerm(term);
+ term.setGlossary(vocabulary.getGlossary().getUri());
+ em.merge(vocabulary.getGlossary(), descriptorFactory.glossaryDescriptor(vocabulary));
+ em.persist(term, descriptorFactory.termDescriptor(vocabulary));
+ Generator.addTermInVocabularyRelationship(term, vocabulary.getUri(), em);
+ });
+
+ final String updatedLabel = "Updated label";
+ term.setPrimaryLabel(updatedLabel);
+ transactional(() -> sut.update(term));
+ final ArgumentCaptor captor = ArgumentCaptor.forClass(ApplicationEvent.class);
+ verify(eventPublisher, atLeastOnce()).publishEvent(captor.capture());
+ final Optional evt = captor.getAllValues().stream().filter(AssetUpdateEvent.class::isInstance)
+ .map(AssetUpdateEvent.class::cast).findFirst();
+ assertTrue(evt.isPresent());
+ assertEquals(term, evt.get().getAsset());
+ }
+
@Test
void findAllRootsReturnsOnlyTermsWithMatchingLabelLanguage() {
final List terms = generateTerms(5);
@@ -745,17 +830,15 @@ private void verifyTermSourceStatements(Term term) {
final ValueFactory vf = conn.getValueFactory();
final IRI subject = vf.createIRI(term.getUri().toString());
final IRI hasSource = vf.createIRI(DC.Terms.SOURCE);
- final List sourceStatements = conn.getStatements(subject, hasSource, null).stream().collect(
- Collectors.toList());
+ final List sourceStatements = conn.getStatements(subject, hasSource, null).stream().toList();
assertEquals(term.getSources().size(), sourceStatements.size());
sourceStatements.forEach(ss -> {
assertTrue(term.getSources().contains(ss.getObject().stringValue()));
- if (ss.getObject() instanceof Literal) {
- final Literal litSource = (Literal) ss.getObject();
+ if (ss.getObject() instanceof Literal litSource) {
assertFalse(litSource.getLanguage().isPresent());
assertEquals(XSD.STRING, litSource.getDatatype());
} else {
- assertTrue(ss.getObject() instanceof IRI);
+ assertInstanceOf(IRI.class, ss.getObject());
}
});
}
@@ -1153,7 +1236,7 @@ void removeEvictsParentsSubTermsCache() {
em.merge(vocabulary.getGlossary(), descriptorFactory.glossaryDescriptor(vocabulary));
});
final List rootsBefore = sut.findAllRoots(vocabulary, Constants.DEFAULT_PAGE_SPEC,
- Collections.emptyList());
+ Collections.emptyList());
assertEquals(1, rootsBefore.size());
assertTrue(rootsBefore.get(0).getSubTerms().stream().anyMatch(ti -> ti.getUri().equals(term.getUri())));
@@ -1164,6 +1247,26 @@ void removeEvictsParentsSubTermsCache() {
assertThat(roots.get(0).getSubTerms(), anyOf(nullValue(), emptyCollectionOf(TermInfo.class)));
}
+ @Test
+ void removePublishesVocabularyContentModifiedEvent() {
+ final Term term = Generator.generateTermWithId(vocabulary.getUri());
+ term.setGlossary(vocabulary.getGlossary().getUri());
+ transactional(() -> {
+ vocabulary.getGlossary().addRootTerm(term);
+ em.persist(term, descriptorFactory.termDescriptor(vocabulary));
+ em.merge(vocabulary.getGlossary(), descriptorFactory.glossaryDescriptor(vocabulary));
+ });
+
+ transactional(() -> sut.remove(term));
+ final ArgumentCaptor captor = ArgumentCaptor.forClass(ApplicationEvent.class);
+ verify(eventPublisher, atLeastOnce()).publishEvent(captor.capture());
+ final Optional evt = captor.getAllValues().stream()
+ .filter(VocabularyContentModified.class::isInstance)
+ .map(VocabularyContentModified.class::cast).findFirst();
+ assertTrue(evt.isPresent());
+ assertEquals(vocabulary.getUri(), evt.get().getVocabularyIri());
+ }
+
@Test
void setStateUpdatesStateOfSpecifiedTerm() {
final Term term = Generator.generateTermWithId(vocabulary.getUri());
@@ -1184,4 +1287,25 @@ void setStateUpdatesStateOfSpecifiedTerm() {
.setParameter("hasState", URI.create(cz.cvut.kbss.termit.util.Vocabulary.s_p_ma_stav_pojmu))
.setParameter("oldState", Generator.TERM_STATES[0]).getSingleResult());
}
+
+ @Test
+ void setStatePublishesAssetUpdateEvent() {
+ final Term term = Generator.generateTermWithId(vocabulary.getUri());
+ term.setState(Generator.TERM_STATES[0]);
+ transactional(() -> {
+ vocabulary.getGlossary().addRootTerm(term);
+ term.setGlossary(vocabulary.getGlossary().getUri());
+ em.merge(vocabulary.getGlossary(), descriptorFactory.glossaryDescriptor(vocabulary));
+ em.persist(term, descriptorFactory.termDescriptor(vocabulary));
+ Generator.addTermInVocabularyRelationship(term, vocabulary.getUri(), em);
+ });
+
+ transactional(() -> sut.setState(term, Generator.TERM_STATES[1]));
+ final ArgumentCaptor captor = ArgumentCaptor.forClass(ApplicationEvent.class);
+ verify(eventPublisher, atLeastOnce()).publishEvent(captor.capture());
+ final Optional evt = captor.getAllValues().stream().filter(AssetUpdateEvent.class::isInstance)
+ .map(AssetUpdateEvent.class::cast).findFirst();
+ assertTrue(evt.isPresent());
+ assertEquals(term, evt.get().getAsset());
+ }
}
diff --git a/src/test/java/cz/cvut/kbss/termit/persistence/dao/VocabularyDaoTest.java b/src/test/java/cz/cvut/kbss/termit/persistence/dao/VocabularyDaoTest.java
index a2917724a..423fcf2e4 100644
--- a/src/test/java/cz/cvut/kbss/termit/persistence/dao/VocabularyDaoTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/persistence/dao/VocabularyDaoTest.java
@@ -26,6 +26,8 @@
import cz.cvut.kbss.termit.dto.Snapshot;
import cz.cvut.kbss.termit.environment.Environment;
import cz.cvut.kbss.termit.environment.Generator;
+import cz.cvut.kbss.termit.event.AssetPersistEvent;
+import cz.cvut.kbss.termit.event.AssetUpdateEvent;
import cz.cvut.kbss.termit.event.RefreshLastModifiedEvent;
import cz.cvut.kbss.termit.model.*;
import cz.cvut.kbss.termit.model.changetracking.AbstractChangeRecord;
@@ -41,7 +43,10 @@
import org.eclipse.rdf4j.repository.RepositoryConnection;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ApplicationEventPublisher;
import org.springframework.test.annotation.DirtiesContext;
import java.net.URI;
@@ -58,6 +63,8 @@
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.verify;
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class VocabularyDaoTest extends BaseDaoTestRunner {
@@ -68,6 +75,9 @@ class VocabularyDaoTest extends BaseDaoTestRunner {
@Autowired
private DescriptorFactory descriptorFactory;
+ @Autowired
+ private ApplicationEventPublisher eventPublisher;
+
@Autowired
private VocabularyDao sut;
@@ -78,6 +88,7 @@ void setUp() {
this.author = Generator.generateUserWithId();
transactional(() -> em.persist(author));
Environment.setCurrentUser(author);
+ sut.setApplicationEventPublisher(eventPublisher);
}
@Test
@@ -328,6 +339,20 @@ void persistRefreshesLastModifiedValue() {
assertThat(after, greaterThan(before));
}
+ @Test
+ void persistPublishesAssetPersistEvent() {
+ final Vocabulary voc = Generator.generateVocabularyWithId();
+ transactional(() -> sut.persist(voc));
+
+ final ArgumentCaptor captor = ArgumentCaptor.forClass(ApplicationEvent.class);
+ verify(eventPublisher).publishEvent(captor.capture());
+ final Optional evt = captor.getAllValues().stream()
+ .filter(AssetPersistEvent.class::isInstance)
+ .map(AssetPersistEvent.class::cast).findFirst();
+ assertTrue(evt.isPresent());
+ assertEquals(voc, evt.get().getAsset());
+ }
+
@Test
void removeRefreshesLastModifiedValue() {
final long before = sut.getLastModified();
@@ -353,6 +378,23 @@ void updateRefreshesLastModifiedValue() {
assertThat(after, greaterThan(before));
}
+ @Test
+ void updatePublishesAssetUpdateEvent() {
+ final Vocabulary voc = Generator.generateVocabularyWithId();
+ transactional(() -> em.persist(voc, descriptorFactory.vocabularyDescriptor(voc)));
+ final String newLabel = "New vocabulary label";
+ voc.setLabel(MultilingualString.create(newLabel, Environment.LANGUAGE));
+
+ transactional(() -> sut.update(voc));
+ final ArgumentCaptor captor = ArgumentCaptor.forClass(ApplicationEvent.class);
+ verify(eventPublisher, atLeastOnce()).publishEvent(captor.capture());
+ final Optional evt = captor.getAllValues().stream()
+ .filter(AssetUpdateEvent.class::isInstance)
+ .map(AssetUpdateEvent.class::cast).findFirst();
+ assertTrue(evt.isPresent());
+ assertEquals(voc, evt.get().getAsset());
+ }
+
@Test
void getChangesOfContentLoadsAggregatedChangesOfTermsInVocabulary() {
enableRdfsInference(em);
diff --git a/src/test/java/cz/cvut/kbss/termit/persistence/validation/ResultCachingValidatorTest.java b/src/test/java/cz/cvut/kbss/termit/persistence/validation/ResultCachingValidatorTest.java
index e2f1e967f..cc38b77fc 100644
--- a/src/test/java/cz/cvut/kbss/termit/persistence/validation/ResultCachingValidatorTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/persistence/validation/ResultCachingValidatorTest.java
@@ -32,6 +32,7 @@
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
@@ -75,8 +76,9 @@ void evictCacheClearsCachedValidationResults() {
when(validator.validate(anyCollection())).thenReturn(results);
final Set vocabularies = Collections.singleton(Generator.generateUri());
final List resultOne = sut.validate(vocabularies);
- sut.evictCache(new VocabularyContentModified(this));
+ sut.evictCache(new VocabularyContentModified(this, null));
final List resultTwo = sut.validate(vocabularies);
verify(validator, times(2)).validate(vocabularies);
+ assertNotSame(resultOne, resultTwo);
}
}
diff --git a/src/test/java/cz/cvut/kbss/termit/rest/ResourceControllerTest.java b/src/test/java/cz/cvut/kbss/termit/rest/ResourceControllerTest.java
index c6aa208cf..a9ef5cae9 100644
--- a/src/test/java/cz/cvut/kbss/termit/rest/ResourceControllerTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/rest/ResourceControllerTest.java
@@ -226,7 +226,7 @@ void getFilesLoadsFilesFromDocumentWithSpecifiedIdentifier() throws Exception {
document.setUri(RESOURCE_URI);
final File fOne = generateFile();
document.addFile(fOne);
- when(resourceServiceMock.getRequiredReference(document.getUri())).thenReturn(document);
+ when(resourceServiceMock.getReference(document.getUri())).thenReturn(document);
when(resourceServiceMock.getFiles(document)).thenReturn(new ArrayList<>(document.getFiles()));
when(identifierResolverMock.resolveIdentifier(RESOURCE_NAMESPACE, RESOURCE_NAME)).thenReturn(document.getUri());
@@ -245,7 +245,7 @@ void getFilesReturnsConflictWhenRequestedResourceIsNotDocument() throws Exceptio
resource.setUri(RESOURCE_URI);
resource.setLabel(RESOURCE_NAME);
when(identifierResolverMock.resolveIdentifier(RESOURCE_NAMESPACE, RESOURCE_NAME)).thenReturn(RESOURCE_URI);
- when(resourceServiceMock.getRequiredReference(RESOURCE_URI)).thenReturn(resource);
+ when(resourceServiceMock.getReference(RESOURCE_URI)).thenReturn(resource);
when(resourceServiceMock.getFiles(resource)).thenThrow(UnsupportedAssetOperationException.class);
mockMvc.perform(get(PATH + "/" + RESOURCE_NAME + "/files").param(QueryParams.NAMESPACE, RESOURCE_NAMESPACE))
.andExpect(status().isConflict());
@@ -395,7 +395,7 @@ void getHistoryReturnsListOfChangeRecordsForSpecifiedVocabulary() throws Excepti
final Resource resource = Generator.generateResourceWithId();
resource.setUri(RESOURCE_URI);
when(identifierResolverMock.resolveIdentifier(RESOURCE_NAMESPACE, RESOURCE_NAME)).thenReturn(resource.getUri());
- when(resourceServiceMock.getRequiredReference(RESOURCE_URI)).thenReturn(resource);
+ when(resourceServiceMock.getReference(RESOURCE_URI)).thenReturn(resource);
final List records = Collections.singletonList(Generator.generatePersistChange(resource));
when(resourceServiceMock.getChanges(resource)).thenReturn(records);
diff --git a/src/test/java/cz/cvut/kbss/termit/rest/SearchControllerTest.java b/src/test/java/cz/cvut/kbss/termit/rest/SearchControllerTest.java
index da053fa69..d8abed694 100644
--- a/src/test/java/cz/cvut/kbss/termit/rest/SearchControllerTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/rest/SearchControllerTest.java
@@ -29,7 +29,6 @@
import cz.cvut.kbss.termit.environment.Generator;
import cz.cvut.kbss.termit.service.business.SearchService;
import cz.cvut.kbss.termit.util.Constants;
-import cz.cvut.kbss.termit.util.Vocabulary;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -76,7 +75,7 @@ void setUp() {
void fullTextSearchExecutesSearchOnService() throws Exception {
final List expected = Collections
.singletonList(
- new FullTextSearchResult(Generator.generateUri(), "test", null, null, Vocabulary.s_c_term,
+ new FullTextSearchResult(Generator.generateUri(), "test", null, null, SKOS.CONCEPT,
"test", "test", 1.0));
when(searchServiceMock.fullTextSearch(any())).thenReturn(expected);
final String searchString = "test";
@@ -97,7 +96,7 @@ void fullTextSearchOfTermsWithoutVocabularySpecificationExecutesSearchOnService(
final URI vocabularyIri = URI.create("https://test.org/vocabulary");
final List expected = Collections
.singletonList(new FullTextSearchResult(Generator.generateUri(), "test", vocabularyIri, null,
- Vocabulary.s_c_term, "test", "test", 1.0));
+ SKOS.CONCEPT, "test", "test", 1.0));
when(searchServiceMock.fullTextSearchOfTerms(any(), any())).thenReturn(expected);
final String searchString = "test";
diff --git a/src/test/java/cz/cvut/kbss/termit/rest/TermControllerTest.java b/src/test/java/cz/cvut/kbss/termit/rest/TermControllerTest.java
index 91b462006..3133f713c 100644
--- a/src/test/java/cz/cvut/kbss/termit/rest/TermControllerTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/rest/TermControllerTest.java
@@ -147,7 +147,7 @@ void termsExistCheckReturnOkIfTermLabelExistsInVocabulary() throws Exception {
final String language = "en";
final URI vocabularyUri = URI.create(namespace + VOCABULARY_NAME);
when(idResolverMock.resolveIdentifier(namespace, VOCABULARY_NAME)).thenReturn(vocabularyUri);
- when(termServiceMock.getRequiredVocabularyReference(vocabularyUri)).thenReturn(vocabulary);
+ when(termServiceMock.getVocabularyReference(vocabularyUri)).thenReturn(vocabulary);
when(termServiceMock.existsInVocabulary(any(), any(), any())).thenReturn(true);
mockMvc.perform(
head(PATH + VOCABULARY_NAME + "/terms")
@@ -165,7 +165,7 @@ void termsExistCheckReturn404IfTermLabelDoesNotExistInVocabulary() throws Except
final String language = "en";
final URI vocabularyUri = URI.create(namespace + VOCABULARY_NAME);
when(idResolverMock.resolveIdentifier(namespace, VOCABULARY_NAME)).thenReturn(vocabularyUri);
- when(termServiceMock.getRequiredVocabularyReference(vocabularyUri)).thenReturn(vocabulary);
+ when(termServiceMock.getVocabularyReference(vocabularyUri)).thenReturn(vocabulary);
when(termServiceMock.existsInVocabulary(any(), any(), any())).thenReturn(false);
mockMvc.perform(
head(PATH + VOCABULARY_NAME + "/terms")
@@ -1042,7 +1042,7 @@ void getAllTermsCallsServiceWithSearchString() throws Exception {
void checkTermsRetrievesNumberOfTermsInVocabularyWithSpecifiedIdentifier() throws Exception {
when(idResolverMock.resolveIdentifier(config.getNamespace().getVocabulary(), VOCABULARY_NAME))
.thenReturn(URI.create(VOCABULARY_URI));
- when(termServiceMock.getRequiredVocabularyReference(vocabulary.getUri())).thenReturn(vocabulary);
+ when(termServiceMock.getVocabularyReference(vocabulary.getUri())).thenReturn(vocabulary);
final Integer termCount = Generator.randomInt(0, 200);
when(termServiceMock.getTermCount(vocabulary)).thenReturn(termCount);
diff --git a/src/test/java/cz/cvut/kbss/termit/rest/UserControllerTest.java b/src/test/java/cz/cvut/kbss/termit/rest/UserControllerTest.java
index 62a261d88..b23e3ccf4 100644
--- a/src/test/java/cz/cvut/kbss/termit/rest/UserControllerTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/rest/UserControllerTest.java
@@ -171,7 +171,7 @@ void changeRoleUsesProvidedNamespaceToResolveUserUri() throws Exception {
void getManagedAssetsRetrievesManagedAssetsForUserWithSpecifiedUri() throws Exception {
final String namespace = Vocabulary.s_c_uzivatel_termitu + "/";
when(idResolverMock.resolveIdentifier(any(), any())).thenReturn(user.getUri());
- when(userService.getRequiredReference(user.getUri())).thenReturn(user);
+ when(userService.getReference(user.getUri())).thenReturn(user);
final List resources = Collections.singletonList(
new RdfsResource(Generator.generateUri(), MultilingualString.create("Test term", Environment.LANGUAGE),
null,
diff --git a/src/test/java/cz/cvut/kbss/termit/rest/UserGroupControllerTest.java b/src/test/java/cz/cvut/kbss/termit/rest/UserGroupControllerTest.java
index 219873b6e..b0f7740d1 100644
--- a/src/test/java/cz/cvut/kbss/termit/rest/UserGroupControllerTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/rest/UserGroupControllerTest.java
@@ -80,7 +80,7 @@ void createReturnsCreatedResponseWithLocationHeader() throws Exception {
void removeRemovesSpecifiedGroupViaService() throws Exception {
final UserGroup toRemove = Generator.generateUserGroup();
final String fragment = IdentifierResolver.extractIdentifierFragment(toRemove.getUri());
- when(groupService.getRequiredReference(toRemove.getUri())).thenReturn(toRemove);
+ when(groupService.getReference(toRemove.getUri())).thenReturn(toRemove);
mockMvc.perform(delete(UserGroupController.PATH + "/" + fragment)).andExpect(status().isNoContent());
verify(groupService).remove(toRemove);
}
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 2dbfcb2de..afc335516 100644
--- a/src/test/java/cz/cvut/kbss/termit/rest/VocabularyControllerTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/rest/VocabularyControllerTest.java
@@ -352,7 +352,7 @@ void getTransitiveImportsReturnsCollectionOfImportIdentifiersRetrievedFromServic
.thenReturn(VOCABULARY_URI);
final Set imports = IntStream.range(0, 5).mapToObj(i -> Generator.generateUri())
.collect(Collectors.toSet());
- when(serviceMock.getRequiredReference(VOCABULARY_URI)).thenReturn(vocabulary);
+ when(serviceMock.getReference(VOCABULARY_URI)).thenReturn(vocabulary);
when(serviceMock.getTransitivelyImportedVocabularies(vocabulary)).thenReturn(imports);
final MvcResult mvcResult =
@@ -361,7 +361,7 @@ void getTransitiveImportsReturnsCollectionOfImportIdentifiersRetrievedFromServic
final Set result = readValue(mvcResult, new TypeReference>() {
});
assertEquals(imports, result);
- verify(serviceMock).getRequiredReference(VOCABULARY_URI);
+ verify(serviceMock).getReference(VOCABULARY_URI);
verify(serviceMock).getTransitivelyImportedVocabularies(vocabulary);
}
@@ -379,7 +379,7 @@ void getTransitiveImportsReturnsEmptyCollectionWhenNoImportsAreFoundForVocabular
});
assertNotNull(result);
assertTrue(result.isEmpty());
- verify(serviceMock).getRequiredReference(VOCABULARY_URI);
+ verify(serviceMock).getReference(VOCABULARY_URI);
verify(serviceMock).getTransitivelyImportedVocabularies(vocabulary);
}
@@ -470,7 +470,7 @@ private Vocabulary generateVocabularyAndInitReferenceResolution() {
vocabulary.setUri(VOCABULARY_URI);
when(idResolverMock.resolveIdentifier(configMock.getNamespace().getVocabulary(), FRAGMENT))
.thenReturn(VOCABULARY_URI);
- when(serviceMock.getRequiredReference(VOCABULARY_URI)).thenReturn(vocabulary);
+ when(serviceMock.getReference(VOCABULARY_URI)).thenReturn(vocabulary);
return vocabulary;
}
diff --git a/src/test/java/cz/cvut/kbss/termit/rest/readonly/ReadOnlyTermControllerTest.java b/src/test/java/cz/cvut/kbss/termit/rest/readonly/ReadOnlyTermControllerTest.java
index 6d34885de..2b8be7ed8 100644
--- a/src/test/java/cz/cvut/kbss/termit/rest/readonly/ReadOnlyTermControllerTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/rest/readonly/ReadOnlyTermControllerTest.java
@@ -277,7 +277,7 @@ void getCommentsRetrievesCommentsForSpecifiedTermUsingDefaultTimeInterval() thro
final URI termUri = initTermUriResolution();
final Term term = Generator.generateTerm();
term.setUri(termUri);
- when(termService.getRequiredReference(term.getUri())).thenReturn(term);
+ when(termService.getReference(term.getUri())).thenReturn(term);
final List comments = generateComments(term);
when(termService.getComments(eq(term), any(Instant.class), any(Instant.class))).thenReturn(comments);
@@ -296,7 +296,7 @@ void getCommentsRetrievesCommentsInSpecifiedTimeInterval() throws Exception {
final URI termUri = initTermUriResolution();
final Term term = Generator.generateTerm();
term.setUri(termUri);
- when(termService.getRequiredReference(term.getUri())).thenReturn(term);
+ when(termService.getReference(term.getUri())).thenReturn(term);
final List comments = generateComments(term);
when(termService.getComments(eq(term), any(Instant.class), any(Instant.class))).thenReturn(comments);
final Instant from = Utils.timestamp().minus(Generator.randomInt(50, 100), ChronoUnit.DAYS);
@@ -317,7 +317,7 @@ void getDefinitionallyRelatedOfRetrievesDefinitionalOccurrencesOfSpecifiedTerm()
final URI termUri = initTermUriResolution();
final Term term = Generator.generateTerm();
term.setUri(termUri);
- when(termService.getRequiredReference(termUri)).thenReturn(term);
+ when(termService.getReference(termUri)).thenReturn(term);
final List occurrences = generateOccurrences(term, true);
when(termService.getDefinitionallyRelatedOf(term)).thenReturn(occurrences);
@@ -327,7 +327,7 @@ void getDefinitionallyRelatedOfRetrievesDefinitionalOccurrencesOfSpecifiedTerm()
final List result = readValue(mvcResult, new TypeReference>() {
});
assertThat(result, containsSameEntities(occurrences));
- verify(termService).getRequiredReference(termUri);
+ verify(termService).getReference(termUri);
verify(termService).getDefinitionallyRelatedOf(term);
}
@@ -348,7 +348,7 @@ void getDefinitionallyRelatedTargetingRetrievesDefinitionalOccurrencesTargetingS
final URI termUri = initTermUriResolution();
final Term term = Generator.generateTerm();
term.setUri(termUri);
- when(termService.getRequiredReference(termUri)).thenReturn(term);
+ when(termService.getReference(termUri)).thenReturn(term);
final List occurrences = generateOccurrences(term, false);
when(termService.getDefinitionallyRelatedTargeting(term)).thenReturn(occurrences);
@@ -358,7 +358,7 @@ void getDefinitionallyRelatedTargetingRetrievesDefinitionalOccurrencesTargetingS
final List result = readValue(mvcResult, new TypeReference>() {
});
assertThat(result, containsSameEntities(occurrences));
- verify(termService).getRequiredReference(termUri);
+ verify(termService).getReference(termUri);
verify(termService).getDefinitionallyRelatedTargeting(term);
}
diff --git a/src/test/java/cz/cvut/kbss/termit/service/BaseServiceTestRunner.java b/src/test/java/cz/cvut/kbss/termit/service/BaseServiceTestRunner.java
index f46527af9..8ee8d349e 100644
--- a/src/test/java/cz/cvut/kbss/termit/service/BaseServiceTestRunner.java
+++ b/src/test/java/cz/cvut/kbss/termit/service/BaseServiceTestRunner.java
@@ -46,7 +46,7 @@
TestServiceConfig.class}, initializers = {ConfigDataApplicationContextInitializer.class})
@ActiveProfiles("test")
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
-public class BaseServiceTestRunner extends TransactionalTestRunner {
+public abstract class BaseServiceTestRunner extends TransactionalTestRunner {
private static final String EXISTENCE_CHECK_QUERY = "ASK { ?x a ?type . }";
diff --git a/src/test/java/cz/cvut/kbss/termit/service/IdentifierResolverTest.java b/src/test/java/cz/cvut/kbss/termit/service/IdentifierResolverTest.java
index 650bf3a77..d918e4574 100644
--- a/src/test/java/cz/cvut/kbss/termit/service/IdentifierResolverTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/service/IdentifierResolverTest.java
@@ -307,4 +307,12 @@ void generateIdentifierHandlesStringsWithReservedUriCharacters() {
final String invalidString = "Bug #$# test";
assertDoesNotThrow(() -> sut.generateIdentifier(namespace, invalidString));
}
+
+ @Test
+ void generateIdentifierRemovesSectionSign() {
+ final String namespace = Vocabulary.s_c_slovnik;
+ final String label = "je povinným subjektem podle §2 zákona 106/1999 Sb.";
+ final URI result = sut.generateIdentifier(namespace, label);
+ assertEquals(URI.create(namespace + "/je-povinným-subjektem-podle-2-zákona-106-1999-sb."), result);
+ }
}
diff --git a/src/test/java/cz/cvut/kbss/termit/service/business/ResourceServiceTest.java b/src/test/java/cz/cvut/kbss/termit/service/business/ResourceServiceTest.java
index 9c02130a7..b98434ce4 100644
--- a/src/test/java/cz/cvut/kbss/termit/service/business/ResourceServiceTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/service/business/ResourceServiceTest.java
@@ -105,7 +105,7 @@ void updateUpdatesResourceViaRepositoryService() {
@Test
void removeRemovesResourceViaRepositoryService() {
final Resource resource = Generator.generateResourceWithId();
- when(resourceRepositoryService.getRequiredReference(resource.getUri())).thenReturn(resource);
+ when(resourceRepositoryService.getReference(resource.getUri())).thenReturn(resource);
sut.remove(resource);
verify(resourceRepositoryService).remove(resource);
}
@@ -117,7 +117,7 @@ void removeEnsuresAttributesForDocumentManagerArePresent() {
toRemove.setUri(Generator.generateUri());
final Resource resource = Generator.generateResource();
resource.setUri(toRemove.getUri());
- when(resourceRepositoryService.getRequiredReference(resource.getUri())).thenReturn(resource);
+ when(resourceRepositoryService.getReference(resource.getUri())).thenReturn(resource);
sut.remove(resource);
verify(resourceRepositoryService).remove(resource);
verify(documentManager).remove(resource);
@@ -216,7 +216,7 @@ void runTextAnalysisInvokesAnalysisAlsoWithImportedVocabulariesOfVocabularyRElat
final Vocabulary vocabulary = Generator.generateVocabularyWithId();
file.getDocument().setVocabulary(vocabulary.getUri());
final Set imported = new HashSet<>(Arrays.asList(Generator.generateUri(), Generator.generateUri()));
- when(vocabularyService.getRequiredReference(vocabulary.getUri())).thenReturn(vocabulary);
+ when(vocabularyService.getReference(vocabulary.getUri())).thenReturn(vocabulary);
when(vocabularyService.getTransitivelyImportedVocabularies(vocabulary)).thenReturn(imported);
sut.runTextAnalysis(file, Collections.emptySet());
@@ -233,9 +233,9 @@ void runTextAnalysisInvokesAnalysisWithProvidedVocabulariesAndTheirImports() {
final Set vOneImports = new HashSet<>(Arrays.asList(Generator.generateUri(), Generator.generateUri()));
final Vocabulary vTwo = Generator.generateVocabularyWithId();
final Set vTwoImports = Collections.singleton(Generator.generateUri());
- when(vocabularyService.getRequiredReference(vOne.getUri())).thenReturn(vOne);
+ when(vocabularyService.getReference(vOne.getUri())).thenReturn(vOne);
when(vocabularyService.getTransitivelyImportedVocabularies(vOne)).thenReturn(vOneImports);
- when(vocabularyService.getRequiredReference(vTwo.getUri())).thenReturn(vTwo);
+ when(vocabularyService.getReference(vTwo.getUri())).thenReturn(vTwo);
when(vocabularyService.getTransitivelyImportedVocabularies(vTwo)).thenReturn(vTwoImports);
sut.runTextAnalysis(file, new HashSet<>(Arrays.asList(vOne.getUri(), vTwo.getUri())));
@@ -255,13 +255,6 @@ void getReferenceDelegatesCallToRepositoryService() {
verify(resourceRepositoryService).getReference(uri);
}
- @Test
- void getRequiredReferenceDelegatesCallToRepositoryService() {
- final URI uri = Generator.generateUri();
- sut.getRequiredReference(uri);
- verify(resourceRepositoryService).getRequiredReference(uri);
- }
-
@Test
void getFilesReturnsFilesFromDocument() {
final Document doc = Generator.generateDocumentWithId();
@@ -324,11 +317,11 @@ void addFileToDocumentPersistsFileIntoVocabularyContextForDocumentWithVocabulary
final Document doc = Generator.generateDocumentWithId();
doc.setVocabulary(vocabulary.getUri());
final File fOne = Generator.generateFileWithId("test.html");
- when(vocabularyService.getRequiredReference(vocabulary.getUri())).thenReturn(vocabulary);
+ when(vocabularyService.getReference(vocabulary.getUri())).thenReturn(vocabulary);
sut.addFileToDocument(doc, fOne);
verify(resourceRepositoryService).persist(fOne, vocabulary);
- verify(vocabularyService).getRequiredReference(vocabulary.getUri());
+ verify(vocabularyService).getReference(vocabulary.getUri());
}
@Test
@@ -337,11 +330,11 @@ void addFileToDocumentUpdatesDocumentInVocabularyContextForDocumentWithVocabular
final Document doc = Generator.generateDocumentWithId();
doc.setVocabulary(vocabulary.getUri());
final File fOne = Generator.generateFileWithId("test.html");
- when(vocabularyService.getRequiredReference(vocabulary.getUri())).thenReturn(vocabulary);
+ when(vocabularyService.getReference(vocabulary.getUri())).thenReturn(vocabulary);
sut.addFileToDocument(doc, fOne);
verify(resourceRepositoryService).persist(doc);
- verify(vocabularyService).getRequiredReference(vocabulary.getUri());
+ verify(vocabularyService).getReference(vocabulary.getUri());
}
@Test
@@ -400,7 +393,7 @@ void hasContentReturnsFalseForNonFile() {
@Test
void removeRemovesAssociatedDiskContent() {
final Resource resource = Generator.generateResourceWithId();
- when(resourceRepositoryService.getRequiredReference(resource.getUri())).thenReturn(resource);
+ when(resourceRepositoryService.getReference(resource.getUri())).thenReturn(resource);
sut.remove(resource);
verify(documentManager).remove(resource);
}
diff --git a/src/test/java/cz/cvut/kbss/termit/service/business/TermServiceTest.java b/src/test/java/cz/cvut/kbss/termit/service/business/TermServiceTest.java
index a7d26dde4..cd1fed9b7 100644
--- a/src/test/java/cz/cvut/kbss/termit/service/business/TermServiceTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/service/business/TermServiceTest.java
@@ -271,20 +271,10 @@ void findAllCallsFindAllInRepositoryService() {
@Test
void getReferenceRetrievesTermReferenceFromRepositoryService() {
final Term t = Generator.generateTermWithId();
- when(termRepositoryService.getReference(t.getUri())).thenReturn(Optional.of(t));
- final Optional result = sut.getReference(t.getUri());
- assertTrue(result.isPresent());
- assertEquals(t, result.get());
- verify(termRepositoryService).getReference(t.getUri());
- }
-
- @Test
- void getRequiredReferenceRetrievesTermReferenceFromRepositoryService() {
- final Term t = Generator.generateTermWithId();
- when(termRepositoryService.getRequiredReference(t.getUri())).thenReturn(t);
- final Term result = sut.getRequiredReference(t.getUri());
+ when(termRepositoryService.getReference(t.getUri())).thenReturn(t);
+ final Term result = sut.getReference(t.getUri());
assertEquals(t, result);
- verify(termRepositoryService).getRequiredReference(t.getUri());
+ verify(termRepositoryService).getReference(t.getUri());
}
@Test
@@ -465,7 +455,7 @@ void persistChildInvokesTextAnalysisOnAllTermsInParentTermVocabulary() {
final Term parent = generateTermWithId();
parent.setVocabulary(vocabulary.getUri());
final Term childToPersist = generateTermWithId();
- when(vocabularyService.getRequiredReference(vocabulary.getUri())).thenReturn(vocabulary);
+ when(vocabularyService.getReference(vocabulary.getUri())).thenReturn(vocabulary);
when(vocabularyContextMapper.getVocabularyContext(vocabulary.getUri())).thenReturn(vocabulary.getUri());
sut.persistChild(childToPersist, parent);
@@ -483,7 +473,7 @@ void updateInvokesTextAnalysisOnAllTermsInTermsVocabularyWhenLabelHasChanged() {
update.setDescription(new MultilingualString(original.getDescription().getValue()));
update.setVocabulary(vocabulary.getUri());
when(termRepositoryService.findRequired(original.getUri())).thenReturn(original);
- when(vocabularyService.getRequiredReference(vocabulary.getUri())).thenReturn(vocabulary);
+ when(vocabularyService.getReference(vocabulary.getUri())).thenReturn(vocabulary);
update.getLabel().set(Environment.LANGUAGE, "updatedLabel");
sut.update(update);
diff --git a/src/test/java/cz/cvut/kbss/termit/service/business/readonly/ReadOnlyTermServiceTest.java b/src/test/java/cz/cvut/kbss/termit/service/business/readonly/ReadOnlyTermServiceTest.java
index dfc4626e5..2dd2eda9c 100644
--- a/src/test/java/cz/cvut/kbss/termit/service/business/readonly/ReadOnlyTermServiceTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/service/business/readonly/ReadOnlyTermServiceTest.java
@@ -70,7 +70,7 @@ class ReadOnlyTermServiceTest {
private ReadOnlyTermService sut;
@Test
- void getRequiredVocabularyReferenceRetrievesReferenceToVocabularyFromService() {
+ void getVocabularyReferenceRetrievesReferenceToVocabularyFromService() {
final Vocabulary vocabulary = Generator.generateVocabularyWithId();
when(termService.findVocabularyRequired(any())).thenReturn(vocabulary);
diff --git a/src/test/java/cz/cvut/kbss/termit/service/changetracking/ChangeTrackerTest.java b/src/test/java/cz/cvut/kbss/termit/service/changetracking/ChangeTrackerTest.java
index 69ead3e5f..c5f924074 100644
--- a/src/test/java/cz/cvut/kbss/termit/service/changetracking/ChangeTrackerTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/service/changetracking/ChangeTrackerTest.java
@@ -23,6 +23,8 @@
import cz.cvut.kbss.jopa.vocabulary.SKOS;
import cz.cvut.kbss.termit.environment.Environment;
import cz.cvut.kbss.termit.environment.Generator;
+import cz.cvut.kbss.termit.event.AssetPersistEvent;
+import cz.cvut.kbss.termit.event.AssetUpdateEvent;
import cz.cvut.kbss.termit.model.Term;
import cz.cvut.kbss.termit.model.User;
import cz.cvut.kbss.termit.model.Vocabulary;
@@ -41,9 +43,13 @@
import java.util.List;
import static cz.cvut.kbss.termit.service.changetracking.MetamodelBasedChangeCalculatorTest.cloneOf;
-import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.CoreMatchers.anyOf;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
class ChangeTrackerTest extends BaseServiceTestRunner {
@@ -72,13 +78,13 @@ void setUp() {
}
@Test
- void recordAddEventStoresCreationChangeRecordInRepository() {
+ void onAssetPersistEventStoresCreationChangeRecordInRepository() {
enableRdfsInference(em);
final Term newTerm = Generator.generateTermWithId();
newTerm.setGlossary(vocabulary.getGlossary().getUri());
transactional(() -> {
em.persist(newTerm, descriptorFactory.termDescriptor(vocabulary));
- sut.recordAddEvent(newTerm);
+ sut.onAssetPersistEvent(new AssetPersistEvent(this, newTerm));
});
final List result = findRecords(newTerm);
@@ -91,7 +97,8 @@ void recordAddEventStoresCreationChangeRecordInRepository() {
}
private List findRecords(HasIdentifier entity) {
- return em.createNativeQuery("SELECT ?x WHERE { ?x a ?changeRecord ; ?concerns ?entity . }", AbstractChangeRecord.class)
+ return em.createNativeQuery("SELECT ?x WHERE { ?x a ?changeRecord ; ?concerns ?entity . }",
+ AbstractChangeRecord.class)
.setParameter("changeRecord", URI.create(cz.cvut.kbss.termit.util.Vocabulary.s_c_zmena))
.setParameter("concerns", URI.create(cz.cvut.kbss.termit.util.Vocabulary.s_p_ma_zmenenou_entitu))
.setParameter("entity", entity.getUri())
@@ -99,20 +106,20 @@ private List findRecords(HasIdentifier entity) {
}
@Test
- void recordUpdateEventDoesNothingWhenAssetDidNotChange() {
+ void onAssetUpdateEventEventDoesNothingWhenAssetDidNotChange() {
enableRdfsInference(em);
final Term original = Generator.generateTermWithId();
original.setVocabulary(vocabulary.getUri());
transactional(() -> em.persist(original, descriptorFactory.termDescriptor(original)));
final Term update = cloneOf(original);
- transactional(() -> sut.recordUpdateEvent(update, original));
+ transactional(() -> sut.onAssetUpdateEvent(new AssetUpdateEvent(this, update)));
assertTrue(findRecords(original).isEmpty());
}
@Test
- void recordUpdateRecordsSingleChangeToLiteralAttribute() {
+ void onAssetUpdateEventRecordsSingleChangeToLiteralAttribute() {
enableRdfsInference(em);
final Term original = Generator.generateTermWithId();
original.setGlossary(vocabulary.getGlossary().getUri());
@@ -120,7 +127,7 @@ void recordUpdateRecordsSingleChangeToLiteralAttribute() {
final Term update = cloneOf(original);
update.setDefinition(MultilingualString.create("Updated definition of this term.", Environment.LANGUAGE));
- transactional(() -> sut.recordUpdateEvent(update, original));
+ transactional(() -> sut.onAssetUpdateEvent(new AssetUpdateEvent(this, update)));
final List result = findRecords(original);
assertEquals(1, result.size());
@@ -131,7 +138,7 @@ void recordUpdateRecordsSingleChangeToLiteralAttribute() {
}
@Test
- void recordUpdateRecordsMultipleChangesToAttributes() {
+ void onAssetUpdateEventRecordsMultipleChangesToAttributes() {
enableRdfsInference(em);
final Term original = Generator.generateTermWithId();
original.setGlossary(vocabulary.getGlossary().getUri());
@@ -140,7 +147,7 @@ void recordUpdateRecordsMultipleChangesToAttributes() {
final Term update = cloneOf(original);
update.setDefinition(MultilingualString.create("Updated definition of this term.", Environment.LANGUAGE));
update.setSources(Collections.singleton(Generator.generateUri().toString()));
- transactional(() -> sut.recordUpdateEvent(update, original));
+ transactional(() -> sut.onAssetUpdateEvent(new AssetUpdateEvent(this, update)));
final List result = findRecords(original);
assertEquals(2, result.size());
@@ -148,7 +155,7 @@ void recordUpdateRecordsMultipleChangesToAttributes() {
assertEquals(original.getUri(), record.getChangedEntity());
assertThat(record, instanceOf(UpdateChangeRecord.class));
assertThat(((UpdateChangeRecord) record).getChangedAttribute().toString(), anyOf(equalTo(SKOS.DEFINITION),
- equalTo(DC.Terms.SOURCE)));
+ equalTo(DC.Terms.SOURCE)));
});
}
}
diff --git a/src/test/java/cz/cvut/kbss/termit/service/document/TextAnalysisServiceTest.java b/src/test/java/cz/cvut/kbss/termit/service/document/TextAnalysisServiceTest.java
index 3327c4dab..4f56a27ba 100644
--- a/src/test/java/cz/cvut/kbss/termit/service/document/TextAnalysisServiceTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/service/document/TextAnalysisServiceTest.java
@@ -167,6 +167,8 @@ private TextAnalysisInput textAnalysisInput() {
);
input.setVocabularyRepository(repositoryUrl);
input.setLanguage(config.getPersistence().getLanguage());
+ input.setVocabularyRepositoryUserName(config.getRepository().getUsername());
+ input.setVocabularyRepositoryPassword(config.getRepository().getPassword());
return input;
}
@@ -183,6 +185,23 @@ void analyzeFilePassesContentTypeAndAcceptHeadersToService() throws Exception {
mockServer.verify();
}
+ @Test
+ void analyzeFilePassesRepositoryUsernameAndPasswordToServiceWhenProvided() throws Exception {
+ final String username = "user";
+ config.getRepository().setUsername(username);
+ final String password = "password";
+ config.getRepository().setPassword(password);
+ final TextAnalysisInput input = textAnalysisInput();
+ input.setVocabularyRepositoryUserName(username);
+ input.setVocabularyRepositoryPassword(password);
+ mockServer.expect(requestTo(config.getTextAnalysis().getUrl()))
+ .andExpect(method(HttpMethod.POST))
+ .andExpect(content().string(objectMapper.writeValueAsString(input)))
+ .andRespond(withSuccess(CONTENT, MediaType.APPLICATION_XML));
+ sut.analyzeFile(file, Collections.singleton(vocabulary.getUri()));
+ mockServer.verify();
+ }
+
@Test
void analyzeFileThrowsWebServiceIntegrationExceptionOnError() throws Exception {
final TextAnalysisInput input = textAnalysisInput();
@@ -353,4 +372,26 @@ void analyzeTermDefinitionDoesNothingWhenTextAnalysisServiceUrlIsNotConfigured()
verify(annotationGeneratorMock, never()).generateAnnotations(any(), any(Term.class));
verify(textAnalysisRecordDao, never()).persist(any());
}
+
+ @Test
+ void analyzeTermDefinitionInvokesTextAnalysisServiceWithVocabularyRepositoryUsernameAndPassword()
+ throws Exception {
+ final Term term = Generator.generateTermWithId();
+ term.setVocabulary(vocabulary.getUri());
+ final TextAnalysisInput input = textAnalysisInput();
+ input.setContent(term.getDefinition().get(Environment.LANGUAGE));
+ final String username = "user";
+ config.getRepository().setUsername(username);
+ final String password = "password";
+ config.getRepository().setPassword(password);
+ input.setVocabularyRepositoryUserName(username);
+ input.setVocabularyRepositoryPassword(password);
+ mockServer.expect(requestTo(config.getTextAnalysis().getUrl()))
+ .andExpect(method(HttpMethod.POST))
+ .andExpect(content().string(objectMapper.writeValueAsString(input)))
+ .andRespond(withSuccess(CONTENT, MediaType.APPLICATION_XML));
+
+ sut.analyzeTermDefinition(term, vocabulary.getUri());
+ mockServer.verify();
+ }
}
diff --git a/src/test/java/cz/cvut/kbss/termit/service/repository/BaseRepositoryServiceTest.java b/src/test/java/cz/cvut/kbss/termit/service/repository/BaseRepositoryServiceTest.java
index 9bbcbd4ca..2c9b4a07d 100644
--- a/src/test/java/cz/cvut/kbss/termit/service/repository/BaseRepositoryServiceTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/service/repository/BaseRepositoryServiceTest.java
@@ -256,4 +256,19 @@ void findRequiredInvokesPostLoadOnLoadedInstance() {
inOrder.verify(userAccountDaoMock).find(instance.getUri());
inOrder.verify(sut).postLoad(instance);
}
+
+ @Test
+ void getReferenceRetrievesReferenceFromDaoWhenInstanceExists() {
+ final UserAccount instance = Generator.generateUserAccountWithPassword();
+ transactional(() -> em.persist(instance));
+ final UserAccount result = sut.getReference(instance.getUri());
+ assertNotNull(result);
+ assertEquals(instance.getUri(), result.getUri());
+ }
+
+ @Test
+ void getReferenceThrowsNotFoundExceptionWhenInstanceDoesNotExist() {
+ final URI id = Generator.generateUri();
+ assertThrows(NotFoundException.class, () -> sut.getReference(id));
+ }
}
diff --git a/src/test/java/cz/cvut/kbss/termit/service/repository/RepositoryAccessControlListServiceTest.java b/src/test/java/cz/cvut/kbss/termit/service/repository/RepositoryAccessControlListServiceTest.java
index 492f4c4d2..a4532d325 100644
--- a/src/test/java/cz/cvut/kbss/termit/service/repository/RepositoryAccessControlListServiceTest.java
+++ b/src/test/java/cz/cvut/kbss/termit/service/repository/RepositoryAccessControlListServiceTest.java
@@ -138,11 +138,11 @@ void updateRecordLoadsTargetAccessControlListAndUpdatesSpecifiedRecords() {
}
@Test
- void getRequiredReferenceThrowsNotFoundExceptionWhenMatchingAccessControlListIsNotFound() {
+ void getReferenceThrowsNotFoundExceptionWhenMatchingAccessControlListIsNotFound() {
final URI uri = Generator.generateUri();
when(dao.getReference(uri)).thenReturn(Optional.empty());
- assertThrows(NotFoundException.class, () -> sut.getRequiredReference(uri));
+ assertThrows(NotFoundException.class, () -> sut.getReference(uri));
verify(dao).getReference(uri);
}