[Mulgara-svn] r1408 - in trunk/src/jar: query/java/org/mulgara/query/operation web/java/org/mulgara/webquery web/resources

pag at mulgara.org pag at mulgara.org
Sat Dec 6 14:23:17 UTC 2008


Author: pag
Date: 2008-12-06 06:23:16 -0800 (Sat, 06 Dec 2008)
New Revision: 1408

Modified:
   trunk/src/jar/query/java/org/mulgara/query/operation/DataInputTx.java
   trunk/src/jar/query/java/org/mulgara/query/operation/Load.java
   trunk/src/jar/query/java/org/mulgara/query/operation/ServerCommand.java
   trunk/src/jar/web/java/org/mulgara/webquery/QueryServlet.java
   trunk/src/jar/web/java/org/mulgara/webquery/Template.java
   trunk/src/jar/web/resources/template.html
   trunk/src/jar/web/resources/template_head.html
   trunk/src/jar/web/resources/tutorial.html
   trunk/src/jar/web/resources/tutorial_head.html
Log:
Added upload capability. Also testing for invalid LOCAL operations

Modified: trunk/src/jar/query/java/org/mulgara/query/operation/DataInputTx.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/operation/DataInputTx.java	2008-12-06 14:22:21 UTC (rev 1407)
+++ trunk/src/jar/query/java/org/mulgara/query/operation/DataInputTx.java	2008-12-06 14:23:16 UTC (rev 1408)
@@ -43,7 +43,7 @@
   private static final String ZIP_EXTENSION = ".zip";
 
   /** A stream to enable an API to load or restore data directly. */
-  private InputStream overrideInputStream = null;
+  protected InputStream overrideInputStream = null;
   
   /**
    * Create a new data transfer command for moving data into a graph or server.

Modified: trunk/src/jar/query/java/org/mulgara/query/operation/Load.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/operation/Load.java	2008-12-06 14:22:21 UTC (rev 1407)
+++ trunk/src/jar/query/java/org/mulgara/query/operation/Load.java	2008-12-06 14:23:16 UTC (rev 1408)
@@ -76,7 +76,7 @@
     URI src = getSource();
     URI dest = getDestination();
 
-    if (isLocal() && !conn.isRemote()) {
+    if (isLocal() && !conn.isRemote() && overrideInputStream == null) {
       logger.error("Used a LOCAL modifier when loading <" + src + "> to <" + dest + "> on a non-remote server.");
       throw new QueryException("LOCAL modifier is not valid for LOAD command when not using a client-server connection.");
     }
@@ -107,4 +107,15 @@
     return conn.getSession().setModel(inputStream, getDestination(), srcRsc);
   }
 
+
+  /**
+   * Get the text of the command, or generate a virtual command if no text was parsed.
+   * @return The query that created this command, or a generated query if no query exists.
+   */
+  public String getText() {
+    String text = super.getText();
+    if (text == null || text.length() == 0) text = "load " + getSource() + " into <" + getDestination() + ">";
+    return text;
+  }
+
 }

Modified: trunk/src/jar/query/java/org/mulgara/query/operation/ServerCommand.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/operation/ServerCommand.java	2008-12-06 14:22:21 UTC (rev 1407)
+++ trunk/src/jar/query/java/org/mulgara/query/operation/ServerCommand.java	2008-12-06 14:23:16 UTC (rev 1408)
@@ -28,7 +28,7 @@
 public abstract class ServerCommand implements Command {
 
   /** The text used to create this command. */
-  private String textualForm;
+  private String textualForm = "";
 
   /** The graph being referred to on the server. */
   private final GraphResource serverGraph;

Modified: trunk/src/jar/web/java/org/mulgara/webquery/QueryServlet.java
===================================================================
--- trunk/src/jar/web/java/org/mulgara/webquery/QueryServlet.java	2008-12-06 14:22:21 UTC (rev 1407)
+++ trunk/src/jar/web/java/org/mulgara/webquery/QueryServlet.java	2008-12-06 14:23:16 UTC (rev 1408)
@@ -22,12 +22,15 @@
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import javax.mail.BodyPart;
+import javax.mail.MessagingException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -39,11 +42,15 @@
 import org.mulgara.parser.Interpreter;
 import org.mulgara.parser.MulgaraLexerException;
 import org.mulgara.parser.MulgaraParserException;
+import org.mulgara.protocol.http.MimeMultiNamedPart;
+import org.mulgara.protocol.http.ServletDataSource;
 import org.mulgara.query.Answer;
 import org.mulgara.query.Query;
 import org.mulgara.query.QueryException;
 import org.mulgara.query.TuplesException;
 import org.mulgara.query.operation.Command;
+import org.mulgara.query.operation.CreateGraph;
+import org.mulgara.query.operation.Load;
 import org.mulgara.server.AbstractServer;
 import org.mulgara.server.SessionFactory;
 import org.mulgara.sparql.SparqlInterpreter;
@@ -83,6 +90,12 @@
   /** Session value for the SPARQL interpreter. */
   private static final String SPARQL_INTERPRETER = "session.sparql.interpreter";
 
+  /** Posted RDF data content type. */
+  protected static final String POSTED_DATA_TYPE = "multipart/form-data;";
+
+  /** A made-up scheme for data uploaded through http-put, since http means "downloaded". */
+  protected static final String HTTP_PUT_NS = "http-put://upload/";
+
   /** The name of the host for the application. */
   private final String hostname;
 
@@ -171,7 +184,9 @@
       resp.sendError(SC_BAD_REQUEST, "Sent a command to the wrong page.");
       return;
     }
-    
+
+    String type = req.getContentType();
+    if (type != null && type.startsWith(POSTED_DATA_TYPE)) handleDataUpload(req, resp);
     doQuery(req, resp, req.getParameter(GRAPH_ARG));
   }
 
@@ -296,6 +311,125 @@
 
 
   /**
+   * Do the work of extracting data to be uploaded, and put it in the requested graph. Create the graph if needed.
+   * @param req The HTTP request containing the file.
+   * @param resp The response back to the submitting client.
+   * @throws IOException Due to an error reading the input stream, or writing to the response stream.
+   */
+  private void handleDataUpload(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+    try {
+      // parse in the data to be uploaded
+      MimeMultiNamedPart mime = new MimeMultiNamedPart(new ServletDataSource(req, UPLOAD_GRAPH_ARG));
+
+      // validate the request
+      if (mime.getCount() == 0) throw new RequestException("Request claims to have posted data, but none was supplied.");
+
+      long time = System.currentTimeMillis();
+
+      // Get the destination graph, and ensure it exists
+      URI destGraph = getRequestedGraph(req, mime);
+      Connection conn = getConnection(req);
+      try {
+        new CreateGraph(destGraph).execute(conn);
+      } catch (QueryException e) {
+        throw new RequestException("Unable to create graph: " + e.getMessage());
+      }
+
+      // upload the data
+      Command loadCommand = null;
+      for (int partNr = 0; partNr < mime.getCount(); partNr++) {
+        BodyPart part = mime.getBodyPart(partNr);
+        String partName = mime.getPartName(partNr);
+        try {
+          if (UPLOAD_FILE_ARG.equalsIgnoreCase(partName)) {
+            loadCommand = loadData(destGraph, part, conn);
+            break;
+          }
+        } catch (QueryException e) {
+          throw new RequestException("Unable to load data: " + partName);
+        }
+      }
+
+      time = System.currentTimeMillis() - time;
+
+      // Get the tags to use in the page template
+      Map<String,String> templateTags = getTemplateTagMap();
+      templateTags.put(GRAPH_TAG, defaultGraph(destGraph.toString()));
+
+      // Generate the page
+      QueryResponsePage page = new QueryResponsePage(req, resp, templateTags, getTemplateHeaderFile(), getTemplateTailFile());
+      page.writeResults(time, Collections.singletonList(loadCommand), Collections.singletonList((Object)""));
+
+    } catch (MessagingException e) {
+      resp.sendError(SC_BAD_REQUEST, "Unable to process received MIME data: " + e.getMessage());
+    } catch (RequestException re) {
+      resp.sendError(SC_BAD_REQUEST, re.getMessage());
+    }
+  }
+
+
+  /**
+   * Gets the graph parameter from the MIME data.
+   * @param req The request object from the user.
+   * @return The URI for the requested graph.
+   * @throws RequestException If a graph name was an invalid URI or was not present in the request.
+   */
+  protected URI getRequestedGraph(HttpServletRequest req, MimeMultiNamedPart mime) throws RequestException {
+    // look in the parameters
+    String[] graphArgs = req.getParameterValues(UPLOAD_GRAPH_ARG);
+    if (graphArgs != null) {
+      if (graphArgs.length != 1) throw new RequestException("Multiple graphs requested.");
+      try {
+        return new URI(graphArgs[0]);
+      } catch (URISyntaxException e) {
+        throw new RequestException("Invalid URI for upload graph. " + e.getInput());
+      }
+    }
+    // look in the mime data
+    if (mime != null) {
+      try {
+        String result = mime.getParameterString(UPLOAD_GRAPH_ARG);
+        if (result != null) {
+          try {
+            return new URI(result);
+          } catch (URISyntaxException e) {
+            throw new RequestException("Invalid URI for upload graph <" + e.getInput() + ">: " + result);
+          }
+        }
+      } catch (Exception e) {
+        throw new RequestException("Bad MIME data in upload request: " + e.getMessage());
+      }
+    }
+    throw new RequestException("No graph argument provided.");
+  }
+
+
+  /**
+   * Load MIME data into a graph.
+   * @param graph The graph to load into.
+   * @param data The data to be loaded, with associated meta-data.
+   * @param cxt The connection to the database.
+   * @return The Command that did the loading.
+   * @throws IOException error reading from the client.
+   * @throws RequestException Bad data passed to the load request.
+   * @throws QueryException A query exception occurred during the load operation.
+   */
+  protected Load loadData(URI graph, BodyPart data, Connection cxt) throws RequestException, IOException, QueryException {
+    try {
+      URI absoluteUri = new URI(HTTP_PUT_NS + data.getFileName());
+      Load loadCmd = new Load(absoluteUri, graph, true);
+      loadCmd.setOverrideInputStream(data.getInputStream());
+      loadCmd.execute(cxt);
+      return loadCmd;
+    } catch (MessagingException e) {
+      throw new RequestException("Unable to process data for loading: " + e.getMessage());
+    } catch (URISyntaxException e) {
+      throw new RequestException("Illegal filename: " + e.getInput());
+    }
+  }
+
+
+  /**
    * Close all but one answer.
    * @param answers The answers to close.
    * @param ordinal The ordinal (1-based) of the answer to NOT close.
@@ -574,6 +708,18 @@
 
 
   /**
+   * Compare a parameter name to a set of known parameter names used for uploading.
+   * @param name The name to check.
+   * @return <code>true</code> if the name is known. <code>false</code> if not known or <code>null</code>.
+   */
+  private boolean knownUploadParam(String name) {
+    final String[] knownParams = new String[] { UPLOAD_GRAPH_ARG };
+    for (String p: knownParams) if (p.equalsIgnoreCase(name)) return true;
+    return false;
+  }
+
+
+  /**
    * Returns the filename extension for a given path.
    * @param path The path to get the extension for.
    * @return The extension, including the . character. If there is no extension, then an empty string.

Modified: trunk/src/jar/web/java/org/mulgara/webquery/Template.java
===================================================================
--- trunk/src/jar/web/java/org/mulgara/webquery/Template.java	2008-12-06 14:22:21 UTC (rev 1407)
+++ trunk/src/jar/web/java/org/mulgara/webquery/Template.java	2008-12-06 14:23:16 UTC (rev 1408)
@@ -76,6 +76,12 @@
   /** The ResultOrdinal argument for URL parameters. */
   public static final String RESULT_ORD_ARG = "ResultOrdinal";
 
+  /** The URI of a graph to be uploaded into. */
+  public static final String UPLOAD_GRAPH_ARG = "UploadGraph";
+
+  /** The path of a file to be uploaded. */
+  public static final String UPLOAD_FILE_ARG = "UploadFile";
+
   /** A label out of the CSS file. That file could be structurally generated, but for no good reason. */
   public static final String CSS_LARGE = "styleLarge";
 

