Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#161 case insensitive find entity by partial sign community and pattern #163

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,47 @@ public List<? extends Thing> findBySignValue(
return database.toTopObjects(queryResults);
}

/**
* Find the Set of {@link Thing} represented by the given partial sign value.
*
* <p>
* The search is case-insensitive.
* This could probably be replaced with a (rather complex) SPARQL query if {@link MagmaCoreDatabase}
* allowed the execution of such queries.
* </p>
*
* @param community The {@link RecognizingLanguageCommunity} that recognizes the sign value.
* @param pattern The {@link Pattern} the sign conforms to.
* @param value {@link String} the partial sign value to look for.
* @param pointInTime {@link PointInTime} the point in time we are interested in.
* @return {@link List} of {@link Thing} represented by the value.
* @throws MagmaCoreException if the number of {@link RepresentationByPattern} found is not 1.
*/
public List<? extends Thing> findByPartialSignValue(
final RecognizingLanguageCommunity community,
final Pattern pattern,
final String value,
final PointInTime pointInTime) throws MagmaCoreException {

final Set<Object> pointInTimeValues = pointInTime.value(HQDM.ENTITY_NAME);
if (pointInTimeValues == null || pointInTimeValues.isEmpty()) {
return List.of();
}

final Instant when = Instant.parse(pointInTimeValues.iterator().next().toString());

final QueryResultList queryResultList = database
.executeQuery(String.format(MagmaCoreServiceQueries.FIND_BY_PARTIAL_SIGN_VALUE_CASE_INSENSITIVE_QUERY,
value,
community.getId(),
pattern.getId()));

// Filter by the pointInTime
final QueryResultList queryResults = filterByPointInTime(when, queryResultList);

return database.toTopObjects(queryResults);
}

/**
* Find Things of a giver rdf:type and Class and their signs that are of a particular pattern.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,50 @@ public class MagmaCoreServiceQueries {
}
""";

/**
* This query is used to find the Things represented by a given partial sign value for a particular
* {@link uk.gov.gchq.magmacore.hqdm.model.RecognizingLanguageCommunity} and
* {@link uk.gov.gchq.magmacore.hqdm.model.Pattern}.
* <p>
* It needs three parameters provided using String.format() - the partial sign value {@link String}, the
* {@link uk.gov.gchq.magmacore.hqdm.model.RecognizingLanguageCommunity} IRI {@link String}, and the
* {@link uk.gov.gchq.magmacore.hqdm.model.Pattern} IRI String.
* </p>
* <p>
* The Things are likely to be states of some individual.
* </p>
*/
public static final String FIND_BY_PARTIAL_SIGN_VALUE_CASE_INSENSITIVE_QUERY = """
PREFIX hqdm: <https://hqdmtop.github.io/hqdm#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>


SELECT ?s ?p ?o ?start ?finish
WHERE {
BIND("%s" as ?text)
BIND(<%s> as ?rlc)
BIND(<%s> as ?pattern)

?sign hqdm:value_ ?signvalue;
hqdm:member_of_ ?pattern.
FILTER(CONTAINS(lcase(str(?signvalue)), lcase(?text)))
?sos hqdm:temporal_part_of ?sign;
hqdm:participant_in ?repBySign.
?rlc hqdm:participant_in ?repBySign.
?repBySign hqdm:represents ?s.
?s ?p ?o.
OPTIONAL {
?repBySign hqdm:beginning ?begin.
?begin hqdm:data_EntityName ?start.
}
OPTIONAL {
?repBySign hqdm:ending ?end.
?end hqdm:data_EntityName ?finish.
}

}
""";

