-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #168 from kbss-cvut/163-vocabulary-iri-context-iri…
…-different 163 vocabulary iri context iri different
- Loading branch information
Showing
36 changed files
with
445 additions
and
42 deletions.
There are no files selected for viewing
13 changes: 13 additions & 0 deletions
13
src/main/java/cz/cvut/kbss/termit/event/VocabularyCreatedEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package cz.cvut.kbss.termit.event; | ||
|
||
import org.springframework.context.ApplicationEvent; | ||
|
||
/** | ||
* Indicates that a vocabulary has been created. | ||
*/ | ||
public class VocabularyCreatedEvent extends ApplicationEvent { | ||
|
||
public VocabularyCreatedEvent(Object source) { | ||
super(source); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/main/java/cz/cvut/kbss/termit/exception/AmbiguousVocabularyContextException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package cz.cvut.kbss.termit.exception; | ||
|
||
/** | ||
* Indicates that a vocabulary has been found in multiple repository contexts, and it was not possible to determine | ||
* which one to use. | ||
*/ | ||
public class AmbiguousVocabularyContextException extends TermItException { | ||
|
||
public AmbiguousVocabularyContextException(String message) { | ||
super(message); | ||
} | ||
} |
78 changes: 78 additions & 0 deletions
78
src/main/java/cz/cvut/kbss/termit/persistence/context/CachingVocabularyContextMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package cz.cvut.kbss.termit.persistence.context; | ||
|
||
import cz.cvut.kbss.jopa.model.EntityManager; | ||
import cz.cvut.kbss.termit.event.EvictCacheEvent; | ||
import cz.cvut.kbss.termit.event.VocabularyCreatedEvent; | ||
import cz.cvut.kbss.termit.exception.AmbiguousVocabularyContextException; | ||
import cz.cvut.kbss.termit.util.Vocabulary; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.context.annotation.Profile; | ||
import org.springframework.context.event.ContextRefreshedEvent; | ||
import org.springframework.context.event.EventListener; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.net.URI; | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import static cz.cvut.kbss.termit.util.Utils.uriToString; | ||
|
||
/** | ||
* Caching implementation of the {@link VocabularyContextMapper}. | ||
* <p> | ||
* Context map is loaded on startup and reloaded every time a vocabulary is created. | ||
*/ | ||
@Component | ||
@Profile("!no-cache") | ||
public class CachingVocabularyContextMapper implements VocabularyContextMapper { | ||
|
||
private static final Logger LOG = LoggerFactory.getLogger(CachingVocabularyContextMapper.class); | ||
|
||
private final EntityManager em; | ||
|
||
private Map<URI, List<URI>> contexts; | ||
|
||
public CachingVocabularyContextMapper(EntityManager em) { | ||
this.em = em; | ||
} | ||
|
||
/** | ||
* Loads vocabulary context info into memory (cache). | ||
*/ | ||
@EventListener(value = {VocabularyCreatedEvent.class, EvictCacheEvent.class, ContextRefreshedEvent.class}) | ||
public void load() { | ||
this.contexts = new HashMap<>(); | ||
em.createNativeQuery("SELECT ?v ?g WHERE { GRAPH ?g { ?v a ?type . } }") | ||
.setParameter("type", URI.create(Vocabulary.s_c_slovnik)) | ||
.getResultStream().forEach(row -> { | ||
assert row instanceof Object[]; | ||
assert ((Object[]) row).length == 2; | ||
final Object[] bindingSet = (Object[]) row; | ||
final List<URI> ctx = contexts.computeIfAbsent((URI) bindingSet[0], (k) -> new ArrayList<>()); | ||
ctx.add((URI) bindingSet[1]); | ||
}); | ||
} | ||
|
||
/** | ||
* Gets identifier of the repository context in which vocabulary with the specified identifier is stored. | ||
* | ||
* @param vocabularyUri Vocabulary identifier | ||
* @return Repository context identifier | ||
*/ | ||
public URI getVocabularyContext(URI vocabularyUri) { | ||
if (!contexts.containsKey(vocabularyUri)) { | ||
LOG.debug("No context mapped for vocabulary {}, returning the vocabulary IRI as context identifier.", | ||
uriToString(vocabularyUri)); | ||
return vocabularyUri; | ||
} | ||
final List<URI> vocabularyContexts = contexts.get(vocabularyUri); | ||
if (vocabularyContexts.size() > 1) { | ||
throw new AmbiguousVocabularyContextException( | ||
"Multiple repository contexts found for vocabulary " + uriToString(vocabularyUri)); | ||
} | ||
return vocabularyContexts.get(0); | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
src/main/java/cz/cvut/kbss/termit/persistence/context/DefaultVocabularyContextMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package cz.cvut.kbss.termit.persistence.context; | ||
|
||
import cz.cvut.kbss.jopa.exceptions.NoResultException; | ||
import cz.cvut.kbss.jopa.exceptions.NoUniqueResultException; | ||
import cz.cvut.kbss.jopa.model.EntityManager; | ||
import cz.cvut.kbss.termit.exception.AmbiguousVocabularyContextException; | ||
import cz.cvut.kbss.termit.util.Vocabulary; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.context.annotation.Profile; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.net.URI; | ||
import java.util.Objects; | ||
|
||
import static cz.cvut.kbss.termit.util.Utils.uriToString; | ||
|
||
/** | ||
* Default implementation of the context mapper resolves vocabulary context on every call. | ||
* <p> | ||
* This incurs a performance penalty of executing a simple query, but does not suffer from potentially stale cache | ||
* data. | ||
*/ | ||
@Component | ||
@Profile("no-cache") | ||
public class DefaultVocabularyContextMapper implements VocabularyContextMapper { | ||
|
||
private static final Logger LOG = LoggerFactory.getLogger(DefaultVocabularyContextMapper.class); | ||
|
||
private final EntityManager em; | ||
|
||
public DefaultVocabularyContextMapper(EntityManager em) { | ||
this.em = em; | ||
} | ||
|
||
@Override | ||
public URI getVocabularyContext(URI vocabularyUri) { | ||
Objects.requireNonNull(vocabularyUri); | ||
try { | ||
return em.createNativeQuery("SELECT ?g WHERE { GRAPH ?g { ?vocabulary a ?type . } }", URI.class) | ||
.setParameter("type", URI.create(Vocabulary.s_c_slovnik)) | ||
.setParameter("vocabulary", vocabularyUri) | ||
.getSingleResult(); | ||
} catch (NoResultException e) { | ||
LOG.debug("No context mapped for vocabulary {}, returning the vocabulary IRI as context identifier.", | ||
uriToString(vocabularyUri)); | ||
return vocabularyUri; | ||
} catch (NoUniqueResultException e) { | ||
throw new AmbiguousVocabularyContextException( | ||
"Multiple repository contexts found for vocabulary " + uriToString(vocabularyUri)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
src/main/java/cz/cvut/kbss/termit/persistence/context/VocabularyContextMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package cz.cvut.kbss.termit.persistence.context; | ||
|
||
import cz.cvut.kbss.termit.model.Vocabulary; | ||
|
||
import java.net.URI; | ||
import java.util.Objects; | ||
|
||
/** | ||
* Maps vocabularies to repository contexts in which they are stored. | ||
*/ | ||
public interface VocabularyContextMapper { | ||
|
||
/** | ||
* Gets identifier of the repository context in which the specified vocabulary is stored. | ||
* | ||
* @param vocabulary Vocabulary whose context to retrieve | ||
* @return Repository context identifier | ||
*/ | ||
default URI getVocabularyContext(Vocabulary vocabulary) { | ||
Objects.requireNonNull(vocabulary); | ||
return getVocabularyContext(vocabulary.getUri()); | ||
} | ||
|
||
/** | ||
* Gets identifier of the repository context in which vocabulary with the specified identifier is stored. | ||
* <p> | ||
* If the vocabulary does not exist yet (and thus has no repository context), the vocabulary identifier is returned | ||
* as context. | ||
* | ||
* @param vocabularyUri Vocabulary identifier | ||
* @return Repository context identifier | ||
* @throws cz.cvut.kbss.termit.exception.AmbiguousVocabularyContextException In case multiple contexts for a | ||
* vocabulary are found | ||
*/ | ||
URI getVocabularyContext(URI vocabularyUri); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.