[Mulgara-svn] r1460 - in trunk/src/jar/querylang/java/org/mulgara/protocol: . http

pag at mulgara.org pag at mulgara.org
Fri Jan 30 21:20:40 UTC 2009


Author: pag
Date: 2009-01-30 13:20:39 -0800 (Fri, 30 Jan 2009)
New Revision: 1460

Added:
   trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedN3Answer.java
   trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedRdfXmlAnswer.java
Modified:
   trunk/src/jar/querylang/java/org/mulgara/protocol/http/ProtocolServlet.java
   trunk/src/jar/querylang/java/org/mulgara/protocol/http/SparqlServlet.java
Log:
Handling N3 and RDF/XML output for CONSTRUCT queries

Added: trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedN3Answer.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedN3Answer.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedN3Answer.java	2009-01-30 21:20:39 UTC (rev 1460)
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2008 Fedora Commons, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.mulgara.protocol;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+
+import org.jrdf.graph.BlankNode;
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.TypedNodeVisitable;
+import org.jrdf.graph.TypedNodeVisitor;
+import org.jrdf.graph.URIReference;
+import org.mulgara.query.Answer;
+import org.mulgara.query.GraphAnswer;
+import org.mulgara.query.TuplesException;
+
+/**
+ * Represents a ConstructAnswer as N3.
+ * This is a very primitive implementation, with no attempt to use [] for blank nodes
+ * list structures, or even namespaces.
+ * TODO: Add prefixes
+ *
+ * @created Jan 29, 2009
+ * @author Paul Gearon
+ * @copyright &copy; 2009 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ */
+public class StreamedN3Answer implements StreamedAnswer {
+
+  /** The answer to convert to RDF/XML. */
+  private final GraphAnswer ans;
+
+  /** The writer to send the data to. */
+  private final PrintWriter p;
+
+  /**
+   * Constructs the object and prepares to writing.
+   * @param ans The answer to emit.
+   * @param s The stream to write the answer to.
+   */
+  public StreamedN3Answer(Answer ans, OutputStream s) {
+    if (!(ans instanceof GraphAnswer)) throw new IllegalArgumentException("N3 constructor can only be constructed from a GraphAnswer");
+    this.ans = (GraphAnswer)ans;
+    assert ans.getVariables().length == 3;
+    BufferedOutputStream out = new BufferedOutputStream(s);
+    p = new PrintWriter(out);
+  }
+
+  /**
+   * Converts the Answer to a String and send to output.
+   * @throws TuplesException Indicates an error accessing the Answer.
+   */
+  public void emit() throws TuplesException, IOException {
+    NodePrinter np = new NodePrinter();
+    ans.beforeFirst();
+    try {
+      while (ans.next()) {
+        ((TypedNodeVisitable)ans.getObject(0)).accept(np);
+        ((TypedNodeVisitable)ans.getObject(1)).accept(np);
+        ((TypedNodeVisitable)ans.getObject(2)).accept(np);
+        p.println(".");
+      }
+    } catch (ClassCastException e) {
+      throw new TuplesException("Data in graph is not a node: " + e.getMessage());
+    } finally {
+      p.close();
+    }
+  }
+
+
+  /**
+   * Prints out the nodes as per N3.
+   */
+  private class NodePrinter implements TypedNodeVisitor {
+
+    /**
+     * Prints the blank node and a space to the stream.
+     * @param blankNode The blank node to write.
+     */
+    public void visitBlankNode(BlankNode blankNode) {
+      p.print("_:");
+      p.print(blankNode.toString().substring(1));
+      p.print(" ");
+    }
+
+    /**
+     * Prints the literal and a space to the stream.
+     * @param literal The literal to write.
+     */
+    public void visitLiteral(Literal literal) {
+      p.print(literal.getEscapedForm());
+      p.print(" ");
+    }
+
+    /**
+     * Prints the uri surrounded by <> and a space to the stream.
+     * @param uriReference The uri to write.
+     */
+    public void visitURIReference(URIReference uriReference) {
+      p.print("<");
+      p.print(uriReference);
+      p.print("> ");
+    }
+    
+  }
+}

Added: trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedRdfXmlAnswer.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedRdfXmlAnswer.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedRdfXmlAnswer.java	2009-01-30 21:20:39 UTC (rev 1460)
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2008 Fedora Commons, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.mulgara.protocol;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.mulgara.query.Answer;
+import org.mulgara.query.GraphAnswer;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.RdfXmlEmitter;
+import org.mulgara.query.TuplesException;
+
+/**
+ * Represents a ConstructAnswer as RDF/XML.
+ * This uses the {@link org.mulgara.query.RdfXmlEmitter} class to do the actual work,
+ * hence, it does not manage XML formatting itself. This is why the interfaces do NOT
+ * include StreamedXMLAnswer.
+ *
+ * @created Jan 29, 2009
+ * @author Paul Gearon
+ * @copyright &copy; 2009 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ */
+public class StreamedRdfXmlAnswer implements StreamedAnswer {
+
+  /** The answer to convert to RDF/XML. */
+  private final GraphAnswer ans;
+
+  /** The stream to write to. */
+  private final OutputStream out;
+
+  public StreamedRdfXmlAnswer(Answer ans, OutputStream s) {
+    if (!(ans instanceof GraphAnswer)) throw new IllegalArgumentException("RDF/XML constructor can only be constructed from a GraphAnswer");
+    this.ans = (GraphAnswer)ans;
+    out = s;
+  }
+
+  /**
+   * Converts the Answer to a String and send to output.
+   * @throws TuplesException Indicates an error accessing the Answer.
+   */
+  public void emit() throws TuplesException, IOException {
+    try {
+      RdfXmlEmitter.writeRdfXml(ans, out);
+    } catch (QueryException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof TuplesException) throw (TuplesException)cause;
+      throw new TuplesException(e.getMessage());
+    }
+  }
+
+}