Modified: trunk/src/jar/web/resources/template.html
===================================================================
--- trunk/src/jar/web/resources/template.html	2008-12-06 14:22:21 UTC (rev 1407)
+++ trunk/src/jar/web/resources/template.html	2008-12-06 14:23:16 UTC (rev 1408)
@@ -23,6 +23,23 @@
       return true;
     }
   }
+  function uploadFile() {
+    if (document.QueryForm.GraphURI.value == null ||
+        document.QueryForm.GraphURI.value == "") {
+      alert('Please enter a Graph URI to upload into.');
+      document.QueryForm.GraphURI.focus();
+      return false;
+    }
+    if (document.UploadForm.UploadFile.value == null ||
+        document.UploadForm.UploadFile.value == "") {
+      alert('Please select a file to upload to the Graph.');
+      document.UploadForm.UploadFile.focus();
+      return false;
+    }
+    document.UploadForm.UploadGraph.value = document.QueryForm.GraphURI.value;
+    document.UploadForm.submit();
+    return true;
+  }
   //-->
   </script>
 </head>
@@ -37,11 +54,11 @@
       <table class="formatTable" summary="">
         <tr>
           <td>
-            <form action="@@execute@@" method="post" name="QueryForm">
-              <table class="queryTable" summary="Enter a query">
+            <table class="queryTable" summary="Enter a query">
+              <form action="@@execute@@" method="post" name="QueryForm">
                 <tr>
                   <td><strong>Graph URI:</strong> </td>
-                  <td><input name="GraphURI" size="60" type="text" value=""> </td>
+                  <td><input name="GraphURI" size="60" type="text" value=""/> </td>
                 </tr>
                 <tr>
                   <td><strong>Query Text:</strong> </td>
@@ -50,12 +67,25 @@
                 <tr>
                   <td>&nbsp;</td>
                   <td align="left">
-                    <input type="button" value="Submit Query" onclick="validateAndSubmit()">
-                    <input type="button" value="Clear Query" onclick="javascript:document.QueryForm.QueryText.value='';">
+                    <input type="button" value="Submit Query" onclick="validateAndSubmit()"/>
+                    <input type="button" value="Clear Query" onclick="javascript:document.QueryForm.QueryText.value='';"/>
                   </td>
                 </tr>
-              </table>
-            </form>
+                <tr>
+                  <td colspan="2">&nbsp;</td>
+                </tr>
+              </form>
+              <form enctype='multipart/form-data' action="@@execute@@" method="post" name="UploadForm">
+                <tr>
+                  <td><strong>File:</strong> </td>
+                  <td>
+                    <input type="hidden" name="UploadGraph" value=""/>
+                    <input type="file" name="UploadFile" size="60" value=""/>
+                    <input type="button" value="Upload" onclick="uploadFile()"/>
+                  </td>
+                </tr>
+              </form>
+            </table>
           </td>
         </tr>
       </table>

Modified: trunk/src/jar/web/resources/template_head.html
===================================================================
--- trunk/src/jar/web/resources/template_head.html	2008-12-06 14:22:21 UTC (rev 1407)
+++ trunk/src/jar/web/resources/template_head.html	2008-12-06 14:23:16 UTC (rev 1408)
@@ -23,6 +23,23 @@
       return true;
     }
   }
+  function uploadFile() {
+    if (document.QueryForm.GraphURI.value == null ||
+        document.QueryForm.GraphURI.value == "") {
+      alert('Please enter a Graph URI to upload into.');
+      document.QueryForm.GraphURI.focus();
+      return false;
+    }
+    if (document.UploadForm.UploadFile.value == null ||
+        document.UploadForm.UploadFile.value == "") {
+      alert('Please select a file to upload to the Graph.');
+      document.UploadForm.UploadFile.focus();
+      return false;
+    }
+    document.UploadForm.UploadGraph.value = document.QueryForm.GraphURI.value;
+    document.UploadForm.submit();
+    return true;
+  }
   //-->
   </script>
 </head>
@@ -37,11 +54,11 @@
       <table class="formatTable" summary="">
         <tr>
           <td>
-            <form action="@@execute@@.html" method="post" name="QueryForm">
-              <table class="queryTable" summary="Enter a query">
+            <table class="queryTable" summary="Enter a query">
+              <form action="@@execute@@.html" method="post" name="QueryForm">
                 <tr>
                   <td><strong>Graph URI:</strong> </td>
