[Mulgara-svn] r1128 - in trunk/src/jar: . webquery webquery/java webquery/java/org webquery/java/org/mulgara webquery/java/org/mulgara/webquery webquery/java/org/mulgara/webquery/html webquery/resources webquery/resources/images webquery/resources/styles
pag at mulgara.org
pag at mulgara.org
Sun Aug 10 02:06:09 UTC 2008
Author: pag
Date: 2008-08-09 19:06:08 -0700 (Sat, 09 Aug 2008)
New Revision: 1128
Added:
trunk/src/jar/webquery/
trunk/src/jar/webquery/build.xml
trunk/src/jar/webquery/java/
trunk/src/jar/webquery/java/org/
trunk/src/jar/webquery/java/org/mulgara/
trunk/src/jar/webquery/java/org/mulgara/webquery/
trunk/src/jar/webquery/java/org/mulgara/webquery/QueryParams.java
trunk/src/jar/webquery/java/org/mulgara/webquery/QueryResponsePage.java
trunk/src/jar/webquery/java/org/mulgara/webquery/QueryServlet.java
trunk/src/jar/webquery/java/org/mulgara/webquery/RequestException.java
trunk/src/jar/webquery/java/org/mulgara/webquery/ResourceBinaryFile.java
trunk/src/jar/webquery/java/org/mulgara/webquery/ResourceFile.java
trunk/src/jar/webquery/java/org/mulgara/webquery/ResourceTextFile.java
trunk/src/jar/webquery/java/org/mulgara/webquery/Template.java
trunk/src/jar/webquery/java/org/mulgara/webquery/html/
trunk/src/jar/webquery/java/org/mulgara/webquery/html/Anchor.java
trunk/src/jar/webquery/java/org/mulgara/webquery/html/Break.java
trunk/src/jar/webquery/java/org/mulgara/webquery/html/Div.java
trunk/src/jar/webquery/java/org/mulgara/webquery/html/Emphasis.java
trunk/src/jar/webquery/java/org/mulgara/webquery/html/HtmlElement.java
trunk/src/jar/webquery/java/org/mulgara/webquery/html/Paragraph.java
trunk/src/jar/webquery/java/org/mulgara/webquery/html/Span.java
trunk/src/jar/webquery/java/org/mulgara/webquery/html/Strong.java
trunk/src/jar/webquery/java/org/mulgara/webquery/html/Table.java
trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableAbstr.java
trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableBody.java
trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableData.java
trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableHeader.java
trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableRow.java
trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableStructure.java
trunk/src/jar/webquery/java/org/mulgara/webquery/html/Text.java
trunk/src/jar/webquery/resources/
trunk/src/jar/webquery/resources/debug.html
trunk/src/jar/webquery/resources/images/
trunk/src/jar/webquery/resources/images/logo.jpg
trunk/src/jar/webquery/resources/styles/
trunk/src/jar/webquery/resources/styles/ui.css
trunk/src/jar/webquery/resources/template.html
trunk/src/jar/webquery/resources/template_head.html
trunk/src/jar/webquery/resources/template_more_tail.html
trunk/src/jar/webquery/resources/template_tail.html
trunk/src/jar/webquery/webquery-build.properties
Log:
A new query UI provided as a web service. This is simpler than the webui WAR file, and has no dependencies on XMLC or Barracuda
Added: trunk/src/jar/webquery/build.xml
===================================================================
--- trunk/src/jar/webquery/build.xml (rev 0)
+++ trunk/src/jar/webquery/build.xml 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE project>
+
+<!-- =================================================================== -->
+<!-- Project definition -->
+<!-- =================================================================== -->
+<project name="webquery" default="webquery-jar" basedir="../../..">
+
+ <!-- =================================================================== -->
+ <!-- Property Definitions -->
+ <!-- =================================================================== -->
+
+ <!-- =================================================================== -->
+ <!-- Imports -->
+ <!-- =================================================================== -->
+
+ <!-- =================================================================== -->
+ <!-- Path Definitions -->
+ <!-- =================================================================== -->
+ <path id="webquery-classpath">
+ <path refid="common-classpath"/>
+ <fileset file="${util.dist.dir}/${util.jar}"/>
+ <fileset file="${query.dist.dir}/${query.jar}"/>
+ <fileset file="${itql.dist.dir}/${itql.jar}"/>
+ <fileset file="${server.dist.dir}/${server.jar}"/>
+ <fileset file="${lib.dir}/${jetty.jar}"/>
+ <fileset file="${lib.dir}/${jetty-plus.jar}"/>
+ <fileset file="${lib.dir}/${servlet.jar}"/>
+ </path>
+
+ <path id="webquery-test-classpath">
+ <path refid="webquery-classpath"/>
+ <fileset file="${webquery.dist.dir}/${webquery.jar}"/>
+ </path>
+
+ <target name="webquery-clean" description="Removes all compile generated files for the webquery">
+ <tstamp/>
+ <delete dir="${webquery.obj.dir}"/>
+ <delete dir="${webquery.test.dir}"/>
+ <delete dir="${webquery.dist.dir}"/>
+ </target>
+
+ <target name="-webquery-prepare"
+ description="Creates all directories associated with the webquery's compilation"
+ depends="-prepare-build">
+ <mkdir dir="${webquery.obj.dir}"/>
+ <mkdir dir="${webquery.test.dir}"/>
+ <mkdir dir="${webquery.dist.dir}"/>
+ <mkdir dir="${webquery.obj.dir}/classes"/>
+ <mkdir dir="${webquery.obj.dir}/classes/conf"/>
+ <mkdir dir="${webquery.obj.dir}/java"/>
+ </target>
+
+ <target name="-webquery-unjar-config"
+ depends="-webquery-unjar-config-uptodate"
+ unless="webquery.unjar.config.uptodate">
+ <unjar src="${bin.dir}/${config.jar}" dest="${webquery.obj.dir}/classes"/>
+ </target>
+
+ <target name="-webquery-unjar-config-uptodate">
+ <available file="${webquery.obj.dir}/classes/org/mulgara/config/MulgaraConfig.class"
+ property="webquery.unjar.config.uptodate"/>
+ </target>
+
+ <target name="webquery-compile"
+ depends="-webquery-prepare, util-jar, config-jar, itql-jar, query-jar, -webquery-unjar-config"
+ description="Compiles all webquery related files included generated
+ source code"
+ unless="webquery.classes.uptodate">
+
+ <javac destdir="${webquery.obj.dir}/classes" debug="on" deprecation="on" source="1.5">
+ <classpath refid="webquery-classpath"/>
+ <src path="${webquery.src.dir}/java"/>
+ </javac>
+ </target>
+
+ <target name="webquery-jar"
+ depends="webquery-compile, config-database, -webquery-jar-uptodate"
+ unless="webquery.jar.uptodate"
+ description="Creates the webquery's jar/s">
+
+ <jar jarfile="${webquery.dist.dir}/${webquery.jar}">
+ <fileset dir="${webquery.obj.dir}/classes"/>
+ <fileset dir="${webquery.src.dir}" includes="resources/**/*"/>
+ </jar>
+ </target>
+
+ <target name="-webquery-jar-uptodate">
+ <uptodate property="webquery.jar.uptodate"
+ targetfile="${webquery.dist.dir}/${webquery.jar}">
+ <srcfiles dir="${webquery.obj.dir}" includes="**/*"/>
+ <srcfiles dir="${webquery.src.dir}" includes="resources/**/*"/>
+ </uptodate>
+ </target>
+
+ <target name="webquery-dist"
+ depends="webquery-jar"
+ unless="webquery.uptodate"
+ description="Performs all tasks related to finalising this webquery
+ and readying it for distribution">
+
+ <!-- All that's involved in the final version of the webquery library
+ is the jar so we don't need to do anything because the dependencies
+ take care of the work. -->
+ </target>
+
+ <target name="webquery-test" depends="webquery-jar"
+ description="Carries out unit testing for this webquery">
+
+ <antcall target="component-test">
+ <param name="classpath.id" value="webquery-test-classpath"/>
+ <param name="dir" value="${webquery.src.dir}"/>
+ <param name="jar" value="${webquery.jar}"/>
+ </antcall>
+ </target>
+
+ <target name="webquery-javadoc" depends="webquery-jar"
+ description="Creates the javadoc for this webquery">
+ <antcall target="javadoc">
+ <param name="javadoc.package" value="org.mulgara.webquery.*"/>
+ <param name="javadoc.classpath" value="webquery-classpath"/>
+ <param name="javadoc.sourcepath" value="${webquery.src.dir}/java"/>
+ </antcall>
+ </target>
+
+ <target name="webquery-help" description="Displays the help information for this webquery">
+ <echo message="Welcome to the build script for ${name}."/>
+ <echo message=""/>
+ <echo message="These targets can be invoked as follows:"/>
+ <echo message=" ./build.sh <target>"/>
+ <echo message=""/>
+ <java fork="false" classname="org.apache.tools.ant.Main" newenvironment="false">
+ <jvmarg value="${arch.bits}"/>
+ <arg line="-buildfile ${webquery.src.dir}/build.xml -projecthelp"/>
+ </java>
+ </target>
+</project>
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/QueryParams.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/QueryParams.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/QueryParams.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,130 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.mulgara.util.Pair;
+
+/**
+ * Represents the parameters used in an HTTP request.
+ *
+ * @created Aug 5, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class QueryParams {
+
+ /** The encoding to use for a URL */
+ static final String ENCODING = "UTF-8";
+
+ /** The parameter names and values. */
+ private Map<String,String> params = new LinkedHashMap<String,String>();
+
+ /**
+ * Create an empty set of parameters.
+ */
+ public QueryParams() {
+ }
+
+ /**
+ * Create a set of parameters from a single name/value pair.
+ * @param name The name of the parameter.
+ * @param value The value for the parameter.
+ */
+ public QueryParams(String name, Object value) {
+ params.put(name, value.toString());
+ }
+
+ /**
+ * Create a set of parameters from an array of name/value pairs.
+ * @param pairs An array of name/value pairs.
+ */
+ public QueryParams(Pair<String,String>... pairs) {
+ for (Pair<String,String> p: pairs) params.put(p.first(), p.second());
+ }
+
+ /**
+ * Create a set of parameters from a collection of name/value pairs.
+ * @param pairs A collection of name/value pairs.
+ */
+ public QueryParams(Collection<Pair<String,String>> pairs) {
+ for (Pair<String,String> p: pairs) params.put(p.first(), p.second());
+ }
+
+ /**
+ * Adds a name/value to the parameters.
+ * @param pair The name/value pair to be added.
+ * @return This parameters object.
+ */
+ public QueryParams add(Pair<String,String> pair) {
+ params.put(pair.first(), pair.second());
+ return this;
+ }
+
+ /**
+ * Adds a name/value to the parameters.
+ * @param name The name of the parameter to be added.
+ * @param value The valueof the parameter to be added.
+ * @return This parameters object.
+ */
+ public QueryParams add(String name, String value) {
+ params.put(name, value);
+ return this;
+ }
+
+ /**
+ * Adds an array of name/values to the parameters.
+ * @param pairs The name/value array to be added.
+ * @return This parameters object.
+ */
+ public QueryParams addAll(Pair<String,String>... pairs) {
+ for (Pair<String,String> p: pairs) params.put(p.first(), p.second());
+ return this;
+ }
+
+ /**
+ * Adds a collection of name/values to the parameters.
+ * @param pairs The name/value collection to be added.
+ * @return This parameters object.
+ */
+ public QueryParams addAll(Collection<Pair<String,String>> pairs) {
+ for (Pair<String,String> p: pairs) params.put(p.first(), p.second());
+ return this;
+ }
+
+ /**
+ * Converts this set of parameters to the query portion of a URL.
+ * @return a query to be added to a URL.
+ */
+ public String toString() {
+ try {
+ boolean first = true;
+ StringBuilder b = new StringBuilder();
+ for (Map.Entry<String,String> e: params.entrySet()) {
+ if (first) first = false;
+ else b.append("&");
+ b.append(URLEncoder.encode(e.getKey(), ENCODING));
+ b.append("=").append(URLEncoder.encode(e.getValue(), ENCODING));
+ }
+ return b.toString();
+ } catch (UnsupportedEncodingException e) {
+ throw new IllegalArgumentException("Unable to encode with " + ENCODING + ": " + e.getMessage());
+ }
+ }
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/QueryResponsePage.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/QueryResponsePage.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/QueryResponsePage.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,483 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery;
+
+import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jrdf.graph.BlankNode;
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.jrdf.graph.URIReference;
+import org.mulgara.query.Answer;
+import org.mulgara.query.TuplesException;
+import org.mulgara.query.Variable;
+import org.mulgara.query.operation.Command;
+import org.mulgara.util.Pair;
+import org.mulgara.webquery.html.Anchor;
+import org.mulgara.webquery.html.HtmlElement;
+import org.mulgara.webquery.html.Span;
+import org.mulgara.webquery.html.Strong;
+import org.mulgara.webquery.html.Table;
+import org.mulgara.webquery.html.TableData;
+import org.mulgara.webquery.html.TableHeader;
+import org.mulgara.webquery.html.TableRow;
+import org.mulgara.webquery.html.Text;
+import org.mulgara.webquery.html.HtmlElement.Attr;
+import org.mulgara.webquery.html.HtmlElement.Entity;
+
+import static org.mulgara.webquery.Template.*;
+
+/**
+ * Constructs and emits the response page for a set of queries.
+ *
+ * @created Aug 4, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class QueryResponsePage {
+
+ /** The name of the system property that can override the page size. */
+ public static final String PAGE_SIZE_PROP = "webui.page.size";
+
+ /** The default number of results per page or per cell. */
+ public static final int DEFAULT_RESULTS_PER_PAGE = 250;
+
+ /** The number of results per page or per cell. */
+ static int resultsPerPage;
+
+ /** The request that asked for this page. */
+ HttpServletRequest request;
+
+ /** The structure for sending the page back to the client. */
+ HttpServletResponse response;
+
+ /** A map of tags to the values that should replace them. */
+ Map<String,String> tagMap;
+
+ /** The object for accepting the output stream. */
+ PrintWriter out = null;
+
+ /** The set of unfinished results to render, mapped to the remaining sizes. */
+ Map<Answer,Pair<Long,Command>> unfinishedResults;
+
+
+ static {
+ try {
+ resultsPerPage = Integer.parseInt(System.getProperty(PAGE_SIZE_PROP));
+ } catch (Exception e) {
+ resultsPerPage = DEFAULT_RESULTS_PER_PAGE;
+ }
+ }
+
+
+ /**
+ * Construct this page for responsing to a particular request environment.
+ * @param reqThe request that asked for this page.
+ * @param resp The structure for sending the page back to the client.
+ * @param tagMap A map of tags to the values that should replace them
+ */
+ @SuppressWarnings("unchecked")
+ public QueryResponsePage(HttpServletRequest req, HttpServletResponse resp, Map<String,String> tagMap) {
+ this.request = req;
+ this.response = resp;
+ this.tagMap = tagMap;
+ this.unfinishedResults = (Map<Answer,Pair<Long,Command>>)req.getSession().getAttribute(UNFINISHED_RESULTS);
+ }
+
+
+ /**
+ * Send a result page to the client without any stats. This starts with a form template, and then
+ * follows up with a single result.
+ * @param cmd The command that was run.
+ * @param result The result returned from running the command.
+ * @throws IOException There was an error writing to the client, or reading resources.
+ */
+ public void writeResult(Command cmd, Answer result) throws IOException {
+ List<Command> commands = Collections.singletonList(cmd);
+ List<Object> results = Collections.singletonList((Object)result);
+ writeResults(-1L, commands, results);
+ }
+
+
+ /**
+ * Send a result page to the client. This starts with a form template, and then
+ * follows up with the results.
+ * @param time The time take to execute the commands to get these results.
+ * @param cmds The commands that were run.
+ * @param results The result list returned from running each command.
+ * @throws IOException There was an error writing to the client, or reading resources.
+ */
+ public void writeResults(long time, List<Command> cmds, List<Object> results) throws IOException {
+ response.setContentType("text/html");
+ response.setHeader("pragma", "no-cache");
+ PrintWriter output = getOutput();
+ // write the head of the page
+ new ResourceTextFile(TEMPLATE_HEAD, tagMap).sendTo(output);
+
+ // summarise the results first
+ writeResultSummary(time, results.size());
+
+ // write the results
+ Iterator<Command> c = cmds.iterator();
+ Iterator<Object> r = results.iterator();
+ while (c.hasNext()) writeResult(c.next(), r.next());
+
+ // Check that we exhausted the results, like we were supposed to
+ if (r.hasNext()) response.sendError(SC_INTERNAL_SERVER_ERROR, "Internal error: results do not match queries.");
+
+ // write the tail of the page
+ new ResourceTextFile(TEMPLATE_TAIL).sendTo(output);
+
+ output.close();
+ }
+
+
+ /**
+ * Write a summary for the results of all the executed commands.
+ * @param out The stream to write the results to.
+ * @param time The time taken to execute the commands, in milliseconds.
+ * @param size The number of commands executed.
+ */
+ private void writeResultSummary(long time, int nrCommands) throws IOException {
+ // short circuit if we don't have a summary
+ if (time < 0) return;
+ HtmlElement row = new TableRow(ROW_INDENT);
+ row.add(new Span(CSS_LARGE, "Results:"));
+ Text t = new Text("(" + nrCommands);
+ t.append(nrCommands == 1 ? " query, " : " queries, ");
+ t.append(String.format("%.3f", (time / 1000.0))).append(" seconds)");
+ row.add(t);
+
+ emitTopLevelElement(row);
+ }
+
+
+ /**
+ * Write a single result into a row of an existing table.
+ * @param cmd The command executed to give this result.
+ * @param result The result for the command cmd.
+ * @throws IOException Occurs for an error writing the response.
+ */
+ private void writeResult(Command cmd, Object result) throws IOException {
+ if (result instanceof Answer) writeAnswerResult(cmd, (Answer)result);
+ else writeSimpleResult(cmd);
+ }
+
+
+ /**
+ * Write a simple result into a row of an existing table.
+ * @param cmd The command executed to give this result.
+ * @param result The result for the command cmd.
+ * @throws IOException Occurs for an error writing the response.
+ */
+ private void writeSimpleResult(Command cmd) throws IOException {
+ HtmlElement row = new TableRow(ROW_INDENT);
+ row.add(new Span(CSS_LARGE, "Query Executed:"));
+ row.add(new TableData(cmd.getText()).addAttr(Attr.VALIGN, "top").addAttr(Attr.WIDTH, "100%"));
+
+ emitTopLevelElement(row);
+
+ row = new TableRow(ROW_INDENT);
+ row.add(new Span(CSS_LARGE, "Result Message:"));
+ row.add(new TableData(cmd.getResultMessage()).addAttr(Attr.VALIGN, "top").addAttr(Attr.WIDTH, "100%"));
+
+ emitTopLevelElement(row);
+ }
+
+
+ /**
+ * Write a complex result into a row of an existing table.
+ * @param cmd The command executed to give this result.
+ * @param result The result for the command cmd.
+ * @throws IOException Occurs for an error writing the response.
+ */
+ private void writeAnswerResult(Command cmd, Answer result) throws IOException {
+ // create a row with the query that was executed
+ TableRow row = new TableRow(ROW_INDENT);
+ row.add(new Span(CSS_LARGE, "Query Executed:"));
+ row.add(new TableData(cmd.getText()).addAttr(Attr.VALIGN, "top").addAttr(Attr.WIDTH, "100%"));
+
+ emitTopLevelElement(row);
+
+ // create the result table, and put it in a cell
+ TableData resultData = new TableData(createResultTable(result, cmd));
+ resultData.addAttr(Attr.COLSPAN, 2).addAttr(Attr.CLASS, CSS_RESULT_TABLE_CELL);
+ // create a new row to hold the result table
+ row = new TableRow(ROW_INDENT, resultData);
+
+ emitTopLevelElement(row);
+ }
+
+
+ /**
+ * Convert a result into an HTML table.
+ * @param result The result to convert.
+ * @return A new table containing all the requested results.
+ * @throws IOException If there was an error reading the results
+ */
+ private Table createResultTable(Answer result, Command cmd) throws IOException {
+ // create the table for the results
+ Table resultTable = new Table();
+ resultTable.addAttr(Attr.CLASS, CSS_RESULT_TABLE);
+
+ // Get the columns to be displayed
+ Variable[] vars = result.getVariables();
+
+ // add the headers for the table
+ TableRow headerRow = new TableRow();
+ for (Variable v: vars) headerRow.add(new TableHeader(new Strong(v.getName())));
+ resultTable.add(headerRow);
+
+ // add the result data
+ try {
+ int rowsLeft = resultsPerPage;
+ // if this is the first time we've seen this result, then go to the start
+ if (!isResuming(result)) result.beforeFirst();
+
+ while (result.next()) {
+ TableRow row = new TableRow();
+ for (int c = 0; c < vars.length; c++) row.add(createEmbeddableElement(result.getObject(c), cmd));
+ resultTable.add(row);
+ // exit early if this is too big
+ if (--rowsLeft == 0) {
+ addUnfinishedResult(result, resultsPerPage, cmd);
+ appendNextPageLink(result, resultTable);
+ return resultTable;
+ }
+ }
+ // got to the end of this result, so clean it up
+ resultFinished(result);
+ } catch (TuplesException e) {
+ throw new IOException("Error accessing the results of the query: " + e.getMessage());
+ }
+ return resultTable;
+ }
+
+
+ /**
+ * Converts an object returned from a query into an element in a table.
+ * If the object is a simple type, then it returns text linked to a query
+ * for that element. For Answer object, it returns a new table.
+ * @param obj The object to convert into a table element.
+ * @param cmd The command that gave rise to the object.
+ * @return A new table data element.
+ * @throws IOException If the data could not be read.
+ */
+ private TableData createEmbeddableElement(Object obj, Command cmd) throws IOException {
+ HtmlElement result = null;
+ if (obj instanceof Answer) result = createResultTable((Answer)obj, cmd);
+ if (obj instanceof BlankNode) result = new Text(obj.toString());
+ if (obj instanceof URIReference || obj instanceof Literal) result = getElementQuery((Node)obj);
+
+ // only null should make it this far without setting the result
+ if (result == null) {
+ if (obj != null) throw new IllegalArgumentException("Unknown type in result data");
+ result = new TableData(new Text(Entity.NBSP));
+ }
+
+ if (!(result instanceof TableData)) result = new TableData(result);
+ result.addAttr(Attr.CLASS, "rtd"); // set the style to Result-Table-Data
+ return (TableData)result;
+ }
+
+
+ /**
+ * Gets the URL used for the sample data.
+ * @return A URL for the sample data, expressed in the template as:
+ * rmi://@@hostname@@/@@servername@@#sampledata
+ */
+ private Anchor getElementQuery(Node n) throws IOException {
+ try {
+ URI graphUri = new URI("rmi", tagMap.get(HOSTNAME_TAG), "/" + tagMap.get(SERVERNAME_TAG), "sampledata");
+ QueryParams params = new QueryParams();
+ params.add(MODEL_ARG, graphUri.toString());
+ String text;
+ if (n instanceof URIReference) {
+ params.add(QUERY_RESOURCE_ARG, n.toString());
+ text = n.toString();
+ } else {
+ params.add(QUERY_LITERAL_ARG, parameterizeLiteral((Literal)n));
+ text = ((Literal)n).getEscapedForm();
+ }
+ return new Anchor(new URI(EXECUTE_LINK + "?" + params), text);
+ } catch (URISyntaxException e) {
+ throw new IOException("Bad data returned from server");
+ }
+ }
+
+
+ /**
+ * Adds on a row without borders that links to the next page in this result.
+ * @param result The result being displayed.
+ * @param resultTable The existing page of data representing the result.
+ * @return The table with a new row appended to it, containing the required link.
+ * @throws IOException If there was an error structuring the table data.
+ */
+ private Table appendNextPageLink(Answer result, Table resultTable) throws IOException {
+ if (isResuming(result)) {
+ TableRow tr = createNextLinkRow(result, resultTable.getWidth());
+ tr.addAttr(Attr.CLASS, "borderLess");
+ resultTable.add(tr);
+ }
+ return resultTable;
+ }
+
+
+ /**
+ * Creates a link that will take the user to the next page for this data.
+ * @param result The result to create the link for.
+ * @param width The width the row has to fill.
+ * @return A table row containing the link to the next unfinished result.
+ * @throws IOException If there was an error structuring the table data.
+ */
+ private TableRow createNextLinkRow(Answer result, int width) throws IOException {
+ try {
+ QueryParams param = new QueryParams(RESULT_ORD_ARG, getNrToBeResumed(result));
+ Anchor a = new Anchor(new URI(EXECUTE_LINK + "?" + param), "Next page >");
+ a.addAttr(Attr.TITLE, "Forward to next page of results");
+ return new TableRow(new TableData(a).addAttr(Attr.COLSPAN, width));
+ } catch (URISyntaxException e) {
+ throw new IOException("Unabled to emit a relative URL: " + e.getMessage());
+ }
+ }
+
+
+ /**
+ * Writes a top-level element to the output stream.
+ * @param elt The element to write.
+ * @throws IOException If there was an error getting the stream or using it.
+ */
+ private void emitTopLevelElement(HtmlElement elt) throws IOException {
+ PrintWriter output = getOutput();
+ elt.sendTo(output);
+ output.append("\n");
+ }
+
+
+ /**
+ * Encode a Literal for use as a parameter in a query.
+ * @param l The literal to encode.
+ * @return An form of the literal that is safe to use in a parameter.
+ */
+ private String parameterizeLiteral(Literal l) {
+ StringBuilder p = new StringBuilder("'");
+ p.append(l.getLexicalForm().replaceAll("'", "\\\\'")).append('\'');
+
+ URI datatype = l.getDatatypeURI();
+ String language = l.getLanguage();
+
+ if (datatype != null) {
+ p.append("^^<").append(datatype).append(">");
+ } else if (language != null && !language.equals("")) {
+ p.append("@").append(language);
+ }
+
+ return p.toString();
+ }
+
+
+ /**
+ * Gets the PrintWriter for this page.
+ * @return The print writer to use for this page.
+ * @throws IOException If there was a problem getting the object.
+ */
+ private PrintWriter getOutput() throws IOException {
+ if (out == null) out = response.getWriter();
+ return out;
+ }
+
+
+ /**
+ * Determines how many results are to be resumed.
+ * @return <code>true</code> if this result has already been partly resumed.
+ */
+ private int getNrToBeResumed(Answer ans) {
+ if (unfinishedResults == null) throw new IllegalStateException("Should not be creating a link to a result when that result was not saved.");
+ Iterator<Answer> answers = unfinishedResults.keySet().iterator();
+ // should either be the first one added, or the last one
+ return (answers.next() == ans) ? 1 : unfinishedResults.size();
+ }
+
+
+ /**
+ * Tests a result to see it is being resumed.
+ * @param result The Answer to test.
+ * @return <code>true</code> if this result has already been partly resumed.
+ */
+ private boolean isResuming(Answer result) {
+ return (unfinishedResults != null) && unfinishedResults.keySet().contains(result);
+ }
+
+
+ /**
+ * Marks a result as finished.
+ * @param result The Answer that just finished.
+ * @throws TuplesException Error while cleaning up the result.
+ */
+ private void resultFinished(Answer result) throws TuplesException {
+ if (unfinishedResults != null) unfinishedResults.remove(result);
+ result.close();
+ }
+
+
+ /**
+ * Adds an unfinished Answer to the current session for later display. The Answer is not
+ * added if all the rows have been displayed.
+ * @param result The Answer to add to the session.
+ * @param numDisplayed The number of rows that have just been displayed from the result.
+ * @param cmd The Command associated with the Answer in <var>result</var>.
+ * @throws TuplesException If it is not possible to get the number of remaining rows.
+ */
+ private void addUnfinishedResult(Answer result, int numDisplayed, Command cmd) throws TuplesException {
+ // Determine how many results have yet to be displayed from this Answer
+ long remainingRows;
+ if (unfinishedResults == null) remainingRows = result.getRowCount();
+ else {
+ // get the remaining from the session, or use the full value if not in the session
+ Pair<Long,Command> lastRemainingRows = unfinishedResults.get(result);
+ remainingRows = (lastRemainingRows == null) ? result.getRowCount() : lastRemainingRows.first();
+ }
+ // just diplayed a page, so decrement by a page
+ remainingRows -= numDisplayed;
+ if (remainingRows < 0) throw new IllegalStateException("Cannot display more rows than are available.");
+
+ // No more to display, so clean up and leave
+ if (remainingRows == 0) {
+ result.close();
+ unfinishedResults.remove(result);
+ return;
+ }
+
+ // Remember that there is more for this result
+ if (unfinishedResults == null) {
+ unfinishedResults = new LinkedHashMap<Answer,Pair<Long,Command>>();
+ request.getSession().setAttribute(UNFINISHED_RESULTS, unfinishedResults);
+ }
+ unfinishedResults.put(result, new Pair<Long,Command>(remainingRows, cmd));
+ }
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/QueryServlet.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/QueryServlet.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/QueryServlet.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,477 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.mulgara.connection.Connection;
+import org.mulgara.connection.SessionConnection;
+import org.mulgara.itql.TqlInterpreter;
+import org.mulgara.parser.Interpreter;
+import org.mulgara.parser.MulgaraParserException;
+import org.mulgara.query.Answer;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.TuplesException;
+import org.mulgara.query.operation.Command;
+import org.mulgara.server.AbstractServer;
+import org.mulgara.server.SessionFactory;
+import org.mulgara.util.FnE;
+import org.mulgara.util.C;
+import org.mulgara.util.Pair;
+import org.mulgara.util.StackTrace;
+
+import static org.mulgara.webquery.Template.*;
+
+import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
+import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE;
+
+/**
+ * A web UI for the server.
+ *
+ * @created Jul 28, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class QueryServlet extends HttpServlet {
+
+ /** Serialization by default */
+ private static final long serialVersionUID = -8407263937557243990L;
+
+ /** The default name to use for the host. */
+ private static final String DEFAULT_HOSTNAME = "localhost";
+
+ /** Session value for database connection. */
+ private static final String CONNECTION = "session.connection";
+
+ /** Session value for interpreter. */
+ private static final String INTERPRETER = "session.interpreter";
+
+ /** The name of the host for the application. */
+ private String hostname;
+
+ /** The name of the server for the application. */
+ private String servername;
+
+ /** The server for finding a session factory. */
+ private AbstractServer server;
+
+ /** Session factory for accessing the database. */
+ private SessionFactory cachedSessionFactory;
+
+ /** The path down to the TEMPLATE resource. */
+ private String templatePath;
+
+ /** The path prefix for resources. */
+ private String resourcePath;
+
+ /** Debugging text. */
+ private String debugText = "";
+
+ /**
+ * Creates the servlet for the named host.
+ * @param hostname The host name to use, or <code>null</code> if this is not known.
+ * @param servername The name of the current server.
+ */
+ public QueryServlet(String hostname, String servername, AbstractServer server) throws IOException {
+ this.hostname = (hostname != null) ? hostname : DEFAULT_HOSTNAME;
+ this.servername = servername;
+ this.cachedSessionFactory = null;
+ this.server = server;
+ URL path = getClass().getClassLoader().getResource(ResourceFile.RESOURCES + TEMPLATE);
+ if (path == null) throw new IOException("Resource not found: " + ResourceFile.RESOURCES + TEMPLATE);
+ templatePath = path.toString();
+ resourcePath = templatePath.split("!")[0];
+ }
+
+
+ /**
+ * Respond to a request for the servlet.
+ * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ String path = req.getPathInfo();
+ debugText = path;
+ // case analysis for request type
+ String ext = getExtension(path);
+ if (ext.equals(".jpg") || ext.equals(".png") || ext.equals(".jpeg")) {
+ resp.setContentType("image/jpeg");
+ new ResourceBinaryFile(path).sendTo((OutputStream)resp.getOutputStream());
+ } else if (ext.equals(".css")) {
+ resp.setContentType("text/css");
+ new ResourceBinaryFile(path).sendTo(resp.getOutputStream());
+ } else {
+ // file request
+ resp.setContentType("text/html");
+ resp.setHeader("pragma", "no-cache");
+
+ // check for some parameters
+ String resultOrdinal = req.getParameter(RESULT_ORD_ARG);
+ String queryGetGraph = req.getParameter(MODEL_ARG);
+
+ // return the appropriate page for the given parameters
+ if (resultOrdinal != null) {
+ doNextPage(req, resp, resultOrdinal);
+ } else if (queryGetGraph != null) {
+ doQuery(req, resp, queryGetGraph);
+ } else {
+ clearOldResults(req);
+ outputStandardTemplate(resp);
+ }
+ }
+ }
+
+
+ /**
+ * Respond to a request for the servlet.
+ * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ if (!req.getPathInfo().startsWith("/" + EXECUTE_LINK)) {
+ resp.sendError(SC_BAD_REQUEST, "Sent a command to the wrong page.");
+ return;
+ }
+
+ doQuery(req, resp, req.getParameter(MODEL_ARG));
+ }
+
+
+ /**
+ * Provide a description for the servlet.
+ * @see javax.servlet.GenericServlet#getServletInfo()
+ */
+ public String getServletInfo() {
+ return "Mulgara Query UI";
+ }
+
+
+ /**
+ * Generates the standard page from the template HTML file.
+ * @param resp The object used to respond to the client.
+ * @throws IOException Caused by an error writing to the client.
+ */
+ private void outputStandardTemplate(HttpServletResponse resp) throws IOException {
+ PrintWriter out = resp.getWriter();
+ new ResourceTextFile(TEMPLATE, getTemplateTags()).sendTo(out);
+ out.close();
+ }
+
+
+ /**
+ * Execute the appropriate query, and display the results.
+ * @param req The user request.
+ * @param resp The response object for output to the user.
+ * @param graphUri The URI in a user request.
+ * @throws IOException Error sending a response to the client.
+ */
+ private void doQuery(HttpServletRequest req, HttpServletResponse resp, String graphUri) throws IOException {
+ clearOldResults(req);
+
+ // work out which commands to run
+ String command = generateCommand(req, graphUri);
+
+ // No command to run, so show the entry page
+ if (command == null || command.length() == 0) {
+ outputStandardTemplate(resp);
+ return;
+ }
+
+ // execute all the commands, and accumulate the results
+ List<Object> results = null;
+ List<Command> cmds = null;
+ long time = 0;
+ try {
+ // record how long this takes
+ time = System.currentTimeMillis();
+ final Connection c = getConnection(req);
+ cmds = getInterpreter(req).parseCommands(command);
+ results = C.map(cmds, new FnE<Command,Object,Exception>() { public Object fn(Command cmd) throws Exception { return cmd.execute(c); } });
+ time = System.currentTimeMillis() - time;
+ } catch (MulgaraParserException mpe) {
+ resp.sendError(SC_BAD_REQUEST, "Error parsing command: " + mpe.getMessage());
+ return;
+ } catch (IllegalStateException ise) {
+ resp.sendError(SC_SERVICE_UNAVAILABLE, ise.getMessage());
+ return;
+ } catch (Exception e) {
+ resp.sendError(SC_BAD_REQUEST, "Error executing command: " + StackTrace.throwableToString(e));
+ return;
+ }
+
+ // Get the tags to use in the page template
+ Map<String,String> templateTags = getTemplateTagMap();
+ templateTags.put(GRAPH_TAG, defaultGraph(graphUri));
+ // Generate the page
+ QueryResponsePage page = new QueryResponsePage(req, resp, templateTags);
+ page.writeResults(time, cmds, results);
+ }
+
+
+ /**
+ * Print out the next page of a set of results, specified by the ordinal number
+ * @param req The request environment.
+ * @param resp The response object.
+ * @param ordinalStr The result number to display the next page for.
+ * @throws IOException Error responding to the client.
+ */
+ private void doNextPage(HttpServletRequest req, HttpServletResponse resp, String ordinalStr) throws IOException {
+ // get the session/request parameters, and validate
+ Map<Answer,Pair<Long,Command>> unfinishedResults = getUnfinishedResults(req);
+ int ordinal = 0;
+ try {
+ ordinal = Integer.parseInt(ordinalStr);
+ } catch (NumberFormatException nfe) {
+ ordinal = -1;
+ }
+
+ if (ordinal <= 0 || unfinishedResults == null || ordinal > unfinishedResults.size()) {
+ resp.sendError(SC_BAD_REQUEST, "Result not available. Did you use the \"Back button\"? (result " + ordinalStr +
+ " of " + ((unfinishedResults == null) ? 0 : unfinishedResults.size()) + ")");
+ clearOldResults(req);
+ return;
+ }
+
+ // Close and remove all the results we don't need
+ Answer remaining = closeExcept(unfinishedResults.keySet(), ordinal);
+
+ // Get the tags to use in the page template
+ Map<String,String> templateTags = getTemplateTagMap();
+ templateTags.put(GRAPH_TAG, defaultGraph(req.getParameter(MODEL_ARG)));
+
+ // Generate the page
+ QueryResponsePage page = new QueryResponsePage(req, resp, templateTags);
+ page.writeResult(unfinishedResults.get(remaining).second(), remaining);
+ }
+
+
+ /**
+ * Close all but one answer.
+ * @param answers The answers to close.
+ * @param ordinal The ordinal (1-based) of the answer to NOT close.
+ * @return The Answer that did NOT get removed.
+ */
+ private Answer closeExcept(Set<Answer> answers, int ordinal) {
+ Answer excludedResult = null;
+
+ Iterator<Answer> i = answers.iterator();
+ int nrResults = answers.size();
+ for (int r = 0; r < nrResults; r++) {
+ assert i.hasNext();
+ if (r == ordinal - 1) {
+ excludedResult = i.next();
+ } else {
+ try {
+ i.next().close();
+ } catch (TuplesException e) { /* ignore */ }
+ i.remove();
+ }
+ }
+ assert !i.hasNext();
+ assert excludedResult != null;
+
+ return excludedResult;
+ }
+
+
+ /**
+ * Clears out any old results found in the session.
+ * @param req The current environment.
+ */
+ private void clearOldResults(HttpServletRequest req) {
+ Map<Answer,Pair<Long,Command>> results = getUnfinishedResults(req);
+ try {
+ if (results != null) {
+ for (Answer a: results.keySet()) a.close();
+ results.clear();
+ }
+ } catch (TuplesException e) {
+ // ignoring these problems, since the answer is being thrown away
+ }
+ }
+
+
+ /**
+ * Finds any unfinished data in the current session.
+ * @param req The current request environment.
+ * @return The unfinished results that were recorded in this session, or <code>null</code>
+ * if there were no unfinished results.
+ */
+ @SuppressWarnings("unchecked")
+ private Map<Answer,Pair<Long,Command>> getUnfinishedResults(HttpServletRequest req) {
+ Map<Answer,Pair<Long,Command>> oldResultData = (Map<Answer,Pair<Long,Command>>)req.getSession().getAttribute(UNFINISHED_RESULTS);
+ return (oldResultData == null) ? null : oldResultData;
+ }
+
+ /**
+ * Analyse the request parameters and work out what kind of query to generate.
+ * Resource and Literal queries are mutually exclusive, and both override
+ * an explicit query argument.
+ * @param req The request environment.
+ * @param graphUri The graphUri set for this request.
+ * @return The command or commands to execute.
+ */
+ private String generateCommand(HttpServletRequest req, String graphUri) {
+ String queryResource = req.getParameter(QUERY_RESOURCE_ARG);
+ if (queryResource != null) return buildResourceQuery(graphUri, queryResource);
+
+ String queryLiteral = req.getParameter(QUERY_LITERAL_ARG);
+ if (queryLiteral != null) return buildLiteralQuery(graphUri, queryLiteral);
+
+ return req.getParameter(QUERY_TEXT_ARG);
+ }
+
+
+ /**
+ * Get a query string to display a resource.
+ * @param graph The name of the graph to get the resource from.
+ * @param resource The name of the resource.
+ * @return The query string.
+ */
+ private String buildResourceQuery(String graph, String resource) {
+ StringBuilder urlString = new StringBuilder("select $Predicate $Object from <");
+ urlString.append(graph).append("> where <").append(resource).append("> $Predicate $Object;");
+ urlString.append("select $Subject $Predicate from <").append(graph);
+ urlString.append("> where $Subject $Predicate <").append(resource).append(">;");
+ urlString.append("select $Subject $Object from <").append(graph);
+ urlString.append("> where $Subject <").append(resource).append("> $Object;");
+ return urlString.toString();
+ }
+
+
+ /**
+ * Get a query string to display a literal.
+ * @param graph The name of the graph to get the resource from.
+ * @param literal The value of the literal.
+ * @return The query string.
+ */
+ private String buildLiteralQuery(String graph, String literal) {
+ return "select $Subject $Predicate from <" + graph + "> where $Subject $Predicate " + literal + ";";
+ }
+
+
+ /**
+ * Takes each of the template tags and creates a map out of them.
+ * @return A map of all tags to the data to replace them.
+ */
+ private Map<String,String> getTemplateTagMap() {
+ Map<String,String> tagMap = new HashMap<String,String>();
+ String[][] source = getTemplateTags();
+ for (String[] tag: source) tagMap.put(tag[0], tag[1]);
+ return tagMap;
+ }
+
+
+ /**
+ * Gets the list of tags to be replaced in a template document, along with the values
+ * to replace them with.
+ * @return An array of string pairs. The first string in the pair is the tag to replace,
+ * the second string is the value to repace the tag with.
+ */
+ private String[][] getTemplateTags() {
+ return new String[][] {
+ new String[] {HOSTNAME_TAG, hostname},
+ new String[] {SERVERNAME_TAG, servername},
+ new String[] {JARURL_TAG, resourcePath},
+ new String[] {EXECUTE_TAG, EXECUTE_LINK},
+ new String[] {DEBUG_TAG, debugText},
+ };
+ }
+
+
+ /**
+ * Creates the default graph name for the sample data.
+ * @param The graph name that the user has already set.
+ * @return The default graph name to use when no graph has been set.
+ */
+ private String defaultGraph(String graphParam) {
+ if (graphParam != null && graphParam.length() > 0) return graphParam;
+ return "rmi://" + hostname + "/" + servername + "#sampledata";
+ }
+
+
+ /**
+ * Gets the interpreter for the current session, creating it if it doesn't exist yet.
+ * @param req The current request environment.
+ * @return A connection that is tied to this HTTP session.
+ */
+ private Interpreter getInterpreter(HttpServletRequest req) {
+ HttpSession httpSession = req.getSession();
+ Interpreter interpreter = (Interpreter)httpSession.getAttribute(INTERPRETER);
+ if (interpreter == null) {
+ interpreter = new TqlInterpreter();
+ httpSession.setAttribute(INTERPRETER, interpreter);
+ }
+ return interpreter;
+ }
+
+
+ /**
+ * Gets the connection for the current session, creating it if it doesn't exist yet.
+ * @param req The current request environment.
+ * @return A connection that is tied to this HTTP session.
+ * @throws IOException When an error occurs creating a new session.
+ */
+ private Connection getConnection(HttpServletRequest req) throws IOException, IllegalStateException {
+ HttpSession httpSession = req.getSession();
+ Connection connection = (Connection)httpSession.getAttribute(CONNECTION);
+ if (connection == null) {
+ try {
+ connection = new SessionConnection(getSessionFactory().newSession(), null, null);
+ } catch (QueryException qe) {
+ throw new IOException("Unable to create a connection to the database. " + qe.getMessage());
+ }
+ httpSession.setAttribute(CONNECTION, connection);
+ }
+ return connection;
+ }
+
+
+ /**
+ * This method allows us to put off getting a session factory until the server is
+ * ready to provide one.
+ * @return A new session factory.
+ */
+ private SessionFactory getSessionFactory() throws IllegalStateException {
+ if (cachedSessionFactory == null) {
+ cachedSessionFactory = server.getSessionFactory();
+ if (cachedSessionFactory == null) throw new IllegalStateException("Server not yet ready. Try again soon.");
+ }
+ return cachedSessionFactory;
+ }
+
+
+ /**
+ * 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.
+ */
+ private String getExtension(String path) {
+ int dot = path.lastIndexOf('.');
+ if (dot < 0) return "";
+ return path.substring(dot);
+ }
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/RequestException.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/RequestException.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/RequestException.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,43 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery;
+
+/**
+ * An internal exception for communicating issues that need to be sent out as HTTP responses.
+ *
+ * @created Aug 7, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class RequestException extends Exception {
+
+ /** The generated serialization ID. */
+ private static final long serialVersionUID = 1578918131388079524L;
+
+ /**
+ * @param message The description of the problem.
+ */
+ public RequestException(String message) {
+ super(message);
+ }
+
+ /**
+ * @param message The description of the problem.
+ * @param cause A throwable that caused the problem.
+ */
+ public RequestException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/ResourceBinaryFile.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/ResourceBinaryFile.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/ResourceBinaryFile.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,102 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+
+import javax.servlet.ServletOutputStream;
+
+/**
+ * Loads a resource file, and sends the results to an output stream.
+ * This object closes any streams it receives, since any files written to those
+ * streams are "binary" and are therefore considered complete.
+ *
+ * @created Aug 1, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class ResourceBinaryFile extends ResourceFile {
+
+ /** The default buffer size is 10K. */
+ private static final int BUFFER_SIZE = 10240;
+
+ /** The buffer size to use. */
+ private int bufferSize = BUFFER_SIZE;
+
+ /**
+ * Loads a binary resource file.
+ * @param resourceFile The path of the resource to load.
+ */
+ public ResourceBinaryFile(String resourceFile) {
+ super(resourceFile);
+ }
+
+ /**
+ * Loads a binary resource file.
+ * @param resourceFile The path of the resource to load.
+ */
+ public ResourceBinaryFile(String resourceFile, int bufferSize) {
+ super(resourceFile);
+ this.bufferSize = bufferSize;
+ }
+
+ /**
+ * Sets the buffer size to use when reading/writing resource files.
+ * @param bufferSize The new buffer size to use, in bytes.
+ */
+ public void setBufferSize(int bufferSize) {
+ this.bufferSize = bufferSize;
+ }
+
+ /**
+ * Sends the resource to a given output.
+ * @param out The output that will receive the file.
+ * @return The provided OutputStream.
+ */
+ public OutputStream sendTo(OutputStream out) throws IOException {
+ InputStream in = getStream();
+ try {
+ if (in == null) return out;
+ byte[] buffer = new byte[bufferSize];
+ int r;
+ while ((r = in.read(buffer)) != -1) out.write(buffer, 0, r);
+ } finally {
+ in.close();
+ out.close();
+ }
+ return out;
+ }
+
+ /**
+ * Sends the resource to a given output, using text transfers.
+ * @param out The output that will receive the file.
+ * @return The provided ServletOutputStream.
+ */
+ public ServletOutputStream sendTextTo(ServletOutputStream out) throws IOException {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(getStream()));
+ try {
+ String line;
+ while ((line = reader.readLine()) != null) out.println(line);
+ } finally {
+ reader.close();
+ out.close();
+ }
+ return out;
+ }
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/ResourceFile.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/ResourceFile.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/ResourceFile.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,31 @@
+package org.mulgara.webquery;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public abstract class ResourceFile {
+
+ /** The location of resource files. */
+ static final String RESOURCES = "resources";
+
+ /** The path of the resource file to load. */
+ protected String resourceFile;
+
+ /**
+ * Create the ResourceFile.
+ * @param resourceFile The path to the resource file.
+ */
+ ResourceFile(String resourceFile) {
+ this.resourceFile = RESOURCES + resourceFile;
+ }
+
+ /**
+ * Get the data from the resource file as a stream.
+ * @return An InputStream for accessing the resource file.
+ */
+ protected InputStream getStream() throws IOException {
+ InputStream in = getClass().getClassLoader().getResourceAsStream(resourceFile);
+ if (in == null) throw new IOException("Unable to load resource: " + resourceFile);
+ return in;
+ }
+}
\ No newline at end of file
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/ResourceTextFile.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/ResourceTextFile.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/ResourceTextFile.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,133 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.mulgara.util.StackTrace;
+
+/**
+ * Loads a resource file, replaces any tags, and sends the results to an output stream.
+ *
+ * @created Aug 1, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class ResourceTextFile extends ResourceFile {
+
+ /** The marker for tags in a resource file. */
+ private static final String MARKER = "@@";
+
+ /** A mapping of tags in the file to their replacement text. */
+ Map<String,String> tagMap;
+
+ /**
+ * Loads a text file with no tag replacement.
+ * @param resourceFile The path of the resource to load.
+ */
+ public ResourceTextFile(String resourceFile) {
+ super(resourceFile);
+ tagMap = Collections.emptyMap();
+ }
+
+ /**
+ * Loads a text file with a map for replacing tags.
+ * @param resourceFile The path of the resource to load.
+ * @param tagMap A mapping of tags to their replacement text.
+ */
+ public ResourceTextFile(String resourceFile, Map<String,String> tagMap) {
+ super(resourceFile);
+ setTags(tagMap);
+ }
+
+ /**
+ * Loads a text file with a map for replacing tags.
+ * @param resourceFile The path of the resource to load.
+ * @param tagMap Pairs of tagging strings to the values they are to be replaced with.
+ */
+ public ResourceTextFile(String resourceFile, String[][] tagMap) {
+ super(resourceFile);
+ setTags(tagMap);
+ }
+
+ /**
+ * Set the tags and the values they map to.
+ * @param tagMap A map of simple tag strings to the values they are to be replaced with.
+ * @return The current object.
+ */
+ public ResourceFile setTags(Map<String,String> tagMap) {
+ this.tagMap = new HashMap<String,String>();
+ for (Map.Entry<String,String> tag: tagMap.entrySet()) {
+ this.tagMap.put(MARKER + tag.getKey() + MARKER, tag.getValue());
+ }
+ return this;
+ }
+
+ /**
+ * Set the tags and the values they map to.
+ * @param tagPairs Pairs of tagging strings to the values they are to be replaced with.
+ * @return The current object.
+ */
+ public ResourceFile setTags(String[][] tagPairs) {
+ tagMap = new HashMap<String,String>();
+ for (String[] tag: tagPairs) {
+ if (tag.length != 2) throw new IllegalArgumentException("Require pairs of values for mapping tags. Got " + tag.length + " values.");
+ tagMap.put(MARKER + tag[0] + MARKER, tag[1]);
+ }
+ return this;
+ }
+
+ /**
+ * Sends the resource to a print writer after replacing all detected tags.
+ * @param out The PrintWriter that will receive the file.
+ * @return The provided PrintWriter.
+ */
+ public PrintWriter sendTo(PrintWriter out) throws IOException {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(getStream()));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ for (Map.Entry<String,String> tag: tagMap.entrySet()) line = line.replaceAll(tag.getKey(), tag.getValue());
+ out.println(line);
+ }
+ reader.close();
+ return out;
+ }
+
+ /**
+ * Loads the resource, replaces any detected tags, and returns the result as a string.
+ * @return The string containing the resource, with all known tags replaced.
+ * @throws IOException The resource could not be read.
+ */
+ public String toString() {
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(getStream()));
+ StringBuilder buffer = new StringBuilder(reader.readLine());
+ String line;
+ while ((line = reader.readLine()) != null) {
+ for (Map.Entry<String,String> tag: tagMap.entrySet()) line = line.replaceAll(tag.getKey(), tag.getValue());
+ buffer.append(line).append("\n");
+ }
+ reader.close();
+ return buffer.toString();
+ } catch (IOException ioe) {
+ return StackTrace.throwableToString(ioe);
+ }
+ }
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/Template.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/Template.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/Template.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,85 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery;
+
+/**
+ * Contains data for the template responses.
+ *
+ * @created Aug 4, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class Template {
+
+ /** Session variable for the set of results that have not been finished. */
+ public static final String UNFINISHED_RESULTS = "unfinishedRsults";
+
+ /** The name of the template HTML file. */
+ public static final String TEMPLATE = "/template.html";
+
+ /** The name of the HTML file containing the head of a result. */
+ public static final String TEMPLATE_HEAD = "/template_head.html";
+
+ /** The name of the HTML file containing the tail of a result. */
+ public static final String TEMPLATE_TAIL = "/template_tail.html";
+
+ /** The tag to replace in the the template file for the host name. */
+ public static final String HOSTNAME_TAG = "hostname";
+
+ /** The tag to replace in the the template file for the server name. */
+ public static final String SERVERNAME_TAG = "servername";
+
+ /** The tag to replace in the the template file for the jar file path. */
+ public static final String JARURL_TAG = "jarurl";
+
+ /** The tag to replace in the the template file for the execute link. */
+ public static final String EXECUTE_TAG = "execute";
+
+ /** The tag to replace in the the template file for debugging info. */
+ public static final String DEBUG_TAG = "debug";
+
+ /** The tag to replace in the template file for the user-set graph URI. */
+ public static final String GRAPH_TAG = "graph";
+
+ /** The amount of indenting to use for the rows in the template. */
+ public static final int ROW_INDENT = 8;
+
+ /** The link used for executing a query. */
+ public static final String EXECUTE_LINK = "ExecuteQuery";
+
+ /** The name of the field holding the query text to execute. */
+ public static final String QUERY_TEXT_ARG = "QueryText";
+
+ /** The ModelURI argument for URL parameters. */
+ public static final String MODEL_ARG = "ModelURI";
+
+ /** The QueryResource argument for URL parameters. */
+ public static final String QUERY_RESOURCE_ARG = "QueryResource";
+
+ /** The QueryLiteral argument for URL parameters. */
+ public static final String QUERY_LITERAL_ARG = "QueryLiteral";
+
+ /** The ResultOrdinal argument for URL parameters. */
+ public static final String RESULT_ORD_ARG = "ResultOrdinal";
+
+ /** 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";
+
+ /** A CSS label for cells holding a result table. */
+ public static final String CSS_RESULT_TABLE_CELL = "resultTableCell";
+
+ /** A CSS label for a result table. */
+ public static final String CSS_RESULT_TABLE = "resultTable";
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/html/Anchor.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/html/Anchor.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/html/Anchor.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,166 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery.html;
+
+import java.net.URI;
+import java.net.URL;
+
+/**
+ * Represents an Anchor element. The constructors expect an HREF or a name.
+ * The constructors ar duplicated between URL and URI parameters, as URL
+ * objects do not hold relative URLs, while URIs can.
+ *
+ * @created Aug 4, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class Anchor extends HtmlElement {
+
+ /**
+ * Creates an anchor with a given indent.
+ * @param indent The amount to indent by.
+ * @param ref The reference to point to.
+ * @param subElements The list of subElements to embed. Probably just a {@link Text}
+ */
+ public Anchor(int indent, URL ref, HtmlElement... subElements) {
+ super(indent, subElements);
+ this.addAttr(Attr.HREF, ref);
+ }
+
+
+ /**
+ * Creates an anchor with no indenting.
+ * @param ref The reference to point to.
+ * @param subElements The list of subElements to embed. Probably just a {@link Text}
+ */
+ public Anchor(URL ref, HtmlElement... subElements) {
+ this(-1, ref, subElements);
+ }
+
+
+ /**
+ * Creates an anchor with a given indent.
+ * @param indent The amount to indent by.
+ * @param ref The reference to point to.
+ * @param subElements The list of subElements to embed. Probably just a {@link Text}
+ */
+ public Anchor(int indent, URI ref, HtmlElement... subElements) {
+ super(indent, subElements);
+ this.addAttr(Attr.HREF, ref);
+ }
+
+
+ /**
+ * Creates an anchor with no indenting.
+ * @param ref The reference to point to.
+ * @param subElements The list of subElements to embed. Probably just a {@link Text}
+ */
+ public Anchor(URI ref, HtmlElement... subElements) {
+ this(-1, ref, subElements);
+ }
+
+
+ /**
+ * Creates an anchor with a given indent, and a list of sub elements.
+ * @param indent The amount to indent by.
+ * @param name The name of the anchor.
+ * @param subElements a list of sub elements inside this anchor.
+ */
+ public Anchor(int indent, String name, HtmlElement... subElements) {
+ super(indent, subElements);
+ this.addAttr(Attr.NAME, name);
+ }
+
+
+ /**
+ * Creates an anchor with no initial indenting, and a list of sub elements.
+ * @param name The name of the anchor.
+ * @param subElements a list of sub elements inside this anchor.
+ */
+ public Anchor(String name, HtmlElement... subElements) {
+ this(-1, name, subElements);
+ }
+
+
+ /**
+ * Creates an anchor with a given indent, and the text for a subelement.
+ * @param indent The amount to indent by.
+ * @param name The name of the anchor.
+ * @param test The text for a Text subElement.
+ */
+ public Anchor(int indent, String name, String text) {
+ super(indent, new Text(text));
+ this.addAttr(Attr.NAME, name);
+ }
+
+
+ /**
+ * Creates an anchor with no initial indenting, and the text for a subelement.
+ * @param name The name of the anchor.
+ * @param test The text for a Text subElement.
+ */
+ public Anchor(String name, String text) {
+ this(-1, name, new Text(text));
+ }
+
+
+ /**
+ * Creates an anchor with a given indent, and the text for a subelement.
+ * @param indent The amount to indent by.
+ * @param ref The reference to point to.
+ * @param test The text for a Text subElement.
+ */
+ public Anchor(int indent, URL ref, String text) {
+ super(indent, new Text(text));
+ this.addAttr(Attr.HREF, ref);
+ }
+
+
+ /**
+ * Creates an anchor with no initial indenting, the text for a subelement.
+ * @param ref The reference to point to.
+ * @param test The text for a Text subElement.
+ */
+ public Anchor(URL ref, String text) {
+ this(-1, ref, new Text(text));
+ }
+
+
+ /**
+ * Creates an anchor with a given indent, and the text for a subelement.
+ * @param indent The amount to indent by.
+ * @param ref The reference to point to.
+ * @param test The text for a Text subElement.
+ */
+ public Anchor(int indent, URI ref, String text) {
+ super(indent, new Text(text));
+ this.addAttr(Attr.HREF, ref);
+ }
+
+
+ /**
+ * Creates an anchor with no initial indenting, and the text for a subelement.
+ * @param ref The reference to point to.
+ * @param test The text for a Text subElement.
+ */
+ public Anchor(URI ref, String text) {
+ this(-1, ref, new Text(text));
+ }
+
+
+ protected String getTag() {
+ return "a";
+ }
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/html/Break.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/html/Break.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/html/Break.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,66 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery.html;
+
+/**
+ * Represents a line break.
+ *
+ * @created Aug 4, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class Break extends HtmlElement {
+
+ /**
+ * Creates a line break with a given indent.
+ * @param indent The amount to indent by.
+ */
+ public Break(int indent) {
+ super(indent);
+ }
+
+
+ /**
+ * Creates a line break with no indenting.
+ */
+ Break() {
+ this(0);
+ }
+
+ /**
+ * @throws UnsupportedOperationException As sub elements are not possible for this element.
+ * @see org.mulgara.webquery.html.HtmlElement#add(org.mulgara.webquery.html.HtmlElement)
+ */
+ public HtmlElement add(HtmlElement elt) {
+ throw new UnsupportedOperationException("Line breaks do not have sub elements.");
+ }
+
+
+ /**
+ * @see org.mulgara.webquery.html.HtmlElement#addAttr(org.mulgara.webquery.html.HtmlElement.Attr, java.lang.String)
+ */
+ public HtmlElement addAttr(Attr attr, String val) {
+ if (attr != Attr.ID && attr != Attr.CLASS && attr != Attr.STYLE && attr != Attr.TITLE) {
+ throw new UnsupportedOperationException("Line breaks do not have attributes.");
+ }
+ return super.addAttr(attr, val);
+ }
+
+
+
+ protected String getTag() {
+ return "br";
+ }
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/html/Div.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/html/Div.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/html/Div.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,72 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery.html;
+
+/**
+ * Represents a div element. This implementation always uses an id attribute.
+ *
+ * @created Aug 4, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class Div extends HtmlElement {
+
+ /**
+ * Creates a div with a given indent.
+ * @param indent The amount to indent by.
+ * @param id The name of the id for the div.
+ */
+ public Div(int indent, String id) {
+ super(indent);
+ this.addAttr(Attr.CLASS, id);
+ }
+
+
+ /**
+ * Creates a div with no indenting.
+ * @param id The name of the id for the div.
+ */
+ Div(String id) {
+ this(0, id);
+ }
+
+
+ /**
+ * Creates a div with a given indent, and a list of sub elements.
+ * @param indent The amount to indent by.
+ * @param id The name of the id for the div.
+ * @param subElements a list of sub elements inside this div.
+ */
+ Div(int indent, String id, HtmlElement... subElements) {
+ super(indent, subElements);
+ this.addAttr(Attr.CLASS, id);
+ }
+
+
+ /**
+ * Creates a div with no initial indenting, and a list of sub elements.
+ * @param id The name of the id for the div.
+ * @param subElements a list of sub elements inside this div.
+ */
+ Div(String id, HtmlElement... subElements) {
+ this(0, id, subElements);
+ }
+
+
+ /** @see org.mulgara.webquery.html.HtmlElement#getTag() */
+ protected String getTag() {
+ return "div";
+ }
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/html/Emphasis.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/html/Emphasis.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/html/Emphasis.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,55 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery.html;
+
+/**
+ * Represents an emphasis element.
+ *
+ * @created Aug 4, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class Emphasis extends HtmlElement {
+
+ /**
+ * Creates an emphasis element.
+ */
+ public Emphasis() {
+ super(-1);
+ }
+
+
+ /**
+ * Creates an emphasis element with embedded text.
+ * @param text The text to embed.
+ */
+ public Emphasis(String text) {
+ super(-1, new Text(text));
+ }
+
+
+ /**
+ * Always returns false, indicating that formatting is never used on this element.
+ * @see org.mulgara.webquery.html.HtmlElement#shouldIndent()
+ */
+ protected boolean shouldIndent() {
+ return false;
+ }
+
+
+ protected String getTag() {
+ return "em";
+ }
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/html/HtmlElement.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/html/HtmlElement.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/html/HtmlElement.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,228 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery.html;
+
+import java.io.PrintWriter;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.mulgara.util.C;
+
+/**
+ * Represents an HTML element that can be written to an output stream.
+ * Indents are hard coded to 2 characters.
+ *
+ * @created Aug 4, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public abstract class HtmlElement {
+
+ /** The amount to indent by. */
+ private static final String INDENT_CHARS = " ";
+
+ /** The number of indents to use for this element. */
+ protected int indent;
+
+ /** The current indent string, where indentStr = {@link #INDENT_CHARS}*{@link #indent}. */
+ private String indentStr;
+
+ /** The list of elements under this element */
+ protected List<HtmlElement> subElements;
+
+ /** The attributes for this element */
+ protected Map<Attr,String> attributes;
+
+ /** A limited list of attributes. Expand on this as required. */
+ public enum Attr {
+ CLASS,
+ ID,
+ STYLE,
+ TITLE,
+ NAME,
+ HEIGHT,
+ WIDTH,
+ SIZE,
+ ALIGN,
+ VALIGN,
+ BORDER,
+ CELLPADDING,
+ CELLSPACING,
+ COLS,
+ ROWS,
+ COLSPAN,
+ ALT,
+ HREF,
+ SELECTED,
+ VALUE,
+ METHOD,
+ SUMMARY;
+
+ public String toString() { return this.name().toLowerCase(); };
+ };
+
+ /** A limited list of entities. Expand on this as required. */
+ public enum Entity {
+ AMP("&"),
+ GT(">"),
+ LT("<"),
+ QUOT("""),
+ APOS("'"), // ' does not work in IE
+ NBSP(" ");
+
+ private final String t;
+ private Entity(String t) { this.t = t; }
+ public String toString() { return t; }
+ };
+
+ /**
+ * Creates an empty element with a given indent.
+ * @param indent The amount to indent by.
+ */
+ HtmlElement(int indent) {
+ this.indent = indent;
+ indentStr = generateIndent(indent);
+ subElements = new LinkedList<HtmlElement>();
+ attributes = new LinkedHashMap<Attr,String>();
+ }
+
+
+ /**
+ * Creates an empty element with no initial indenting.
+ */
+ HtmlElement() {
+ this(0);
+ }
+
+
+ /**
+ * Creates an element with a given indent, and a list of sub-elements.
+ * @param indent The amount to indent by.
+ * @param subElements a list of elements directly subordinate to this element.
+ */
+ HtmlElement(int indent, HtmlElement... subElements) {
+ this(indent);
+ for (HtmlElement e: subElements) add(e);
+ }
+
+
+ /**
+ * Creates an empty element with no indenting.
+ * @param subElements a list of elements directly subordinate to this element.
+ */
+ HtmlElement(HtmlElement... subElements) {
+ this(0, subElements);
+ }
+
+
+ /**
+ * Adds a sub element to the end of the list of sub elements for this element.
+ * @param elt The new sub element to be added.
+ * @return The current element.
+ */
+ public HtmlElement add(HtmlElement elt) {
+ subElements.add(elt);
+ elt.setIndent(indent < 0 ? indent : indent + 1);
+ return this;
+ }
+
+
+ /**
+ * Adds an attribute to the set of attributes. This will replace any existing values
+ * for this attribute.
+ * @param attr The attribute to add.
+ * @param val The value for the attribute.
+ * @return The current element.
+ */
+ public HtmlElement addAttr(Attr attr, Object val) {
+ attributes.put(attr, val.toString());
+ return this;
+ }
+
+
+ /**
+ * This method sends the given text to the output stream.
+ * For indented text, this is always called when a new line has just been started.
+ * The method always finishes while at the end of a line.
+ * @param out the writer to send the HTML to.
+ */
+ public void sendTo(PrintWriter out) {
+ if (shouldIndent()) out.append(indentStr);
+ out.append('<').append(getTag());
+ for (Map.Entry<Attr,String> attr: attributes.entrySet()) out.append(' ').append(attr.getKey().toString()).append("=\"").append(attr.getValue()).append('\"');
+ if (subElements.isEmpty()) {
+ // no sub elements, so close the tag
+ out.append("/>");
+ } else {
+ out.append('>');
+ // iterate over the sub elements
+ for (HtmlElement e: subElements) {
+ if (e.shouldIndent()) out.append('\n');
+ e.sendTo(out);
+ }
+ if (C.tail(subElements).shouldIndent()) out.append('\n').append(indentStr);
+ out.append("</").append(getTag()).append('>');
+ }
+ }
+
+
+ /**
+ * Tests if this element should be indented in the current output.
+ * @return <code>true</code> if indenting should occur.
+ */
+ protected boolean shouldIndent() {
+ return indentStr != null;
+ }
+
+
+ /**
+ * Sets the indent of this element. Used by the parent.
+ * @param indent The new indent to use.
+ */
+ private void setIndent(int indent) {
+ this.indent = indent;
+ if (indent < 0) {
+ indentStr = null;
+ for (HtmlElement e: subElements) e.setIndent(indent);
+ } else {
+ indentStr = generateIndent(indent);
+ for (HtmlElement e: subElements) e.setIndent(indent + 1);
+ }
+ }
+
+
+ /**
+ * Create a string of spaces for indenting.
+ * @param i The number of indents to use.
+ * @return A string of spaces, equal to i * {@link #INDENT_CHARS}, or <code>null</code>
+ * if i < 0.
+ */
+ private static String generateIndent(int i) {
+ if (i < 0) return null;
+ StringBuilder s = new StringBuilder();
+ while (--i > 0) s.append(INDENT_CHARS);
+ return s.toString();
+ }
+
+
+ /**
+ * Any implementing classes must implement this method to create the text representation
+ * of the tag in the emitted HTML.
+ * @return The string for this element.
+ */
+ protected abstract String getTag();
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/html/Paragraph.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/html/Paragraph.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/html/Paragraph.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,65 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery.html;
+
+/**
+ * Represents a paragraph element.
+ *
+ * @created Aug 4, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class Paragraph extends HtmlElement {
+
+ /**
+ * Creates a paragraph with a given indent.
+ * @param indent The amount to indent by.
+ */
+ public Paragraph(int indent) {
+ super(indent);
+ }
+
+
+ /**
+ * Creates a paragraph with no indenting.
+ */
+ Paragraph() {
+ this(-1);
+ }
+
+
+ /**
+ * Creates a paragraph with a given indent, and a list of sub elements.
+ * @param indent The amount to indent by.
+ * @param subElements a list of sub elements inside this paragraph.
+ */
+ Paragraph(int indent, HtmlElement... subElements) {
+ super(indent, subElements);
+ }
+
+
+ /**
+ * Creates a paragraph with no initial indenting, and a list of sub elements.
+ * @param subElements a list of sub elements inside this paragraph.
+ */
+ Paragraph( HtmlElement... subElements) {
+ this(-1, subElements);
+ }
+
+
+ protected String getTag() {
+ return "p";
+ }
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/html/Span.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/html/Span.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/html/Span.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,93 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery.html;
+
+/**
+ * Represents a span element. This implementation always uses a class attribute.
+ *
+ * @created Aug 4, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class Span extends HtmlElement {
+
+ /**
+ * Creates a span with a given indent.
+ * @param indent The amount to indent by.
+ * @param spanClass The name of the class for the span.
+ */
+ public Span(int indent, String spanClass) {
+ super(indent);
+ this.addAttr(Attr.CLASS, spanClass);
+ }
+
+
+ /**
+ * Creates a span with no indenting.
+ * @param spanClass The name of the class for the span.
+ */
+ public Span(String spanClass) {
+ this(-1, spanClass);
+ }
+
+
+ /**
+ * Creates a span with a given indent, and a list of sub elements.
+ * @param indent The amount to indent by.
+ * @param spanClass The name of the class for the span.
+ * @param subElements a list of sub elements inside this span.
+ */
+ public Span(int indent, String spanClass, HtmlElement... subElements) {
+ super(indent, subElements);
+ this.addAttr(Attr.CLASS, spanClass);
+ }
+
+
+ /**
+ * Creates a span with no initial indenting, and a list of sub elements.
+ * @param spanClass The name of the class for the span.
+ * @param subElements a list of sub elements inside this span.
+ */
+ public Span(String spanClass, HtmlElement... subElements) {
+ this(-1, spanClass, subElements);
+ }
+
+
+ /**
+ * Creates a span with a given indent, and a list of sub elements.
+ * @param indent The amount to indent by.
+ * @param spanClass The name of the class for the span.
+ * @param test The text for a Text subElement.
+ */
+ public Span(int indent, String spanClass, String text) {
+ super(indent, new Text(text));
+ this.addAttr(Attr.CLASS, spanClass);
+ }
+
+
+ /**
+ * Creates a span with no initial indenting, and a list of sub elements.
+ * @param spanClass The name of the class for the span.
+ * @param test The text for a Text subElement.
+ */
+ public Span(String spanClass, String text) {
+ this(-1, spanClass, new Text(text));
+ }
+
+
+ protected String getTag() {
+ return "span";
+ }
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/html/Strong.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/html/Strong.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/html/Strong.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,55 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery.html;
+
+/**
+ * Represents a strong element.
+ *
+ * @created Aug 4, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class Strong extends HtmlElement {
+
+ /**
+ * Creates an empty strong element.
+ */
+ public Strong() {
+ super(-1);
+ }
+
+
+ /**
+ * Creates a strong element with embedded text.
+ * @param text The text to embed.
+ */
+ public Strong(String text) {
+ super(-1, new Text(text));
+ }
+
+
+ /**
+ * Always returns false, indicating that formatting is never used on this element.
+ * @see org.mulgara.webquery.html.HtmlElement#shouldIndent()
+ */
+ protected boolean shouldIndent() {
+ return false;
+ }
+
+
+ protected String getTag() {
+ return "strong";
+ }
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/html/Table.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/html/Table.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/html/Table.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,78 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery.html;
+
+/**
+ * Represents a table.
+ *
+ * @created Aug 4, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class Table extends TableAbstr {
+
+ /**
+ * Creates a table with a given indent.
+ * @param indent The amount to indent by.
+ */
+ public Table(int indent) {
+ super(indent);
+ }
+
+
+ /**
+ * Creates a table with no indenting.
+ */
+ public Table() {
+ super();
+ }
+
+
+ /**
+ * Creates a table with a given indent, and a list of sub elements.
+ * @param indent The amount to indent by.
+ * @param subElements a list of sub elements inside this table.
+ */
+ public Table(int indent, HtmlElement... subElements) {
+ super(indent, subElements);
+ }
+
+
+ /**
+ * Creates a table with no initial indenting, and a list of sub elements.
+ * @param subElements a list of sub elements inside this table.
+ */
+ public Table(HtmlElement... subElements) {
+ super(subElements);
+ }
+
+
+ /**
+ * Adds a table element to the end of the list of table elements for this table.
+ * @param elt The new element to be added.
+ * @return The current table.
+ * @throws IllegalArgumentException If elt is anything other than a table structure.
+ */
+ public HtmlElement add(HtmlElement elt) {
+ if (elt instanceof Table) throw new IllegalArgumentException("Tables can only be embedded in cell, not directly into table elements");
+ return super.add(elt);
+ }
+
+
+ /** @see org.mulgara.webquery.html.HtmlElement#getTag() */
+ protected String getTag() {
+ return "table";
+ }
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableAbstr.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableAbstr.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableAbstr.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,100 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery.html;
+
+/**
+ * An abstraction of a table.
+ *
+ * @created Aug 4, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public abstract class TableAbstr extends HtmlElement implements TableStructure {
+
+ /** The width of this table structure */
+ private int width = 0;
+
+
+ /**
+ * Creates a table with a given indent.
+ * @param indent The amount to indent by.
+ */
+ TableAbstr(int indent) {
+ super(indent);
+ }
+
+
+ /**
+ * Creates a table with no indenting.
+ */
+ TableAbstr() {
+ this(0);
+ }
+
+
+ /**
+ * Creates a table with a given indent, and a list of sub elements.
+ * @param indent The amount to indent by.
+ * @param subElements a list of sub elements inside this table cell.
+ */
+ TableAbstr(int indent, HtmlElement... subElements) {
+ super(indent, subElements);
+ for (HtmlElement e: subElements) if (e instanceof TableStructure) updateWidth((TableStructure)e);
+ }
+
+
+ /**
+ * Creates a table body with no initial indenting, and a list of sub elements.
+ * @param subElements a list of sub elements inside this table cell.
+ */
+ TableAbstr(HtmlElement... subElements) {
+ this(0, subElements);
+ }
+
+
+ /**
+ * Adds a table element to the end of the list of table elements for this table.
+ * @param elt The new element to be added.
+ * @return The current table.
+ * @throws IllegalArgumentException If elt is anything other than a table structure.
+ */
+ public HtmlElement add(HtmlElement elt) {
+ if (!(elt instanceof TableStructure)) throw new IllegalArgumentException("Tables can only add table structural elements");
+ updateWidth((TableStructure)elt);
+ return super.add(elt);
+ }
+
+
+ /**
+ * Gets the width of this table body.
+ * @return The maximum width in this table structure.
+ */
+ public int getWidth() {
+ return width;
+ }
+
+
+ /** @see org.mulgara.webquery.html.HtmlElement#getTag() */
+ abstract protected String getTag();
+
+
+ /**
+ * Update the width of this structure to its widest element.
+ * @param s A new element that has been added.
+ */
+ private void updateWidth(TableStructure s) {
+ int w = s.getWidth();
+ if (w > width) width = w;
+ }
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableBody.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableBody.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableBody.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,78 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery.html;
+
+/**
+ * Represents a table body.
+ *
+ * @created Aug 4, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class TableBody extends TableAbstr {
+
+ /**
+ * Creates a table body with a given indent.
+ * @param indent The amount to indent by.
+ */
+ public TableBody(int indent) {
+ super(indent);
+ }
+
+
+ /**
+ * Creates a table body with no indenting.
+ */
+ public TableBody() {
+ super();
+ }
+
+
+ /**
+ * Creates a table body with a given indent, and a list of sub elements.
+ * @param indent The amount to indent by.
+ * @param subElements a list of sub elements inside this table cell.
+ */
+ public TableBody(int indent, HtmlElement... subElements) {
+ super(indent, subElements);
+ }
+
+
+ /**
+ * Creates a table body with no initial indenting, and a list of sub elements.
+ * @param subElements a list of sub elements inside this table cell.
+ */
+ public TableBody(HtmlElement... subElements) {
+ super(subElements);
+ }
+
+
+ /**
+ * Adds a table element to the end of the list of table elements for this table.
+ * @param elt The new element to be added.
+ * @return The current table.
+ * @throws IllegalArgumentException If elt is anything other than a table structure.
+ */
+ public HtmlElement add(HtmlElement elt) {
+ if (!(elt instanceof TableRow)) throw new IllegalArgumentException("Table bodies can only add table rows");
+ return super.add(elt);
+ }
+
+
+ /** @see org.mulgara.webquery.html.HtmlElement#getTag() */
+ protected String getTag() {
+ return "tbody";
+ }
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableData.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableData.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableData.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,85 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery.html;
+
+/**
+ * Represents data in a table.
+ *
+ * @created Aug 4, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class TableData extends HtmlElement {
+
+ /**
+ * Creates a data element with a given indent.
+ * @param indent The amount to indent by.
+ */
+ public TableData(int indent) {
+ super(indent);
+ }
+
+
+ /**
+ * Creates a data element with no indenting.
+ */
+ public TableData() {
+ this(0);
+ }
+
+
+ /**
+ * Creates a data element with a given indent, and a list of sub elements.
+ * @param indent The amount to indent by.
+ * @param subElements a list of sub elements inside this table cell.
+ */
+ public TableData(int indent, HtmlElement... subElements) {
+ super(indent, subElements);
+ }
+
+
+ /**
+ * Creates a data element with no initial indenting, and a list of sub elements.
+ * @param subElements a list of sub elements inside this table cell.
+ */
+ public TableData(HtmlElement... subElements) {
+ this(0, subElements);
+ }
+
+
+ /**
+ * Creates a data element with a given indent, and embedded text.
+ * @param indent The amount to indent by.
+ * @param text The text to set for this element.
+ */
+ public TableData(int indent, String text) {
+ super(indent, new Text(text));
+ }
+
+
+ /**
+ * Creates a data element with no initial indenting, and embedded text.
+ * @param text The text to set for this element.
+ */
+ public TableData(String text) {
+ this(0, new Text(text));
+ }
+
+
+ /** @see org.mulgara.webquery.html.HtmlElement#getTag() */
+ protected String getTag() {
+ return "td";
+ }
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableHeader.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableHeader.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableHeader.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,85 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery.html;
+
+/**
+ * Represents header data in a table.
+ *
+ * @created Aug 4, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class TableHeader extends TableData {
+
+ /**
+ * Creates a header element with a given indent.
+ * @param indent The amount to indent by.
+ */
+ public TableHeader(int indent) {
+ super(indent);
+ }
+
+
+ /**
+ * Creates a header element with no indenting.
+ */
+ public TableHeader() {
+ super();
+ }
+
+
+ /**
+ * Creates a header element with a given indent, and a list of sub elements.
+ * @param indent The amount to indent by.
+ * @param subElements a list of sub elements inside this header cell.
+ */
+ public TableHeader(int indent, HtmlElement... subElements) {
+ super(indent, subElements);
+ }
+
+
+ /**
+ * Creates a header element with no initial indenting, and a list of sub elements.
+ * @param subElements a list of sub elements inside this header cell.
+ */
+ public TableHeader(HtmlElement... subElements) {
+ super(subElements);
+ }
+
+
+ /**
+ * Creates a header element with a given indent, and embedded text.
+ * @param indent The amount to indent by.
+ * @param text The text to set for this header.
+ */
+ public TableHeader(int indent, String text) {
+ super(indent, text);
+ }
+
+
+ /**
+ * Creates a header element with no initial indenting, and embedded text.
+ * @param text The text to set for this header.
+ */
+ public TableHeader(String text) {
+ super(text);
+ }
+
+
+ /** @see org.mulgara.webquery.html.HtmlElement#getTag() */
+ protected String getTag() {
+ return "th";
+ }
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableRow.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableRow.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableRow.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,88 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery.html;
+
+/**
+ * Represents a row in a table. Any child elements will be wrapped in TableData elements
+ * before being added.
+ *
+ * @created Aug 4, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class TableRow extends HtmlElement implements TableStructure {
+
+ /**
+ * Creates a row with a given indent.
+ * @param indent The amount to indent by.
+ */
+ public TableRow(int indent) {
+ super(indent);
+ }
+
+
+ /**
+ * Creates a row with no indenting.
+ */
+ public TableRow() {
+ this(0);
+ }
+
+
+ /**
+ * Creates a row with a given indent, and a list of data elements.
+ * @param indent The amount to indent by.
+ * @param rowData a list of data elements to go inside this row.
+ */
+ public TableRow(int indent, HtmlElement... rowData) {
+ super(indent, rowData);
+ }
+
+
+ /**
+ * Creates an row with no initial indenting, and a list of data elements.
+ * @param subElements a list of data elements to go inside this row.
+ */
+ public TableRow(HtmlElement... rowData) {
+ this(0, rowData);
+ }
+
+
+ /**
+ * Adds a sub element to the end of the list of sub elements for this element.
+ * @param elt The new sub element to be added.
+ * @return The current element.
+ * @throws IllegalArgumentException If elt is anything other than TableData.
+ */
+ public HtmlElement add(HtmlElement elt) {
+ if (!(elt instanceof TableData)) elt = new TableData(elt);
+ return super.add(elt);
+ }
+
+
+ /**
+ * Gets the width of this row.
+ * @return The number of TD elements in this row.
+ */
+ public int getWidth() {
+ return subElements.size();
+ }
+
+
+ /** @see org.mulgara.webquery.html.HtmlElement#getTag() */
+ protected String getTag() {
+ return "tr";
+ }
+
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableStructure.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableStructure.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/html/TableStructure.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,30 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery.html;
+
+/**
+ * Describes some part of a table's structure.
+ *
+ * @created Aug 8, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public interface TableStructure {
+
+ /**
+ * Returns the width of this part of the structure.
+ * @return The width of this structure.
+ */
+ public int getWidth();
+}
Added: trunk/src/jar/webquery/java/org/mulgara/webquery/html/Text.java
===================================================================
--- trunk/src/jar/webquery/java/org/mulgara/webquery/html/Text.java (rev 0)
+++ trunk/src/jar/webquery/java/org/mulgara/webquery/html/Text.java 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,87 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.webquery.html;
+
+import java.io.PrintWriter;
+
+import org.mulgara.util.StringUtil;
+
+/**
+ * Represents free floating text. Indent is irrelevant for this class.
+ *
+ * @created Aug 4, 2008
+ * @author Paul Gearon
+ * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class Text extends HtmlElement {
+
+ private StringBuilder buffer;
+
+ /**
+ * Creates a text element with no initial text.
+ */
+ public Text() {
+ super(-1);
+ buffer = new StringBuilder();
+ }
+
+
+ /**
+ * Creates a text element from an arbitrary object.
+ * @param obj The object to convert to text for this element.
+ */
+ public Text(Object obj) {
+ super(-1);
+ buffer = new StringBuilder(StringUtil.quoteAV(obj.toString()));
+ }
+
+
+ /**
+ * Appends new text from an arbitrary object to this element.
+ * @param obj The object to convert to text to append to this element.
+ * @return The current instance.
+ */
+ public Text append(Object obj) {
+ buffer.append(StringUtil.quoteAV(obj.toString()));
+ return this;
+ }
+
+
+ /**
+ * Not used for this implementation.
+ * @see org.mulgara.webquery.html.HtmlElement#getTag()
+ */
+ protected String getTag() {
+ return "";
+ }
+
+
+ /**
+ * Always returns false, indicating that formatting is never used on this element.
+ * @see org.mulgara.webquery.html.HtmlElement#shouldIndent()
+ */
+ protected boolean shouldIndent() {
+ return false;
+ }
+
+
+ /**
+ * Appends this text raw to the writer. There are no tags, or formating.
+ * @see org.mulgara.webquery.html.HtmlElement#sendTo(java.io.PrintWriter)
+ */
+ public void sendTo(PrintWriter out) {
+ out.append(buffer);
+ }
+
+}
Added: trunk/src/jar/webquery/resources/debug.html
===================================================================
--- trunk/src/jar/webquery/resources/debug.html (rev 0)
+++ trunk/src/jar/webquery/resources/debug.html 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,23 @@
+<!DOCTYPE html PUBLIC "-//W3C//Dtd XHTML 1.0 Transitional//EN" "http://www.w3.org/tr/xhtml1/Dtd/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Mulgara Debugger</title>
+ <link href="styles/ui.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+ <div id="wrapper">
+ <div id="header">
+ <div id="logo">
+ <a href="http://mulgara.org/"><img src="images/logo.jpg" alt="Mulgara - Semantic Store" border="0" /></a>
+ </div>
+ </div>
+ <div id="content">
+ <div id="columnLeft">
+ <h1>Debug Output:</h1>
+@@debug@@
+ </div>
+ </div>
+ </div>
+</body>
+</html>
Added: trunk/src/jar/webquery/resources/images/logo.jpg
===================================================================
(Binary files differ)
Property changes on: trunk/src/jar/webquery/resources/images/logo.jpg
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/jar/webquery/resources/styles/ui.css
===================================================================
--- trunk/src/jar/webquery/resources/styles/ui.css (rev 0)
+++ trunk/src/jar/webquery/resources/styles/ui.css 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,133 @@
+ at charset "utf-8";
+* {
+ padding:0;
+ margin:0;
+}
+body {
+ font-family: "Trebuchet MS", Arial;
+ font-size: 12px;
+ color: #000000;
+ margin: 0px;
+ padding: 0px;
+ background-color: #FFFFFF;
+}
+a {
+ color: #0066cc;
+}
+a:hover {
+ text-decoration: none;
+}
+a:visited {
+ color: #330066;
+}
+
+#wrapper {
+ width: 1013px;
+ margin-right: auto;
+ margin-left: auto;
+ background-color: #FFFFFF;
+ padding-right: 8px;
+ padding-left: 8px;
+ background-repeat: repeat-y;
+}
+#header {
+ background-image: url(../images/logo.jpg);
+ background-repeat: no-repeat;
+ background-position: left;
+ height: 109px;
+}
+#content {
+ padding-top: 18px;
+}
+#content h1 {
+ font-style: italic;
+ border-bottom-width: 1px;
+ border-bottom-style: dotted;
+ border-bottom-color: #999999;
+ padding-bottom: 15px;
+}
+#content h2 {
+ padding-top: 8px;
+}
+.clearer {
+ clear: both;
+}
+#logo {
+ float: left;
+}
+#content p {
+ margin-top: 15px;
+}
+#content ul {
+ margin-top: 15px;
+ margin-left: 15px;
+}
+#content td {
+ padding-left: 5px;
+ padding-right: 5px;
+}
+#content tr {
+ spacing: 15px;
+}
+.styleBlack {
+ color: #FFFFFF
+}
+.styleLB {
+ font-size: 14px;
+ font-weight: bold;
+}
+.styleLarge {
+ font-size: 14px;
+ font-weight: bold;
+}
+.styleLColored {
+ font-size: 14px;
+ font-weight: bold;
+ color: #666666;
+}
+
+.formatTable td {
+ padding-top: 5px;
+}
+
+.queryTable td {
+ padding-top: 5px;
+}
+
+.allResultsTable td {
+ white-space: nowrap;
+ padding-top: 5px;
+}
+
+.fwdLinkTable td {
+ white-space: nowrap;
+ padding-top: 5px;
+}
+
+.resultTable {
+ margin-top: 5px;
+ border-spacing: 0;
+ border-collapse: collapse;
+ margin-bottom: 10px;
+}
+
+.resultTable th {
+ background-color: #CCCCCC;
+ border: solid #000 1px;
+ font-weight: bold;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+.rtd {
+ white-space: nowrap;
+ padding: 5px;
+ border: solid #000 1px;
+}
+
+.borderLess {
+ white-space: nowrap;
+ padding: 0px;
+ font-weight: bold;
+ border: blank;
+}
Added: trunk/src/jar/webquery/resources/template.html
===================================================================
--- trunk/src/jar/webquery/resources/template.html (rev 0)
+++ trunk/src/jar/webquery/resources/template.html 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,98 @@
+<!DOCTYPE html PUBLIC "-//W3C//Dtd XHTML 1.0 Transitional//EN" "http://www.w3.org/tr/xhtml1/Dtd/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+@@debug@@
+-->
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Mulgara Viewer</title>
+ <link href="styles/ui.css" rel="stylesheet" type="text/css" />
+ <script language="JavaScript" type="text/javascript">
+ <!--
+ // Put the selected example query into the query text area. The graph
+ // name is also inserted in to the query.
+ function setQuery() {
+ // Must have a Model URI
+ if (document.QueryForm.ModelURI.value == '') {
+ alert('Please enter a Model URI and then select the query again');
+ document.QueryForm.ModelURI.focus;
+ return;
+ }
+ var index = document.QueryForm.ExampleQuery.selectedIndex;
+ var exampleText = document.QueryForm.ExampleQuery[index].value;
+ var graphURI= document.QueryForm.ModelURI.value;
+ // Add the graph name
+ var queryString = exampleText.replace(/-graph-/gi, graphURI);
+ document.QueryForm.QueryText.value = queryString;
+ }
+
+ // Validate the form and submit it if all is OK
+ function validateAndSubmit() {
+ // Is there a query?
+ if (document.QueryForm.QueryText.value == null ||
+ document.QueryForm.QueryText.value == "") {
+ alert('Please enter a query');
+ document.QueryForm.QueryText.focus();
+ return false;
+ } else {
+ // Submit the form
+ document.QueryForm.submit();
+ return true;
+ }
+ }
+ //-->
+ </script>
+</head>
+<body>
+ <div id="wrapper">
+ <div id="header">
+ <div id="logo">
+ <a href="http://mulgara.org/"><img src="images/logo.jpg" alt="Mulgara - Semantic Store" border="0" /></a>
+ </div>
+ </div>
+ <div id="content">
+ <table class="formatTable" summary="">
+ <tr>
+ <td>
+ <form action="@@execute@@" method="post" name="QueryForm">
+ <table class="queryTable" summary="Enter a query">
+ <tr>
+ <td><strong>Model URI:</strong> </td>
+ <td><input name="ModelURI" size="60" type="text" value="rmi://@@hostname@@/@@servername@@#sampledata"> </td>
+ </tr>
+ <tr>
+ <td><strong>Example Queries:</strong> </td>
+ <td>
+ <select name="ExampleQuery" onchange="javascript:setQuery()">
+ <option selected value="">Select a query..</option>
+ <option value="create <-graph->;">Step 1. Create a graph</option>
+ <option value="load <@@jarurl@@!/data/w3c-news.rss> into <-graph->;">Step 2. Load RSS data into the graph</option>
+ <option value="select $subject $predicate $object from <-graph-> where $subject $predicate $object;">Step 3. List everything in the graph</option>
+ <option value="select $title $link $description from <-graph-> where $article <http://purl.org/rss/1.0/title> $title and $article <http://purl.org/rss/1.0/link> $link and $article <http://purl.org/rss/1.0/description> $description;">Step 4. List the news articles</option>
+ <option value="create <rmi://@@hostname@@/@@servername@@#rdfs>;">Step 5. Create a standalone RDF schema graph</option>
+ <option value="load <@@jarurl@@!/data/rss-1.0.rdfs> into <rmi://@@hostname@@/@@servername@@#rdfs>; load <jar:file:/Users/pag/debug/mulgara-2.0.0.jar!/data/dc.rdfs> into <rmi://@@hostname@@/@@servername@@#rdfs>; load <@@jarurl@@!/data/rdfs.rdfs> into <rmi://@@hostname@@/@@servername@@#rdfs>;">Step 6. Load in the referenced schemas</option>
+ <option value="select $rdfSubject $rdfProperty $value from <-graph-> or <rmi://@@hostname@@/@@servername@@#rdfs> where $rdfSubject $rdfProperty $value and $rdfProperty <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/1999/02/22-rdf-syntax-ns#Property> and $rdfProperty <http://www.w3.org/2000/01/rdf-schema#isDefinedBy> <http://purl.org/rss/1.0/>;">Step 7. List the RSS properties using both graphs</option>
+ <option value="drop <-graph->; drop <rmi://@@hostname@@/@@servername@@#rdfs>;">Step 8. Drop the graphs</option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td><strong>Query Text:</strong> </td>
+ <td><textarea cols="80" name="QueryText" rows="10"></textarea> </td>
+ </tr>
+ <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='';">
+ </td>
+ </tr>
+ </table>
+ </form>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+</body>
+</html>
Added: trunk/src/jar/webquery/resources/template_head.html
===================================================================
--- trunk/src/jar/webquery/resources/template_head.html (rev 0)
+++ trunk/src/jar/webquery/resources/template_head.html 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,96 @@
+<!DOCTYPE html PUBLIC "-//W3C//Dtd XHTML 1.0 Transitional//EN" "http://www.w3.org/tr/xhtml1/Dtd/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+@@debug@@
+-->
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Mulgara Viewer</title>
+ <link href="styles/ui.css" rel="stylesheet" type="text/css" />
+ <script language="JavaScript" type="text/javascript">
+ <!--
+ // Put the selected example query into the query text area. The graph
+ // name is also inserted in to the query.
+ function setQuery() {
+ // Must have a Model URI
+ if (document.QueryForm.ModelURI.value == '') {
+ alert('Please enter a Model URI and then select the query again');
+ document.QueryForm.ModelURI.focus;
+ return;
+ }
+ var index = document.QueryForm.ExampleQuery.selectedIndex;
+ var exampleText = document.QueryForm.ExampleQuery[index].value;
+ var graphURI= document.QueryForm.ModelURI.value;
+ // Add the graph name
+ var queryString = exampleText.replace(/-graph-/gi, graphURI);
+ document.QueryForm.QueryText.value = queryString;
+ }
+
+ // Validate the form and submit it if all is OK
+ function validateAndSubmit() {
+ // Is there a query?
+ if (document.QueryForm.QueryText.value == null ||
+ document.QueryForm.QueryText.value == "") {
+ alert('Please enter a query');
+ document.QueryForm.QueryText.focus();
+ return false;
+ } else {
+ // Submit the form
+ document.QueryForm.submit();
+ return true;
+ }
+ }
+ //-->
+ </script>
+</head>
+<body>
+ <div id="wrapper">
+ <div id="header">
+ <div id="logo">
+ <a href="http://mulgara.org/"><img src="images/logo.jpg" alt="Mulgara - Semantic Store" border="0" /></a>
+ </div>
+ </div>
+ <div id="content">
+ <table class="formatTable" summary="">
+ <tr>
+ <td>
+ <form action="@@execute@@.html" method="post" name="QueryForm">
+ <table class="queryTable" summary="Enter a query">
+ <tr>
+ <td><strong>Graph URI:</strong> </td>
+ <td><input name="ModelURI" size="60" type="text" value="@@graph@@"> </td>
+ </tr>
+ <tr>
+ <td><strong>Example Queries:</strong> </td>
+ <td>
+ <select name="ExampleQuery" onchange="javascript:setQuery()">
+ <option selected value="">Select a query..</option>
+ <option value="create <-graph->;">Step 1. Create a graph</option>
+ <option value="load <@@jarurl@@!/data/w3c-news.rss> into <-graph->;">Step 2. Load RSS data into the graph</option>
+ <option value="select $subject $predicate $object from <-graph-> where $subject $predicate $object;">Step 3. List everything in the graph</option>
+ <option value="select $title $link $description from <-graph-> where $article <http://purl.org/rss/1.0/title> $title and $article <http://purl.org/rss/1.0/link> $link and $article <http://purl.org/rss/1.0/description> $description;">Step 4. List the news articles</option>
+ <option value="create <rmi://@@hostname@@/@@servername@@#rdfs>;">Step 5. Create a standalone RDF schema graph</option>
+ <option value="load <@@jarurl@@!/data/rss-1.0.rdfs> into <rmi://@@hostname@@/@@servername@@#rdfs>; load <jar:file:/Users/pag/debug/mulgara-2.0.0.jar!/data/dc.rdfs> into <rmi://@@hostname@@/@@servername@@#rdfs>; load <@@jarurl@@!/data/rdfs.rdfs> into <rmi://@@hostname@@/@@servername@@#rdfs>;">Step 6. Load in the referenced schemas</option>
+ <option value="select $rdfSubject $rdfProperty $value from <-graph-> or <rmi://@@hostname@@/@@servername@@#rdfs> where $rdfSubject $rdfProperty $value and $rdfProperty <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/1999/02/22-rdf-syntax-ns#Property> and $rdfProperty <http://www.w3.org/2000/01/rdf-schema#isDefinedBy> <http://purl.org/rss/1.0/>;">Step 7. List the RSS properties using both graphs</option>
+ <option value="drop <-graph->; drop <rmi://@@hostname@@/@@servername@@#rdfs>;">Step 8. Drop the graphs</option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td><strong>Query Text:</strong> </td>
+ <td><textarea cols="80" name="QueryText" rows="10"></textarea> </td>
+ </tr>
+ <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='';">
+ </td>
+ </tr>
+ </table>
+ </form>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table class="allResultsTable" border="0" cellpadding="5" width="100%">
\ No newline at end of file
Added: trunk/src/jar/webquery/resources/template_more_tail.html
===================================================================
--- trunk/src/jar/webquery/resources/template_more_tail.html (rev 0)
+++ trunk/src/jar/webquery/resources/template_more_tail.html 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,23 @@
+ </table>
+ </td>
+ </tr>
+<!--
+ // scrollHREF = "ExecuteQuery.event?" + URLEncoder.encode(WebUIKeys.RESULT_INDEX + "=" + resultIndex, "UTF-8");
+-->
+ <tr id="ResultScrollRow">
+ <td colspan="2">
+ <table class="fwdLinkTable">
+ <tr>
+ <td>
+ <a href="ExecuteQuery" id="ResultForwardLink" title="Forward to next page of results">Next page ></a>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ </table>
+ </div>
+ </div>
+</body>
+</html>
\ No newline at end of file
Added: trunk/src/jar/webquery/resources/template_tail.html
===================================================================
--- trunk/src/jar/webquery/resources/template_tail.html (rev 0)
+++ trunk/src/jar/webquery/resources/template_tail.html 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,8 @@
+ </table>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+</body>
+</html>
\ No newline at end of file
Added: trunk/src/jar/webquery/webquery-build.properties
===================================================================
--- trunk/src/jar/webquery/webquery-build.properties (rev 0)
+++ trunk/src/jar/webquery/webquery-build.properties 2008-08-10 02:06:08 UTC (rev 1128)
@@ -0,0 +1,15 @@
+#
+# Properties used by the webquery module
+#
+
+# Module Name
+webquery.name = webquery
+
+# General module properties
+webquery.conf.dir = ${conf.dir}
+webquery.src.dir = ${jar.src.dir}/webquery
+webquery.obj.dir = ${jar.obj.dir}/webquery
+webquery.dist.dir = ${bin.dir}
+webquery.test.dir = ${test.dir}/webquery
+webquery.jxtest.dir = ${jxtest.dir}/webquery
+webquery.jar = webquery-base-${mulgara-version}.jar
More information about the Mulgara-svn
mailing list