-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Exchange old hydra models with new one
- Loading branch information
Showing
22 changed files
with
324 additions
and
654 deletions.
There are no files selected for viewing
69 changes: 33 additions & 36 deletions
69
src/main/java/eu/nampi/backend/model/hydra/AbstractHydraBuilder.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 |
---|---|---|
@@ -1,60 +1,57 @@ | ||
package eu.nampi.backend.model.hydra; | ||
|
||
import org.apache.jena.arq.querybuilder.ConstructBuilder; | ||
import java.util.Optional; | ||
import org.apache.jena.arq.querybuilder.ExprFactory; | ||
import org.apache.jena.arq.querybuilder.WhereBuilder; | ||
import org.apache.jena.graph.Node; | ||
import org.apache.jena.graph.NodeFactory; | ||
import org.apache.jena.query.QuerySolution; | ||
import org.apache.jena.rdf.model.Model; | ||
import org.apache.jena.rdf.model.ModelFactory; | ||
import org.apache.jena.rdf.model.RDFNode; | ||
import org.apache.jena.rdf.model.Resource; | ||
import org.apache.jena.rdf.model.ResourceFactory; | ||
import org.apache.jena.vocabulary.RDF; | ||
import org.apache.jena.vocabulary.RDFS; | ||
import org.apache.jena.vocabulary.XSD; | ||
import eu.nampi.backend.service.JenaService; | ||
import eu.nampi.backend.vocabulary.Api; | ||
import eu.nampi.backend.vocabulary.Core; | ||
import eu.nampi.backend.vocabulary.Hydra; | ||
import eu.nampi.backend.vocabulary.SchemaOrg; | ||
|
||
public abstract class AbstractHydraBuilder extends ConstructBuilder | ||
implements InterfaceHydraBuilder { | ||
|
||
public abstract class AbstractHydraBuilder implements InterfaceHydraBuilder { | ||
protected JenaService jenaService; | ||
protected Resource mainType; | ||
protected String baseUri; | ||
public ExprFactory ef; | ||
public Model model = ModelFactory.createDefaultModel(); | ||
public Resource root; | ||
public WhereBuilder coreData = new WhereBuilder(); | ||
public static final Node VAR_MAIN = NodeFactory.createVariable("main"); | ||
public static final Node VAR_MAIN_LABEL = NodeFactory.createVariable("label"); | ||
public static final Node VAR_MAIN_COMMENT = NodeFactory.createVariable("comment"); | ||
public static final Node VAR_COMMENT = NodeFactory.createVariable("comment"); | ||
public static final Node VAR_LABEL = NodeFactory.createVariable("label"); | ||
|
||
public final ExprFactory ef; | ||
public final Node baseNode; | ||
public final Resource mainType; | ||
|
||
public AbstractHydraBuilder(Node baseNode, Resource mainType) { | ||
super(); | ||
// @formatter:off | ||
this | ||
.addPrefix("api", Api.getURI()) | ||
.addPrefix("core", Core.getURI()) | ||
.addPrefix("hydra", Hydra.getURI()) | ||
.addPrefix("rdf", RDF.getURI()) | ||
.addPrefix("rdfs", RDFS.getURI()) | ||
.addPrefix("schema", SchemaOrg.getURI()) | ||
.addPrefix("xsd", XSD.getURI()) | ||
.addConstruct(VAR_MAIN, RDF.type, mainType) | ||
.addConstruct(VAR_MAIN, RDFS.label, VAR_MAIN_LABEL) | ||
.addConstruct(VAR_MAIN, RDFS.comment, VAR_MAIN_COMMENT); | ||
// @formatter:on | ||
this.baseNode = baseNode; | ||
this.ef = this.getExprFactory(); | ||
protected AbstractHydraBuilder(JenaService jenaService, String baseUri, Resource mainType) { | ||
this.jenaService = jenaService; | ||
this.baseUri = baseUri; | ||
this.mainType = mainType; | ||
this.root = ResourceFactory.createResource(baseUri); | ||
coreData.addWhere(VAR_MAIN, RDF.type, mainType); | ||
model | ||
.setNsPrefix("api", Api.getURI()) | ||
.setNsPrefix("core", Core.getURI()) | ||
.setNsPrefix("hydra", Hydra.getURI()) | ||
.setNsPrefix("rdf", RDF.getURI()) | ||
.setNsPrefix("rdfs", RDFS.getURI()) | ||
.setNsPrefix("schema", SchemaOrg.getURI()) | ||
.setNsPrefix("xsd", XSD.getURI()); | ||
this.ef = coreData.getExprFactory(); | ||
} | ||
|
||
public WhereBuilder mainWhere() { | ||
return new WhereBuilder().addWhere(VAR_MAIN, RDF.type, mainType); | ||
} | ||
|
||
public WhereBuilder labelWhere() { | ||
return new WhereBuilder().addWhere(VAR_MAIN, RDFS.label, VAR_MAIN_LABEL); | ||
} | ||
|
||
public WhereBuilder commentWhere() { | ||
return new WhereBuilder().addOptional(VAR_MAIN, RDFS.comment, VAR_MAIN_COMMENT); | ||
protected Optional<RDFNode> get(QuerySolution row, Node variable) { | ||
return Optional.ofNullable(row.get(variable.getName())); | ||
} | ||
|
||
} |
204 changes: 87 additions & 117 deletions
204
src/main/java/eu/nampi/backend/model/hydra/HydraCollectionBuilder.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 |
---|---|---|
@@ -1,143 +1,113 @@ | ||
package eu.nampi.backend.model.hydra; | ||
|
||
import java.util.Optional; | ||
import java.util.function.BiFunction; | ||
import org.apache.jena.arq.querybuilder.SelectBuilder; | ||
import org.apache.jena.arq.querybuilder.WhereBuilder; | ||
import org.apache.jena.graph.Node; | ||
import org.apache.jena.graph.NodeFactory; | ||
import org.apache.jena.query.QuerySolution; | ||
import org.apache.jena.rdf.model.Model; | ||
import org.apache.jena.rdf.model.RDFNode; | ||
import org.apache.jena.rdf.model.Resource; | ||
import org.apache.jena.rdf.model.ResourceFactory; | ||
import org.apache.jena.sparql.expr.Expr; | ||
import org.apache.jena.sparql.lang.sparql_11.ParseException; | ||
import org.apache.jena.vocabulary.RDF; | ||
import org.apache.jena.vocabulary.RDFS; | ||
import eu.nampi.backend.model.QueryParameters; | ||
import eu.nampi.backend.service.JenaService; | ||
import eu.nampi.backend.vocabulary.Api; | ||
import eu.nampi.backend.vocabulary.Hydra; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
@Slf4j | ||
public class HydraCollectionBuilder extends AbstractHydraBuilder { | ||
private Resource orderByVar; | ||
protected QueryParameters params; | ||
public ParameterMapper mapper; | ||
public WhereBuilder extendedData = new WhereBuilder(); | ||
|
||
public static final Node VAR_FIRST = NodeFactory.createVariable("first"); | ||
public static final Node VAR_LAST = NodeFactory.createVariable("last"); | ||
public static final Node VAR_MANAGES = NodeFactory.createVariable("manages"); | ||
public static final Node VAR_NEXT = NodeFactory.createVariable("next"); | ||
public static final Node VAR_PREVIOUS = NodeFactory.createVariable("previous"); | ||
public static final Node VAR_SEARCH = NodeFactory.createVariable("search"); | ||
public static final Node VAR_TOTAL_ITEMS = NodeFactory.createVariable("totalItems"); | ||
|
||
public final ParameterMapper mapper; | ||
public final WhereBuilder countWhere; | ||
public final WhereBuilder dataWhere; | ||
|
||
private final Resource orderByVar; | ||
private final QueryParameters params; | ||
private final SelectBuilder bindSelect = new SelectBuilder(); | ||
private final WhereBuilder bindWhere = new WhereBuilder(); | ||
|
||
public HydraCollectionBuilder(String baseUri, Resource mainType, Resource orderByVar, | ||
QueryParameters params) { | ||
this(baseUri, mainType, orderByVar, params, true, false); | ||
} | ||
|
||
public HydraCollectionBuilder(String baseUri, Resource mainType, Resource orderByVar, | ||
QueryParameters params, boolean includeTextFilter, boolean optionalLabel) { | ||
super(NodeFactory.createURI(baseUri), mainType); | ||
this.countWhere = mainWhere(); | ||
this.dataWhere = mainWhere(); | ||
this.mapper = new ParameterMapper(baseUri, VAR_SEARCH, this, bindSelect); | ||
public HydraCollectionBuilder(JenaService jenaService, String baseUri, Resource mainType, | ||
Resource orderByVar, QueryParameters params, boolean includeTextFilter) { | ||
super(jenaService, baseUri, mainType); | ||
this.mapper = new ParameterMapper(baseUri, root, model); | ||
this.orderByVar = orderByVar; | ||
this.params = params; | ||
|
||
// Add text filter | ||
if (optionalLabel) { | ||
dataWhere.addOptional(labelWhere()); | ||
} else { | ||
dataWhere.addWhere(labelWhere()); | ||
// Set up manages node | ||
Resource manages = ResourceFactory.createResource(); | ||
this.model | ||
.add(root, Hydra.manages, manages) | ||
.add(manages, Hydra.object, mainType); | ||
|
||
boolean orderByLabel = this.params.getOrderByClauses().containsKey("label"); | ||
if (orderByLabel) { | ||
coreData.addWhere(VAR_MAIN, RDFS.label, VAR_LABEL); | ||
} | ||
if (includeTextFilter && params.getText().isPresent()) { | ||
Expr regex = ef.regex(VAR_MAIN_LABEL, params.getText().get(), "i"); | ||
dataWhere.addFilter(regex); | ||
if (optionalLabel) { | ||
countWhere.addOptional(labelWhere()).addFilter(regex); | ||
} else { | ||
countWhere.addWhere(labelWhere()).addFilter(regex); | ||
|
||
// Add default data | ||
extendedData | ||
.addOptional(VAR_MAIN, RDFS.label, VAR_LABEL) | ||
.addOptional(VAR_MAIN, RDFS.comment, VAR_COMMENT); | ||
|
||
// Add default text filter | ||
params.getText().filter(text -> includeTextFilter).ifPresent(text -> { | ||
if (!orderByLabel) { | ||
coreData.addWhere(VAR_MAIN, RDFS.label, VAR_LABEL); | ||
} | ||
} | ||
Expr matchText = ef.regex(VAR_LABEL, text, "i"); | ||
coreData.addFilter(matchText); | ||
}); | ||
|
||
// Add type filter | ||
if (params.getType().isPresent()) { | ||
Resource typeResource = ResourceFactory.createResource(params.getType().get()); | ||
dataWhere.addWhere(VAR_MAIN, RDF.type, typeResource); | ||
countWhere.addWhere(VAR_MAIN, RDF.type, typeResource); | ||
} | ||
params.getType().map(ResourceFactory::createResource).ifPresent(res -> { | ||
coreData.addWhere(VAR_MAIN, RDF.type, res); | ||
}); | ||
} | ||
|
||
public HydraCollectionBuilder(JenaService jenaService, String baseUri, Resource mainType, | ||
Resource orderByVar, QueryParameters params) { | ||
this(jenaService, baseUri, mainType, orderByVar, params, true); | ||
} | ||
|
||
@Override | ||
public String buildHydra() { | ||
// @formatter:off | ||
try { | ||
|
||
// Construct the result | ||
this | ||
// Add general hydra data | ||
.addConstruct(baseNode, RDF.type, Hydra.Collection) | ||
.addConstruct(baseNode, Hydra.totalItems, VAR_TOTAL_ITEMS) | ||
.addConstruct(baseNode, Hydra.manages, VAR_MANAGES) | ||
.addConstruct(VAR_MANAGES, Hydra.object, mainType) | ||
.addConstruct(baseNode, Hydra.search, VAR_SEARCH ) | ||
.addConstruct(VAR_SEARCH, RDF.type, Hydra.IriTemplate) | ||
.addConstruct(VAR_SEARCH, Hydra.variableRepresentation, Hydra.BasicRepresentation) | ||
.addConstruct(baseNode, Hydra.member, VAR_MAIN); | ||
|
||
// Add all variable bindings | ||
bindWhere | ||
.addBind(ef.bnode(), VAR_SEARCH) | ||
.addBind(ef.bnode(), VAR_MANAGES); | ||
|
||
// Set up selects | ||
SelectBuilder dataSelect = new SelectBuilder() | ||
.addVar("*") | ||
.addWhere(dataWhere); | ||
params.getOrderByClauses().appendAllTo(dataSelect); | ||
dataSelect.addOrderBy(VAR_MAIN) | ||
.setOffset(params.getOffset()) | ||
.setLimit(params.getLimit()); | ||
SelectBuilder countSelect = new SelectBuilder() | ||
.addVar("count(*)", VAR_TOTAL_ITEMS) | ||
.addWhere(countWhere); | ||
SelectBuilder contentSelect = new SelectBuilder() | ||
.addVar("*") | ||
.addUnion(dataSelect) | ||
.addUnion(countSelect); | ||
bindSelect | ||
.addVar("*") | ||
.addWhere(bindWhere); | ||
|
||
Node view = mapper | ||
.add("limit", Hydra.limit, params.getLimit()) | ||
.add("offset", Hydra.offset, params.getOffset()) | ||
.add("orderBy", orderByVar, params.getOrderByClauses().toQueryString()) | ||
.add("pageIndex", Hydra.pageIndex, null) | ||
.add("text", Api.textVar, params.getText().orElse("")) | ||
.add("type", RDF.type, params.getType().orElse("")) | ||
.addTemplate(baseNode); | ||
|
||
this | ||
.addConstruct(view, Hydra.first, VAR_FIRST) | ||
.addConstruct(view, Hydra.previous, VAR_PREVIOUS) | ||
.addConstruct(view, Hydra.next, VAR_NEXT) | ||
.addConstruct(view, Hydra.last, VAR_LAST) | ||
.addWhere(new WhereBuilder() | ||
.addUnion(contentSelect) | ||
.addUnion(bindSelect)) | ||
.addBind("if(contains('" + view + "', 'offset=0'), 1+'', replace('" + view + "', 'offset=\\\\d*', 'offset=0'))", VAR_FIRST) | ||
.addBind("if(" + params.getOffset() + " >= floor(" + VAR_TOTAL_ITEMS + " / " + params.getLimit() + ") * " + params.getLimit() + " , 1+'', replace('" + view + "', 'offset=\\\\d*', concat('offset=', str(xsd:integer(floor(" + VAR_TOTAL_ITEMS + " / " + params.getLimit() + ") * " + params.getLimit() + ")))))", VAR_LAST) | ||
.addBind("if(" + (params.getOffset() - params.getLimit()) + " >= 0, replace('" + view + "', 'offset=\\\\d*', concat('offset=', str(" + (params.getOffset() - params.getLimit()) + "))), 1+'')", VAR_PREVIOUS) | ||
.addBind("if(" + (params.getOffset() + params.getLimit()) + " < " + VAR_TOTAL_ITEMS + ", replace('" + view + "', 'offset=\\\\d*', concat('offset=', str(" + (params.getOffset() + params.getLimit()) + "))), 1+'')", VAR_NEXT); | ||
} catch (ParseException e) { | ||
log.error(e.getMessage()); | ||
} | ||
// @formatter:on | ||
return buildString(); | ||
public void build(BiFunction<Model, QuerySolution, RDFNode> rowToNode) { | ||
// Count all possible matches | ||
int totalItems = jenaService.count(coreData, VAR_MAIN); | ||
|
||
// Finalize the core select | ||
SelectBuilder coreSelect = new SelectBuilder() | ||
.setDistinct(true) | ||
.addVar(VAR_MAIN) | ||
.addWhere(coreData); | ||
|
||
this.params | ||
.getOrderByClauses() | ||
.appendAllTo(coreSelect); | ||
coreSelect | ||
.addOrderBy(VAR_MAIN) | ||
.setOffset(params.getOffset()) | ||
.setLimit(params.getLimit()); | ||
|
||
SelectBuilder finalSelect = new SelectBuilder() | ||
.addSubQuery(coreSelect) | ||
.addWhere(extendedData); | ||
|
||
// Setup the root hydra collection | ||
this.model | ||
.add(this.root, RDF.type, Hydra.Collection) | ||
.addLiteral(root, Hydra.totalItems, ResourceFactory.createTypedLiteral(totalItems)); | ||
|
||
// Query the data using the jena service and add the content provided by the row mapper function | ||
// to the model | ||
jenaService.select(finalSelect, row -> this.model | ||
.add(root, Hydra.member, rowToNode.apply(this.model, row))); | ||
|
||
// Set up the search and view nodes with the main query parameters | ||
this.mapper | ||
.add("limit", Hydra.limit, params.getLimit()) | ||
.add("offset", Hydra.offset, params.getOffset()) | ||
.add("orderBy", orderByVar, params.getOrderByClauses().toQueryString()) | ||
.add("pageIndex", Hydra.pageIndex, Optional.empty()) | ||
.add("text", Api.textVar, params.getText()) | ||
.add("type", RDF.type, params.getType()) | ||
.insertTemplate() | ||
.insertView(totalItems); | ||
} | ||
} |
32 changes: 22 additions & 10 deletions
32
src/main/java/eu/nampi/backend/model/hydra/HydraSingleBuilder.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 |
---|---|---|
@@ -1,22 +1,34 @@ | ||
package eu.nampi.backend.model.hydra; | ||
|
||
import org.apache.jena.graph.NodeFactory; | ||
import java.util.function.BiFunction; | ||
import org.apache.jena.arq.querybuilder.SelectBuilder; | ||
import org.apache.jena.query.QuerySolution; | ||
import org.apache.jena.rdf.model.Model; | ||
import org.apache.jena.rdf.model.RDFNode; | ||
import org.apache.jena.rdf.model.Resource; | ||
import org.apache.jena.vocabulary.RDFS; | ||
import eu.nampi.backend.service.JenaService; | ||
|
||
public class HydraSingleBuilder extends AbstractHydraBuilder { | ||
|
||
public final String iri; | ||
public HydraSingleBuilder(JenaService jenaService, String baseUri, Resource mainType, | ||
boolean optionalLabel) { | ||
super(jenaService, baseUri, mainType); | ||
// Add default data | ||
coreData | ||
.addFilter(ef.sameTerm(VAR_MAIN, root)) | ||
.addOptional(VAR_MAIN, RDFS.label, VAR_LABEL) | ||
.addOptional(VAR_MAIN, RDFS.comment, VAR_COMMENT); | ||
} | ||
|
||
public HydraSingleBuilder(String iri, Resource type) { | ||
super(NodeFactory.createURI(iri), type); | ||
this.iri = iri; | ||
addWhere(mainWhere()); | ||
addFilter(ef.sameTerm(VAR_MAIN, baseNode)); | ||
addWhere(labelWhere()); | ||
public HydraSingleBuilder(JenaService jenaService, String baseUri, Resource mainType) { | ||
this(jenaService, baseUri, mainType, false); | ||
} | ||
|
||
public String buildHydra() { | ||
return buildString(); | ||
@Override | ||
public void build(BiFunction<Model, QuerySolution, RDFNode> rowToNode) { | ||
SelectBuilder core = new SelectBuilder().addVar("*").addWhere(coreData); | ||
jenaService.select(core, row -> rowToNode.apply(this.model, row)); | ||
} | ||
|
||
} |
7 changes: 6 additions & 1 deletion
7
src/main/java/eu/nampi/backend/model/hydra/InterfaceHydraBuilder.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 |
---|---|---|
@@ -1,7 +1,12 @@ | ||
package eu.nampi.backend.model.hydra; | ||
|
||
import java.util.function.BiFunction; | ||
import org.apache.jena.query.QuerySolution; | ||
import org.apache.jena.rdf.model.Model; | ||
import org.apache.jena.rdf.model.RDFNode; | ||
|
||
public interface InterfaceHydraBuilder { | ||
|
||
public String buildHydra(); | ||
public void build(BiFunction<Model, QuerySolution, RDFNode> rowToNode); | ||
|
||
} |
Oops, something went wrong.