Modified: trunk/src/jar/querylang/java/org/mulgara/protocol/http/ProtocolServlet.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/protocol/http/ProtocolServlet.java	2009-01-30 21:19:48 UTC (rev 1459)
+++ trunk/src/jar/querylang/java/org/mulgara/protocol/http/ProtocolServlet.java	2009-01-30 21:20:39 UTC (rev 1460)
@@ -39,6 +39,7 @@
 import org.mulgara.parser.Interpreter;
 import org.mulgara.protocol.StreamedAnswer;
 import org.mulgara.query.Answer;
+import org.mulgara.query.ConstructQuery;
 import org.mulgara.query.Query;
 import org.mulgara.query.QueryException;
 import org.mulgara.query.TuplesException;
@@ -168,7 +169,7 @@
   
       Answer result = executeQuery(query, req);
 
-      Output outputType = getOutputType(req);
+      Output outputType = getOutputType(req, query);
       sendAnswer(result, outputType, resp);
 
       try {
@@ -401,7 +402,7 @@
 
     Object result = executeCommand(cmd, req);
 
-    Output outputType = getOutputType(req);
+    Output outputType = getOutputType(req, cmd);
     if (result instanceof Answer) {
       sendAnswer((Answer)result, outputType, resp);
     } else {
@@ -548,13 +549,15 @@
    * @param req The request object for the servlet connection.
    * @return xml, json, rdfXml or rdfN3.
    */
-  private Output getOutputType(HttpServletRequest req) {
+  private Output getOutputType(HttpServletRequest req, Command cmd) {
     Output type = DEFAULT_OUTPUT_TYPE;
 
     // get the accepted types
     String accepted = req.getHeader(ACCEPT_HEADER);
     if (accepted != null) {
-      type = Output.forMime(accepted);
+      // if this is a known type, then return it
+      Output t = Output.forMime(accepted);
+      if (t != null) type = t;
     }
 
     // check the URI parameters
@@ -563,6 +566,14 @@
       Output reqOutput = Output.valueOf(reqOutputName.toUpperCase());
       if (reqOutput != null) type = reqOutput;
     }
+
+    // need graph types if constructing a graph
+    if (cmd instanceof ConstructQuery) {
+      if (type == Output.XML) type = Output.RDFXML;
+    } else {
+      if (type == Output.RDFXML || type == Output.N3) type = Output.XML;
+    }
+
     return type;
   }
 

Modified: trunk/src/jar/querylang/java/org/mulgara/protocol/http/SparqlServlet.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/protocol/http/SparqlServlet.java	2009-01-30 21:19:48 UTC (rev 1459)
+++ trunk/src/jar/querylang/java/org/mulgara/protocol/http/SparqlServlet.java	2009-01-30 21:20:39 UTC (rev 1460)
@@ -23,6 +23,8 @@
 import javax.servlet.http.HttpSession;
 
 import org.mulgara.protocol.StreamedAnswer;
+import org.mulgara.protocol.StreamedN3Answer;
+import org.mulgara.protocol.StreamedRdfXmlAnswer;
 import org.mulgara.protocol.StreamedSparqlJSONAnswer;
 import org.mulgara.protocol.StreamedSparqlJSONObject;
 import org.mulgara.protocol.StreamedSparqlXMLAnswer;
@@ -60,10 +62,17 @@
     AnswerStreamConstructor xmlBuilder = new AnswerStreamConstructor() {
       public StreamedAnswer fn(Answer ans, OutputStream s) { return new StreamedSparqlXMLAnswer(ans, s); }
     };
+    AnswerStreamConstructor rdfXmlBuilder = new AnswerStreamConstructor() {
+      public StreamedAnswer fn(Answer ans, OutputStream s) { return new StreamedRdfXmlAnswer(ans, s); }
+    };
+    AnswerStreamConstructor n3Builder = new AnswerStreamConstructor() {
+      public StreamedAnswer fn(Answer ans, OutputStream s) { return new StreamedN3Answer(ans, s); }
+    };
+    
     streamBuilders.put(Output.JSON, jsonBuilder);
     streamBuilders.put(Output.XML, xmlBuilder);
-    streamBuilders.put(Output.RDFXML, xmlBuilder);  // TODO: create an RDF/XML Builder
-    streamBuilders.put(Output.N3, xmlBuilder);      // TODO: create an N3 Builder
+    streamBuilders.put(Output.RDFXML, rdfXmlBuilder);
+    streamBuilders.put(Output.N3, n3Builder);
 
     ObjectStreamConstructor jsonObjBuilder = new ObjectStreamConstructor() {
       public StreamedAnswer fn(Object o, OutputStream s) { return new StreamedSparqlJSONObject(o, s); }




More information about the Mulgara-svn mailing list