Logo Search packages:      
Sourcecode: f-spot version File versions

Resource.cs

using System;
using System.Collections;

namespace SemWeb {
      
      public abstract class Resource : IComparable {
            internal object ekKey, ekValue;
            internal ArrayList extraKeys;
            
            internal class ExtraKey {
                  public object Key;
                  public object Value; 
                  public ExtraKey(object k, object v) { Key = k; Value = v; }
            }
            
            public abstract string Uri { get; }
            
            internal Resource() {
            }
            
            // These get rid of the warning about overring ==, !=.
            // Since Entity and Literal override these, we're ok.
            public override bool Equals(object other) {
                  return base.Equals(other);
            }
            public override int GetHashCode() {
                  return base.GetHashCode();
            }
            
            public static bool operator ==(Resource a, Resource b) {
                  if ((object)a == null && (object)b == null) return true;
                  if ((object)a == null || (object)b == null) return false;
                  return a.Equals(b);
            }
            public static bool operator !=(Resource a, Resource b) {
                  return !(a == b);
            }
            
            internal object GetResourceKey(object key) {
                  if (ekKey == key) return ekValue;
                  if (extraKeys == null) return null;
                  for (int i = 0; i < extraKeys.Count; i++) {
                        Resource.ExtraKey ekey = (Resource.ExtraKey)extraKeys[i];
                        if (ekey.Key == key)
                              return ekey.Value;
                  }
                  return null;
            }
            internal void SetResourceKey(object key, object value) {
                  if (ekKey == null || ekKey == key) {
                        ekKey = key;
                        ekValue = value;
                        return;
                  }
                  
                  if (this is BNode) throw new InvalidOperationException("Only one resource key can be set for a BNode.");
            
                  if (extraKeys == null) extraKeys = new ArrayList();
                  
                  foreach (Resource.ExtraKey ekey in extraKeys)
                        if (ekey.Key == key) { ekey.Value = value; return; }
                  
                  Resource.ExtraKey k = new Resource.ExtraKey(key, value);
                  extraKeys.Add(k);
            }

            int IComparable.CompareTo(object other) {
                  // We'll make an ordering over resources.
                  // First named entities, then bnodes, then literals.
                  // Named entities are sorted by URI.
                  // Bnodes by hashcode.
                  // Literals by their value, language, datatype.
            
                  Resource r = (Resource)other;
                  if (Uri != null && r.Uri == null) return -1;
                  if (Uri == null && r.Uri != null) return 1;
                  if (this is BNode && r is Literal) return -1;
                  if (this is Literal && r is BNode) return 1;
                  
                  if (Uri != null) return String.Compare(Uri, r.Uri, false, System.Globalization.CultureInfo.InvariantCulture);
                  
                  if (this is BNode) return GetHashCode().CompareTo(r.GetHashCode());

                  if (this is Literal) {
                        int x = String.Compare(((Literal)this).Value, ((Literal)r).Value, false, System.Globalization.CultureInfo.InvariantCulture);
                        if (x != 0) return x;
                        x = String.Compare(((Literal)this).Language, ((Literal)r).Language, false, System.Globalization.CultureInfo.InvariantCulture);
                        if (x != 0) return x;
                        x = String.Compare(((Literal)this).DataType, ((Literal)r).DataType, false, System.Globalization.CultureInfo.InvariantCulture);
                        return x;
                  }
                  
                  return 0; // unreachable
            }
      }
      
      public class Entity : Resource {
            private string uri;
            
            public Entity(string uri) {
                  if (uri == null) throw new ArgumentNullException("To construct entities with no URI, use the BNode class.");
                  //if (uri.Length == 0) throw new ArgumentException("uri cannot be the empty string");
                  this.uri = uri;
            }
            
            // For the BNode constructor only.
            internal Entity() {
            }
            
            public override string Uri {
                  get {
                        return uri;
                  }
            }
            
            public static implicit operator Entity(string uri) { return new Entity(uri); }
            
            public override int GetHashCode() {
                  if (uri == null) return base.GetHashCode(); // this is called from BNode.GetHashCode().
                  return uri.GetHashCode();
            }
                  
            public override bool Equals(object other) {
                  if (!(other is Resource)) return false;
                  if (object.ReferenceEquals(this, other)) return true;
                  return ((Resource)other).Uri != null && ((Resource)other).Uri == Uri;
            }
            
