[Mulgara-svn] r1943 - in trunk/src/jar/querylang/java/org/mulgara/protocol: . http
pag at mulgara.org
pag at mulgara.org
Thu Apr 22 03:49:19 UTC 2010
Author: pag
Date: 2010-04-21 20:49:18 -0700 (Wed, 21 Apr 2010)
New Revision: 1943
Modified:
trunk/src/jar/querylang/java/org/mulgara/protocol/AbstractStreamedAnswer.java
trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlJSONAnswer.java
trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlXMLAnswer.java
trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedTqlXMLAnswer.java
trunk/src/jar/querylang/java/org/mulgara/protocol/http/ProtocolServlet.java
trunk/src/jar/querylang/java/org/mulgara/protocol/http/TqlServlet.java
Log:
Fixed up sub-answer responses, which were being incorrectly structured. Also fixed up multi-answer responses for POST requests, to return all answers, and to correctly close them.
Modified: trunk/src/jar/querylang/java/org/mulgara/protocol/AbstractStreamedAnswer.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/protocol/AbstractStreamedAnswer.java 2010-04-22 03:47:35 UTC (rev 1942)
+++ trunk/src/jar/querylang/java/org/mulgara/protocol/AbstractStreamedAnswer.java 2010-04-22 03:49:18 UTC (rev 1943)
@@ -85,6 +85,9 @@
/** Adds the entire header to the stream */
protected abstract void addHeader(Answer a) throws IOException;
+
+ /** Adds the answer footer to the stream */
+ protected abstract void addFooter(Answer a) throws IOException;
/** Closes the document in the stream */
protected abstract void addDocFooter() throws IOException;
@@ -157,6 +160,7 @@
vars = (a != null) ? a.getVariables() : null;
addHeader(a);
addResults(a);
+ addFooter(a);
}
addDocFooter();
}
Modified: trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlJSONAnswer.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlJSONAnswer.java 2010-04-22 03:47:35 UTC (rev 1942)
+++ trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlJSONAnswer.java 2010-04-22 03:49:18 UTC (rev 1943)
@@ -172,6 +172,12 @@
comma().append("\"").append(var.getName()).append("\"");
}
+ /**
+ * No Answer footer needed for this type of document
+ */
+ protected void addFooter(Answer answer) throws IOException {
+ }
+
/** {@inheritDoc} */
protected void addResults(Answer answer) throws TuplesException, IOException {
if (answer != null) {
Modified: trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlXMLAnswer.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlXMLAnswer.java 2010-04-22 03:47:35 UTC (rev 1942)
+++ trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlXMLAnswer.java 2010-04-22 03:49:18 UTC (rev 1943)
@@ -131,6 +131,12 @@
s.append(i(1)).append("</head>");
}
+ /**
+ * No Answer footer needed for this type of document
+ */
+ protected void addFooter(Answer answer) throws IOException {
+ }
+
/** {@inheritDoc} */
protected void addHeaderVariable(Variable var) throws IOException {
s.append(i(2)).append("<variable name=\"");
Modified: trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedTqlXMLAnswer.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedTqlXMLAnswer.java 2010-04-22 03:47:35 UTC (rev 1942)
+++ trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedTqlXMLAnswer.java 2010-04-22 03:49:18 UTC (rev 1943)
@@ -67,16 +67,24 @@
/** {@inheritDoc} */
protected void addHeader(Answer answer) throws IOException {
+ s.append(i(1)).append("<query>");
addHeader(answer, 0);
}
void addHeader(Answer a, int indent) throws IOException {
- s.append(i(indent + 1)).append("<query>");
s.append(i(indent + 2)).append("<variables>");
if (a != null && a.getVariables() != null) for (Variable v: a.getVariables()) addHeaderVariable(v, indent);
s.append(i(indent + 2)).append("</variables>");
}
+ protected void addFooter(Answer answer) throws IOException {
+ addFooter(answer, 0);
+ }
+
+ void addFooter(Answer answer, int indent) throws IOException {
+ s.append(i(indent + 1)).append("</query>");
+ }
+
/** {@inheritDoc} */
protected void addHeaderVariable(Variable var) throws IOException {
addHeaderVariable(var, 0);
@@ -91,7 +99,6 @@
protected void addResults(Answer a) throws TuplesException, IOException {
a.beforeFirst();
while (a.next()) addResult(a);
- s.append(i(1)).append("</query>");
}
/**
@@ -181,6 +188,7 @@
public void addAnswer(Answer data) throws TuplesException, IOException {
addHeader(data);
addResults(data);
+ addFooter(data);
}
}
Modified: trunk/src/jar/querylang/java/org/mulgara/protocol/http/ProtocolServlet.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/protocol/http/ProtocolServlet.java 2010-04-22 03:47:35 UTC (rev 1942)
+++ trunk/src/jar/querylang/java/org/mulgara/protocol/http/ProtocolServlet.java 2010-04-22 03:49:18 UTC (rev 1943)
@@ -564,6 +564,7 @@
}
List<Command> cmds = getCommand(queryStr, req);
+ List<Pair<Answer,Output>> results = new ArrayList<Pair<Answer,Output>>();
boolean tx = cmds.size() > 1;
if (tx) executeCommand(new SetAutoCommit(false), req);
@@ -583,6 +584,7 @@
tmpOutputType = getOutputType(req, cmd);
// remember the last answer we see
if (tmpResult instanceof Answer) {
+ results.add(Pair.p((Answer)tmpResult, tmpOutputType));
finalResult = tmpResult;
finalOutputType = tmpOutputType;
}
@@ -598,9 +600,10 @@
finalOutputType = tmpOutputType;
}
- if (finalResult instanceof Answer) {
- sendAnswer((Answer)finalResult, finalOutputType, resp);
+ if (!results.isEmpty()) {
+ doResponseList(results, resp);
} else {
+ assert !(finalResult instanceof Answer);
sendStatus(finalResult, finalOutputType, resp);
}
} finally {
@@ -614,7 +617,29 @@
}
}
+ /**
+ * Sends back a response when a list has been requested. In the normal case,
+ * this is just the final response. All results are also closed.
+ * @param results The list of Answer/Output pairs.
+ * @param resp The response object to send the data on.
+ * @throws BadRequestException More than one type appeared in the request.
+ * @throws InternalErrorException There was a problem processing the request.
+ * @throws IOException There was an error responding to the client.
+ */
+ protected void doResponseList(List<Pair<Answer,Output>> results, HttpServletResponse resp) throws BadRequestException, InternalErrorException, IOException {
+ Pair<Answer,Output> lastResult = C.last(results);
+ sendAnswer(lastResult.first(), lastResult.second(), resp);
+ // now clean it all up
+ for (Pair<Answer,Output> result: results) {
+ try {
+ result.first().close();
+ } catch (TuplesException e) {
+ logger.warn("Error closing resources: " + e.getMessage());
+ }
+ }
+ }
+
/**
* Load MIME data into a graph.
* @param graph The graph to load into.
Modified: trunk/src/jar/querylang/java/org/mulgara/protocol/http/TqlServlet.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/protocol/http/TqlServlet.java 2010-04-22 03:47:35 UTC (rev 1942)
+++ trunk/src/jar/querylang/java/org/mulgara/protocol/http/TqlServlet.java 2010-04-22 03:49:18 UTC (rev 1943)
@@ -38,6 +38,7 @@
import org.mulgara.query.TuplesException;
import org.mulgara.query.operation.Command;
import org.mulgara.server.SessionFactoryProvider;
+import org.mulgara.util.functional.Pair;
/**
* A query gateway for TQL.
@@ -153,7 +154,7 @@
} else {
assert outputType != null;
if (outputType != getOutputType(req, q)) {
- throw new BadRequestException("Incompatible mMixed response types requested");
+ throw new BadRequestException("Incompatible mixed response types requested");
}
}
assert output != null;
@@ -175,6 +176,55 @@
/**
+ * Sends back a response when a list has been requested. This is separate from the doResponse
+ * method above (which does something similar), because this is processing all results
+ * after they have been completed. This happens during a POST, because many of the operations
+ * may not have been queries, whereas the doResponse above is onyl dealing with a series of
+ * read-only queries.
+ * @param results The list of Answer/Output pairs.
+ * @param resp The response object to send the data on.
+ * @throws BadRequestException More than one type appeared in the request.
+ * @throws InternalErrorException There was a problem processing the request.
+ * @throws IOException There was an error responding to the client.
+ */
+ protected void doResponseList(List<Pair<Answer,Output>> results, HttpServletResponse resp) throws BadRequestException, InternalErrorException, IOException {
+ // these variables are to remember state throughout the loop
+ boolean firstItem = true;
+ Output outputType = null;
+ StreamedAnswer output = null;
+ // respond to everything in the list
+ for (Pair<Answer,Output> result: results) {
+ try {
+ if (firstItem) {
+ firstItem = false;
+ // start the response
+ outputType = result.second();
+ output = sendDocumentHeader(streamBuilders, outputType, resp);
+ } else {
+ assert outputType != null;
+ if (outputType != result.second()) {
+ throw new BadRequestException("Incompatible mixed response types requested");
+ }
+ }
+ assert output != null;
+ output.addAnswer(result.first());
+ } catch (TuplesException e) {
+ throw new InternalErrorException("Error reading answers: " + e.getMessage());
+ } finally {
+ try {
+ if (result != null) result.first().close();
+ } catch (TuplesException e) {
+ logger.warn("Error closing: " + e.getMessage(), e);
+ }
+ }
+ }
+ output.addDocFooter();
+ output.close();
+
+ }
+
+
+ /**
* Converts a SPARQL query string into a Query object. This uses extra parameters from the
* client where appropriate, such as the default graph.
* @param query The query string issued by the client.
More information about the Mulgara-svn
mailing list