From f9d50e38ff6dadc018c405892da22f368da172af Mon Sep 17 00:00:00 2001
From: Miel Vander Sande
Date: Tue, 15 Dec 2015 15:28:44 +0100
Subject: [PATCH 1/8] Added default mimeType
---
.../servlet/TriplePatternFragmentServlet.java | 13 +++++-----
.../linkeddatafragments/util/MIMEParse.java | 26 ++++++++++++++++---
2 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/src/org/linkeddatafragments/servlet/TriplePatternFragmentServlet.java b/src/org/linkeddatafragments/servlet/TriplePatternFragmentServlet.java
index 7c598dd..adb25cd 100644
--- a/src/org/linkeddatafragments/servlet/TriplePatternFragmentServlet.java
+++ b/src/org/linkeddatafragments/servlet/TriplePatternFragmentServlet.java
@@ -27,6 +27,7 @@
import org.linkeddatafragments.datasource.tdb.JenaTDBDataSourceType;
import org.linkeddatafragments.exceptions.DataSourceException;
import org.linkeddatafragments.exceptions.DataSourceNotFoundException;
+import org.linkeddatafragments.exceptions.NoRegisteredMimeTypesException;
import org.linkeddatafragments.fragments.LinkedDataFragment;
import org.linkeddatafragments.fragments.LinkedDataFragmentRequest;
import org.linkeddatafragments.fragments.LinkedDataFragmentRequestBase;
@@ -87,10 +88,10 @@ public void init(ServletConfig servletConfig) throws ServletException {
}
// register content types
- mimeTypes.add(Lang.TTL.getHeaderString());
- mimeTypes.add(Lang.JSONLD.getHeaderString());
- mimeTypes.add(Lang.NTRIPLES.getHeaderString());
- mimeTypes.add(Lang.RDFXML.getHeaderString());
+ MIMEParse.register(Lang.TTL.getHeaderString());
+ MIMEParse.register(Lang.JSONLD.getHeaderString());
+ MIMEParse.register(Lang.NTRIPLES.getHeaderString());
+ MIMEParse.register(Lang.RDFXML.getHeaderString());
} catch (IOException | DataSourceException e) {
throw new ServletException(e);
}
@@ -152,7 +153,7 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
output.add( fragment.getControls() );
// do conneg
- String bestMatch = MIMEParse.bestMatch(mimeTypes, request.getHeader("Accept"));
+ String bestMatch = MIMEParse.bestMatch(request.getHeader("Accept"));
Lang contentType = RDFLanguages.contentTypeToLang(bestMatch);
// serialize the output
@@ -161,7 +162,7 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
response.setCharacterEncoding("utf-8");
RDFDataMgr.write(response.getOutputStream(), output, contentType);
- } catch (IOException e) {
+ } catch (IOException | NoRegisteredMimeTypesException e) {
throw new ServletException(e);
} catch (DataSourceNotFoundException ex) {
try {
diff --git a/src/org/linkeddatafragments/util/MIMEParse.java b/src/org/linkeddatafragments/util/MIMEParse.java
index d45d605..4814635 100644
--- a/src/org/linkeddatafragments/util/MIMEParse.java
+++ b/src/org/linkeddatafragments/util/MIMEParse.java
@@ -1,5 +1,7 @@
package org.linkeddatafragments.util;
+import org.linkeddatafragments.exceptions.NoRegisteredMimeTypesException;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -24,10 +26,21 @@
* http://code.google.com/p/mimeparse/
*
* Ported by Tom Zellman .
+ * Extended by Miel Vander Sande
*
*/
public final class MIMEParse
{
+ private final static List mimeTypes = new ArrayList<>();
+
+ /**
+ * Register mimeType in collection
+ * @param mimeType
+ */
+ public static void register(String mimeType) {
+ mimeTypes.add(mimeType);
+ }
+
/**
* Parse results container
@@ -233,8 +246,11 @@ public static float quality(String mimeType, String ranges)
* @param header
* @return
*/
- public static String bestMatch(Collection supported, String header)
+ public static String bestMatch(List supported, String header) throws NoRegisteredMimeTypesException
{
+ if (supported.isEmpty())
+ throw new NoRegisteredMimeTypesException();
+
List parseResults = new LinkedList();
List weightedMatches = new LinkedList();
for (String r : StringUtils.split(header, ','))
@@ -251,8 +267,12 @@ public static String bestMatch(Collection supported, String header)
FitnessAndQuality lastOne = weightedMatches
.get(weightedMatches.size() - 1);
- return NumberUtils.compare(lastOne.quality, 0) != 0 ? lastOne.mimeType
- : "";
+ return NumberUtils.compare(lastOne.quality, 0) != 0 ? lastOne.mimeType : supported.get(0);
+ }
+
+ public static String bestMatch(String header) throws NoRegisteredMimeTypesException
+ {
+ return bestMatch(mimeTypes, header);
}
// hidden
From 19dfaf912abe3b0ed2f00a6c1f66baca68101514 Mon Sep 17 00:00:00 2001
From: Miel Vander Sande
Date: Wed, 16 Dec 2015 10:49:44 +0100
Subject: [PATCH 2/8] Added HTML writer with Freemarker
---
pom.xml | 7 ++-
.../NoRegisteredMimeTypesException.java | 13 +++++
.../servlet/TriplePatternFragmentServlet.java | 35 ++++++++----
.../standalone/JettyServer.java | 13 ++++-
.../linkeddatafragments/views/HtmlWriter.java | 56 +++++++++++++++++++
views/base.ftl.html | 40 +++++++++++++
views/index.ftl.html | 13 +++++
7 files changed, 164 insertions(+), 13 deletions(-)
create mode 100644 src/org/linkeddatafragments/exceptions/NoRegisteredMimeTypesException.java
create mode 100644 src/org/linkeddatafragments/views/HtmlWriter.java
create mode 100644 views/base.ftl.html
create mode 100644 views/index.ftl.html
diff --git a/pom.xml b/pom.xml
index bad49c4..235b14f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,7 +30,7 @@
httpclient
4.3.5
-
+
com.google.code.gson
gson
2.5
@@ -73,6 +73,11 @@
jena-tdb
1.1.2
+
+ org.freemarker
+ freemarker
+ 2.3.23
+
src
diff --git a/src/org/linkeddatafragments/exceptions/NoRegisteredMimeTypesException.java b/src/org/linkeddatafragments/exceptions/NoRegisteredMimeTypesException.java
new file mode 100644
index 0000000..3d2aaee
--- /dev/null
+++ b/src/org/linkeddatafragments/exceptions/NoRegisteredMimeTypesException.java
@@ -0,0 +1,13 @@
+package org.linkeddatafragments.exceptions;
+
+/**
+ *
+ * @author mielvandersande
+ */
+public class NoRegisteredMimeTypesException extends Exception {
+
+ public NoRegisteredMimeTypesException() {
+ super("List of supported mimeTypes is empty.");
+ }
+
+}
diff --git a/src/org/linkeddatafragments/servlet/TriplePatternFragmentServlet.java b/src/org/linkeddatafragments/servlet/TriplePatternFragmentServlet.java
index adb25cd..8a211ba 100644
--- a/src/org/linkeddatafragments/servlet/TriplePatternFragmentServlet.java
+++ b/src/org/linkeddatafragments/servlet/TriplePatternFragmentServlet.java
@@ -3,6 +3,9 @@
import com.google.gson.JsonObject;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
+import com.hp.hpl.jena.rdf.model.Statement;
+import com.hp.hpl.jena.rdf.model.StmtIterator;
+import freemarker.template.TemplateException;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
@@ -10,6 +13,10 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.Map.Entry;
+import java.util.function.Consumer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@@ -33,6 +40,7 @@
import org.linkeddatafragments.fragments.LinkedDataFragmentRequestBase;
import org.linkeddatafragments.fragments.tpf.TriplePatternFragmentRequestImpl;
import org.linkeddatafragments.util.MIMEParse;
+import org.linkeddatafragments.views.HtmlWriter;
/**
* Servlet that responds with a Linked Data Fragment.
@@ -88,6 +96,7 @@ public void init(ServletConfig servletConfig) throws ServletException {
}
// register content types
+ MIMEParse.register("text/html");
MIMEParse.register(Lang.TTL.getHeaderString());
MIMEParse.register(Lang.JSONLD.getHeaderString());
MIMEParse.register(Lang.NTRIPLES.getHeaderString());
@@ -145,24 +154,30 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
final LinkedDataFragmentRequest ldfRequest = new TriplePatternFragmentRequestImpl( request, config );
final IFragmentRequestProcessor processor = dataSource.getRequestProcessor( ldfRequest );
final LinkedDataFragment fragment = processor.createRequestedFragment();
-
- final Model output = ModelFactory.createDefaultModel();
- output.setNsPrefixes(config.getPrefixes());
- output.add( fragment.getMetadata() );
- output.add( fragment.getTriples() );
- output.add( fragment.getControls() );
-
+
// do conneg
String bestMatch = MIMEParse.bestMatch(request.getHeader("Accept"));
- Lang contentType = RDFLanguages.contentTypeToLang(bestMatch);
// serialize the output
response.setHeader("Server", "Linked Data Fragments Server");
response.setContentType(bestMatch);
response.setCharacterEncoding("utf-8");
+
+ if (bestMatch.equals("text/html")) {
+ new HtmlWriter().write(response.getOutputStream(), dataSources, dataSource, fragment);
+ return;
+ }
+
+ final Model output = ModelFactory.createDefaultModel();
+ output.setNsPrefixes(config.getPrefixes());
+ output.add( fragment.getMetadata() );
+ output.add( fragment.getTriples() );
+ output.add( fragment.getControls() );
+
+ Lang contentType = RDFLanguages.contentTypeToLang(bestMatch);
+ RDFDataMgr.write(response.getOutputStream(), output, contentType);
- RDFDataMgr.write(response.getOutputStream(), output, contentType);
- } catch (IOException | NoRegisteredMimeTypesException e) {
+ } catch (IOException | NoRegisteredMimeTypesException | TemplateException e) {
throw new ServletException(e);
} catch (DataSourceNotFoundException ex) {
try {
diff --git a/src/org/linkeddatafragments/standalone/JettyServer.java b/src/org/linkeddatafragments/standalone/JettyServer.java
index 23ff9c1..3272ded 100644
--- a/src/org/linkeddatafragments/standalone/JettyServer.java
+++ b/src/org/linkeddatafragments/standalone/JettyServer.java
@@ -5,11 +5,11 @@
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
-
import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.servlet.DefaultServlet;
+import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
-
import org.linkeddatafragments.servlet.TriplePatternFragmentServlet;
/**
@@ -67,6 +67,15 @@ public static void main(String[] args) throws Exception {
ServletHolder tpfServletHolder = new ServletHolder(new TriplePatternFragmentServlet());
tpfServletHolder.setInitParameter(TriplePatternFragmentServlet.CFGFILE, config);
handler.addServletWithMapping(tpfServletHolder, "/*");
+
+ // TODO: create a servlet to serve assets
+ //String assetsPath = System.getProperty("user.dir") + "/assets";
+ //ServletHolder assetsHolder = new ServletHolder(new DefaultServlet());
+ //assetsHolder.setInitParameter("resourceBase", assetsPath);
+ //assetsHolder.setInitParameter("dirAllowed","true");
+ //assetsHolder.setInitParameter("pathInfoOnly","true");
+ //handler.addServletWithMapping(assetsHolder,"/assets/*");
+
// start the server
server.start();
diff --git a/src/org/linkeddatafragments/views/HtmlWriter.java b/src/org/linkeddatafragments/views/HtmlWriter.java
new file mode 100644
index 0000000..ae4d172
--- /dev/null
+++ b/src/org/linkeddatafragments/views/HtmlWriter.java
@@ -0,0 +1,56 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.linkeddatafragments.views;
+
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateExceptionHandler;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+import org.linkeddatafragments.datasource.IDataSource;
+import org.linkeddatafragments.fragments.LinkedDataFragment;
+
+/**
+ *
+ * @author mielvandersande
+ */
+public class HtmlWriter {
+ private final Configuration cfg;
+
+ public HtmlWriter() throws IOException {
+ cfg = new Configuration(Configuration.VERSION_2_3_22);
+ cfg.setDirectoryForTemplateLoading(new File(System.getProperty("user.dir") + "/views"));
+ cfg.setDefaultEncoding("UTF-8");
+ cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
+ }
+
+ public void write(OutputStream outputStream, HashMap dataSources, IDataSource datasource, LinkedDataFragment fragment) throws IOException, TemplateException{
+ /* Get the template (uses cache internally) */
+ Template temp = cfg.getTemplate("index.ftl.html");
+
+ Map data = new HashMap();
+ data.put("assetsPath", "css/");
+ data.put("header", datasource.getTitle());
+ data.put("datasources", dataSources);
+ data.put("content", "");
+
+ data.put("controls", fragment.getControls());
+ data.put("metadata", fragment.getMetadata());
+ data.put("triples", fragment.getTriples());
+
+
+ /* Merge data-model with template */
+ Writer out = new OutputStreamWriter(outputStream);
+ temp.process(data, out);
+ }
+}
diff --git a/views/base.ftl.html b/views/base.ftl.html
new file mode 100644
index 0000000..5e5f37e
--- /dev/null
+++ b/views/base.ftl.html
@@ -0,0 +1,40 @@
+<#-- @license ©2015 Miel Vander Sande - Multimedia Lab / iMinds / Ghent University -->
+
+
+
+
+
+ <#attempt>
+ ${ title || header }
+ <#recover>
+ 'Linked Data Fragments Server'
+ #attempt>
+
+
+
+
+
+
+
+
+
+
+
+ ${ content }
+
+
+
+
\ No newline at end of file
diff --git a/views/index.ftl.html b/views/index.ftl.html
new file mode 100644
index 0000000..0003a38
--- /dev/null
+++ b/views/index.ftl.html
@@ -0,0 +1,13 @@
+<#-- @license ©2015 Miel Vander Sande - Multimedia Lab / iMinds / Ghent University -->
+<#include "base.ftl.html">
+
From f160c7c14e0056bab91451fdd9ba2511d17685b6 Mon Sep 17 00:00:00 2001
From: Miel Vander Sande
Date: Wed, 16 Dec 2015 14:47:18 +0100
Subject: [PATCH 3/8] Started fragment template
---
.../servlet/TriplePatternFragmentServlet.java | 6 ------
src/org/linkeddatafragments/views/HtmlWriter.java | 5 ++++-
views/base.ftl.html | 10 ++--------
views/index.ftl.html | 4 +++-
4 files changed, 9 insertions(+), 16 deletions(-)
diff --git a/src/org/linkeddatafragments/servlet/TriplePatternFragmentServlet.java b/src/org/linkeddatafragments/servlet/TriplePatternFragmentServlet.java
index 8a211ba..8d3237b 100644
--- a/src/org/linkeddatafragments/servlet/TriplePatternFragmentServlet.java
+++ b/src/org/linkeddatafragments/servlet/TriplePatternFragmentServlet.java
@@ -3,8 +3,6 @@
import com.google.gson.JsonObject;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
-import com.hp.hpl.jena.rdf.model.Statement;
-import com.hp.hpl.jena.rdf.model.StmtIterator;
import freemarker.template.TemplateException;
import java.io.File;
import java.io.FileReader;
@@ -13,10 +11,6 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.Map.Entry;
-import java.util.function.Consumer;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
diff --git a/src/org/linkeddatafragments/views/HtmlWriter.java b/src/org/linkeddatafragments/views/HtmlWriter.java
index ae4d172..9e854c9 100644
--- a/src/org/linkeddatafragments/views/HtmlWriter.java
+++ b/src/org/linkeddatafragments/views/HtmlWriter.java
@@ -15,6 +15,7 @@
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
+import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.linkeddatafragments.datasource.IDataSource;
@@ -39,10 +40,12 @@ public void write(OutputStream outputStream, HashMap dataSo
Template temp = cfg.getTemplate("index.ftl.html");
Map data = new HashMap();
- data.put("assetsPath", "css/");
+ data.put("assetsPath", "assets/");
data.put("header", datasource.getTitle());
data.put("datasources", dataSources);
data.put("content", "");
+ data.put("date", new Date());
+
data.put("controls", fragment.getControls());
data.put("metadata", fragment.getMetadata());
diff --git a/views/base.ftl.html b/views/base.ftl.html
index 5e5f37e..59ae42d 100644
--- a/views/base.ftl.html
+++ b/views/base.ftl.html
@@ -3,13 +3,7 @@
-
- <#attempt>
- ${ title || header }
- <#recover>
- 'Linked Data Fragments Server'
- #attempt>
-
+ ${ (title || header)!"Linked Data Fragments Server" }
@@ -33,7 +27,7 @@
-
\ No newline at end of file
+
+#macro>
\ No newline at end of file
diff --git a/views/index.ftl.html b/views/index.ftl.html
index 61b481f..40027bf 100644
--- a/views/index.ftl.html
+++ b/views/index.ftl.html
@@ -1,5 +1,6 @@
<#-- @license ©2015 Miel Vander Sande - Multimedia Lab / iMinds / Ghent University -->
<#include "base.ftl.html">
+<#macro contents>
Available datasets
Browse the following datasets as Triple Pattern Fragments:
@@ -14,4 +15,7 @@
Available datasets
The current dataset index contains metadata about these datasets.
-<#include "fragment.ftl.html">
\ No newline at end of file
+<#include "fragment.ftl.html">
+#macro>
+
+<@display_page/>
\ No newline at end of file
From 4d4b8226d13a0fb364f6f3204d2adbe8ec448b77 Mon Sep 17 00:00:00 2001
From: Miel Vander Sande
Date: Sat, 26 Dec 2015 16:58:56 +0100
Subject: [PATCH 6/8] Completed draft writers
---
.../linkeddatafragments/assets/favicon.ico | Bin 0 -> 318 bytes
src/org/linkeddatafragments/assets/logo.svg | 67 +++++
src/org/linkeddatafragments/assets/style.css | 247 ++++++++++++++++++
.../views/HtmlWriterImpl.java | 10 +-
.../views/LinkedDataFragmentWriterBase.java | 27 ++
.../LinkedDataFragmentWriterFactory.java | 25 ++
.../views/RdfWriterImpl.java | 53 ++++
views/datasource.ftl.html | 7 +
views/error.ftl.html | 11 +
views/fragment.ftl.html | 73 ++++++
views/notfound.ftl.html | 16 ++
11 files changed, 534 insertions(+), 2 deletions(-)
create mode 100644 src/org/linkeddatafragments/assets/favicon.ico
create mode 100644 src/org/linkeddatafragments/assets/logo.svg
create mode 100644 src/org/linkeddatafragments/assets/style.css
create mode 100644 src/org/linkeddatafragments/views/LinkedDataFragmentWriterBase.java
create mode 100644 src/org/linkeddatafragments/views/LinkedDataFragmentWriterFactory.java
create mode 100644 src/org/linkeddatafragments/views/RdfWriterImpl.java
create mode 100644 views/datasource.ftl.html
create mode 100644 views/error.ftl.html
create mode 100644 views/fragment.ftl.html
create mode 100644 views/notfound.ftl.html
diff --git a/src/org/linkeddatafragments/assets/favicon.ico b/src/org/linkeddatafragments/assets/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..65418193a24cd6f59b00198636351f7270b6dd41
GIT binary patch
literal 318
zcmZQzU<5(|0RbS%!l1#(z#zuJz@P!d0zj+)#2|4HXaJKC0wf0l(z3D)k^bixltlM2
z{Qv(SB1i&h3~db%3#_M#y2to@)=;tsYa9FRIEw?&DS39
literal 0
HcmV?d00001
diff --git a/src/org/linkeddatafragments/assets/logo.svg b/src/org/linkeddatafragments/assets/logo.svg
new file mode 100644
index 0000000..dce588f
--- /dev/null
+++ b/src/org/linkeddatafragments/assets/logo.svg
@@ -0,0 +1,67 @@
+
+
+
diff --git a/src/org/linkeddatafragments/assets/style.css b/src/org/linkeddatafragments/assets/style.css
new file mode 100644
index 0000000..4728a61
--- /dev/null
+++ b/src/org/linkeddatafragments/assets/style.css
@@ -0,0 +1,247 @@
+/*! @license ©2013 Ruben Verborgh - Multimedia Lab / iMinds / Ghent University */
+
+html, input, th, td {
+ font-family: "Open Sans", Verdana, Arial, sans-serif;
+ font-size: 11pt;
+}
+
+html {
+ background: #f6f6f6;
+}
+
+body {
+ max-width: 800px;
+ margin: 0 auto;
+ line-height: 1.3;
+ color: #333333;
+ background-color: white;
+ padding: 10px 40px;
+ box-shadow: 2px 2px 15px 0px rgba(50, 50, 50, 0.75);
+}
+
+h1, h2, h3, legend {
+ margin: .4em 0 .2em;
+ overflow: hidden;
+}
+h1 {
+ margin-right: 180px;
+}
+h1 a {
+ color: black;
+}
+h2 {
+ color: #be1622;
+}
+h3 {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+p {
+ margin: 0;
+}
+
+a {
+ color: #be1622;
+ text-decoration: none;
+ border-bottom: none 1px;
+}
+a:hover {
+ color: #be1622 !important;
+ border-bottom-style: solid;
+}
+
+ul {
+ padding: 0;
+ margin: 0 0 .5em 1.5em;
+ list-style: none;
+}
+
+pre {
+ margin: 0;
+}
+
+form {
+ margin: 0 0 1.5em;
+}
+
+fieldset {
+ border: none;
+ padding: .5em 0 0 20px;
+}
+fieldset ul {
+ margin-left: 0;
+}
+fieldset li {
+ line-height: 2em;
+}
+
+legend {
+ font-size: 1.17em;
+ font-weight: bold;
+ padding: 0;
+ margin-left: -20px;
+}
+
+label {
+ width: 100px;
+ display: block;
+ float: left;
+ clear: both;
+ font-weight: bold;
+}
+label:after {
+ content: ":";
+}
+
+input {
+ outline: none;
+ font-size: .95em;
+}
+fieldset input {
+ width: 500px;
+ color: #be1622;
+ background-color: transparent;
+ border: none;
+ border-bottom: 1px solid #bbbbbb;
+ cursor: pointer;
+}
+input[type=submit] {
+ font-weight: bold;
+ color: #be1622;
+ background-color: #f6f6f6;
+ border-radius: 3px;
+ padding: 5px 8px;
+ border: 1px solid #999999;
+ cursor: pointer;
+}
+input[type=submit]:hover {
+ border-color: #666666;
+}
+input[type=submit]:active {
+ padding: 6px 7px 4px 9px;
+}
+.uri {
+ font-family: "Droid Sans Mono", monospace;
+}
+
+header .logo {
+ text-align: right;
+}
+header .logo a {
+ position: absolute;
+ top: 20px;
+ margin-left: -100px;
+ border-bottom-width: 0px;
+}
+header .logo img {
+ width: 160px;
+}
+
+footer {
+ clear: both;
+ margin: 1.5em 0 .5em;
+ font-size: small;
+}
+footer * {
+ color: gray;
+ margin-right: 5px;
+}
+
+.counts {
+ color: gray;
+}
+ul.links {
+ margin: 0;
+ padding: 0;
+ display: inline;
+}
+ul.links li {
+ display: inline;
+ padding-left: 20px;
+ font-weight: bold;
+}
+
+ul.triples {
+ margin: .3em 0 1em 20px;
+ font-size: .95em;
+ line-height: 1.5;
+ font-family: "Droid Sans Mono", monospace;
+ overflow-x: hidden;
+}
+ul.triples li {
+ text-indent: -20px;
+ padding-left: 20px;
+ max-width: 100%;
+ max-height: 1.5em;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+ul.triples li:hover {
+ max-height: 100em;
+ white-space: normal;
+ transition: max-height .5s ease-in;
+ transition-delay: .5s;
+}
+ul.triples li:not(:hover) a {
+ color: inherit;
+}
+ul.triples a:nth-child(2) {
+ margin: 0 1em;
+}
+abbr {
+ border: none;
+}
+
+.index {
+ margin-bottom: 2em;
+}
+.datasets {
+ margin: .5em 20px;
+}
+dt {
+ font-weight: bold;
+ display: block;
+ float: left;
+ clear: left;
+}
+dd {
+ color: gray;
+ margin: .1em 0 0 12em;
+ font-size: .95em;
+}
+
+#about {
+ margin-top: 1.5em;
+ font-size: .9em;
+}
+
+@media screen and (max-width: 700px) {
+ html, input, th, td {
+ font-size: 10pt;
+ }
+ body {
+ padding: 15px;
+ }
+ header figure {
+ display: none;
+ }
+ h1, legend {
+ margin: 0;
+ }
+ fieldset, ul.triples {
+ padding: .5em 0;
+ margin: 0;
+ }
+ fieldset input {
+ width: 70%;
+ }
+ label {
+ width: 80px;
+ }
+ ul.triples li {
+ margin: 1em 0;
+ }
+}
diff --git a/src/org/linkeddatafragments/views/HtmlWriterImpl.java b/src/org/linkeddatafragments/views/HtmlWriterImpl.java
index abba13b..07c2397 100644
--- a/src/org/linkeddatafragments/views/HtmlWriterImpl.java
+++ b/src/org/linkeddatafragments/views/HtmlWriterImpl.java
@@ -49,11 +49,13 @@ public HtmlWriterImpl(Map prefixes, HashMap
@Override
public void writeFragment(ServletOutputStream outputStream, IDataSource datasource, LinkedDataFragment fragment, LinkedDataFragmentRequest ldfRequest) throws IOException, TemplateException{
Map data = new HashMap();
+
+ // base.ftl.html
data.put("assetsPath", "assets/");
data.put("header", datasource.getTitle());
-
data.put("date", new Date());
+ // fragment.ftl.html
data.put("datasourceUrl", ldfRequest.getDatasetURL());
data.put("datasource", datasource);
data.put("controls", fragment.getControls());
@@ -79,8 +81,10 @@ public void writeFragment(ServletOutputStream outputStream, IDataSource datasour
@Override
public void writeNotFound(ServletOutputStream outputStream, HttpServletRequest request) throws Exception {
Map data = new HashMap();
- data.put("url", request.getRequestURL().toString());
+ data.put("assetsPath", "assets/");
data.put("datasources", getDatasources());
+ data.put("date", new Date());
+ data.put("url", request.getRequestURL().toString());
Writer out = new OutputStreamWriter(outputStream);
notfoundTemplate.process(data, out);
@@ -89,6 +93,8 @@ public void writeNotFound(ServletOutputStream outputStream, HttpServletRequest r
@Override
public void writeError(ServletOutputStream outputStream, Exception ex) throws Exception {
Map data = new HashMap();
+ data.put("assetsPath", "assets/");
+ data.put("date", new Date());
data.put("error", ex);
Writer out = new OutputStreamWriter(outputStream);
diff --git a/src/org/linkeddatafragments/views/LinkedDataFragmentWriterBase.java b/src/org/linkeddatafragments/views/LinkedDataFragmentWriterBase.java
new file mode 100644
index 0000000..901103b
--- /dev/null
+++ b/src/org/linkeddatafragments/views/LinkedDataFragmentWriterBase.java
@@ -0,0 +1,27 @@
+package org.linkeddatafragments.views;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.linkeddatafragments.datasource.IDataSource;
+
+/**
+ *
+ * @author mielvandersande
+ */
+public abstract class LinkedDataFragmentWriterBase implements LinkedDataFragmentWriter {
+ private final Map prefixes;
+ private final HashMap datasources;
+
+ public LinkedDataFragmentWriterBase(Map prefixes, HashMap datasources) {
+ this.prefixes = prefixes;
+ this.datasources = datasources;
+ }
+
+ public Map getPrefixes() {
+ return prefixes;
+ }
+
+ public HashMap getDatasources() {
+ return datasources;
+ }
+}
diff --git a/src/org/linkeddatafragments/views/LinkedDataFragmentWriterFactory.java b/src/org/linkeddatafragments/views/LinkedDataFragmentWriterFactory.java
new file mode 100644
index 0000000..b4aeebc
--- /dev/null
+++ b/src/org/linkeddatafragments/views/LinkedDataFragmentWriterFactory.java
@@ -0,0 +1,25 @@
+package org.linkeddatafragments.views;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import org.linkeddatafragments.datasource.IDataSource;
+
+/**
+ *
+ * @author mielvandersande
+ */
+public class LinkedDataFragmentWriterFactory {
+
+ private final static String HTML = "text/html";
+
+
+ public static LinkedDataFragmentWriter create(Map prefixes, HashMap datasources, String mimeType) throws IOException {
+ switch (mimeType) {
+ case HTML:
+ return new HtmlWriterImpl(prefixes, datasources);
+ default:
+ return new RdfWriterImpl(prefixes, datasources, mimeType);
+ }
+ }
+}
diff --git a/src/org/linkeddatafragments/views/RdfWriterImpl.java b/src/org/linkeddatafragments/views/RdfWriterImpl.java
new file mode 100644
index 0000000..4b1a99c
--- /dev/null
+++ b/src/org/linkeddatafragments/views/RdfWriterImpl.java
@@ -0,0 +1,53 @@
+package org.linkeddatafragments.views;
+
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.ModelFactory;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import org.apache.jena.riot.Lang;
+import org.apache.jena.riot.RDFDataMgr;
+import org.apache.jena.riot.RDFLanguages;
+import org.linkeddatafragments.datasource.IDataSource;
+import org.linkeddatafragments.fragments.LinkedDataFragment;
+import org.linkeddatafragments.fragments.LinkedDataFragmentRequest;
+
+/**
+ *
+ * @author mielvandersande
+ */
+class RdfWriterImpl extends LinkedDataFragmentWriterBase implements LinkedDataFragmentWriter {
+
+ private final Lang contentType;
+
+ public RdfWriterImpl(Map prefixes, HashMap datasources, String mimeType) {
+ super(prefixes, datasources);
+ this.contentType = RDFLanguages.contentTypeToLang(mimeType);
+ }
+
+ @Override
+ public void writeNotFound(ServletOutputStream outputStream, HttpServletRequest request) throws IOException {
+ outputStream.println(request.getRequestURL().toString() + " not found!");
+ outputStream.close();
+ }
+
+ @Override
+ public void writeError(ServletOutputStream outputStream, Exception ex) throws IOException {
+ outputStream.println(ex.getMessage());
+ outputStream.close();
+ }
+
+ @Override
+ public void writeFragment(ServletOutputStream outputStream, IDataSource datasource, LinkedDataFragment fragment, LinkedDataFragmentRequest ldfRequest) throws Exception {
+ final Model output = ModelFactory.createDefaultModel();
+ output.setNsPrefixes(getPrefixes());
+ output.add(fragment.getMetadata());
+ output.add(fragment.getTriples());
+ output.add(fragment.getControls());
+
+ RDFDataMgr.write(outputStream, output, contentType);
+ }
+
+}
diff --git a/views/datasource.ftl.html b/views/datasource.ftl.html
new file mode 100644
index 0000000..97cd099
--- /dev/null
+++ b/views/datasource.ftl.html
@@ -0,0 +1,7 @@
+<#-- @license ©2015 Miel Vander Sande - Multimedia Lab / iMinds / Ghent University -->
+<#assign title = datasource.getTitle() + ' | ' + title!"">
+<#include "base.ftl.html">
+<#macro contents>
+<#include "fragment.ftl.html">
+#macro>
+<@display_page/>
diff --git a/views/error.ftl.html b/views/error.ftl.html
new file mode 100644
index 0000000..84ce658
--- /dev/null
+++ b/views/error.ftl.html
@@ -0,0 +1,11 @@
+<#-- @license ©2015 Miel Vander Sande - Multimedia Lab / iMinds / Ghent University -->
+<#include "base.ftl.html">
+<#macro contents>
+Error executing your request
+Your request could not be executed due to an internal server error.
+Please try reloading the page or return to the index page.
+
+Error details
+<#if error??>${(error.getMessage())!error!""}#if>
+#macro>
+<@display_page/>
\ No newline at end of file
diff --git a/views/fragment.ftl.html b/views/fragment.ftl.html
new file mode 100644
index 0000000..7174554
--- /dev/null
+++ b/views/fragment.ftl.html
@@ -0,0 +1,73 @@
+<#-- @license ©2015 Miel Vander Sande - Multimedia Lab / iMinds / Ghent University -->
+<#setting url_escaping_charset='UTF-8'>
+
+
+Matches in ${datasource.getTitle()} for ${ (query.getPatternString())!"" }
+
+<#assign HYDRA = "http://www.w3.org/ns/hydra/core#">
+
+
+ <#list metadata as triple>
+ <#if triple.getPredicate().getURI() == (HYDRA + "totalItems")>
+ Total number of triples: ${triple.getObject().getString()}
+ #if>
+ #list>
+
+
+
+
+<#list controls as triple>
+
+ <#if triple.getPredicate().getURI() == (HYDRA + "firstPage")>
+ - first
+ #if>
+ <#if triple.getPredicate().getURI() == (HYDRA + "previousPage")>
+ - previous
+ #if>
+ <#if triple.getPredicate().getURI() == (HYDRA + "nextPage")>
+ - next
+ #if>
+
+#list>
\ No newline at end of file
diff --git a/views/notfound.ftl.html b/views/notfound.ftl.html
new file mode 100644
index 0000000..363b8ab
--- /dev/null
+++ b/views/notfound.ftl.html
@@ -0,0 +1,16 @@
+<#-- @license ©2015 Miel Vander Sande - Multimedia Lab / iMinds / Ghent University -->
+<#include "base.ftl.html">
+<#macro contents>
+Resource not found
+
+ No resource with URL ${ url!"" }
was found.
+
+
+Available datasets
+
+#macro>
+<@display_page/>
\ No newline at end of file
From 1c62dcd9f30ccdcd62b9b1297da036feed534675 Mon Sep 17 00:00:00 2001
From: Miel Vander Sande
Date: Wed, 30 Dec 2015 10:59:54 +0100
Subject: [PATCH 7/8] Added assets folder
---
assets/logo.svg | 67 +++++++++++++
assets/style.css | 247 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 314 insertions(+)
create mode 100644 assets/logo.svg
create mode 100644 assets/style.css
diff --git a/assets/logo.svg b/assets/logo.svg
new file mode 100644
index 0000000..dce588f
--- /dev/null
+++ b/assets/logo.svg
@@ -0,0 +1,67 @@
+
+
+
diff --git a/assets/style.css b/assets/style.css
new file mode 100644
index 0000000..4728a61
--- /dev/null
+++ b/assets/style.css
@@ -0,0 +1,247 @@
+/*! @license ©2013 Ruben Verborgh - Multimedia Lab / iMinds / Ghent University */
+
+html, input, th, td {
+ font-family: "Open Sans", Verdana, Arial, sans-serif;
+ font-size: 11pt;
+}
+
+html {
+ background: #f6f6f6;
+}
+
+body {
+ max-width: 800px;
+ margin: 0 auto;
+ line-height: 1.3;
+ color: #333333;
+ background-color: white;
+ padding: 10px 40px;
+ box-shadow: 2px 2px 15px 0px rgba(50, 50, 50, 0.75);
+}
+
+h1, h2, h3, legend {
+ margin: .4em 0 .2em;
+ overflow: hidden;
+}
+h1 {
+ margin-right: 180px;
+}
+h1 a {
+ color: black;
+}
+h2 {
+ color: #be1622;
+}
+h3 {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+p {
+ margin: 0;
+}
+
+a {
+ color: #be1622;
+ text-decoration: none;
+ border-bottom: none 1px;
+}
+a:hover {
+ color: #be1622 !important;
+ border-bottom-style: solid;
+}
+
+ul {
+ padding: 0;
+ margin: 0 0 .5em 1.5em;
+ list-style: none;
+}
+
+pre {
+ margin: 0;
+}
+
+form {
+ margin: 0 0 1.5em;
+}
+
+fieldset {
+ border: none;
+ padding: .5em 0 0 20px;
+}
+fieldset ul {
+ margin-left: 0;
+}
+fieldset li {
+ line-height: 2em;
+}
+
+legend {
+ font-size: 1.17em;
+ font-weight: bold;
+ padding: 0;
+ margin-left: -20px;
+}
+
+label {
+ width: 100px;
+ display: block;
+ float: left;
+ clear: both;
+ font-weight: bold;
+}
+label:after {
+ content: ":";
+}
+
+input {
+ outline: none;
+ font-size: .95em;
+}
+fieldset input {
+ width: 500px;
+ color: #be1622;
+ background-color: transparent;
+ border: none;
+ border-bottom: 1px solid #bbbbbb;
+ cursor: pointer;
+}
+input[type=submit] {
+ font-weight: bold;
+ color: #be1622;
+ background-color: #f6f6f6;
+ border-radius: 3px;
+ padding: 5px 8px;
+ border: 1px solid #999999;
+ cursor: pointer;
+}
+input[type=submit]:hover {
+ border-color: #666666;
+}
+input[type=submit]:active {
+ padding: 6px 7px 4px 9px;
+}
+.uri {
+ font-family: "Droid Sans Mono", monospace;
+}
+
+header .logo {
+ text-align: right;
+}
+header .logo a {
+ position: absolute;
+ top: 20px;
+ margin-left: -100px;
+ border-bottom-width: 0px;
+}
+header .logo img {
+ width: 160px;
+}
+
+footer {
+ clear: both;
+ margin: 1.5em 0 .5em;
+ font-size: small;
+}
+footer * {
+ color: gray;
+ margin-right: 5px;
+}
+
+.counts {
+ color: gray;
+}
+ul.links {
+ margin: 0;
+ padding: 0;
+ display: inline;
+}
+ul.links li {
+ display: inline;
+ padding-left: 20px;
+ font-weight: bold;
+}
+
+ul.triples {
+ margin: .3em 0 1em 20px;
+ font-size: .95em;
+ line-height: 1.5;
+ font-family: "Droid Sans Mono", monospace;
+ overflow-x: hidden;
+}
+ul.triples li {
+ text-indent: -20px;
+ padding-left: 20px;
+ max-width: 100%;
+ max-height: 1.5em;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+ul.triples li:hover {
+ max-height: 100em;
+ white-space: normal;
+ transition: max-height .5s ease-in;
+ transition-delay: .5s;
+}
+ul.triples li:not(:hover) a {
+ color: inherit;
+}
+ul.triples a:nth-child(2) {
+ margin: 0 1em;
+}
+abbr {
+ border: none;
+}
+
+.index {
+ margin-bottom: 2em;
+}
+.datasets {
+ margin: .5em 20px;
+}
+dt {
+ font-weight: bold;
+ display: block;
+ float: left;
+ clear: left;
+}
+dd {
+ color: gray;
+ margin: .1em 0 0 12em;
+ font-size: .95em;
+}
+
+#about {
+ margin-top: 1.5em;
+ font-size: .9em;
+}
+
+@media screen and (max-width: 700px) {
+ html, input, th, td {
+ font-size: 10pt;
+ }
+ body {
+ padding: 15px;
+ }
+ header figure {
+ display: none;
+ }
+ h1, legend {
+ margin: 0;
+ }
+ fieldset, ul.triples {
+ padding: .5em 0;
+ margin: 0;
+ }
+ fieldset input {
+ width: 70%;
+ }
+ label {
+ width: 80px;
+ }
+ ul.triples li {
+ margin: 1em 0;
+ }
+}
From 2846239b71c51000086671a5e1993d9b6fad8b5c Mon Sep 17 00:00:00 2001
From: Miel Vander Sande
Date: Tue, 12 Jan 2016 10:13:09 +0100
Subject: [PATCH 8/8] Added javadoc and cleaning
---
.../datasource/DataSourceBase.java | 2 +-
.../DataSourceCreationException.java | 2 +-
.../exceptions/DataSourceException.java | 2 +-
.../DataSourceNotFoundException.java | 2 +-
.../NoRegisteredMimeTypesException.java | 2 +-
.../UnknownDataSourceTypeException.java | 2 +-
.../fragments/ILinkedDataFragment.java | 4 +-
.../fragments/LinkedDataFragmentBase.java | 8 +++
.../servlet/LinkedDataFragmentServlet.java | 19 +++++--
.../util/CommonResources.java | 3 ++
... HtmlTriplePatternFragmentWriterImpl.java} | 53 ++++++++-----------
.../views/ILinkedDataFragmentWriter.java | 30 ++++++++++-
.../views/LinkedDataFragmentWriterBase.java | 3 +-
.../LinkedDataFragmentWriterFactory.java | 17 ++++--
.../views/RdfWriterImpl.java | 5 +-
.../TriplePatternFragmentWriterBase.java | 31 +++++++++++
16 files changed, 135 insertions(+), 50 deletions(-)
rename src/org/linkeddatafragments/views/{HtmlWriterImpl.java => HtmlTriplePatternFragmentWriterImpl.java} (75%)
create mode 100644 src/org/linkeddatafragments/views/TriplePatternFragmentWriterBase.java
diff --git a/src/org/linkeddatafragments/datasource/DataSourceBase.java b/src/org/linkeddatafragments/datasource/DataSourceBase.java
index 484cbb4..c074dcf 100644
--- a/src/org/linkeddatafragments/datasource/DataSourceBase.java
+++ b/src/org/linkeddatafragments/datasource/DataSourceBase.java
@@ -2,7 +2,7 @@
/**
*
- * @author mielvandersande
+ * @author Miel Vander Sande
* @author Bart Hanssens
*/
public abstract class DataSourceBase implements IDataSource {
diff --git a/src/org/linkeddatafragments/exceptions/DataSourceCreationException.java b/src/org/linkeddatafragments/exceptions/DataSourceCreationException.java
index 6fd9499..0dcf13f 100644
--- a/src/org/linkeddatafragments/exceptions/DataSourceCreationException.java
+++ b/src/org/linkeddatafragments/exceptions/DataSourceCreationException.java
@@ -2,7 +2,7 @@
/**
*
- * @author mielvandersande
+ * @author Miel Vander Sande
*/
public class DataSourceCreationException extends DataSourceException {
diff --git a/src/org/linkeddatafragments/exceptions/DataSourceException.java b/src/org/linkeddatafragments/exceptions/DataSourceException.java
index 10fb1c0..11a8e21 100644
--- a/src/org/linkeddatafragments/exceptions/DataSourceException.java
+++ b/src/org/linkeddatafragments/exceptions/DataSourceException.java
@@ -4,7 +4,7 @@
/**
*
- * @author mielvandersande
+ * @author Miel Vander Sande
*/
abstract public class DataSourceException extends Exception {
diff --git a/src/org/linkeddatafragments/exceptions/DataSourceNotFoundException.java b/src/org/linkeddatafragments/exceptions/DataSourceNotFoundException.java
index d002aa6..5a8466d 100644
--- a/src/org/linkeddatafragments/exceptions/DataSourceNotFoundException.java
+++ b/src/org/linkeddatafragments/exceptions/DataSourceNotFoundException.java
@@ -2,7 +2,7 @@
/**
*
- * @author mielvandersande
+ * @author Miel Vander Sande
*/
public class DataSourceNotFoundException extends DataSourceException {
diff --git a/src/org/linkeddatafragments/exceptions/NoRegisteredMimeTypesException.java b/src/org/linkeddatafragments/exceptions/NoRegisteredMimeTypesException.java
index 3d2aaee..5310b3c 100644
--- a/src/org/linkeddatafragments/exceptions/NoRegisteredMimeTypesException.java
+++ b/src/org/linkeddatafragments/exceptions/NoRegisteredMimeTypesException.java
@@ -2,7 +2,7 @@
/**
*
- * @author mielvandersande
+ * @author Miel Vander Sande
*/
public class NoRegisteredMimeTypesException extends Exception {
diff --git a/src/org/linkeddatafragments/exceptions/UnknownDataSourceTypeException.java b/src/org/linkeddatafragments/exceptions/UnknownDataSourceTypeException.java
index 5c7b358..cc1877c 100644
--- a/src/org/linkeddatafragments/exceptions/UnknownDataSourceTypeException.java
+++ b/src/org/linkeddatafragments/exceptions/UnknownDataSourceTypeException.java
@@ -2,7 +2,7 @@
/**
*
- * @author mielvandersande
+ * @author Miel Vander Sande
*/
public class UnknownDataSourceTypeException extends DataSourceCreationException {
diff --git a/src/org/linkeddatafragments/fragments/ILinkedDataFragment.java b/src/org/linkeddatafragments/fragments/ILinkedDataFragment.java
index 59ad1ea..c999d78 100644
--- a/src/org/linkeddatafragments/fragments/ILinkedDataFragment.java
+++ b/src/org/linkeddatafragments/fragments/ILinkedDataFragment.java
@@ -1,5 +1,7 @@
package org.linkeddatafragments.fragments;
+import java.io.Closeable;
+
import com.hp.hpl.jena.rdf.model.StmtIterator;
/**
@@ -7,7 +9,7 @@
*
* @author Olaf Hartig
*/
-public interface ILinkedDataFragment
+public interface ILinkedDataFragment extends Closeable
{
/**
* Returns an iterator over the RDF data of this fragment (possibly only
diff --git a/src/org/linkeddatafragments/fragments/LinkedDataFragmentBase.java b/src/org/linkeddatafragments/fragments/LinkedDataFragmentBase.java
index 6dc89d8..faf1716 100644
--- a/src/org/linkeddatafragments/fragments/LinkedDataFragmentBase.java
+++ b/src/org/linkeddatafragments/fragments/LinkedDataFragmentBase.java
@@ -35,6 +35,14 @@ protected LinkedDataFragmentBase( final String fragmentURL,
this.isLastPage = isLastPage;
}
+ /**
+ * Does nothing. May be overridden by subclasses that hold some objects
+ * that need to be closed (such as iterators from the underlying data
+ * source).
+ */
+ @Override
+ public void close() {}
+
@Override
public boolean isPageOnly() {
return true;
diff --git a/src/org/linkeddatafragments/servlet/LinkedDataFragmentServlet.java b/src/org/linkeddatafragments/servlet/LinkedDataFragmentServlet.java
index e330cc9..9f4af28 100644
--- a/src/org/linkeddatafragments/servlet/LinkedDataFragmentServlet.java
+++ b/src/org/linkeddatafragments/servlet/LinkedDataFragmentServlet.java
@@ -137,16 +137,18 @@ private IDataSource getDataSource(HttpServletRequest request) throws DataSourceN
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
+ ILinkedDataFragment fragment = null;
try {
// do conneg
String bestMatch = MIMEParse.bestMatch(request.getHeader("Accept"));
- // serialize the output
+ // set additional response headers
response.setHeader("Server", "Linked Data Fragments Server");
response.setContentType(bestMatch);
response.setCharacterEncoding("utf-8");
+ // create a writer depending on the best matching mimeType
ILinkedDataFragmentWriter writer = LinkedDataFragmentWriterFactory.create(config.getPrefixes(), dataSources, bestMatch);
try {
@@ -157,8 +159,7 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
dataSource.getRequestParser()
.parseIntoFragmentRequest( request, config );
- final ILinkedDataFragment fragment =
- dataSource.getRequestProcessor()
+ fragment = dataSource.getRequestProcessor()
.createRequestedFragment( ldfRequest );
writer.writeFragment(response.getOutputStream(), dataSource, fragment, ldfRequest);
@@ -171,7 +172,6 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
throw new ServletException(ex1);
}
} catch (Exception e) {
- e.printStackTrace();
response.setStatus(500);
writer.writeError(response.getOutputStream(), e);
}
@@ -179,6 +179,17 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
} catch (Exception e) {
throw new ServletException(e);
}
+ finally {
+ // close the fragment
+ if ( fragment != null ) {
+ try {
+ fragment.close();
+ }
+ catch ( Exception e ) {
+ // ignore
+ }
+ }
+ }
}
}
diff --git a/src/org/linkeddatafragments/util/CommonResources.java b/src/org/linkeddatafragments/util/CommonResources.java
index 150ca17..7c4a89e 100644
--- a/src/org/linkeddatafragments/util/CommonResources.java
+++ b/src/org/linkeddatafragments/util/CommonResources.java
@@ -4,6 +4,9 @@
import com.hp.hpl.jena.rdf.model.ResourceFactory;
@SuppressWarnings("javadoc")
+/**
+ * All common URIs needed for parsing and serializations
+ */
public class CommonResources {
public final static String RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
public final static Property RDF_TYPE = createProperty(RDF + "type");
diff --git a/src/org/linkeddatafragments/views/HtmlWriterImpl.java b/src/org/linkeddatafragments/views/HtmlTriplePatternFragmentWriterImpl.java
similarity index 75%
rename from src/org/linkeddatafragments/views/HtmlWriterImpl.java
rename to src/org/linkeddatafragments/views/HtmlTriplePatternFragmentWriterImpl.java
index e0bcfc3..4c35f65 100644
--- a/src/org/linkeddatafragments/views/HtmlWriterImpl.java
+++ b/src/org/linkeddatafragments/views/HtmlTriplePatternFragmentWriterImpl.java
@@ -10,7 +10,6 @@
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
-import java.io.Writer;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@@ -21,13 +20,17 @@
import org.linkeddatafragments.datasource.index.IndexDataSource;
import org.linkeddatafragments.fragments.ILinkedDataFragment;
import org.linkeddatafragments.fragments.ILinkedDataFragmentRequest;
+import org.linkeddatafragments.fragments.tpf.ITriplePatternFragment;
import org.linkeddatafragments.fragments.tpf.ITriplePatternFragmentRequest;
+//TODO: Refactor to a composable & flexible architecture using DataSource types, fragments types and request types
+
/**
+ * Serializes an {@link ILinkedDataFragment} to the HTML format
*
- * @author mielvandersande
+ * @author Miel Vander Sande
*/
-public class HtmlWriterImpl extends LinkedDataFragmentWriterBase implements ILinkedDataFragmentWriter {
+public class HtmlTriplePatternFragmentWriterImpl extends TriplePatternFragmentWriterBase implements ILinkedDataFragmentWriter {
private final Configuration cfg;
private final Template indexTemplate;
@@ -39,7 +42,7 @@ public class HtmlWriterImpl extends LinkedDataFragmentWriterBase implements ILin
private final String VOID = "http://rdfs.org/ns/void#";
- public HtmlWriterImpl(Map prefixes, HashMap datasources) throws IOException {
+ public HtmlTriplePatternFragmentWriterImpl(Map prefixes, HashMap datasources) throws IOException {
super(prefixes, datasources);
cfg = new Configuration(Configuration.VERSION_2_3_22);
@@ -52,9 +55,9 @@ public HtmlWriterImpl(Map prefixes, HashMap
notfoundTemplate = cfg.getTemplate("notfound.ftl.html");
errorTemplate = cfg.getTemplate("error.ftl.html");
}
-
+
@Override
- public void writeFragment(ServletOutputStream outputStream, IDataSource datasource, ILinkedDataFragment fragment, ILinkedDataFragmentRequest ldfRequest) throws IOException, TemplateException{
+ public void writeFragment(ServletOutputStream outputStream, IDataSource datasource, ITriplePatternFragment fragment, ITriplePatternFragmentRequest tpfRequest) throws IOException, TemplateException{
Map data = new HashMap();
// base.ftl.html
@@ -63,9 +66,10 @@ public void writeFragment(ServletOutputStream outputStream, IDataSource datasour
data.put("date", new Date());
// fragment.ftl.html
- data.put("datasourceUrl", ldfRequest.getDatasetURL());
+ data.put("datasourceUrl", tpfRequest.getDatasetURL());
data.put("datasource", datasource);
+ // Parse controls to template variables
StmtIterator controls = fragment.getControls();
while (controls.hasNext()) {
Statement control = controls.next();
@@ -78,41 +82,32 @@ public void writeFragment(ServletOutputStream outputStream, IDataSource datasour
}
}
- StmtIterator metadata = fragment.getMetadata();
- while (metadata.hasNext()) {
- Statement item = metadata.next();
- String predicate = item.getPredicate().getURI();
-
- if (predicate.equals(HYDRA + "totalItems") || predicate.equals( VOID + "triples")) {
- data.put("totalEstimate", item.getObject().asLiteral().getLong());
- break;
- }
- }
+ // Add metadata
+ data.put("totalEstimate", fragment.getTotalSize());
data.put("itemsPerPage", fragment.getMaxPageSize());
+ // Add triples and datasources
List triples = fragment.getTriples().toList();
data.put("triples", triples);
data.put("datasources", getDatasources());
-
- Map query = new HashMap();
- ITriplePatternFragmentRequest tpfRequest = (ITriplePatternFragmentRequest) ldfRequest;
+ // Calculate start and end triple number
Long start = ((tpfRequest.getPageNumber() - 1) * fragment.getMaxPageSize()) + 1;
data.put("start", start);
data.put("end", start + (triples.size() < fragment.getMaxPageSize() ? triples.size() : fragment.getMaxPageSize()));
-
+ // Compose query object
+ Map query = new HashMap();
query.put("subject", !tpfRequest.getSubject().isVariable() ? tpfRequest.getSubject().asConstantTerm() : "");
query.put("predicate", !tpfRequest.getPredicate().isVariable() ? tpfRequest.getPredicate().asConstantTerm() : "");
query.put("object", !tpfRequest.getObject().isVariable() ? tpfRequest.getObject().asConstantTerm() : "");
data.put("query", query);
- /* Get the template (uses cache internally) */
+ // Get the template (uses cache internally)
Template temp = datasource instanceof IndexDataSource ? indexTemplate : datasourceTemplate;
- /* Merge data-model with template */
- Writer out = new OutputStreamWriter(outputStream);
- temp.process(data, out);
+ // Merge data-model with template
+ temp.process(data, new OutputStreamWriter(outputStream));
}
@Override
@@ -123,8 +118,7 @@ public void writeNotFound(ServletOutputStream outputStream, HttpServletRequest r
data.put("date", new Date());
data.put("url", request.getRequestURL().toString());
- Writer out = new OutputStreamWriter(outputStream);
- notfoundTemplate.process(data, out);
+ notfoundTemplate.process(data, new OutputStreamWriter(outputStream));
}
@Override
@@ -133,8 +127,7 @@ public void writeError(ServletOutputStream outputStream, Exception ex) throws E
data.put("assetsPath", "assets/");
data.put("date", new Date());
data.put("error", ex);
-
- Writer out = new OutputStreamWriter(outputStream);
- errorTemplate.process(data, out);
+
+ errorTemplate.process(data, new OutputStreamWriter(outputStream));
}
}
diff --git a/src/org/linkeddatafragments/views/ILinkedDataFragmentWriter.java b/src/org/linkeddatafragments/views/ILinkedDataFragmentWriter.java
index 5be757c..d6b93e3 100644
--- a/src/org/linkeddatafragments/views/ILinkedDataFragmentWriter.java
+++ b/src/org/linkeddatafragments/views/ILinkedDataFragmentWriter.java
@@ -7,11 +7,37 @@
import org.linkeddatafragments.fragments.ILinkedDataFragmentRequest;
/**
- *
- * @author mielvandersande
+ * Represents a possible writer to serialize an {@link ILinkedDataFragment} object
+ *
+ * @author Miel Vander Sande
*/
public interface ILinkedDataFragmentWriter {
+ /**
+ * Writes a 404 Not Found error
+ *
+ * @param outputStream The response stream to write to
+ * @param request Request that is unable to answer
+ * @throws Exception Error that occurs while serializing
+ */
public void writeNotFound(ServletOutputStream outputStream, HttpServletRequest request) throws Exception;
+
+ /**
+ * Writes a 5XX error
+ *
+ * @param outputStream The response stream to write to
+ * @param ex Exception that occurred
+ * @throws Exception Error that occurs while serializing
+ */
public void writeError(ServletOutputStream outputStream, Exception ex) throws Exception;
+
+ /**
+ * Serializes and writes a {@link ILinkedDataFragment}
+ *
+ * @param outputStream The response stream to write to
+ * @param datasource
+ * @param fragment
+ * @param ldfRequest Parsed request for fragment
+ * @throws Exception Error that occurs while serializing
+ */
public void writeFragment(ServletOutputStream outputStream, IDataSource datasource, ILinkedDataFragment fragment, ILinkedDataFragmentRequest ldfRequest) throws Exception;
}
diff --git a/src/org/linkeddatafragments/views/LinkedDataFragmentWriterBase.java b/src/org/linkeddatafragments/views/LinkedDataFragmentWriterBase.java
index c3449b5..27eea77 100644
--- a/src/org/linkeddatafragments/views/LinkedDataFragmentWriterBase.java
+++ b/src/org/linkeddatafragments/views/LinkedDataFragmentWriterBase.java
@@ -5,8 +5,9 @@
import org.linkeddatafragments.datasource.IDataSource;
/**
+ * Base class of any implementation of {@link ILinkedDataFragmentWriter}.
*
- * @author mielvandersande
+ * @author Miel Vander Sande
*/
public abstract class LinkedDataFragmentWriterBase implements ILinkedDataFragmentWriter {
private final Map prefixes;
diff --git a/src/org/linkeddatafragments/views/LinkedDataFragmentWriterFactory.java b/src/org/linkeddatafragments/views/LinkedDataFragmentWriterFactory.java
index 569653c..7619460 100644
--- a/src/org/linkeddatafragments/views/LinkedDataFragmentWriterFactory.java
+++ b/src/org/linkeddatafragments/views/LinkedDataFragmentWriterFactory.java
@@ -6,18 +6,27 @@
import org.linkeddatafragments.datasource.IDataSource;
/**
- *
- * @author mielvandersande
+ * A factory for {@link ILinkedDataFragmentWriter}s.
+ *
+ * @author Miel Vander Sande
*/
public class LinkedDataFragmentWriterFactory {
private final static String HTML = "text/html";
-
+ /**
+ * Creates {@link ILinkedDataFragmentWriter} for a given mimeType
+ *
+ * @param prefixes Configured prefixes to be used in serialization
+ * @param datasources Configured datasources
+ * @param mimeType mimeType to create writer for
+ * @return created writer
+ * @throws IOException
+ */
public static ILinkedDataFragmentWriter create(Map prefixes, HashMap datasources, String mimeType) throws IOException {
switch (mimeType) {
case HTML:
- return new HtmlWriterImpl(prefixes, datasources);
+ return new HtmlTriplePatternFragmentWriterImpl(prefixes, datasources);
default:
return new RdfWriterImpl(prefixes, datasources, mimeType);
}
diff --git a/src/org/linkeddatafragments/views/RdfWriterImpl.java b/src/org/linkeddatafragments/views/RdfWriterImpl.java
index eb183f5..f8ec1e4 100644
--- a/src/org/linkeddatafragments/views/RdfWriterImpl.java
+++ b/src/org/linkeddatafragments/views/RdfWriterImpl.java
@@ -15,8 +15,9 @@
import org.linkeddatafragments.fragments.ILinkedDataFragmentRequest;
/**
- *
- * @author mielvandersande
+ * Serializes an {@link ILinkedDataFragment} to an RDF format
+ *
+ * @author Miel Vander Sande
*/
class RdfWriterImpl extends LinkedDataFragmentWriterBase implements ILinkedDataFragmentWriter {
diff --git a/src/org/linkeddatafragments/views/TriplePatternFragmentWriterBase.java b/src/org/linkeddatafragments/views/TriplePatternFragmentWriterBase.java
new file mode 100644
index 0000000..97ade31
--- /dev/null
+++ b/src/org/linkeddatafragments/views/TriplePatternFragmentWriterBase.java
@@ -0,0 +1,31 @@
+package org.linkeddatafragments.views;
+
+import freemarker.template.TemplateException;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import javax.servlet.ServletOutputStream;
+import org.linkeddatafragments.datasource.IDataSource;
+import org.linkeddatafragments.fragments.ILinkedDataFragment;
+import org.linkeddatafragments.fragments.ILinkedDataFragmentRequest;
+import org.linkeddatafragments.fragments.tpf.ITriplePatternFragment;
+import org.linkeddatafragments.fragments.tpf.ITriplePatternFragmentRequest;
+
+/**
+ * Base class of any implementation of {@link ITriplePatternFragmentWriter}.
+ *
+ * @author Miel Vander Sande
+ */
+public abstract class TriplePatternFragmentWriterBase extends LinkedDataFragmentWriterBase implements ILinkedDataFragmentWriter {
+
+ public TriplePatternFragmentWriterBase(Map prefixes, HashMap datasources) {
+ super(prefixes, datasources);
+ }
+
+ @Override
+ public void writeFragment(ServletOutputStream outputStream, IDataSource datasource, ILinkedDataFragment fragment, ILinkedDataFragmentRequest ldfRequest) throws Exception {
+ writeFragment(outputStream, datasource, (ITriplePatternFragment) fragment, (ITriplePatternFragmentRequest) ldfRequest);
+ }
+
+ abstract public void writeFragment(ServletOutputStream outputStream, IDataSource datasource, ITriplePatternFragment fragment, ITriplePatternFragmentRequest tpfRequest) throws IOException, TemplateException;
+}