Skip to content
Snippets Groups Projects
Commit 1628808c authored by Andreas Schärtl's avatar Andreas Schärtl
Browse files

ulo-storage-endpoint: add /explore and /explore/contributor pages

parent 290f8847
No related branches found
No related tags found
No related merge requests found
Showing
with 234 additions and 10 deletions
package info.mathhub.uloapi.html;
/**
* Class that provides useful methods for working with base64 strings.
*/
public final class Base64 {
private Base64() {}
/**
* Encode a string to a base64 representation.
*
* @param value The string to encode in base64.
* @return The base64-encoded version of value.
*/
public static String encode(String value) {
final java.util.Base64.Encoder encoder = java.util.Base64.getEncoder();
return encoder.encodeToString(value.getBytes());
}
/**
* Decode from a base64 representation.
*
* @param base64 The base64-encoded string to decode.
* @return The decoded version of argument base64.
*/
public static String decode(String base64) {
final java.util.Base64.Decoder decoder = java.util.Base64.getDecoder();
final byte[] bytes = decoder.decode(base64);
return new String(bytes);
}
}
...@@ -14,6 +14,8 @@ public class Main { ...@@ -14,6 +14,8 @@ public class Main {
get("/", Routes.index, new FreeMarkerEngine()); get("/", Routes.index, new FreeMarkerEngine());
get("/statistics", Routes.statistics, new FreeMarkerEngine()); get("/statistics", Routes.statistics, new FreeMarkerEngine());
get("/queries", Routes.queries, new FreeMarkerEngine()); get("/queries", Routes.queries, new FreeMarkerEngine());
get("/explore", Routes.explore, new FreeMarkerEngine());
get("/explore/contributor/:contributor", Routes.exploreContributor, new FreeMarkerEngine());
internalServerError(Errors.internalServerError); internalServerError(Errors.internalServerError);
notFound(Errors.notFound); notFound(Errors.notFound);
......
...@@ -3,17 +3,21 @@ package info.mathhub.uloapi.html; ...@@ -3,17 +3,21 @@ package info.mathhub.uloapi.html;
import info.mathhub.uloapi.query.Query; import info.mathhub.uloapi.query.Query;
import info.mathhub.uloapi.query.Statistics; import info.mathhub.uloapi.query.Statistics;
import info.mathhub.uloapi.query.Timer; import info.mathhub.uloapi.query.Timer;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.Statement; import org.eclipse.rdf4j.model.Statement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import spark.*; import spark.*;
import java.util.HashMap; import java.util.*;
import java.util.List;
import java.util.Map;
/** /**
* This class contains all routes of our application. * This class contains all routes of our application.
*/ */
public class Routes { public class Routes {
private static final Logger log = LoggerFactory.getLogger(Routes.class);
private Routes() {}; private Routes() {};
public static final TemplateViewRoute index = (Request request, Response response) -> { public static final TemplateViewRoute index = (Request request, Response response) -> {
...@@ -45,4 +49,27 @@ public class Routes { ...@@ -45,4 +49,27 @@ public class Routes {
return new ModelAndView(model, "queries.flt"); return new ModelAndView(model, "queries.flt");
}; };
public static final TemplateViewRoute explore = (Request request, Response response) -> {
final Query query = Query.getSingleton();
final List<Literal> contributors = query.getContributors();
final Map<String, Object> model = new HashMap<>();
model.put("contributors", contributors);
return new ModelAndView(model, "explore.flt");
};
public static final TemplateViewRoute exploreContributor = (Request request, Response response) -> {
final Query query = Query.getSingleton();
final String contributor = request.params("contributor");
final List<IRI> contributions = query.getContributions(contributor);
final Map<String, Object> model = new HashMap<>();
model.put("contributor", contributor);
model.put("contributions", contributions);
return new ModelAndView(model, "explore_contributor.flt");
};
} }
package info.mathhub.uloapi.query;
import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
public class Literals {
private Literals() {}
/**
* Create a {@link Literal} from argument {@code value}.
*
* @param value The argument to turn into a {@link Literal}
* @return A {@link Literal} that contains argument {@code value}.
*/
public static Literal fromString(String value) {
if (value == null) {
throw new NullPointerException("argument value must not be null");
}
final ValueFactory valueFactory = SimpleValueFactory.getInstance();
return valueFactory.createLiteral(value);
}
}
package info.mathhub.uloapi.query; package info.mathhub.uloapi.query;
import info.mathhub.uloapi.config.Config; import info.mathhub.uloapi.config.Config;
import info.mathhub.uloapi.ontology.DCTerms;
import info.mathhub.uloapi.ontology.ULO; import info.mathhub.uloapi.ontology.ULO;
import org.eclipse.rdf4j.model.Statement; import org.eclipse.rdf4j.model.*;
import org.eclipse.rdf4j.repository.RepositoryResult; import org.eclipse.rdf4j.repository.RepositoryResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.*;
import java.util.Iterator;
import java.util.List;
/** /**
* Class {@link Query} wraps various common queries to an RDF4j endpoint. Objects of type {@link Query} * Class {@link Query} wraps various common queries to an RDF4j endpoint. Objects of type {@link Query}
...@@ -20,6 +21,8 @@ public class Query { ...@@ -20,6 +21,8 @@ public class Query {
private static Query singleton; private static Query singleton;
private static final Logger log = LoggerFactory.getLogger(Query.class);
/** /**
* Create a new object for the given endpoint. * Create a new object for the given endpoint.
* *
...@@ -90,4 +93,78 @@ public class Query { ...@@ -90,4 +93,78 @@ public class Query {
return GraphDB.execute(this.serverUrl, this.repository, operation); return GraphDB.execute(this.serverUrl, this.repository, operation);
} }
/**
* Return a list of contributors found in the data set.
*
* This method looks for various objects that might qualify as a "contributor", e.g.
* creator author and so on.
*/
public List<Literal> getContributors() {
final GraphDB.Operation<List<Literal>> operation = (manager, repository, connection) -> {
final List<IRI> predicates = Arrays.asList(
DCTerms.creator, DCTerms.contributor, DCTerms.publisher
);
final Set<Literal> contributors = new HashSet<>();
for (final IRI predicate : predicates) {
final RepositoryResult<Statement> result = connection.getStatements(null, predicate, null);
for (final Statement statement : result) {
final Value object = statement.getObject();
if (!(object instanceof Literal)) {
log.warn("found object that is not an Literal");
continue;
}
final Literal asLiteral = (Literal) object;
contributors.add(asLiteral);
}
}
return new ArrayList<>(contributors);
};
return GraphDB.execute(this.serverUrl, this.repository, operation);
}
/**
* Return a list of works authored by a given contributor
*
* @param contributor The name of the contributor, as stored in the data set as a literal.
*/
public List<IRI> getContributions(String contributor) {
final GraphDB.Operation<List<IRI>> operation = (manager, repository, connection) -> {
final List<IRI> predicates = Arrays.asList(
DCTerms.creator, DCTerms.contributor, DCTerms.publisher
);
final String contributorName = contributor.replace("\"", "");
final Literal object = Literals.fromString(contributorName);
final Set<IRI> contributions = new HashSet<>();
for (final IRI predicate : predicates) {
final RepositoryResult<Statement> result = connection.getStatements(null, predicate, object);
for (final Statement statement : result) {
final Resource subject = statement.getSubject();
if (!(subject instanceof IRI)) {
log.warn("found subject that is not an IRI");
continue;
}
final IRI asIri = (IRI) subject;
contributions.add(asIri);
}
}
return new ArrayList<>(contributions);
};
return GraphDB.execute(this.serverUrl, this.repository, operation);
}
} }
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8">
<title><@page_title/></title> <title><@page_title/></title>
<style> <style>
* { * {
...@@ -28,7 +29,7 @@ ...@@ -28,7 +29,7 @@
footer { footer {
border-top: solid 1px; border-top: solid 1px;
color: grey; color: grey;
font-size: 12pt; margin-top: 1em;
padding: 1em; padding: 1em;
text-align: right; text-align: right;
} }
...@@ -43,6 +44,7 @@ ...@@ -43,6 +44,7 @@
h1 { h1 {
display: inline-block; display: inline-block;
font-size: 12pt;
font-weight: bold; font-weight: bold;
} }
...@@ -50,6 +52,10 @@ ...@@ -50,6 +52,10 @@
font-size: 14pt; font-size: 14pt;
} }
h3 {
font-size: 12pt;
}
table { table {
text-align: left; text-align: left;
} }
...@@ -57,7 +63,10 @@ ...@@ -57,7 +63,10 @@
</head> </head>
<body> <body>
<nav> <nav>
<h1><a href="/">uloapi</a></h1> | <a href="/statistics">Statistics</a> | <a href="/queries">Queries</a> <h1><a href="/">uloapi</a></h1> |
📈 <a href="/statistics">Statistics</a> |
<a href="/queries">Queries</a> |
🧭 <a href="/explore">Explore</a>
</nav> </nav>
<main> <main>
<@page_main/> <@page_main/>
......
<#ftl output_format="HTML" auto_esc=false>
<#setting url_escaping_charset='UTF-8'>
<#include "base.flt">
<#macro page_title>
Explore
</#macro>
<#macro page_main>
<h2>Explore</h2>
<p>
Explore how some entries in the data set are connected with each other.
</p>
<ul>
<#list contributors as contributor>
<li>
<a href="/explore/contributor/${contributor?url}">${contributor}</a>
</li>
</#list>
</ul>
</#macro>
<@display_page/>
<#ftl output_format="HTML" auto_esc=false>
<#setting url_escaping_charset='UTF-8'>
<#include "base.flt">
<#macro page_title>
Explore ${contributor}
</#macro>
<#macro page_main>
<h2>Explore ${contributor}</h2>
<h3>Contributions</h3>
<ul>
<#list contributions as contribution>
<li>
<code>${contribution}</code>
</li>
</#list>
</ul>
</#macro>
<@display_page/>
info.mathhub.uloapi.config.serverurl=http://rdf:7200 info.mathhub.uloapi.config.serverurl=http://rdf:7200
info.mathhub.uloapi.config.repository=coq0 info.mathhub.uloapi.config.repository=fckw
\ No newline at end of file \ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment