[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> </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"> </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> </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> </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> </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