|
||||||||||
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 | |
---|---|
protected java.net.URI |
remoteServiceURI
URI to be called to pass on service invocation to a remote service. |
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. |
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. |
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. |
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 |
---|
public static final java.lang.String RRG_RETRIEVAL_SUFFIX
protected java.net.URI remoteServiceURI
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.
protected 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)
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
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |