1313import javax .servlet .http .HttpServletRequest ;
1414import javax .servlet .http .HttpServletResponse ;
1515
16+ import org .apache .http .client .utils .URIBuilder ;
1617import org .linkeddatafragments .config .ConfigReader ;
1718import org .linkeddatafragments .datasource .BasicLinkedDataFragment ;
1819import org .linkeddatafragments .datasource .DataSource ;
@@ -37,6 +38,7 @@ public class BasicLdfServlet extends HttpServlet {
3738 private final static long serialVersionUID = 1L ;
3839 private final static Pattern STRINGPATTERN = Pattern .compile ("^\" (.*)\" (?:@(.*)|\\ ^\\ ^<(.*)>)?$" );
3940 private final static TypeMapper types = TypeMapper .getInstance ();
41+ private final static long TRIPLESPERPAGE = 100 ;
4042
4143 private ConfigReader config ;
4244 private HashMap <String , DataSource > dataSources = new HashMap <String , DataSource >();
@@ -76,18 +78,21 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
7678 final Resource subject = parseAsResource (request .getParameter ("subject" ));
7779 final Property predicate = parseAsProperty (request .getParameter ("predicate" ));
7880 final RDFNode object = parseAsNode (request .getParameter ("object" ));
79- final BasicLinkedDataFragment fragment = dataSource .getFragment (subject , predicate , object );
81+ final long page = Math .max (1 , parseAsInteger (request .getParameter ("page" )));
82+ final long limit = TRIPLESPERPAGE , offset = limit * (page - 1 );
83+ final BasicLinkedDataFragment fragment = dataSource .getFragment (subject , predicate , object , offset , limit );
8084
8185 // fill the output model
8286 final Model output = fragment .getTriples ();
87+ final boolean isEmpty = output .size () == 0 ;
8388 output .setNsPrefixes (config .getPrefixes ());
8489
8590 // add dataset metadata
8691 final String hostName = request .getHeader ("Host" );
8792 final String datasetUrl = request .getScheme () + "://" +
8893 (hostName == null ? request .getServerName () : hostName ) + request .getRequestURI ();
8994 final String fragmentUrl = query == null ? datasetUrl : (datasetUrl + "?" + query );
90- final Resource datasetId = output .createResource (datasetUrl );
95+ final Resource datasetId = output .createResource (datasetUrl + "#dataset" );
9196 final Resource fragmentId = output .createResource (fragmentUrl );
9297 output .add (datasetId , RDF_TYPE , VOID_DATASET );
9398 output .add (datasetId , RDF_TYPE , HYDRA_COLLECTION );
@@ -99,6 +104,20 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
99104 final Literal total = output .createTypedLiteral (fragment .getTotalSize (), XSDDatatype .XSDinteger );
100105 output .add (fragmentId , VOID_TRIPLES , total );
101106 output .add (fragmentId , HYDRA_TOTALITEMS , total );
107+ output .add (fragmentId , HYDRA_ITEMSPERPAGE , output .createTypedLiteral (limit , XSDDatatype .XSDinteger ));
108+
109+ // add pages
110+ final URIBuilder pagedUrl = new URIBuilder (fragmentUrl );
111+ pagedUrl .setParameter ("page" , "1" );
112+ output .add (fragmentId , HYDRA_FIRSTPAGE , output .createResource (pagedUrl .toString ()));
113+ if (offset > 0 ) {
114+ pagedUrl .setParameter ("page" , Long .toString (page - 1 ));
115+ output .add (fragmentId , HYDRA_PREVIOUSPAGE , output .createResource (pagedUrl .toString ()));
116+ }
117+ if (offset + limit < fragment .getTotalSize ()) {
118+ pagedUrl .setParameter ("page" , Long .toString (page + 1 ));
119+ output .add (fragmentId , HYDRA_NEXTPAGE , output .createResource (pagedUrl .toString ()));
120+ }
102121
103122 // add controls
104123 final Resource triplePattern = output .createResource ();
@@ -118,17 +137,27 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
118137 output .add (objectMapping , HYDRA_PROPERTY , RDF_OBJECT );
119138
120139 // serialize the output as Turtle
121- response .setStatus (fragment . getTotalSize () == 0 ? 404 : 200 );
140+ response .setStatus (isEmpty ? 404 : 200 );
122141 response .setHeader ("Server" , "Linked Data Fragments Server" );
123142 response .setContentType ("text/turtle" );
124143 response .setCharacterEncoding ("utf-8" );
125- output .write (response .getWriter (), "Turtle" );
144+ output .write (response .getWriter (), "Turtle" , fragmentUrl );
126145 }
127146 catch (Exception e ) {
128147 throw new ServletException (e );
129148 }
130149 }
131150
151+ /**
152+ * Parses the given value as an integer.
153+ * @param value the value
154+ * @return the parsed value
155+ */
156+ private int parseAsInteger (String value ) {
157+ try { return Integer .parseInt (value ); }
158+ catch (NumberFormatException ex ) { return 0 ; }
159+ }
160+
132161 /**
133162 * Parses the given value as an RDF resource.
134163 * @param value the value
0 commit comments