            // Although these do the same as Resource's operator overloads,
            // having these plus the implict string conversion allows
            // these operators to work with entities and strings.

            public static bool operator ==(Entity a, Entity b) {
                  if ((object)a == null && (object)b == null) return true;
                  if ((object)a == null || (object)b == null) return false;
                  return a.Equals(b);
            }
            public static bool operator !=(Entity a, Entity b) {
                  return !(a == b);
            }
            
            public override string ToString() {
                  return "<" + Uri + ">";
            }
      }
      
      public class BNode : Entity {
            string localname;
      
            public BNode() {
            }
            
            public BNode(string localName) {
                  localname = localName;
                  if (localname != null && localname.Length == 0) throw new ArgumentException("localname cannot be the empty string");
            }
            
            public string LocalName { get { return localname; } }

            public override int GetHashCode() {
                  if (ekKey != null)
                        return ekKey.GetHashCode() ^ ekValue.GetHashCode();
                  
                  // If there's no ExtraKeys info, then this
                  // object is only equal to itself.  It's then safe
                  // to use object.GetHashCode().
                  return base.GetHashCode();
            }
                  
            public override bool Equals(object other) {
                  if (object.ReferenceEquals(this, other)) return true;
                  if (!(other is BNode)) return false;
                  
                  object okKey = ((Resource)other).ekKey;
                  object okValue = ((Resource)other).ekValue;
                  
                  return (ekKey != null && okKey != null)
                        && (ekKey == okKey)
                        && ekValue.Equals(okValue);
            }
            
            public override string ToString() {
                  if (LocalName != null)
                        return "_:" + LocalName;
                  else
                        return "_:bnode" + GetHashCode();
            }
      }
      
      public class Variable : BNode {
            public Variable() : base() {
            }
            
            public Variable(string variableName) : base(variableName) {
            }
            
            public override string ToString() {
                  if (LocalName != null)
                        return "?" + LocalName;
                  else
                        return "?var" + GetHashCode();
            }
      }

      public sealed class Literal : Resource { 
            private const string XMLSCHEMANS = "http://www.w3.org/2001/XMLSchema#";

            private string value, lang, type;
            
            public Literal(string value) : this(value, null, null) {
            }
            
            public Literal(string value, string language, string dataType) {
              if (value == null)
                    throw new ArgumentNullException("value");
              this.value = string.Intern(value);
              this.lang = language;
              this.type = dataType;
              
              if (language != null && language.Length == 0) throw new ArgumentException("language cannot be the empty string");
              if (dataType != null && dataType.Length == 0) throw new ArgumentException("dataType cannot be the empty string");
            }
            
            public static explicit operator Literal(string value) { return new Literal(value); }

            public override string Uri { get { return null; } }
            
            public string Value { get { return value; } }
            public string Language { get { return lang; } }
            public string DataType { get { return type; } }
            
            public override bool Equals(object other) {
                  if (other == null) return false;
                  if (!(other is Literal)) return false;
                  Literal literal = (Literal)other;
                  if (Value != literal.Value) return false;
                  if (different(Language, literal.Language)) return false;
                  if (different(DataType, literal.DataType)) return false;          
                  return true;
            }
            
            private bool different(string a, string b) {
                  if ((object)a == (object)b) return false;
                  if (a == null || b == null) return true;
                  return a != b;
            }
            
            public override int GetHashCode() {
                  return Value.GetHashCode(); 
             }
            
            public override string ToString() {
                  System.Text.StringBuilder ret = new System.Text.StringBuilder();
                  ret.Append('"');
                  ret.Append(N3Writer.Escape(Value));
                  ret.Append('"');
                  
                  if (Language != null) {
                        ret.Append('@');
                        ret.Append(N3Writer.Escape(Language));
                  }
                  
                  if (DataType != null) {
                        ret.Append("^^<");
                        ret.Append(N3Writer.Escape(DataType));
                        ret.Append(">");
                  }
                  return ret.ToString();
            }
            
