Skip to content

Commit 1400984

Browse files
author
Olaf Hartig
committed
added i'faces and classes for LDF requests and for processors of such requests
1 parent 70383b0 commit 1400984

7 files changed

+408
-0
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package org.linkeddatafragments.datasource;
2+
3+
import com.hp.hpl.jena.rdf.model.Model;
4+
import com.hp.hpl.jena.rdf.model.Property;
5+
import com.hp.hpl.jena.rdf.model.RDFNode;
6+
import com.hp.hpl.jena.rdf.model.Resource;
7+
8+
/**
9+
* Base class for implementations of {@link IFragmentRequestProcessor} that
10+
* process triple pattern based requests.
11+
*
12+
* @author <a href="http://olafhartig.de">Olaf Hartig</a>
13+
*/
14+
public abstract class AbstractRequestProcessorForTriplePatterns
15+
implements IFragmentRequestProcessor
16+
{
17+
public final TriplePatternFragmentRequest request;
18+
public final long pageNumber;
19+
20+
public AbstractRequestProcessorForTriplePatterns(
21+
final TriplePatternFragmentRequest request )
22+
{
23+
this.request = request;
24+
if ( request.isPageRequest() )
25+
this.pageNumber = request.getPageNumber();
26+
else
27+
this.pageNumber = 1L;
28+
}
29+
30+
@Override
31+
public void close() {}
32+
33+
@Override
34+
public LinkedDataFragment createRequestedFragment()
35+
{
36+
final long limit = LinkedDataFragmentRequest.TRIPLESPERPAGE;
37+
final long offset = limit * ( pageNumber - 1L );
38+
39+
return createFragment( request.getSubject(),
40+
request.getPredicate(),
41+
request.getObject(),
42+
offset, limit );
43+
44+
}
45+
46+
protected LinkedDataFragment createFragment( final String subj,
47+
final String pred,
48+
final String obj,
49+
final long offset,
50+
final long limit )
51+
{
52+
final Resource s = FragmentRequestProcessorUtils.parseAsResource(subj);
53+
final Property p = FragmentRequestProcessorUtils.parseAsProperty(pred);
54+
final RDFNode o = FragmentRequestProcessorUtils.parseAsNode(obj);
55+
56+
return createFragment( s, p, o, offset, limit );
57+
}
58+
59+
abstract protected LinkedDataFragment createFragment( final Resource subject,
60+
final Property predicate,
61+
final RDFNode object,
62+
final long offset,
63+
final long limit );
64+
65+
protected TriplePatternFragment createEmptyTriplePatternFragment()
66+
{
67+
return new TriplePatternFragmentImpl( request.getFragmentURL(),
68+
request.getDatasetURL() );
69+
}
70+
71+
protected TriplePatternFragment createTriplePatternFragment(
72+
Model triples, long totalSize, final boolean isLastPage )
73+
{
74+
return new TriplePatternFragmentImpl( triples,
75+
totalSize,
76+
request.getFragmentURL(),
77+
request.getDatasetURL(),
78+
pageNumber,
79+
isLastPage );
80+
}
81+
82+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package org.linkeddatafragments.datasource;
2+
3+
import java.util.regex.Matcher;
4+
import java.util.regex.Pattern;
5+
6+
import org.linkeddatafragments.util.CommonResources;
7+
8+
import com.hp.hpl.jena.datatypes.TypeMapper;
9+
import com.hp.hpl.jena.rdf.model.Property;
10+
import com.hp.hpl.jena.rdf.model.RDFNode;
11+
import com.hp.hpl.jena.rdf.model.Resource;
12+
import com.hp.hpl.jena.rdf.model.ResourceFactory;
13+
import com.hp.hpl.jena.shared.InvalidPropertyURIException;
14+
15+
/**
16+
* Utility functions for dealing with (fragment) requests.
17+
*
18+
* @author Ruben Verborgh
19+
* @author <a href="http://olafhartig.de">Olaf Hartig</a>
20+
*/
21+
public class FragmentRequestProcessorUtils
22+
{
23+
/**
24+
* Parses the given value as an RDF resource.
25+
*
26+
* @param value the value
27+
* @return the parsed value, or null if unspecified
28+
*/
29+
public static Resource parseAsResource(String value) {
30+
RDFNode subject = parseAsNode(value);
31+
return subject == null || subject instanceof Resource
32+
? (Resource) subject
33+
: CommonResources.INVALID_URI;
34+
}
35+
36+
/**
37+
* Parses the given value as an RDF property.
38+
*
39+
* @param value the value
40+
* @return the parsed value, or null if unspecified
41+
*/
42+
public static Property parseAsProperty(String value) {
43+
RDFNode predicateNode = parseAsNode(value);
44+
if (predicateNode instanceof Resource) {
45+
try {
46+
return ResourceFactory.createProperty(((Resource) predicateNode).getURI());
47+
} catch (InvalidPropertyURIException ex) {
48+
return CommonResources.INVALID_URI;
49+
}
50+
}
51+
return predicateNode == null ? null : CommonResources.INVALID_URI;
52+
}
53+
54+
public final static TypeMapper TYPES = TypeMapper.getInstance();
55+
public final static Pattern STRINGPATTERN
56+
= Pattern.compile("^\"(.*)\"(?:@(.*)|\\^\\^<?([^<>]*)>?)?$");
57+
58+
/**
59+
* Parses the given value as an RDF node.
60+
*
61+
* @param value the value
62+
* @return the parsed value, or null if unspecified
63+
*/
64+
public static RDFNode parseAsNode(String value) {
65+
// nothing or empty indicates an unknown
66+
if (value == null || value.isEmpty()) {
67+
return null;
68+
}
69+
// find the kind of entity based on the first character
70+
char firstChar = value.charAt(0);
71+
switch (firstChar) {
72+
// variable or blank node indicates an unknown
73+
case '?':
74+
case '_':
75+
return null;
76+
// angular brackets indicate a URI
77+
case '<':
78+
return ResourceFactory.createResource(value.substring(1, value.length() - 1));
79+
// quotes indicate a string
80+
case '"':
81+
Matcher matcher = STRINGPATTERN.matcher(value);
82+
if (matcher.matches()) {
83+
String body = matcher.group(1);
84+
String lang = matcher.group(2);
85+
String type = matcher.group(3);
86+
if (lang != null) {
87+
return ResourceFactory.createLangLiteral(body, lang);
88+
}
89+
if (type != null) {
90+
return ResourceFactory.createTypedLiteral(body, TYPES.getSafeTypeByName(type));
91+
}
92+
return ResourceFactory.createPlainLiteral(body);
93+
}
94+
return CommonResources.INVALID_URI;
95+
// assume it's a URI without angular brackets
96+
default:
97+
return ResourceFactory.createResource(value);
98+
}
99+
}
100+
101+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.linkeddatafragments.datasource;
2+
3+
import java.io.Closeable;
4+
5+
/**
6+
* Processes a single request sent to a Linked Data Fragments interface.
7+
*
8+
* @author <a href="http://olafhartig.de">Olaf Hartig</a>
9+
*/
10+
public interface IFragmentRequestProcessor extends Closeable
11+
{
12+
LinkedDataFragment createRequestedFragment();
13+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.linkeddatafragments.datasource;
2+
3+
/**
4+
* Basis for representing a request of some type of Linked Data Fragment (LDF).
5+
*
6+
* @author <a href="http://olafhartig.de">Olaf Hartig</a>
7+
*/
8+
public interface LinkedDataFragmentRequest
9+
{
10+
public final static long TRIPLESPERPAGE = 100L;
11+
public final static String PARAMETERNAME_PAGE = "page";
12+
13+
/**
14+
* Returns the URL of the requested LDF.
15+
*/
16+
String getFragmentURL();
17+
18+
/**
19+
* Returns the URL of the dataset to which the requested LDF belongs.
20+
*/
21+
String getDatasetURL();
22+
23+
/**
24+
* Returns true if the request is for a specific page of the requested
25+
* fragment. In this case, {@link #getPageNumber()} can be used to obtain
26+
* the requested page number.
27+
*/
28+
boolean isPageRequest();
29+
30+
/**
31+
* Returns the number of the page requested for the LDF, if any (thatis,
32+
* if {@link #isPageOnly()} returns true).
33+
*
34+
* @throws UnsupportedOperationException
35+
* If the request is not for a specific page.
36+
*/
37+
long getPageNumber() throws UnsupportedOperationException;
38+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package org.linkeddatafragments.datasource;
2+
3+
import javax.servlet.http.HttpServletRequest;
4+
5+
import org.linkeddatafragments.config.ConfigReader;
6+
7+
/**
8+
* Base class for implementations of {@link LinkedDataFragmentRequest} that
9+
* are based on an {@link HttpServletRequest}.
10+
*
11+
* @author <a href="http://olafhartig.de">Olaf Hartig</a>
12+
*/
13+
public abstract class LinkedDataFragmentRequestBase
14+
implements LinkedDataFragmentRequest
15+
{
16+
public final HttpServletRequest request;
17+
public final ConfigReader config;
18+
19+
public final String fragmentURL;
20+
public final String datasetURL;
21+
public final boolean pageNumberWasRequested;
22+
public final long pageNumber;
23+
24+
public LinkedDataFragmentRequestBase( final HttpServletRequest request,
25+
final ConfigReader config )
26+
{
27+
this.request = request;
28+
this.config = config;
29+
30+
this.fragmentURL = extractFragmentURL( request, config );
31+
this.datasetURL = extractDatasetURL( request, config );
32+
33+
final String givenPageNumber = request.getParameter( PARAMETERNAME_PAGE );
34+
if ( givenPageNumber != null ) {
35+
long pageNumber;
36+
try {
37+
pageNumber = Long.parseLong( givenPageNumber );
38+
} catch (NumberFormatException ex) {
39+
pageNumber = 1L;
40+
}
41+
this.pageNumber = ( pageNumber > 0 ) ? pageNumber : 1L;
42+
this.pageNumberWasRequested = true;
43+
}
44+
else {
45+
this.pageNumber = 1L;
46+
this.pageNumberWasRequested = false;
47+
}
48+
}
49+
50+
@Override
51+
public String getFragmentURL() {
52+
return fragmentURL;
53+
}
54+
55+
@Override
56+
public String getDatasetURL() {
57+
return datasetURL;
58+
}
59+
60+
@Override
61+
public boolean isPageRequest() {
62+
return pageNumberWasRequested;
63+
}
64+
65+
@Override
66+
public long getPageNumber() throws UnsupportedOperationException {
67+
if ( pageNumberWasRequested )
68+
return pageNumber;
69+
else
70+
throw new UnsupportedOperationException();
71+
}
72+
73+
74+
// ----- HELPERS ---------
75+
76+
public static String extractFragmentURL( final HttpServletRequest request,
77+
final ConfigReader config ) {
78+
final String datasetURL = extractDatasetURL( request, config );
79+
final String query = request.getQueryString();
80+
return query == null ? datasetURL : (datasetURL + "?" + query);
81+
}
82+
83+
public static String extractDatasetURL( final HttpServletRequest request,
84+
final ConfigReader config ) {
85+
return extractBaseURL( request, config ) + request.getRequestURI();
86+
}
87+
88+
public static String extractBaseURL( final HttpServletRequest request,
89+
final ConfigReader config ) {
90+
if (config.getBaseURL() != null) {
91+
return config.getBaseURL();
92+
} else if ((request.getServerPort() == 80)
93+
|| (request.getServerPort() == 443)) {
94+
return request.getScheme() + "://"
95+
+ request.getServerName();
96+
} else {
97+
return request.getScheme() + "://"
98+
+ request.getServerName() + ":" + request.getServerPort();
99+
}
100+
}
101+
102+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.linkeddatafragments.datasource;
2+
3+
/**
4+
* Represents a request of a Triple Pattern Fragment (TPF).
5+
*
6+
* @author <a href="http://olafhartig.de">Olaf Hartig</a>
7+
*/
8+
public interface TriplePatternFragmentRequest extends LinkedDataFragmentRequest
9+
{
10+
public final static String PARAMETERNAME_SUBJ = "subject";
11+
public final static String PARAMETERNAME_PRED = "predicate";
12+
public final static String PARAMETERNAME_OBJ = "object";
13+
14+
/**
15+
* Returns the subject position of the requested triple pattern (or null,
16+
* in which case the requested triple pattern has an unnamed variable as
17+
* subject).
18+
*/
19+
String getSubject();
20+
21+
/**
22+
* Returns the predicate position of the requested triple pattern (or null,
23+
* in which case the requested triple pattern has an unnamed variable as
24+
* predicate).
25+
*/
26+
String getPredicate();
27+
28+
/**
29+
* Returns the object position of the requested triple pattern (or null,
30+
* in which case the requested triple pattern has an unnamed variable as
31+
* object).
32+
*/
33+
String getObject();
34+
}

0 commit comments

Comments
 (0)