/**
* This query finds PARTICIPANTS in associations of a specified kind between two individuals.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,43 @@ public void testFindBySignSuccess() throws MagmaCoreException {
assertEquals(SignPatternTestData.person2.getId(), ((IRI) parent2.iterator().next()).getIri());
}

/**
* Test that findByPartialSignValue can be used to find the right Things represented by
* a sign value for
* the given {@link uk.gov.gchq.magmacore.hqdm.model.Pattern} and
* {@link uk.gov.gchq.magmacore.hqdm.model.RecognizingLanguageCommunity} at the
* given
* {@link uk.gov.gchq.magmacore.hqdm.model.PointInTime}.
*/
@Test
public void testFindByPartialSignSuccess() throws MagmaCoreException {

// Create and populate an in-memory database.
final MagmaCoreDatabase db = new MagmaCoreJenaDatabase();
SignPatternTestData.createSignPattern(db);

// Use it to create the services
final MagmaCoreService service = new MagmaCoreService(db);

// Create the PointInTime we're looking for
final PointInTime now = SpatioTemporalExtentServices.createPointInTime("now");
now.addValue(HQDM.ENTITY_NAME, Instant.now().toString());

// Find the required Things by sign in a transaction.
db.begin();
final List<? extends Thing> found1 = service.findByPartialSignValue(SignPatternTestData.community1,
SignPatternTestData.pattern1, "son1", now);
final List<? extends Thing> found2 = service.findByPartialSignValue(SignPatternTestData.community2,
SignPatternTestData.pattern2, "ERSON", now);
db.commit();

// Assert the results are correct.
assertNotNull(found1);
assertNotNull(found2);
assertEquals(1, found1.size());
assertEquals(2, found2.size());
}