            public static Literal Parse(string literal, NamespaceManager namespaces) {
                  if (literal.Length < 2 || literal[0] != '\"') throw new FormatException("Literal value must start with a quote.");
                  int quote = literal.LastIndexOf('"');
                  if (quote <= 0) throw new FormatException("Literal value must have an end quote (" + literal + ")");
                  string value = literal.Substring(1, quote-1);
                  literal = literal.Substring(quote+1);
                  
                  value = value.Replace("\\\"", "\"");
                  value = value.Replace("\\\\", "\\");
                  
                  string lang = null;
                  string datatype = null;
                  
                  if (literal.Length >= 2 && literal[0] == '@') {
                        int type = literal.IndexOf("^^");
                        if (type == -1) lang = literal.Substring(1);
                        else {
                              lang = literal.Substring(1, type);
                              literal = literal.Substring(type);
                        }
                  }
                  
                  if (literal.StartsWith("^^")) {
                        if (literal.StartsWith("^^<") && literal.EndsWith(">")) {
                              datatype = literal.Substring(3, literal.Length-4);
                        } else {
                              if (namespaces == null)
                                    throw new ArgumentException("No NamespaceManager was given to resolve the QName in the literal string.");
                              datatype = namespaces.Resolve(literal.Substring(2));
                        }
                  }
                  
                  return new Literal(value, lang, datatype);
            }
            
            public object ParseValue() {
                  string dt = DataType;
                  if (dt == null || !dt.StartsWith(XMLSCHEMANS)) return Value;
                  dt = dt.Substring(XMLSCHEMANS.Length);
                  
                  if (dt == "string" || dt == "normalizedString" || dt == "anyURI") return Value;
                  if (dt == "boolean") return (Value == "true" || Value == "1");
                  if (dt == "decimal" || dt == "integer" || dt == "nonPositiveInteger" || dt == "negativeInteger" || dt == "nonNegativeInteger" || dt == "positiveInteger") return Decimal.Parse(Value);
                  if (dt == "float") return float.Parse(Value);
                  if (dt == "double") return double.Parse(Value);
                  if (dt == "duration") return TimeSpan.Parse(Value); // syntax?
                  if (dt == "dateTime" || dt == "time" || dt == "date") return DateTime.Parse(Value); // syntax?
                  if (dt == "long") return long.Parse(Value);
                  if (dt == "int") return int.Parse(Value);
                  if (dt == "short") return short.Parse(Value);
                  if (dt == "byte") return sbyte.Parse(Value);
                  if (dt == "unsignedLong") return ulong.Parse(Value);
                  if (dt == "unsignedInt") return uint.Parse(Value);
                  if (dt == "unsignedShort") return ushort.Parse(Value);
                  if (dt == "unsignedByte") return byte.Parse(Value);
                  
                  return Value;
            }
            
            public Literal Normalize() {
                  if (DataType == null) return this;
                  return new Literal(ParseValue().ToString(), Language, DataType);
            }
            
            public static Literal Create(bool value) {
                  return new Literal(value ? "true" : "false", null, XMLSCHEMANS + "boolean");
            }
      }

      /*
      public abstract class LiteralFilter : Resource {
            public LiteralFilter() : base(null) { }
            
            public override string Uri { get { return null; } }
            
            public abstract bool Matches(Literal literal);
      }
      
      public interface SQLLiteralFilter {
            string GetSQLFunction();
      }
      
      public class LiteralNumericComparison : LiteralFilter, SQLLiteralFilter {
            double value;
            Op comparison;
            
            public LiteralNumericComparison(double value, Op comparison) {
                  this.value = value; this.comparison = comparison;
            }
            
            public enum Op {
                  Equal,
                  NotEqual,
                  GreaterThan,
                  GreaterThanOrEqual,
                  LessThan,
                  LessThanOrEqual,
            }
            
            public override bool Matches(Literal literal) {
                  double v;
                  if (!double.TryParse(literal.Value, System.Globalization.NumberStyles.Any, null, out v)) return false;
                  
                  switch (comparison) {
                        case Op.Equal: return v == value;
                        case Op.NotEqual: return v != value;
                        case Op.GreaterThan: return v > value;
                        case Op.GreaterThanOrEqual: return v >= value;
                        case Op.LessThan: return v < value;
                        case Op.LessThanOrEqual: return v <= value;
                        default: return false;
                  }
            }
            
            public string GetSQLFunction() {
                  switch (comparison) {
                        case Op.Equal: return "literal = " + value;
                        case Op.NotEqual: return "literal != " + value;
                        case Op.GreaterThan: return "literal > " + value;
                        case Op.GreaterThanOrEqual: return "literal >= " + value;
                        case Op.LessThan: return "literal < " + value;
                        case Op.LessThanOrEqual: return "literal <= " + value;
                        default: return null;
                  }
            }
      }
      
      public class LiteralStringComparison : LiteralFilter, SQLLiteralFilter {
            string value;
            Op comparison;
            
            public LiteralStringComparison(string value, Op comparison) {
                  this.value = value; this.comparison = comparison;
            }
            
            public enum Op {
                  Equal,
                  NotEqual,
                  GreaterThan,
                  GreaterThanOrEqual,
                  LessThan,
                  LessThanOrEqual,
            }
            
            public override bool Matches(Literal literal) {
                  string v = literal.Value;
                  
                  switch (comparison) {
                        case Op.Equal: return v == value;
                        case Op.NotEqual: return v != value;
                        case Op.GreaterThan: return v.CompareTo(value) > 0;
                        case Op.GreaterThanOrEqual: return v.CompareTo(value) >= 0;
                        case Op.LessThan: return v.CompareTo(value) < 0;
                        case Op.LessThanOrEqual: return v.CompareTo(value) <= 0;
                        default: return false;
                  }
            }
            
            public string GetSQLFunction() {
                  switch (comparison) {
                        case Op.Equal: return "literal = " + value;
                        case Op.NotEqual: return "literal != " + value;
                        case Op.GreaterThan: return "literal > " + value;
                        case Op.GreaterThanOrEqual: return "literal >= " + value;
                        case Op.LessThan: return "literal < " + value;
                        case Op.LessThanOrEqual: return "literal <= " + value;
                        default: return null;
                  }
            }
      }
      */
}

namespace SemWeb.Util.Bind {
      public class Any {
            Entity ent;
            Store model;
                        
            public Any(Entity entity, Store model) {
                  this.ent = entity;
                  this.model = model;
            }
            
            public Entity Entity { get { return ent; } }
            public Store Model { get { return model; } }
            
            public string Uri { get { return ent.Uri; } }
            
            private Resource toRes(object value) {
                  if (value == null) return null;
                  if (value is Resource) return (Resource)value; // shouldn't happen
                  if (value is string) return new Literal((string)value);
                  if (value is Any) return ((Any)value).ent;
                  throw new ArgumentException("value is not of a recognized type");
            }
            
            protected void AddValue(Entity predicate, object value, bool forward) {
                  if (value == null) throw new ArgumentNullException("value");
                  Resource v = toRes(value);
                  if (!forward && !(v is Entity)) throw new ArgumentException("Cannot set this property to a literal value.");
                  Statement add = new Statement(ent, predicate, v);
                  if (!forward) add = add.Invert();
                  model.Add(add);
            }
            protected void RemoveValue(Entity predicate, object value, bool forward) {
                  if (value == null) throw new ArgumentNullException("value");
                  Resource v = toRes(value);
                  if (!forward && !(v is Entity)) throw new ArgumentException("Cannot set this property to a literal value.");
                  Statement rem = new Statement(ent, predicate, v);
                  if (!forward) rem = rem.Invert();
                  model.Remove(rem);
            }
            
            protected void SetFuncProperty(Entity predicate, object value, bool forward) {
                  Resource v = toRes(value);
                  Statement search = new Statement(ent, predicate, null);
                  Statement replace = new Statement(ent, predicate, v);
                  if (!forward) {
                        if (v != null && !(v is Entity)) throw new ArgumentException("Cannot set this property to a literal value.");
                        search = search.Invert();
                        replace = replace.Invert();
                  }
                  
                  if (v != null) {
                        foreach (Statement s in model.Select(search)) {
                              model.Replace(s, replace);
                              return;
                        }
                        model.Add(replace);
                  } else {
                        model.Remove(search);
                  }
            }
            
            protected void SetNonFuncProperty(Entity predicate, object[] values, bool forward) {
                  Statement search = new Statement(ent, predicate, null);
                  if (!forward)
                        search = search.Invert();
                  
                  model.Remove(search);
                  if (values != null) {
                        foreach (object value in values) {
                              Resource v = toRes(value);
                              if (v == null) throw new ArgumentNullException("element of values array");
                              if (!forward && !(v is Entity)) throw new ArgumentException("Cannot set this property to a literal value.");
                              Statement add = new Statement(ent, predicate, v);
                              if (!forward) add = add.Invert();
                              model.Add(add);
                        }
                  }
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index