[Mulgara-svn] r1800 - trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst
pag at mulgara.org
pag at mulgara.org
Tue Oct 6 06:32:48 UTC 2009
Author: pag
Date: 2009-10-05 23:32:47 -0700 (Mon, 05 Oct 2009)
New Revision: 1800
Modified:
trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IRIReference.java
Log:
Now includes QNames. Also scanning known namespaces to attempt to build up QNames
Modified: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IRIReference.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IRIReference.java 2009-10-06 06:31:49 UTC (rev 1799)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IRIReference.java 2009-10-06 06:32:47 UTC (rev 1800)
@@ -16,9 +16,14 @@
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.mulgara.query.rdf.Mulgara;
import org.mulgara.sparql.parser.ParseException;
+import javax.xml.namespace.QName;
/**
* Represents IRI references in SPARQL. This is a superset of URI references.
@@ -47,12 +52,38 @@
/** Constant IRI for RDF_NIL */
public static final IRIReference RDF_NIL = new IRIReference(URI.create(RDF_NS + "nil"));
+ /** The made-up namespace for op: XPath functions */
+ public static final String OP_NS = "op";
+
+ /** The "op" prefix for XPath functions */
+ public static final String OP_PREFIX = OP_NS + ":";
+
+ /** The prefix for the sparql: namespace */
+ static final String SPARQL_PREFIX = "sparql";
+
+ /** The sparql: namespace */
+ static final URI SPARQL_NS;
+
+ /** The prefix for the fn: namespace */
+ static final String FN_PREFIX = "fn";
+
+ /** The fn: namespace */
+ static final URI FN_NS;
+
/** The internal URI value */
private URI uri;
/** The original text of the URI */
private String text;
+ /** The qname form, if available */
+ private QName qname;
+
+ static {
+ SPARQL_NS = URI.create("http://www.w3.org/2006/sparql-functions#");
+ FN_NS = URI.create("http://www.w3.org/2005/xpath-functions/#");
+ }
+
/**
* Create an IRI reference from a URI.
* @param uri The URI referred to.
@@ -60,13 +91,26 @@
public IRIReference(URI uri) {
this.uri = uri;
text = "<" + uri.toString() + ">";
+ qname = parseQName(uri.toString());
}
/**
* Create an IRI reference from a URI.
* @param uri The URI referred to.
+ * @param namespaces The environment's map of prefix to namespace URIs.
*/
- public IRIReference(String uri) throws ParseException {
+ public IRIReference(URI uri, Map<String,URI> namespaces) {
+ this.uri = uri;
+ text = "<" + uri.toString() + ">";
+ qname = parseQName(uri.toString(), namespaces);
+ }
+
+ /**
+ * Create an IRI reference from a URI.
+ * @param uri The URI referred to.
+ * @param namespaces The environment's map of prefix to namespace URIs.
+ */
+ public IRIReference(String uri, Map<String,URI> namespaces) throws ParseException {
try {
this.uri = new URI(uri);
} catch (URISyntaxException e) {
@@ -75,16 +119,27 @@
this.uri = URI.create("#");
}
text = "<" + uri + ">";
+ qname = parseQName(uri.toString(), namespaces);
}
/**
- * Create an IRI reference from a URI with an abbreviated namespace.
+ * Create an IRI reference from a URI with an abbreviated namespace, with a known namespace.
* @param uri The URI referred to.
* @param text The abbreviated form.
*/
- public IRIReference(String uri, String text) throws ParseException {
- this(uri);
- this.text = text;
+ public IRIReference(URI namespace, String prefix, String localPart) throws ParseException {
+ try {
+ this.uri = new URI(namespace + localPart);
+ } catch (URISyntaxException e) {
+ throw new ParseException("Unable to create URI: " + namespace + localPart);
+ }
+ if (prefix == null) {
+ text = "<:" + localPart + ">";
+ qname = new QName(namespace.toString(), localPart);
+ } else {
+ text = prefix + ":" + localPart;
+ qname = new QName(namespace.toString(), localPart, prefix);
+ }
}
/**
@@ -100,5 +155,100 @@
public String getImage() {
return text;
}
-
+
+ /**
+ * Retrieves the qname for this URI, if one is known.
+ * @return The known QName, or <code>null</code> if none available.
+ */
+ public QName getQName() {
+ return qname;
+ }
+
+ /**
+ * Parse a URI, looking for a valid QName structure.
+ * @param uri The URI to parse.
+ * @return a new QName if one could be parsed, or <code>null</code> if one couldn't be found.
+ * @param namespaces The environment's map of prefix to namespace URIs.
+ */
+ private QName parseQName(String uri) {
+ Map<String,URI> e = Collections.emptyMap();
+ return parseQName(uri, e);
+ }
+
+ /**
+ * Parse a URI, looking for a valid QName structure.
+ * @param uri The URI to parse.
+ * @return a new QName if one could be parsed, or <code>null</code> if one couldn't be found.
+ * @param namespaces The environment's map of prefix to namespace URIs.
+ */
+ private QName parseQName(String uri, Map<String,URI> namespaces) {
+ // the "op" prefix is special, in that it has no namespace
+ // check if the URI starts with "op:" and is followed by a valid local name character
+ if (uri.startsWith(OP_PREFIX) && localStartNameChar(uri.charAt(OP_PREFIX.length()))) {
+ return new QName(OP_NS, uri.substring(OP_PREFIX.length()), OP_PREFIX);
+ }
+
+ // expand the namespaces to include some defaults, if missing
+ namespaces = expandedNamespaces(namespaces);
+
+ // search for a namespace we know about
+ for (Map.Entry<String,URI> e: namespaces.entrySet()) {
+ String namespaceUri = e.getValue().toString();
+ if (uri.startsWith(namespaceUri)) {
+ return new QName(namespaceUri, uri.substring(namespaceUri.length()), e.getKey());
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Expand on a namespace map to include some useful defaults.
+ * @param original The original namespace map of prefixes to namespace URIs.
+ * @return A new namespace map with the added entries.
+ */
+ private static Map<String,URI> expandedNamespaces(Map<String,URI> original) {
+ Map<String,URI> result = new HashMap<String,URI>(original);
+ if (!result.containsKey(SPARQL_PREFIX)) result.put(SPARQL_PREFIX, URI.create("http://www.w3.org/2006/sparql-functions#"));
+ if (!result.containsKey(FN_PREFIX)) result.put(FN_PREFIX, URI.create("http://www.w3.org/2005/xpath-functions/#"));
+ if (!result.containsKey(Mulgara.NS_PREFIX)) result.put(Mulgara.NS_PREFIX, Mulgara.NS_URI);
+ return result;
+ }
+
+ /**
+ * Indicates if the char is a valid XML name character, minus the colon character.
+ * @see http://www.w3.org/TR/REC-xml/#NT-NameStartChar
+ * @param c The character to test.
+ * @return <code>true</code> if the character is a valid start to an XML name.
+ */
+ @SuppressWarnings("unused")
+ private static final boolean localNameChar(char c) {
+ return localStartNameChar(c) ||
+ c == '-' || c == '.' || (c >= '0' && c <= '9') ||
+ c == 0xB7 || (c >= 0x0300 && c <= 0x036F) || (c >= 0x203F && c <= 0x2040);
+ }
+
+ /**
+ * Indicates if the char is a valid start for an XML name character, minus the colon character.
+ * @see http://www.w3.org/TR/REC-xml/#NT-NameStartChar
+ * @param c The character to test.
+ * @return <code>true</code> if the character is a valid start to an XML name.
+ */
+ private static final boolean localStartNameChar(char c) {
+ return (c >= 'A' && c <= 'Z') ||
+ (c >= 'a' && c <= 'z') ||
+ c == '_' ||
+ (c >= 0xC0 && c <= 0xD6) ||
+ (c >= 0xD8 && c <= 0xF6) ||
+ (c >= 0xF8 && c <= 0x2FF) ||
+ (c >= 0x370 && c <= 0x37D) ||
+ (c >= 0x37F && c <= 0x1FFF) ||
+ (c >= 0x200C && c <= 0x200D) ||
+ (c >= 0x2070 && c <= 0x218F) ||
+ (c >= 0x2C00 && c <= 0x2FEF) ||
+ (c >= 0x3001 && c <= 0xD7FF) ||
+ (c >= 0xF900 && c <= 0xFDCF) ||
+ (c >= 0xFDF0 && c <= 0xFFFD) ||
+ (c >= 0x10000 && c <= 0xEFFFF);
+ }
}
More information about the Mulgara-svn
mailing list