|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectjavax.servlet.GenericServlet
javax.servlet.http.HttpServlet
info.sswap.api.servlet.AbstractSSWAPServlet
public abstract class AbstractSSWAPServlet
Handles HTTP GETs and POSTs to a SSWAP service point. This class is a bridge between handling a HTTP request and the SSWAP Java API that allows on-demand, transaction-time reasoning to satisfy the request.
Note: A simple way to implement a service without the constraints and
subtleties of servlet programming is to use a servlet launcher to launch a
regular Java class. For most developers this is the recommended way; see
SimpleSSWAPServlet
and MapsTo
To use, extend this abstract class and override the
handleRequest
method. When an Resource Invocation Graph (
RIG
) is sent to the servlet, handleRequest
will
allow action on the RIG
to create a Resource Response Graph (
RRG
) to be returned back to the client. The RIG
supports a translate
method to allow semantic mapping of the
RIG
into the vocabulary and concepts of the service's Resource
Description Graph (RDG
).
Upon return from handleRequest
, this class generates an
RRG
which is serialized back to the client.
The servlet responds to HTTP GETs and POSTs in the following manner:
RDG
;
RIG
from the GET query string and the service's
RDG
. The service is then self-invoked. During GET query string
parsing, query string terms are semantically matched to terms on the
SSWAPResource
or SSWAPSubject
s of the
RDG
. An RIG
is generated and the service is invoked
as if it was POSTed the RIG
.
<form>
element so as to not prepend the POST body with a parameter name. If
necessary, use Javascript to POST the contents directly or POST to a handler
servlet that extracts the RIG
content and POSTs only it to the
service. URLs within the RIG
may be URL encoded (if needed), but
the RIG
itself should be plain RDF/XML.
GET query string parameters (e.g., http://.../MyService?property=value&prefix:property=value2) are converted into service parameters according to the following rules:
RDG
. prefix:property is resolved to a fully qualified
URI (ontology term) and assigned the value;
By default, property=value assignments are matched against statements
on the RDG
's SSWAPSubject
s. To instead force a
match against the SSWAPResource
properties, prepend a tilde (~)
immediately before the prefix or property: e.g.,
~property=value or ~prefix:property=value. The tilde (~) is a
query string flag only: it is not part of the property name.
To use the servlet, create a typical mapping in your servlet container's web.xml file, such as:
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>org.mySite.sswap.MyServlet</servlet-class>
<!-- if not defined, will be derived from <url-pattern>
<init-param>
<param-name>RDGPath</param-name>
<param-value>/pathTo/MyRDG</param-value>
</init-param>
-->
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyService/*</url-pattern> <!-- always end in /* -->
</servlet-mapping>
Replace and customize the values for <servlet-name>
,
<servlet-class>
, <param-value>
, and <url-pattern>
per
usual web.xml practices. All other values should be as above. In the above
example, MyServlet extends AbstractSSWAPServlet
and defines
handleRequest
. The use and definition of RDGPath
is
optional but recommended. If it is not defined, then the RDG must reside at
the request URI; if it is defined, then its value must be the path to a valid
RDG
on the local web server.
Error handling:
If an error is due to a client misconfigured RIG
, then an error
message is returned to the client and set in the HTTP header. An
RRG
is not returned to the client. But if the RIG
passes validation--both syntactically as OWL RDF/XML, and semantically as
being complaint with the RDG--but yet an error occurs on the server-side,
then the RIG
is returned to the client without semantic
modification (still, no RRG
).
handleRequest(info.sswap.api.model.RIG)
,
SimpleSSWAPServlet
,
MapsTo
,
RDG
,
RIG
,
RRG
,
SSWAPResource
,
SSWAPSubject
,
Serialized FormField Summary | |
---|---|
private boolean |
initCompleted
Flag to check if init has completed. |
private static org.apache.log4j.Logger |
LOGGER
Interface to Logging API |
private java.lang.String |
rdgFile
Absolute, fully resolved path and file name of the RDG on the file system |
private java.lang.String |
rdgPath
Real path to the RDG on the file system as specified in web.xml (may be a directory) |
protected java.net.URI |
remoteServiceURI
URI to be called to pass on service invocation to a remote service. |
private static java.lang.String |
resourceFlag
Flag string appended to terms in the GET query string to identify them as pertaining to the SSWAPResouce |
static java.lang.String |
RRG_RETRIEVAL_SUFFIX
The suffix to the request string for RRG retrieval; that is, if a request ends with this suffix (attached to the regular service's URL), it indicates that the request is for retrieving a cached RRG, and not invoking the service. |
private static long |
serialVersionUID
Default |
private int |
suggestedPollingInterval
Suggested polling interval read from web.xml (if defined) or a default value. |
Constructor Summary | |
---|---|
AbstractSSWAPServlet()
|
Method Summary | |
---|---|
protected void |
doGet(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
An HTTP GET equates to returning an RDG or creating a
just-in-time RIG from the query string and invoking this
service. |
protected void |
doPost(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
An HTTP POST equates to a request service invocation. |
private java.lang.String |
extractOutputURI(SSWAPModel model)
Extracts sswap:outputURI from the sswap:Resource in this SSWAPModel. |
private static java.lang.String |
getMajorMIMEType(java.lang.String mimeType)
Returns the major type in a MIME type (everything up to the first '/'; if there is one) |
private static java.lang.String |
getMinorMIMEType(java.lang.String mimeType)
Returns the minor type in a MIME type (everything after the first '/'; if there is one) |
private RDG |
getRDG(java.lang.String rdgURIStr)
Dereference the servlet's RDG and map any Exceptions to a general IOException. |
private java.lang.String |
getRRGToken()
Generates an RRG token for an asynchronous invocation. |
int |
getTimeout()
The servlet timeout value, in milliseconds. |
protected abstract void |
handleRequest(RIG rig)
Override this method to convert an incoming Resource Invocation Graph RIG into an outgoing Resource Response Graph
RRG . |
void |
init(javax.servlet.ServletConfig servletConfig)
Override this method (or GenericServlet.init() for custom servlet
initialization code. |
private void |
initializeRequest(javax.servlet.http.HttpServletRequest request)
Initialization per request |
private RRG |
invokeRemoteService(java.net.URI remoteService)
Invoke a HTTP GET; Wrapper to invokeRemoteService(URI remoteService,null) |
private RRG |
invokeRemoteService(java.net.URI remoteService,
java.io.InputStream bodyStream)
Invoke a HTTP GET or POST on 'remoteService'. |
private boolean |
isAsyncRIG(RIG asyncRIGCandidate)
Verifies whether the submitted RIG is an asynchronous RIG. |
private static boolean |
isMIMETypeAcceptable(javax.servlet.http.HttpServletRequest request,
java.lang.String mimeType)
|
private static boolean |
isMIMETypeAcceptable(java.lang.String acceptHeaderValue,
java.lang.String mimeType)
Checks whether the given MIME type is acceptable according to the values for the accept header |
private static boolean |
isMIMETypeMatch(java.lang.String pattern,
java.lang.String mimeType)
Checks whether a MIME type matches a MIME type pattern (i.e., a string that may contain '*" in the place of major type, minor type or both |
private java.util.Map<java.lang.String,java.lang.String[]> |
makeParameterMap(javax.servlet.http.HttpServletRequest request)
Parse the HTTP servlet request into a "mutable" parameter:value map. |
private static java.lang.String[] |
parseMIMETypeList(java.lang.String mimeTypeList)
Parses a list of MIME types, as they occur in the Accept header; for example: text/xml, text/plain; q=0.8, text/html; q=0.7, text/ *; q=0.3, * /*; q=0.1 |
private com.clarkparsia.utils.web.ParameterList |
partitionParameters(com.clarkparsia.utils.web.ParameterList parameterList)
Partition the parameter list by removing (and returning a list of) those parameters that will apply to the only the SSWAPResource. |
(package private) void |
publishRRG(java.lang.String token,
RRG rrg)
Publishes an RRG (so that it can be retrieved by the caller in the asynchronous invocation protocol). |
private void |
resolveParameters(RIG rig,
java.util.Map<java.lang.String,java.lang.String[]> queryStringParameterMap)
Resolves query string parameters against name spaces to get absolute URIs. |
private void |
resolveProperties(RIG rig,
SSWAPNode sswapNode,
com.clarkparsia.utils.web.ParameterList resolvedQNameMap)
Removes all properties from sswapNode and adds back only those properties (parameters) from resolvedQNameMap that are ObjectProperties or DatatypeProperties |
private com.clarkparsia.utils.web.ParameterList |
resolveQueryString(RIG rig,
java.util.Map<java.lang.String,java.lang.String[]> queryStringParameterMap)
Map query string parameters into fully qualified URLs or URNs. |
private void |
sendError(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response,
java.lang.String errMsg,
int responseCode)
Return an error message. |
private void |
serializeResponse(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response,
SSWAPModel model)
Serialize the model back to the HTTP response. |
private void |
setNamespaces(RIG rig,
java.util.Map<java.lang.String,java.lang.String[]> queryStringParameterMap)
Parse the GET query string parameter map for prefixes (namespace assignments) and set the namespaces in the rig's NsPrefixMap. |
void |
setTimeout(int timeout_ms)
Set servlet timeout value, in milliseconds. |
Methods inherited from class javax.servlet.http.HttpServlet |
---|
doDelete, doHead, doOptions, doPut, doTrace, getLastModified, service, service |
Methods inherited from class javax.servlet.GenericServlet |
---|
destroy, getInitParameter, getInitParameterNames, getServletConfig, getServletContext, getServletInfo, getServletName, init, log, log |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
private static final long serialVersionUID
private static final org.apache.log4j.Logger LOGGER
public static final java.lang.String RRG_RETRIEVAL_SUFFIX
private java.lang.String rdgPath
private java.lang.String rdgFile
private static final java.lang.String resourceFlag
protected java.net.URI remoteServiceURI
private int suggestedPollingInterval
private boolean initCompleted
Constructor Detail |
---|
public AbstractSSWAPServlet()
Method Detail |
---|
public void init(javax.servlet.ServletConfig servletConfig) throws javax.servlet.ServletException
GenericServlet.init()
for custom servlet
initialization code. If overriding this method, overriding method MUST call
super.init(servletConfig)
as the first line of code. This method
is called once at the end of all internal initialization and before any
requests are serviced.
The method is passed the Servlet Configuration and may throw a ServletException. Thrown errors are not caught and will terminate servlet initialization.
Uses for this method are to set the servlet timeout (see
setTimeout(int)
), effect changes to URI caching (see
SSWAP.getCache()
), and so forth.
init
in interface javax.servlet.Servlet
init
in class javax.servlet.GenericServlet
servletConfig
- the ServletConfig object of the servlet
javax.servlet.ServletException
- on a servlet configuration errorSSWAP
,
ServletConfig
public int getTimeout()
public void setTimeout(int timeout_ms)
Timeout values less than 1000 (1 sec) are silently ignored.
private void initializeRequest(javax.servlet.http.HttpServletRequest request) throws javax.servlet.ServletException
javax.servlet.ServletException
- if servlet init() method is not calledprotected final void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException
RDG
or creating a
just-in-time RIG
from the query string and invoking this
service.
This method is marked protected
solely for package access
purposes. It should not be called directly and cannot be overridden. The
servlet handler will call this method automatically on an HTTP GET. To
handle the request, override the method handleRequest()
.
An HTTP GET with no (extra) path info and no query string equates to a request for the RDG (Resource Description Graph).
An HTTP GET with a query string equates to an invocation, with measures taken to semantically resolve the query string parameters in terms of this RDG's semantics. A RIG is automatically generated from the query string and this service is invoked.
doGet
in class javax.servlet.http.HttpServlet
request
- HTTP Servlet requestresponse
- HTTP Servlet response
javax.servlet.ServletException
- as thrown by the servlet containerhandleRequest(RIG rig)
,
RDG
,
RIG
,
RRG
protected final void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException
This method is marked protected
solely for package access
purposes. It should not be called directly and cannot be overridden. The
servlet handler will call this method automatically on an HTTP POST. To
handle the request, override the method handleRequest()
.
doPost
in class javax.servlet.http.HttpServlet
request
- HTTP Servlet requestresponse
- HTTP Servlet response
javax.servlet.ServletException
- as thrown by the servlet containerhandleRequest(RIG rig)
private boolean isAsyncRIG(RIG asyncRIGCandidate)
asyncRIGCandidate
- a RIG to be checked
private void sendError(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, java.lang.String errMsg, int responseCode) throws java.io.IOException
java.io.IOException
protected abstract void handleRequest(RIG rig)
RIG
into an outgoing Resource Response Graph
RRG
. Edits to the RIG
will be the foundation of
the RRG
returned from this service call. Sample code:
public void handleRequest(RIG rig) {
// if we need to check service parameters we could do it here
//SSWAPResource translatedResource = rig.getTranslatedResource();
// loop over every subject, across all matching graphs
for ( SSWAPSubject translatedSubject : rig.getTranslatedSubjects() ) {
// "translation" maps types and properties in the RIG
// into the vocabulary we understand in the RDG.
// for all objects for which the current subject is already stating a mapping
for ( SSWAPObject sswapObject : translatedSubject.getObjects() ) {
// do something:
// edit object based on the type(s) and property values of the subject
}
// if and as necessary, add additional object mappings to subject
SSWAPObject sswapObject;
try { // if and as appropriate
sswapObject = rig.createObject(new URI("http://mySite.org/someData"));
} catch ( Exception e ) {
sswapObject = rig.createObject(); // a "blank node"
}
// do something:
// edit object based on the type(s) and property values of the subject
// add it to the subject
translatedSubject.addObject(sswapObject);
}
// done
// for testing, you may call getRRG()
// if it throws a validation exception, the RRG will not be returned to the caller;
// on error, the caller will get the original RIG returned unchanged
boolean debugging = false;
if ( debugging ) {
try {
rig.getRRG(); // expensive
} catch ( Exception e ) {
System.err.println("Failed to create a valid RRG:");
rig.serialize(System.err);
}
}
}
Providers should do their best to satisfy the request of the RIG, but
they are not required to be exhaustive. For example, SSWAPObjects should
informatively satisfy the contract of the mapping from a SSWAPSubject,
but they do not need themselves to extend a deep graph of relations. The
decision on how much data to return is left to the provider. Regardless,
what data is returned must satisfy the logical contract of the RDG.
If a request is larger than the provider wishes to satisfy (e.g., hundreds or thousands of SSWAPSubjects each requiring database calls), the provider may satisfy none, a few, or all at its choosing. If the provider wants to satisfy none--i.e., it handles requests on an all-or-none basis--and it wants the current state returned as an error to the client, it may return an HTTP 413 Request Entity Too Large response code by throwing the runtime exception RequestEntityTooLargeException. In this case no content (neither RIG nor RRG) is be returned to the client.
If the provider is unable to access data, it should fail silently and allow the RIG to be returned. If the problem is due to a client error, for example, a missing URL, then the provider may throw a ClientException to return an error to the client.
rig
- RIG
invoking the service. This RIG
should be edited and will become the basis for the
RRG
returned by the service. Best practice is to
leave most of the RIG
untouched, modifying only
the SSWAPObject
subgraphs.RIG
,
RRG
,
RequestEntityTooLargeException
,
ClientException
private RDG getRDG(java.lang.String rdgURIStr) throws java.io.IOException
java.io.IOException
private RRG invokeRemoteService(java.net.URI remoteService) throws java.io.IOException, ValidationException
java.io.IOException
ValidationException
private RRG invokeRemoteService(java.net.URI remoteService, java.io.InputStream bodyStream) throws java.io.IOException, ValidationException
java.io.IOException
ValidationException
private java.util.Map<java.lang.String,java.lang.String[]> makeParameterMap(javax.servlet.http.HttpServletRequest request)
request
- HTTP servlet request with possible parameters
private void resolveParameters(RIG rig, java.util.Map<java.lang.String,java.lang.String[]> queryStringParameterMap) throws java.lang.IllegalArgumentException
java.lang.IllegalArgumentException
private void setNamespaces(RIG rig, java.util.Map<java.lang.String,java.lang.String[]> queryStringParameterMap)
rig
- document (model) to set new namespacesqueryStringParameterMap
- source parameter:value mappingprivate com.clarkparsia.utils.web.ParameterList resolveQueryString(RIG rig, java.util.Map<java.lang.String,java.lang.String[]> queryStringParameterMap)
rig
- The RIG with a prefix mapqueryStringParameterMap
- parameter map of parameters and vales, as from request.getParameterMap()
private com.clarkparsia.utils.web.ParameterList partitionParameters(com.clarkparsia.utils.web.ParameterList parameterList)
parameterList
- original list of parameters for both SSWAPSubject and
SSWAPResource
private void resolveProperties(RIG rig, SSWAPNode sswapNode, com.clarkparsia.utils.web.ParameterList resolvedQNameMap) throws java.lang.IllegalArgumentException
java.lang.IllegalArgumentException
private java.lang.String getRRGToken()
void publishRRG(java.lang.String token, RRG rrg)
token
- token under which the RRG should be publishedrrg
- RRG to be publishedprivate java.lang.String extractOutputURI(SSWAPModel model)
model
- the model from which the sswap:outputURI should be extracted
private void serializeResponse(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, SSWAPModel model) throws java.io.IOException
java.io.IOException
private static java.lang.String[] parseMIMETypeList(java.lang.String mimeTypeList)
mimeTypeList
- string containing a mime type list
private static java.lang.String getMajorMIMEType(java.lang.String mimeType)
mimeType
- the MIME type
private static java.lang.String getMinorMIMEType(java.lang.String mimeType)
mimeType
- the MIME type
private static boolean isMIMETypeMatch(java.lang.String pattern, java.lang.String mimeType)
pattern
- the patternmimeType
- the MIME type
private static boolean isMIMETypeAcceptable(java.lang.String acceptHeaderValue, java.lang.String mimeType)
acceptHeaderValue
- the value of the accept headermimeType
- MIME type to be checked
private static boolean isMIMETypeAcceptable(javax.servlet.http.HttpServletRequest request, java.lang.String mimeType)
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |