From 515483112541d149f84000b6184e5237f0ff990a Mon Sep 17 00:00:00 2001 From: Jad El-khoury Date: Sat, 16 Feb 2019 01:06:01 +0100 Subject: [PATCH] Accept a searchTerm in the getResources method (#51) * getResources method accepts a searchTerm, that translates to a simple sparql filter. * tests for getResources() that returns a Jena model. * Update free-text search to work with more than String literals. Unit tests working. --- .../java/org/eclipse/lyo/store/Store.java | 44 +++++- .../lyo/store/internals/JenaTdbStoreImpl.java | 14 +- .../lyo/store/internals/SparqlStoreImpl.java | 134 ++++++++++------- .../eclipse/lyo/store/JenaTdbStoreImplIT.java | 44 ++++++ .../lyo/store/JenaTdbStoreImplPathsIT.java | 44 ++++++ .../lyo/store/JenaTdbStoreImplTest.java | 51 +++++++ .../org/eclipse/lyo/store/StoreTestBase.java | 107 ++++++++++++++ .../resources/Oslc_rmDomainConstants.java | 17 +++ .../lyo/store/resources/Requirement.java | 135 ++++++++++++++++++ 9 files changed, 537 insertions(+), 53 deletions(-) create mode 100644 src/store-core/src/test/java/org/eclipse/lyo/store/resources/Oslc_rmDomainConstants.java create mode 100644 src/store-core/src/test/java/org/eclipse/lyo/store/resources/Requirement.java diff --git a/src/store-core/src/main/java/org/eclipse/lyo/store/Store.java b/src/store-core/src/main/java/org/eclipse/lyo/store/Store.java index 3f96e24..aaefc52 100644 --- a/src/store-core/src/main/java/org/eclipse/lyo/store/Store.java +++ b/src/store-core/src/main/java/org/eclipse/lyo/store/Store.java @@ -149,6 +149,44 @@ List getResources(URI namedGraphUri, final Class cla List getResources(URI namedGraphUri, Class clazz, int limit, int offset) throws StoreAccessException, ModelUnmarshallingException; + /** + * Alternative to {@link Store#getResources(URI, Class)} with paging on the OSLC resource level. + * + * @param namedGraphUri URI of a named graph under which resources were stored + * @param clazz class of the resources being retrieved + * @param prefixes defines the prefixes for prefixed names that appear in the oslc.where query parameter. + * @param where filters the member list, keeping only those member resources that satisfy the boolean test on the member resource properties. (See oslc.where at https://tools.oasis-open.org/version-control/browse/wsvn/oslc-core/trunk/specs/oslc-query.html) + * @param searchTerms score each member resource using a full text search on it text-valued properties. (See oslc.searchTerms at https://tools.oasis-open.org/version-control/browse/wsvn/oslc-core/trunk/specs/oslc-query.html) + * @param limit paging limit + * @param offset paging offset + * + * @return list of OSLC resources, size is less or equal to 'limit' + * + * @throws StoreAccessException if there was a problem with the triplestore (or the + * dataset, more broadly). + * @throws ModelUnmarshallingException if the classes cannot be instantiated or another error + * occurred when working with Jena model. + */ + List getResources(URI namedGraphUri, Class clazz, + String prefixes, String where, String searchTerms, + int limit, int offset) throws StoreAccessException, ModelUnmarshallingException; + + /** + * Retrieve a Jena model that satisfies the given where parameter as defined in the OSLC Query language (https://tools.oasis-open.org/version-control/svn/oslc-core/trunk/specs/oslc-query.html) + * If the namedGraph is null, the query is applied on all namedGraph in the triplestore. + * The method currently only provides support for terms of type Comparisons, where the operator is 'EQUALS', and the operand is either a String or a URI. + * + * @param namedGraph namedGraphUri URI of a named graph under which resources were stored + * @param prefixes defines the prefixes for prefixed names that appear in the oslc.where query parameter. + * @param where filters the member list, keeping only those member resources that satisfy the boolean test on the member resource properties. (See oslc.where at https://tools.oasis-open.org/version-control/browse/wsvn/oslc-core/trunk/specs/oslc-query.html) + * @param limit paging limit + * @param offset paging offset + * + * @return list of resources, size is less or equal to 'limit' + * + */ + Model getResources(URI namedGraph, String prefixes, String where, int limit, int offset); + /** * Retrieve a Jena model that satisfies the given where parameter as defined in the OSLC Query language (https://tools.oasis-open.org/version-control/svn/oslc-core/trunk/specs/oslc-query.html) * If the namedGraph is null, the query is applied on all namedGraph in the triplestore. @@ -156,15 +194,15 @@ List getResources(URI namedGraphUri, Class clazz, in * * @param namedGraph namedGraphUri URI of a named graph under which resources were stored * @param prefixes defines the prefixes for prefixed names that appear in the oslc.where query parameter. - * @param where filters the member list, keeping only those member resources that satisfy the boolean test on the member resource properties + * @param where filters the member list, keeping only those member resources that satisfy the boolean test on the member resource properties. (See oslc.where at https://tools.oasis-open.org/version-control/browse/wsvn/oslc-core/trunk/specs/oslc-query.html) + * @param searchTerms score each member resource using a full text search on it text-valued properties. (See oslc.searchTerms at https://tools.oasis-open.org/version-control/browse/wsvn/oslc-core/trunk/specs/oslc-query.html) * @param limit paging limit * @param offset paging offset * * @return list of resources, size is less or equal to 'limit' * */ - Model getResources(URI namedGraph, String prefixes, String where, int limit, int offset) - throws URISyntaxException; + Model getResources(URI namedGraph, String prefixes, String where, String searchTerms, int limit, int offset); /** * Retrieve a single {@link IResource} instance specified by the concrete diff --git a/src/store-core/src/main/java/org/eclipse/lyo/store/internals/JenaTdbStoreImpl.java b/src/store-core/src/main/java/org/eclipse/lyo/store/internals/JenaTdbStoreImpl.java index eaaf481..df293f5 100644 --- a/src/store-core/src/main/java/org/eclipse/lyo/store/internals/JenaTdbStoreImpl.java +++ b/src/store-core/src/main/java/org/eclipse/lyo/store/internals/JenaTdbStoreImpl.java @@ -162,9 +162,21 @@ public List getResources(final URI namedGraph, return resources.subList(offset, Math.min(resources.size(), offset + limit)); } + @Override + public List getResources(URI namedGraphUri, Class clazz, String prefixes, String where, + String searchTerms, int limit, int offset) throws StoreAccessException, ModelUnmarshallingException { + throw new UnsupportedOperationException(); + } + @Override public Model getResources(URI namedGraph, String prefixes, String where, int limit, - int offset) throws URISyntaxException { + int offset) { + throw new UnsupportedOperationException(); + } + + @Override + public Model getResources(URI namedGraph, String prefixes, String where, String searchTerms, int limit, + int offset) { throw new UnsupportedOperationException(); } diff --git a/src/store-core/src/main/java/org/eclipse/lyo/store/internals/SparqlStoreImpl.java b/src/store-core/src/main/java/org/eclipse/lyo/store/internals/SparqlStoreImpl.java index d06cdcc..1ce39c9 100644 --- a/src/store-core/src/main/java/org/eclipse/lyo/store/internals/SparqlStoreImpl.java +++ b/src/store-core/src/main/java/org/eclipse/lyo/store/internals/SparqlStoreImpl.java @@ -27,11 +27,13 @@ import org.apache.jena.rdf.model.Statement; import org.apache.jena.rdf.model.StmtIterator; import org.apache.jena.rdf.model.impl.ResourceImpl; +import org.apache.jena.sparql.expr.E_Regex; import org.apache.jena.sparql.modify.request.QuadDataAcc; import org.apache.jena.sparql.modify.request.UpdateDataInsert; import org.apache.jena.update.UpdateProcessor; import org.apache.jena.arq.querybuilder.SelectBuilder; import org.apache.jena.arq.querybuilder.DescribeBuilder; +import org.apache.jena.arq.querybuilder.ExprFactory; import org.apache.jena.riot.RiotException; import java.lang.reflect.Array; @@ -254,7 +256,26 @@ public List getResources(final URI namedGraph, } @Override - public Model getResources(final URI namedGraph, final String prefixes, final String where, final int limit, final int offset) throws URISyntaxException { + public List getResources(final URI namedGraph, final Class clazz, final String prefixes, + final String where, final String searchTerms, final int limit, final int offset) + throws StoreAccessException, ModelUnmarshallingException { + + String _prefixes = prefixes; + String _where = where; + + _prefixes = (StringUtils.isEmpty(_prefixes) ? "" : _prefixes + ",") + oslcQueryPrefixes(clazz); + _where = (StringUtils.isEmpty(_where) ? "" : _where + " and ") + oslcQueryWhere(clazz); + Model model = getResources(namedGraph, _prefixes, _where, searchTerms, limit, offset); + return getResourcesFromModel(model, clazz); + } + + @Override + public Model getResources(final URI namedGraph, final String prefixes, final String where, final int limit, final int offset) { + return getResources(namedGraph, prefixes, where, null, limit, offset); + } + + @Override + public Model getResources(final URI namedGraph, final String prefixes, final String where, final String searchTerms, final int limit, final int offset) { if (namedGraph != null) { //Make sure the designated namedGraph exists, if it is specified. @@ -264,7 +285,7 @@ public Model getResources(final URI namedGraph, final String prefixes, final Str } } - SelectBuilder sparqlWhereQuery = constructSparqlWhere (prefixes, where, limit, offset); + SelectBuilder sparqlWhereQuery = constructSparqlWhere (prefixes, where, searchTerms, limit, offset); DescribeBuilder describeBuilder = new DescribeBuilder(); if (namedGraph != null) { describeBuilder.addVar("s") @@ -350,6 +371,14 @@ public void removeAll() { queryExecutor.prepareSparqlUpdate("CLEAR ALL").execute(); } + private String oslcQueryPrefixes(final Class clazz) { + return "rdf=" + "<" + org.apache.jena.vocabulary.RDF.uri + ">"; + } + + private String oslcQueryWhere(final Class clazz) { + return "rdf:type=" + "<" + getResourceNsUri(clazz) + ">"; + } + private List getResourcesFromModel(final Model model, final Class clazz) throws ModelUnmarshallingException, StoreAccessException { try { @@ -461,7 +490,7 @@ private Model modelFromQueryFlatPaged(final URI namedGraph, final URI type, fina } //This method currently only provides support for terms of type Comparisons, where the operator is 'EQUALS', and the operand is either a String or a URI. - private SelectBuilder constructSparqlWhere(final String prefixes, final String where, final int limit, final int offset) { + private SelectBuilder constructSparqlWhere(final String prefixes, final String where, final String searchTerms, final int limit, final int offset) { SelectBuilder distinctResourcesQuery = new SelectBuilder(); @@ -470,65 +499,72 @@ private SelectBuilder constructSparqlWhere(final String prefixes, final String w try { if (!StringUtils.isEmpty(prefixes)) { prefixesMap = QueryUtils.parsePrefixes(prefixes); + for (Entry prefix : prefixesMap.entrySet()) { + distinctResourcesQuery.addPrefix(prefix.getKey(), prefix.getValue()); + } } } catch (ParseException e) { throw new IllegalArgumentException("prefixesExpression could not be parsed", e); } - for (Entry prefix : prefixesMap.entrySet()) { - distinctResourcesQuery.addPrefix(prefix.getKey(), prefix.getValue()); - } - //Setup where + distinctResourcesQuery + .addVar( "s" ) + .setDistinct(true) + .addWhere( "?s", "?p", "?o"); + + //Setup where WhereClause whereClause = null; try { if (!StringUtils.isEmpty(where)) { whereClause = QueryUtils.parseWhere(where, prefixesMap); + List parseChildren = whereClause.children(); + for (Iterator iterator = parseChildren.iterator(); iterator.hasNext();) { + SimpleTerm simpleTerm = iterator.next(); + Type termType = simpleTerm.type(); + PName property = simpleTerm.property(); + + if (!termType.equals(Type.COMPARISON)){ + throw new UnsupportedOperationException("only support for terms of type Comparisons"); + } + ComparisonTerm aComparisonTerm = (ComparisonTerm) simpleTerm; + if (!aComparisonTerm.operator().equals(Operator.EQUALS)){ + throw new UnsupportedOperationException("only support for terms of type Comparisons, where the operator is 'EQUALS'"); + } + + Value comparisonOperand = aComparisonTerm.operand(); + Value.Type operandType = comparisonOperand.type(); + String predicate; + if (property.local.equals("*")) { + predicate = "?p"; + } + else { + predicate = property.toString(); + } + + switch (operandType) { + case STRING: + StringValue stringOperand = (StringValue) comparisonOperand; + distinctResourcesQuery.addWhere( "?s", predicate, stringOperand.value()); + break; + case URI_REF: + UriRefValue uriOperand = (UriRefValue) comparisonOperand; + distinctResourcesQuery.addWhere( "?s", predicate, new ResourceImpl(uriOperand.value())); + break; + default: + throw new UnsupportedOperationException("only support for terms of type Comparisons, where the operator is 'EQUALS', and the operand is either a String or a URI"); + } + } } } catch (ParseException e) { throw new IllegalArgumentException("whereExpression could not be parsed", e); } - - distinctResourcesQuery - .addVar( "s" ) - .setDistinct(true) - .addWhere( "?s", "?p", "?o"); - - List parseChildren = whereClause.children(); - for (Iterator iterator = parseChildren.iterator(); iterator.hasNext();) { - SimpleTerm simpleTerm = iterator.next(); - Type termType = simpleTerm.type(); - PName property = simpleTerm.property(); - - if (!termType.equals(Type.COMPARISON)){ - throw new UnsupportedOperationException("only support for terms of type Comparisons"); - } - ComparisonTerm aComparisonTerm = (ComparisonTerm) simpleTerm; - if (!aComparisonTerm.operator().equals(Operator.EQUALS)){ - throw new UnsupportedOperationException("only support for terms of type Comparisons, where the operator is 'EQUALS'"); - } - - Value comparisonOperand = aComparisonTerm.operand(); - Value.Type operandType = comparisonOperand.type(); - String predicate; - if (property.local.equals("*")) { - predicate = "?p"; - } - else { - predicate = property.toString(); - } - - switch (operandType) { - case STRING: - StringValue stringOperand = (StringValue) comparisonOperand; - distinctResourcesQuery.addWhere( "?s", predicate, stringOperand.value()); - break; - case URI_REF: - UriRefValue uriOperand = (UriRefValue) comparisonOperand; - distinctResourcesQuery.addWhere( "?s", predicate, new ResourceImpl(uriOperand.value())); - break; - default: - throw new UnsupportedOperationException("only support for terms of type Comparisons, where the operator is 'EQUALS', and the operand is either a String or a URI"); - } + + //Setup searchTerms + //Add a sparql filter "FILTER regex(?o, "", "i")" to the distinctResourcesQuery + if (!StringUtils.isEmpty(searchTerms)) { + ExprFactory factory = new ExprFactory(); + E_Regex regex = factory.regex(factory.str("?o"), searchTerms, "i"); + distinctResourcesQuery.addFilter(regex); } if (limit > 0) { diff --git a/src/store-core/src/test/java/org/eclipse/lyo/store/JenaTdbStoreImplIT.java b/src/store-core/src/test/java/org/eclipse/lyo/store/JenaTdbStoreImplIT.java index 31361d8..b1413d3 100644 --- a/src/store-core/src/test/java/org/eclipse/lyo/store/JenaTdbStoreImplIT.java +++ b/src/store-core/src/test/java/org/eclipse/lyo/store/JenaTdbStoreImplIT.java @@ -17,6 +17,7 @@ import org.apache.jena.query.Dataset; import java.io.File; import java.io.IOException; +import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -65,4 +66,47 @@ public void testStoreHandlesNonExistentPath() throws IOException { final Path tempDirectory = Paths.get("/tmp/try_tdb"); // make sure `ls -l /tmp` shows correct permissions StoreFactory.onDisk(tempDirectory); } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForAllRequirementResources() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForRequirementResourcesWithFreeTextSearch() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForRequirementResourcesWithWhereFilter() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForRequirementResourcesWithFreeTextSearchAndWhereFilter() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForRequirementResourcesWithNoMatch() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForAllResources() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForAllResourcesWithFreeTextSearch() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + } diff --git a/src/store-core/src/test/java/org/eclipse/lyo/store/JenaTdbStoreImplPathsIT.java b/src/store-core/src/test/java/org/eclipse/lyo/store/JenaTdbStoreImplPathsIT.java index 7155dda..70281a2 100644 --- a/src/store-core/src/test/java/org/eclipse/lyo/store/JenaTdbStoreImplPathsIT.java +++ b/src/store-core/src/test/java/org/eclipse/lyo/store/JenaTdbStoreImplPathsIT.java @@ -15,11 +15,13 @@ */ import java.io.IOException; +import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; import org.eclipse.lyo.store.internals.DatasetBuilder; import org.eclipse.lyo.store.internals.JenaTdbStoreImpl; import org.junit.Before; +import org.junit.Ignore; /** * DatasetBuilderTest is . @@ -46,4 +48,46 @@ protected JenaTdbStoreImpl buildStore() { } } + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForAllRequirementResources() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForRequirementResourcesWithFreeTextSearch() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForRequirementResourcesWithWhereFilter() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForRequirementResourcesWithFreeTextSearchAndWhereFilter() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForRequirementResourcesWithNoMatch() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForAllResources() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForAllResourcesWithFreeTextSearch() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + } diff --git a/src/store-core/src/test/java/org/eclipse/lyo/store/JenaTdbStoreImplTest.java b/src/store-core/src/test/java/org/eclipse/lyo/store/JenaTdbStoreImplTest.java index 4dd7964..598ce9f 100644 --- a/src/store-core/src/test/java/org/eclipse/lyo/store/JenaTdbStoreImplTest.java +++ b/src/store-core/src/test/java/org/eclipse/lyo/store/JenaTdbStoreImplTest.java @@ -1,5 +1,9 @@ package org.eclipse.lyo.store; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; + /*- * #%L * Contributors: @@ -15,9 +19,14 @@ */ import org.apache.jena.query.Dataset; +import org.apache.jena.rdf.model.Model; import org.apache.jena.tdb.TDBFactory; +import org.assertj.core.api.Assertions; import org.eclipse.lyo.store.internals.JenaTdbStoreImpl; +import org.eclipse.lyo.store.resources.Requirement; import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; /** * DatasetBuilderTest is . @@ -40,4 +49,46 @@ protected JenaTdbStoreImpl buildStore() { return new JenaTdbStoreImpl(memDataset); } + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForAllRequirementResources() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForRequirementResourcesWithFreeTextSearch() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForRequirementResourcesWithWhereFilter() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForRequirementResourcesWithFreeTextSearchAndWhereFilter() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForRequirementResourcesWithNoMatch() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForAllResources() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + + @Override + @Ignore("Not implemented yet") + public void testStoreQueryForAllResourcesWithFreeTextSearch() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + } + } diff --git a/src/store-core/src/test/java/org/eclipse/lyo/store/StoreTestBase.java b/src/store-core/src/test/java/org/eclipse/lyo/store/StoreTestBase.java index 80ce7b5..61752c2 100644 --- a/src/store-core/src/test/java/org/eclipse/lyo/store/StoreTestBase.java +++ b/src/store-core/src/test/java/org/eclipse/lyo/store/StoreTestBase.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.List; import java.util.NoSuchElementException; import java.util.Random; import java.util.Set; @@ -35,8 +36,10 @@ import org.eclipse.lyo.oslc4j.core.model.ServiceProviderCatalog; import org.eclipse.lyo.oslc4j.provider.jena.JenaModelHelper; import org.eclipse.lyo.store.resources.BlankResource; +import org.eclipse.lyo.store.resources.Requirement; import org.eclipse.lyo.store.resources.WithBlankResource; import org.eclipse.lyo.store.resources.WithTwoDepthBlankResource; +import org.junit.Ignore; import org.junit.Test; import static org.assertj.core.api.Assertions.*; @@ -292,7 +295,86 @@ public void testBlankNodeRetrievalDouble() .getIntProperty()).isEqualTo(intProperty); } + @Test + public void testStoreQueryForAllRequirementResources() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + final T manager = buildStore(); + final URI namedGraphUri = buildKey(); + populateStore(manager, namedGraphUri); + + List requirements = manager.getResources(namedGraphUri, Requirement.class, null, null, "", -1, -1); + Assertions.assertThat(requirements).hasSize(6); + } + + @Test + public void testStoreQueryForRequirementResourcesWithFreeTextSearch() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + final T manager = buildStore(); + final URI namedGraphUri = buildKey(); + populateStore(manager, namedGraphUri); + + List requirements = manager.getResources(namedGraphUri, Requirement.class, null, null, "river", -1, -1); + Assertions.assertThat(requirements).hasSize(2); + } + @Test + public void testStoreQueryForRequirementResourcesWithWhereFilter() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + final T manager = buildStore(); + final URI namedGraphUri = buildKey(); + populateStore(manager, namedGraphUri); + + List requirements = manager.getResources(namedGraphUri, Requirement.class, + "dcterms=", "dcterms:identifier=\"observations\"", null, -1, -1); + Assertions.assertThat(requirements).hasSize(1); + } + + @Test + public void testStoreQueryForRequirementResourcesWithFreeTextSearchAndWhereFilter() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + final T manager = buildStore(); + final URI namedGraphUri = buildKey(); + populateStore(manager, namedGraphUri); + + List requirements = manager.getResources(namedGraphUri, Requirement.class, + "dcterms=", "dcterms:identifier=\"observations\"", "roof", -1, -1); + Assertions.assertThat(requirements).hasSize(1); + } + + @Test + public void testStoreQueryForRequirementResourcesWithNoMatch() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + final T manager = buildStore(); + final URI namedGraphUri = buildKey(); + populateStore(manager, namedGraphUri); + + List requirements = manager.getResources(namedGraphUri, Requirement.class, + "dcterms=", "dcterms:identifier=\"observations\"", "velocity", -1, -1); + Assertions.assertThat(requirements).hasSize(0); + } + + @Test + public void testStoreQueryForAllResources() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + final T manager = buildStore(); + final URI namedGraphUri = buildKey(); + populateStore(manager, namedGraphUri); + + Model model = manager.getResources(namedGraphUri, null, null, "", -1, -1); + Assertions.assertThat(model.listSubjects().toList()).hasSize(7); + } + + @Test + public void testStoreQueryForAllResourcesWithFreeTextSearch() + throws StoreAccessException, ModelUnmarshallingException, URISyntaxException { + final T manager = buildStore(); + final URI namedGraphUri = buildKey(); + populateStore(manager, namedGraphUri); + + Model model = manager.getResources(namedGraphUri, null, null, "river", -1, -1); + Assertions.assertThat(model.listSubjects().toList()).hasSize(2); + + } protected abstract T buildStore(); @@ -309,5 +391,30 @@ private IResource buildResource() { resource.setAbout(URI.create("lyo:spc_" + randomHexString())); return resource; } + + private Requirement createRequirement(String identifier, String description) throws URISyntaxException { + Requirement r = new Requirement(buildKey()); + r.setIdentifier(identifier); + r.setDescription(description); + return r; + } + + private void populateStore(final T manager, final URI namedGraphUri) + throws StoreAccessException, URISyntaxException { + manager.appendResource(namedGraphUri, + createRequirement("rob", "Tom got a small piece of pie. Rock music approaches at high velocity.")); + manager.appendResource(namedGraphUri, createRequirement("hang", + "She borrowed the book from him many years ago and hasn't yet returned it. Please wait outside of the house. The river stole the gods.")); + manager.appendResource(namedGraphUri, createRequirement("observations", + "We have never been to Asia, nor have we visited Africa. Malls are great places to shop; I can find everything I need under one roof.")); + manager.appendResource(namedGraphUri, createRequirement("kindly", + "I think I will buy the red car, or I will lease the blue one. The river stole the gods.")); + manager.appendResource(namedGraphUri, createRequirement("itch", + "A song can make or ruin a person’s day if they let it get to them. The body may perhaps compensates for the loss of a true metaphysics.")); + manager.appendResource(namedGraphUri, createRequirement("morning", + "They got there early, and they got really good seats. Lets all be unique together until we realise we are all the same.")); + manager.appendResource(namedGraphUri, buildResource()); + } + } diff --git a/src/store-core/src/test/java/org/eclipse/lyo/store/resources/Oslc_rmDomainConstants.java b/src/store-core/src/test/java/org/eclipse/lyo/store/resources/Oslc_rmDomainConstants.java new file mode 100644 index 0000000..551bef1 --- /dev/null +++ b/src/store-core/src/test/java/org/eclipse/lyo/store/resources/Oslc_rmDomainConstants.java @@ -0,0 +1,17 @@ +package org.eclipse.lyo.store.resources; + +public interface Oslc_rmDomainConstants +{ + public static String REQUIREMENTS_MANAGEMENT_DOMAIN = "http://open-services.net/ns/rm#"; + public static String REQUIREMENTS_MANAGEMENT_NAMSPACE = "http://open-services.net/ns/rm#"; + public static String REQUIREMENTS_MANAGEMENT_NAMSPACE_PREFIX = "oslc_rm"; + + public static String REQUIREMENT_PATH = "requirement"; + public static String REQUIREMENT_NAMESPACE = REQUIREMENTS_MANAGEMENT_NAMSPACE; //namespace of the rdfs:class the resource describes + public static String REQUIREMENT_LOCALNAME = "Requirement"; //localName of the rdfs:class the resource describes + public static String REQUIREMENT_TYPE = REQUIREMENT_NAMESPACE + REQUIREMENT_LOCALNAME; //fullname of the rdfs:class the resource describes + public static String REQUIREMENTCOLLECTION_PATH = "requirementCollection"; + public static String REQUIREMENTCOLLECTION_NAMESPACE = REQUIREMENTS_MANAGEMENT_NAMSPACE; //namespace of the rdfs:class the resource describes + public static String REQUIREMENTCOLLECTION_LOCALNAME = "RequirementCollection"; //localName of the rdfs:class the resource describes + public static String REQUIREMENTCOLLECTION_TYPE = REQUIREMENTCOLLECTION_NAMESPACE + REQUIREMENTCOLLECTION_LOCALNAME; //fullname of the rdfs:class the resource describes +} diff --git a/src/store-core/src/test/java/org/eclipse/lyo/store/resources/Requirement.java b/src/store-core/src/test/java/org/eclipse/lyo/store/resources/Requirement.java new file mode 100644 index 0000000..7376715 --- /dev/null +++ b/src/store-core/src/test/java/org/eclipse/lyo/store/resources/Requirement.java @@ -0,0 +1,135 @@ +package org.eclipse.lyo.store.resources; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Date; +import java.util.HashSet; + +import org.eclipse.lyo.oslc4j.core.annotation.OslcDescription; +import org.eclipse.lyo.oslc4j.core.annotation.OslcName; +import org.eclipse.lyo.oslc4j.core.annotation.OslcNamespace; +import org.eclipse.lyo.oslc4j.core.annotation.OslcOccurs; +import org.eclipse.lyo.oslc4j.core.annotation.OslcPropertyDefinition; +import org.eclipse.lyo.oslc4j.core.annotation.OslcReadOnly; +import org.eclipse.lyo.oslc4j.core.annotation.OslcResourceShape; +import org.eclipse.lyo.oslc4j.core.annotation.OslcValueType; +import org.eclipse.lyo.oslc4j.core.model.AbstractResource; +import org.eclipse.lyo.oslc4j.core.model.Link; +import org.eclipse.lyo.oslc4j.core.model.Occurs; +import org.eclipse.lyo.oslc4j.core.model.ValueType; +import org.eclipse.lyo.store.resources.Oslc_rmDomainConstants; + +@OslcNamespace(Oslc_rmDomainConstants.REQUIREMENT_NAMESPACE) +@OslcName(Oslc_rmDomainConstants.REQUIREMENT_LOCALNAME) +@OslcResourceShape(title = "Requirement Resource Shape", describes = Oslc_rmDomainConstants.REQUIREMENT_TYPE) +public class Requirement + extends AbstractResource +{ + private static final String DUBLIN_CORE_NAMSPACE = "http://purl.org/dc/terms/"; + + private String title; + private String description; + private String identifier; + private Date created; + private HashSet decomposes = new HashSet(); + + public Requirement() + throws URISyntaxException + { + super(); + } + + public Requirement(final URI about) + throws URISyntaxException + { + super(about); + } + + @OslcName("title") + @OslcPropertyDefinition(DUBLIN_CORE_NAMSPACE + "title") + @OslcDescription("Title of the resource represented as rich text in XHTML content. SHOULD include only content that is valid inside an XHTML element.") + @OslcOccurs(Occurs.ExactlyOne) + @OslcValueType(ValueType.XMLLiteral) + @OslcReadOnly(false) + public String getTitle() + { + return title; + } + + @OslcName("description") + @OslcPropertyDefinition(DUBLIN_CORE_NAMSPACE + "description") + @OslcDescription("Descriptive text about resource represented as rich text in XHTML content. SHOULD include only content that is valid and suitable inside an XHTML
element.") + @OslcOccurs(Occurs.ZeroOrOne) + @OslcValueType(ValueType.XMLLiteral) + @OslcReadOnly(false) + public String getDescription() + { + return description; + } + + @OslcName("identifier") + @OslcPropertyDefinition(DUBLIN_CORE_NAMSPACE + "identifier") + @OslcDescription("A unique identifier for a resource. Typically read-only and assigned by the service provider when a resource is created. Not typically intended for end-user display.") + @OslcOccurs(Occurs.ExactlyOne) + @OslcValueType(ValueType.String) + @OslcReadOnly(false) + public String getIdentifier() + { + return identifier; + } + + @OslcName("created") + @OslcPropertyDefinition(DUBLIN_CORE_NAMSPACE + "created") + @OslcDescription("Timestamp of resource creation") + @OslcOccurs(Occurs.ZeroOrOne) + @OslcValueType(ValueType.DateTime) + @OslcReadOnly(false) + public Date getCreated() + { + return created; + } + + @OslcName("decomposes") + @OslcPropertyDefinition(Oslc_rmDomainConstants.REQUIREMENTS_MANAGEMENT_NAMSPACE + "decomposes") + @OslcDescription("The object is decomposed by the subject.") + @OslcOccurs(Occurs.ZeroOrMany) + @OslcValueType(ValueType.Resource) + @OslcReadOnly(false) + public HashSet getDecomposes() + { + return decomposes; + } + + public void setTitle(final String title ) + { + this.title = title; + + } + + public void setDescription(final String description ) + { + this.description = description; + } + + public void setIdentifier(final String identifier ) + { + this.identifier = identifier; + } + + + public void setCreated(final Date created ) + { + this.created = created; + } + + public void setDecomposes(final HashSet decomposes ) + { + this.decomposes.clear(); + if (decomposes != null) + { + this.decomposes.addAll(decomposes); + } + } + + +}