-                  <td><input name="GraphURI" size="60" type="text" value="@@graph@@"> </td>
+                  <td><input name="GraphURI" size="60" type="text" value="@@graph@@"/> </td>
                 </tr>
                 <tr>
                   <td><strong>Query Text:</strong> </td>
@@ -50,12 +67,22 @@
                 <tr>
                   <td>&nbsp;</td>
                   <td align="left">
-                    <input type="button" value="Submit Query" onclick="validateAndSubmit()">
-                    <input type="button" value="Clear Query" onclick="javascript:document.QueryForm.QueryText.value='';">
+                    <input type="button" value="Submit Query" onclick="validateAndSubmit()"/>
+                    <input type="button" value="Clear Query" onclick="javascript:document.QueryForm.QueryText.value='';"/>
                   </td>
                 </tr>
-              </table>
-            </form>
+              </form>
+              <form enctype='multipart/form-data' action="@@execute@@" method="post" name="UploadForm">
+                <tr>
+                  <td><strong>File:</strong> </td>
+                  <td>
+                    <input type="hidden" name="UploadGraph" value=""/>
+                    <input type="file" name="UploadFile" size="60" value=""/>
+                    <input type="button" value="Upload" onclick="uploadFile()"/>
+                  </td>
+                </tr>
+              </form>
+            </table>
           </td>
         </tr>
         <tr>

Modified: trunk/src/jar/web/resources/tutorial.html
===================================================================
--- trunk/src/jar/web/resources/tutorial.html	2008-12-06 14:22:21 UTC (rev 1407)
+++ trunk/src/jar/web/resources/tutorial.html	2008-12-06 14:23:16 UTC (rev 1408)
@@ -58,7 +58,7 @@
               <table class="queryTable" summary="Enter a query">
                 <tr>
                   <td><strong>Graph URI:</strong> </td>
-                  <td><input name="GraphURI" size="60" type="text" value="rmi://@@hostname@@/@@servername@@#sampledata"> </td>
+                  <td><input name="GraphURI" size="60" type="text" value="rmi://@@hostname@@/@@servername@@#sampledata"/> </td>
                 </tr>
                 <tr>
                   <td><strong>Example Queries:</strong> </td>
@@ -83,8 +83,8 @@
                 <tr>
                   <td>&nbsp;</td>
                   <td align="left">
-                    <input type="button" value="Submit Query" onclick="validateAndSubmit()">
-                    <input type="button" value="Clear Query" onclick="javascript:document.QueryForm.QueryText.value='';">
+                    <input type="button" value="Submit Query" onclick="validateAndSubmit()"/>
+                    <input type="button" value="Clear Query" onclick="javascript:document.QueryForm.QueryText.value='';"/>
                   </td>
                 </tr>
               </table>

Modified: trunk/src/jar/web/resources/tutorial_head.html
===================================================================
--- trunk/src/jar/web/resources/tutorial_head.html	2008-12-06 14:22:21 UTC (rev 1407)
+++ trunk/src/jar/web/resources/tutorial_head.html	2008-12-06 14:23:16 UTC (rev 1408)
@@ -58,7 +58,7 @@
               <table class="queryTable" summary="Enter a query">
                 <tr>
                   <td><strong>Graph URI:</strong> </td>
-                  <td><input name="GraphURI" size="60" type="text" value="@@graph@@"> </td>
+                  <td><input name="GraphURI" size="60" type="text" value="@@graph@@"/> </td>
                 </tr>
                 <tr>
                   <td><strong>Example Queries:</strong> </td>
@@ -83,8 +83,8 @@
                 <tr>
                   <td>&nbsp;</td>
                   <td align="left">
-                    <input type="button" value="Submit Query" onclick="validateAndSubmit()">
-                    <input type="button" value="Clear Query" onclick="javascript:document.QueryForm.QueryText.value='';">
+                    <input type="button" value="Submit Query" onclick="validateAndSubmit()"/>
+                    <input type="button" value="Clear Query" onclick="javascript:document.QueryForm.QueryText.value='';"/>
                   </td>
                 </tr>
               </table>




More information about the Mulgara-svn mailing list