[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