Skip to content

Commit

Permalink
[Enhancement #73] Add integration tests for plural contexts support.
Browse files Browse the repository at this point in the history
  • Loading branch information
ledsoft committed Oct 6, 2020
1 parent e1bac05 commit 02285dd
Show file tree
Hide file tree
Showing 13 changed files with 165 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ <K> List<K> resolveUnpersistedItems(List<K> list) {
return Collections.emptyList();
} else {
return list.stream().filter(item -> item != null && !referenceSavingResolver
.shouldSaveReferenceToItem(item, getAttributeValueContext())).collect(Collectors.toList());
.shouldSaveReferenceToItem(item, getAttributeValueContexts())).collect(Collectors.toList());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import java.net.URI;
import java.util.Collection;
import java.util.Set;

abstract class PluralObjectPropertyStrategy<Y extends AbstractPluralAttribute<? super X, ?, ?>, X>
extends FieldStrategy<Y, X> {
Expand Down Expand Up @@ -63,16 +64,16 @@ void buildInstanceFieldValue(Object instance) {
}

/**
* Gets the context in which this attribute values are stored.
* Gets the context(s) in which this attribute values are stored.
* <p>
* I.e., this context may (and usually will be) different from the context in which this attribute's property assertion is stored, since that
* I.e., these contexts may (and usually will be) different from the context in which this attribute's property assertion is stored, since that
* is usually stored in the subject's context.
*
* @return Attribute value (referenced entity) context
* @see Descriptor#areAssertionsInSubjectContext()
*/
URI getAttributeValueContext() {
return entityDescriptor.getAttributeDescriptor(attribute).getSingleContext().orElse(null);
Set<URI> getAttributeValueContexts() {
return entityDescriptor.getAttributeDescriptor(attribute).getContexts();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import java.net.URI;
import java.util.List;
import java.util.Set;

class ReferenceSavingResolver {

Expand All @@ -47,26 +48,26 @@ class ReferenceSavingResolver {
* Otherwise, the reference should not be saved and should be registered as pending.
*
* @param value The value to save
* @param context Storage context
* @param contexts Storage contexts
* @return Whether to save the corresponding assertion or not
*/
boolean shouldSaveReference(Object value, URI context) {
return value == null || IdentifierTransformer.isValidIdentifierType(value.getClass()) || shouldSaveReferenceToItem(value, context);
boolean shouldSaveReference(Object value, Set<URI> contexts) {
return value == null || IdentifierTransformer.isValidIdentifierType(value.getClass()) || shouldSaveReferenceToItem(value, contexts);
}

/**
* Same as {@link #shouldSaveReference(Object, URI)}, but skips null-check and check whether the value is a plain identifier.
* Same as {@link #shouldSaveReference(Object, Set)}, but skips null-check and check whether the value is a plain identifier.
* <p>
* Used for collections.
*/
boolean shouldSaveReferenceToItem(Object value, URI context) {
boolean shouldSaveReferenceToItem(Object value, Set<URI> contexts) {
if (mapper.isManaged(value)) {
return true;
}
final EntityType<?> et = mapper.getEntityType(value.getClass());
assert et != null;
final URI identifier = EntityPropertiesUtils.getIdentifier(value, et);
return identifier != null && mapper.containsEntity(et.getJavaType(), identifier, new EntityDescriptor(context));
return identifier != null && mapper.containsEntity(et.getJavaType(), identifier, new EntityDescriptor(contexts));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private <T> void extractValues(Collection<T> valueCollection, AxiomValueGatherer
if (val == null) {
continue;
}
if (referenceSavingResolver.shouldSaveReferenceToItem(val, getAttributeValueContext())) {
if (referenceSavingResolver.shouldSaveReferenceToItem(val, getAttributeValueContexts())) {
final URI valId = EntityPropertiesUtils.getIdentifier(val, et);
assert valId != null;
assertionValues.add(new Value<>(NamedResource.create(valId)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.slf4j.LoggerFactory;

import java.net.URI;
import java.util.Set;

class SingularObjectPropertyStrategy<X> extends FieldStrategy<Attribute<? super X, ?>, X> {

Expand Down Expand Up @@ -86,8 +87,8 @@ void buildAxiomValuesFromInstance(X instance, AxiomValueGatherer valueBuilder) {
}
}

private URI getAttributeValueContext() {
return entityDescriptor.getAttributeDescriptor(attribute).getSingleContext().orElse(null);
private Set<URI> getAttributeValueContext() {
return entityDescriptor.getAttributeDescriptor(attribute).getContexts();
}

private <V> Value<NamedResource> extractReferenceIdentifier(final V value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ void buildAxiomValuesFromInstanceChecksForReferenceExistenceUsingTargetReference
final OWLClassA aInstance = Generators.generateOwlClassAInstance();
instance.setOwlClassA(Collections.singleton(aInstance));
sut.buildAxiomValuesFromInstance(instance, new AxiomValueGatherer(NamedResource.create(ID), null));
verify(resolverMock).shouldSaveReferenceToItem(aInstance, aDescriptor.getSingleContext().orElse(null));
verify(resolverMock).shouldSaveReferenceToItem(aInstance, aDescriptor.getContexts());
}

@Test
Expand All @@ -141,6 +141,6 @@ void buildAxiomValuesFromInstanceChecksForListItemReferenceExistenceUsingTargetR
final OWLClassA aInstance = Generators.generateOwlClassAInstance();
instance.setSimpleList(Collections.singletonList(aInstance));
sut.buildAxiomValuesFromInstance(instance, new AxiomValueGatherer(NamedResource.create(ID), null));
verify(resolverMock).shouldSaveReferenceToItem(aInstance, aDescriptor.getSingleContext().orElse(null));
verify(resolverMock).shouldSaveReferenceToItem(aInstance, aDescriptor.getContexts());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.mockito.MockitoAnnotations;

import java.net.URI;
import java.util.Collections;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
Expand All @@ -52,28 +53,28 @@ void setUp() throws Exception {

@Test
void shouldSaveReferenceReturnsTrueForNullValue() {
assertTrue(resolver.shouldSaveReference(null, null));
assertTrue(resolver.shouldSaveReference(null, Collections.emptySet()));
}

@Test
void shouldSaveReferenceReturnsTrueForPlainIdentifierValue() {
final URI value = Generators.createIndividualIdentifier();
assertTrue(resolver.shouldSaveReference(value, null));
assertTrue(resolver.shouldSaveReference(value, Collections.emptySet()));
}

@Test
void shouldSaveReferenceReturnsFalseForValueWithNullIdentifier() {
// Because it means it is not managed and does not exist in the storage either
final OWLClassA value = new OWLClassA();
when(mapperMock.getEntityType(OWLClassA.class)).thenReturn(metamodelMocks.forOwlClassA().entityType());
assertFalse(resolver.shouldSaveReference(value, null));
assertFalse(resolver.shouldSaveReference(value, Collections.emptySet()));
}

@Test
void shouldSaveReferenceReturnsTrueForValueBeingManaged() {
final OWLClassA value = Generators.generateOwlClassAInstance();
when(mapperMock.isManaged(value)).thenReturn(true);
assertTrue(resolver.shouldSaveReference(value, null));
assertTrue(resolver.shouldSaveReference(value, Collections.emptySet()));
verify(mapperMock).isManaged(value);
}

Expand All @@ -83,7 +84,7 @@ void shouldSaveReferenceReturnsTrueForValueExistingInStorage() {
when(mapperMock.isManaged(value)).thenReturn(false);
when(mapperMock.getEntityType(OWLClassA.class)).thenReturn(metamodelMocks.forOwlClassA().entityType());
when(mapperMock.containsEntity(eq(OWLClassA.class), eq(value.getUri()), any())).thenReturn(true);
assertTrue(resolver.shouldSaveReference(value, null));
assertTrue(resolver.shouldSaveReference(value, Collections.emptySet()));
verify(mapperMock).containsEntity(OWLClassA.class, value.getUri(), new EntityDescriptor());
}

Expand All @@ -94,7 +95,7 @@ void shouldSaveReferenceReturnsTrueForValueExistingInStorageContext() {
when(mapperMock.isManaged(value)).thenReturn(false);
when(mapperMock.getEntityType(OWLClassA.class)).thenReturn(metamodelMocks.forOwlClassA().entityType());
when(mapperMock.containsEntity(eq(OWLClassA.class), eq(value.getUri()), any())).thenReturn(true);
assertTrue(resolver.shouldSaveReference(value, context));
assertTrue(resolver.shouldSaveReference(value, Collections.singleton(context)));
verify(mapperMock).containsEntity(OWLClassA.class, value.getUri(), new EntityDescriptor(context));
}

Expand All @@ -107,4 +108,4 @@ void registerPendingReferenceRegistersReferenceInMapper() {
resolver.registerPendingReference(subject, assertion, object, null);
verify(mapperMock).registerPendingAssertion(subject, assertion, object, null);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/**
* Copyright (C) 2020 Czech Technical University in Prague
*
* <p>
* 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.
*
* <p>
* 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
Expand Down Expand Up @@ -39,8 +39,7 @@
import java.util.stream.Collectors;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

Expand Down Expand Up @@ -75,7 +74,7 @@ void extractsValuesFromInstance() throws Exception {
strategy.setReferenceSavingResolver(referenceResolverMock);
final OWLClassJ j = new OWLClassJ(PK);
j.setOwlClassA(generateSet(true));
when(referenceResolverMock.shouldSaveReferenceToItem(any(), eq(null))).thenReturn(true);
when(referenceResolverMock.shouldSaveReferenceToItem(any(), anySet())).thenReturn(true);
strategy.buildAxiomValuesFromInstance(j, gatherer);
final Set<URI> expected = j.getOwlClassA().stream().map(OWLClassA::getUri).collect(Collectors.toSet());
verifyExtractedValues(expected);
Expand Down Expand Up @@ -106,7 +105,7 @@ void extractValuesSkipsNullItem() throws Exception {
final OWLClassJ j = new OWLClassJ(PK);
j.setOwlClassA(generateSet(true));
j.getOwlClassA().add(null);
when(referenceResolverMock.shouldSaveReferenceToItem(any(), eq(null))).thenReturn(true);
when(referenceResolverMock.shouldSaveReferenceToItem(any(), anySet())).thenReturn(true);

strategy.buildAxiomValuesFromInstance(j, gatherer);
final Set<URI> expected = j.getOwlClassA().stream().filter(Objects::nonNull).map(OWLClassA::getUri)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.mockito.MockitoAnnotations;

import java.net.URI;
import java.util.Collections;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
Expand Down Expand Up @@ -93,7 +94,7 @@ void buildsAxiomFromPlainIdentifierValue() throws Exception {
final FieldStrategy<? extends FieldSpecification<? super OWLClassP, ?>, OWLClassP> strategy =
strategy(metamodelMocks.forOwlClassP().entityType(), metamodelMocks.forOwlClassP().pUriAttribute());
strategy.setReferenceSavingResolver(referenceResolverMock);
when(referenceResolverMock.shouldSaveReference(p.getIndividualUri(), null)).thenReturn(true);
when(referenceResolverMock.shouldSaveReference(p.getIndividualUri(), Collections.emptySet())).thenReturn(true);
strategy.buildAxiomValuesFromInstance(p, gatherer);
final AxiomValueDescriptor valueDescriptor = OOMTestUtils.getAxiomValueDescriptor(gatherer);
assertEquals(1, valueDescriptor.getAssertions().size());
Expand All @@ -114,7 +115,7 @@ void buildAxiomValuesChecksWhetherReferenceCanBeSaved() throws Exception {
strategy.setReferenceSavingResolver(referenceResolverMock);
strategy.buildAxiomValuesFromInstance(d, gatherer);

verify(referenceResolverMock).shouldSaveReference(d.getOwlClassA(), descriptor.getSingleContext().orElse(null));
verify(referenceResolverMock).shouldSaveReference(d.getOwlClassA(), descriptor.getContexts());
}

@Test
Expand Down Expand Up @@ -182,7 +183,7 @@ void buildAxiomValueAddsReferenceForPolymorphicAttribute() throws Exception {
sut.setReferenceSavingResolver(referenceResolverMock);
sut.buildAxiomValuesFromInstance(instance, gatherer);

verify(referenceResolverMock).shouldSaveReference(r, null);
verify(referenceResolverMock).shouldSaveReference(r, Collections.emptySet());
verify(referenceResolverMock, never()).registerPendingReference(any(), any(), any(), any());
verify(gatherer).addValue(sut.createAssertion(), new Value<>(NamedResource.create(r.getUri())), null);
}
Expand Down Expand Up @@ -247,7 +248,6 @@ void buildAxiomValuesFromInstanceChecksForReferenceExistenceUsingTargetReference
final OWLClassD instance = new OWLClassD(Generators.createIndividualIdentifier());
instance.setOwlClassA(Generators.generateOwlClassAInstance());
sut.buildAxiomValuesFromInstance(instance, gatherer);
verify(referenceResolverMock).shouldSaveReference(instance.getOwlClassA(), aDescriptor.getSingleContext()
.orElse(null));
verify(referenceResolverMock).shouldSaveReference(instance.getOwlClassA(), aDescriptor.getContexts());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ public class OWLClassF {
@OWLObjectProperty(iri = Vocabulary.P_F_HAS_SIMPLE_SET)
private Set<OWLClassA> simpleSet;

public OWLClassF() {
}

public OWLClassF(URI uri) {
this.uri = uri;
}

public URI getUri() {
return uri;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@
import org.slf4j.Logger;

import java.net.URI;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.*;

import static org.junit.jupiter.api.Assertions.*;

Expand Down Expand Up @@ -346,4 +344,25 @@ void persistEntityIntoContextAndAttributeIntoDefaultWorksCorrectly() {
}
});
}

@Test
void persistSupportsMultipleContextsSpecifiedForReferencedEntities() {
this.em = getEntityManager("persistSupportsMultipleContextsSpecifiedForReferencedEntities", true);
final OWLClassA entityA2 = new OWLClassA(Generators.generateUri(), "second instance");
transactional(() -> {
em.persist(entityA, cOneDescriptor);
em.persist(entityA2, cTwoDescriptor);
});

final Descriptor descriptor = new EntityDescriptor();
descriptor.addAttributeContext(fieldSpecification(OWLClassF.class, "simpleSet"), CONTEXT_ONE)
.addAttributeContext(fieldSpecification(OWLClassF.class, "simpleSet"), CONTEXT_TWO);
entityF.setSimpleSet(new HashSet<>(Arrays.asList(entityA, entityA2)));
transactional(() -> em.persist(entityF, descriptor));

final OWLClassF result = findRequired(OWLClassF.class, entityF.getUri(), descriptor);
assertEquals(2, result.getSimpleSet().size());
assertTrue(result.getSimpleSet().stream().anyMatch(a -> a.getUri().equals(entityA.getUri())));
assertTrue(result.getSimpleSet().stream().anyMatch(a -> a.getUri().equals(entityA2.getUri())));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.lang.reflect.Field;
import java.net.URI;
import java.util.Arrays;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.*;

Expand Down Expand Up @@ -194,4 +195,53 @@ void retrieveFromContextWithAttributeInDefaultWorksCorrectly() {
assertNotNull(result.getStringAttribute());
assertEquals(entityA.getStringAttribute(), result.getStringAttribute());
}

@Test
void retrieveSupportsSpecifyingMultipleContextsForObjectPropertyValues() {
this.em = getEntityManager("retrieveSupportsSpecifyingMultipleContextsForObjectPropertyValues", false);
final EntityDescriptor descriptor = new EntityDescriptor();
descriptor.addAttributeContext(fieldSpecification(OWLClassF.class, "simpleSet"), CONTEXT_ONE)
.addAttributeContext(fieldSpecification(OWLClassF.class, "simpleSet"), CONTEXT_TWO);
final OWLClassA a2 = new OWLClassA(Generators.generateUri(), "string two");
final URI ownerUri = Generators.generateUri();
transactionalThrowing(() -> persistTestData(Arrays.asList(
new Quad(entityA.getUri(), URI.create(RDF.TYPE), URI.create(Vocabulary.C_OWL_CLASS_A),
CONTEXT_ONE),
new Quad(entityA.getUri(), URI.create(Vocabulary.P_A_STRING_ATTRIBUTE),
entityA.getStringAttribute(), CONTEXT_ONE),
new Quad(a2.getUri(), URI.create(RDF.TYPE), URI.create(Vocabulary.C_OWL_CLASS_A), CONTEXT_TWO),
new Quad(a2.getUri(), URI.create(Vocabulary.P_A_STRING_ATTRIBUTE), a2.getStringAttribute(),
CONTEXT_TWO),
new Quad(ownerUri, URI.create(RDF.TYPE), URI.create(Vocabulary.C_OWL_CLASS_F)),
new Quad(ownerUri, URI.create(Vocabulary.P_F_HAS_SIMPLE_SET), entityA.getUri()),
new Quad(ownerUri, URI.create(Vocabulary.P_F_HAS_SIMPLE_SET), a2.getUri())), em));

final OWLClassF result = findRequired(OWLClassF.class, ownerUri);
assertEquals(2, result.getSimpleSet().size());
final Optional<OWLClassA> aOneResult =
result.getSimpleSet().stream().filter(a -> a.getUri().equals(entityA.getUri())).findAny();
assertTrue(aOneResult.isPresent());
assertEquals(entityA.getStringAttribute(), aOneResult.get().getStringAttribute());
final Optional<OWLClassA> aTwoResult =
result.getSimpleSet().stream().filter(a -> a.getUri().equals(a2.getUri())).findAny();
assertTrue(aTwoResult.isPresent());
assertEquals(a2.getStringAttribute(), aTwoResult.get().getStringAttribute());
}

@Test
void retrieveSupportsSpecifyingMultipleContextsForEntity() {
this.em = getEntityManager("retrieveSupportsSpecifyingMultipleContextsForEntity", false);
final Descriptor descriptor = new EntityDescriptor(CONTEXT_ONE);
descriptor.addContext(CONTEXT_TWO);
final URI uri = URI.create(entityM.getKey());
transactionalThrowing(() -> persistTestData(Arrays.asList(
new Quad(uri, URI.create(RDF.TYPE), URI.create(Vocabulary.C_OWL_CLASS_M), CONTEXT_ONE),
new Quad(uri, URI.create(Vocabulary.p_m_booleanAttribute), entityM.getBooleanAttribute(), CONTEXT_ONE),
new Quad(uri, URI.create(Vocabulary.p_m_dateAttribute), entityM.getDateAttribute(), CONTEXT_TWO)
), em));

final OWLClassM result = findRequired(OWLClassM.class, entityM.getKey());
assertEquals(entityM.getBooleanAttribute(), result.getBooleanAttribute());
assertEquals(entityM.getDateAttribute(), result.getDateAttribute());
}
}
Loading

0 comments on commit 02285dd

Please sign in to comment.