[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