/**
* Check that we get an empty result if the sign value is null.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ public class SignPatternTestData {
static Pattern pattern2;
static Person person1;
static Person person2;
static Person person3;
static StateOfPerson stateOfPerson1;
static StateOfPerson stateOfPerson2;
static StateOfPerson stateOfPerson3;
static IRI kindOfPersonIri;
static IRI classOfPersonIri;

Expand Down Expand Up @@ -92,13 +94,19 @@ static void createSignPattern(final MagmaCoreDatabase db) {
.createRepresentationByPattern(new IRI(TEST_BASE, "repByPattern2").getIri());
repByPattern2.addValue(RDFS.RDF_TYPE, HQDM.REPRESENTATION_BY_PATTERN);

final RepresentationByPattern repByPattern3 = ClassServices
.createRepresentationByPattern(new IRI(TEST_BASE, "repByPattern3").getIri());
repByPattern3.addValue(RDFS.RDF_TYPE, HQDM.REPRESENTATION_BY_PATTERN);

// Add the relationships for the patterns and communities.

repByPattern1.addValue(HQDM.CONSISTS_OF_IN_MEMBERS, new IRI(community1.getId()));
repByPattern2.addValue(HQDM.CONSISTS_OF_IN_MEMBERS, new IRI(community2.getId()));
repByPattern3.addValue(HQDM.CONSISTS_OF_IN_MEMBERS, new IRI(community2.getId()));

repByPattern1.addValue(HQDM.CONSISTS_OF_BY_CLASS, new IRI(pattern1.getId()));
repByPattern2.addValue(HQDM.CONSISTS_OF_BY_CLASS, new IRI(pattern2.getId()));
repByPattern3.addValue(HQDM.CONSISTS_OF_BY_CLASS, new IRI(pattern2.getId()));

// Create KindOfPerson
kindOfPersonIri = new IRI(TEST_BASE, "kindOfPerson1");
Expand All @@ -117,6 +125,11 @@ static void createSignPattern(final MagmaCoreDatabase db) {
person2.addValue(HQDM.MEMBER_OF_KIND, kindOfPersonIri);
person2.addValue(HQDM.MEMBER_OF, classOfPersonIri);

person3 = SpatioTemporalExtentServices.createPerson(new IRI(TEST_BASE, "person3").getIri());
person3.addValue(RDFS.RDF_TYPE, HQDM.PERSON);
person3.addValue(HQDM.MEMBER_OF_KIND, kindOfPersonIri);
person3.addValue(HQDM.MEMBER_OF, classOfPersonIri);

// Create States for the People
stateOfPerson1 = SpatioTemporalExtentServices
.createStateOfPerson(new IRI(TEST_BASE, "stateOfPerson1").getIri());
Expand All @@ -128,6 +141,11 @@ static void createSignPattern(final MagmaCoreDatabase db) {
stateOfPerson2.addValue(RDFS.RDF_TYPE, HQDM.STATE_OF_PERSON);
stateOfPerson2.addValue(HQDM.TEMPORAL_PART_OF, new IRI(person2.getId()));

stateOfPerson3 = SpatioTemporalExtentServices
.createStateOfPerson(new IRI(TEST_BASE, "stateOfPerson3").getIri());
stateOfPerson3.addValue(RDFS.RDF_TYPE, HQDM.STATE_OF_PERSON);
stateOfPerson3.addValue(HQDM.TEMPORAL_PART_OF, new IRI(person3.getId()));

// Create signs
final Sign sign1 = SpatioTemporalExtentServices.createSign(new IRI(TEST_BASE, "sign1").getIri());
sign1.addValue(RDFS.RDF_TYPE, HQDM.SIGN);
Expand All @@ -139,6 +157,11 @@ static void createSignPattern(final MagmaCoreDatabase db) {
sign2.addValue(HQDM.MEMBER_OF_, pattern2Iri);
sign2.addValue(HQDM.VALUE_, "person2");

final Sign sign3 = SpatioTemporalExtentServices.createSign(new IRI(TEST_BASE, "sign3").getIri());
sign3.addValue(RDFS.RDF_TYPE, HQDM.SIGN);
sign3.addValue(HQDM.MEMBER_OF_, pattern2Iri);
sign3.addValue(HQDM.VALUE_, "person3");

// Create states for the Signs
final StateOfSign stateOfSign1 = SpatioTemporalExtentServices
.createStateOfSign(new IRI(TEST_BASE, "stateOfSign1").getIri());
Expand All @@ -150,6 +173,11 @@ static void createSignPattern(final MagmaCoreDatabase db) {
stateOfSign2.addValue(RDFS.RDF_TYPE, HQDM.STATE_OF_SIGN);
stateOfSign2.addValue(HQDM.TEMPORAL_PART_OF, new IRI(sign2.getId()));

final StateOfSign stateOfSign3 = SpatioTemporalExtentServices
.createStateOfSign(new IRI(TEST_BASE, "stateOfSign3").getIri());
stateOfSign3.addValue(RDFS.RDF_TYPE, HQDM.STATE_OF_SIGN);
stateOfSign3.addValue(HQDM.TEMPORAL_PART_OF, new IRI(sign3.getId()));

// Create Events for the BEGINNING and ENDING of the RepresentationBySigns
final PointInTime begin = SpatioTemporalExtentServices.createPointInTime(new IRI(TEST_BASE, "begin").getIri());
final PointInTime end = SpatioTemporalExtentServices.createPointInTime(new IRI(TEST_BASE, "end").getIri());
Expand Down Expand Up @@ -184,6 +212,16 @@ static void createSignPattern(final MagmaCoreDatabase db) {
community2.addValue(HQDM.PARTICIPANT_IN, new IRI(repBySign2.getId()));
stateOfSign2.addValue(HQDM.PARTICIPANT_IN, new IRI(repBySign2.getId()));

final RepresentationBySign repBySign3 = SpatioTemporalExtentServices
.createRepresentationBySign(new IRI(TEST_BASE, "repBySign3").getIri());
repBySign3.addValue(RDFS.RDF_TYPE, HQDM.REPRESENTATION_BY_SIGN);
repBySign3.addValue(HQDM.REPRESENTS, new IRI(stateOfPerson3.getId()));
repBySign3.addValue(HQDM.MEMBER_OF_, new IRI(repByPattern2.getId()));
repBySign3.addValue(HQDM.BEGINNING, objectId);
repBySign3.addValue(HQDM.ENDING, objectId2);
community2.addValue(HQDM.PARTICIPANT_IN, new IRI(repBySign3.getId()));
stateOfSign3.addValue(HQDM.PARTICIPANT_IN, new IRI(repBySign3.getId()));

// Persist all objects
db.begin();

Expand All @@ -193,18 +231,24 @@ static void createSignPattern(final MagmaCoreDatabase db) {
db.create(pattern2);
db.create(repByPattern1);
db.create(repByPattern2);
db.create(repByPattern3);
db.create(person1);
db.create(person2);
db.create(person3);
db.create(stateOfPerson1);
db.create(stateOfPerson2);
db.create(stateOfPerson3);
db.create(sign1);
db.create(sign2);
db.create(sign3);
db.create(stateOfSign1);
db.create(stateOfSign2);
db.create(stateOfSign3);
db.create(begin);
db.create(end);
db.create(repBySign1);
db.create(repBySign2);
db.create(repBySign3);

db.commit();
}
Expand Down