/// <summary> /// Reads the data for XML deserialization. /// </summary> /// <param name="reader">XML Reader.</param> public sealed override void ReadXml(XmlReader reader) { _uri = UriFactory.Create(reader.ReadElementContentAsString()); // Compute Hash Code _hashcode = (_nodetype + ToString()).GetHashCode(); }
/// <summary> /// Compares two Literal Nodes /// </summary> /// <param name="a">First Literal Node</param> /// <param name="b">Second Literal Node</param> /// <returns></returns> public static int CompareLiterals(ILiteralNode a, ILiteralNode b) { if (ReferenceEquals(a, b)) { return(0); } if (a == null) { if (b == null) { return(0); } return(-1); } else if (b == null) { return(1); } //Literal Nodes are ordered based on Type and lexical form if (a.DataType == null && b.DataType != null) { //Untyped Literals are less than Typed Literals //Return a -1 to indicate this return(-1); } else if (a.DataType != null && b.DataType == null) { //Typed Literals are greater than Untyped Literals //Return a 1 to indicate this return(1); } else if (a.DataType == null && b.DataType == null) { //If neither are typed use Lexical Ordering on the value return(String.CompareOrdinal(a.Value, b.Value)); } else if (EqualityHelper.AreUrisEqual(a.DataType, b.DataType)) { //Are we using a known and orderable DataType? String type = a.DataType.AbsoluteUri; if (!XmlSpecsHelper.IsSupportedType(type)) { //Don't know how to order so use lexical order on the value return(String.CompareOrdinal(a.Value, b.Value)); } else { try { switch (type) { case XmlSpecsHelper.XmlSchemaDataTypeBoolean: //Can use Lexical ordering for this return(String.Compare(a.Value.ToLower(), b.Value.ToLower(), StringComparison.Ordinal)); case XmlSpecsHelper.XmlSchemaDataTypeByte: //Remember that xsd:byte is actually equivalent to SByte in .Net //Extract the Byte Values and compare sbyte aSByte, bSByte; if (SByte.TryParse(a.Value, out aSByte)) { if (SByte.TryParse(b.Value, out bSByte)) { return(aSByte.CompareTo(bSByte)); } else { return(-1); } } else { if (SByte.TryParse(b.Value, out bSByte)) { return(1); } goto default; } case XmlSpecsHelper.XmlSchemaDataTypeUnsignedByte: //Remember that xsd:unsignedByte is equivalent to Byte in .Net //Extract the Byte Values and compare byte aByte, bByte; if (Byte.TryParse(a.Value, out aByte)) { if (Byte.TryParse(b.Value, out bByte)) { return(aByte.CompareTo(bByte)); } else { return(-1); } } else { if (Byte.TryParse(b.Value, out bByte)) { return(1); } else { goto default; } } case XmlSpecsHelper.XmlSchemaDataTypeInt: case XmlSpecsHelper.XmlSchemaDataTypeInteger: case XmlSpecsHelper.XmlSchemaDataTypeLong: case XmlSpecsHelper.XmlSchemaDataTypeShort: //Extract the Integer Values and compare long aInt64, bInt64; if (Int64.TryParse(a.Value, out aInt64)) { if (Int64.TryParse(b.Value, out bInt64)) { return(aInt64.CompareTo(bInt64)); } else { return(-1); } } else { if (Int64.TryParse(b.Value, out bInt64)) { return(1); } else { goto default; } } case XmlSpecsHelper.XmlSchemaDataTypeNegativeInteger: case XmlSpecsHelper.XmlSchemaDataTypeNonPositiveInteger: //Extract the Integer Values, ensure negative and compare long aNegInt, bNegInt; if (Int64.TryParse(a.Value, out aNegInt)) { if (Int64.TryParse(b.Value, out bNegInt)) { if (aNegInt >= 0) { if (bNegInt >= 0) { goto default; } else { return(1); } } else if (bNegInt >= 0) { return(-1); } else { return(aNegInt.CompareTo(bNegInt)); } } else if (aNegInt >= 0) { goto default; } else { return(-1); } } else { if (Int64.TryParse(b.Value, out bNegInt)) { if (bNegInt >= 0) { goto default; } else { return(1); } } else { goto default; } } case XmlSpecsHelper.XmlSchemaDataTypeUnsignedInt: case XmlSpecsHelper.XmlSchemaDataTypeUnsignedLong: case XmlSpecsHelper.XmlSchemaDataTypeUnsignedShort: case XmlSpecsHelper.XmlSchemaDataTypeNonNegativeInteger: case XmlSpecsHelper.XmlSchemaDataTypePositiveInteger: //Unsigned Integers //Note that for NonNegativeInteger and PositiveInteger we don't need to do the //same checking we have to do for their inverse types since parsing into an //Unsigned Long ensures that they must be positive ulong aUInt64, bUInt64; if (UInt64.TryParse(a.Value, out aUInt64)) { if (UInt64.TryParse(b.Value, out bUInt64)) { return(aUInt64.CompareTo(bUInt64)); } else { return(-1); } } else { if (UInt64.TryParse(b.Value, out bUInt64)) { return(1); } else { goto default; } } case XmlSpecsHelper.XmlSchemaDataTypeDouble: //Extract the Double Values and compare double aDouble, bDouble; if (Double.TryParse(a.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out aDouble)) { if (Double.TryParse(b.Value, out bDouble)) { return(aDouble.CompareTo(bDouble)); } else { return(-1); } } else { if (Double.TryParse(b.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out bDouble)) { return(1); } else { goto default; } } case XmlSpecsHelper.XmlSchemaDataTypeDecimal: //Extract the Decimal Values and compare decimal aDecimal, bDecimal; if (decimal.TryParse(a.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out aDecimal)) { if (decimal.TryParse(b.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out bDecimal)) { return(aDecimal.CompareTo(bDecimal)); } else { return(-1); } } else { if (decimal.TryParse(b.Value, out bDecimal)) { return(1); } else { goto default; } } case XmlSpecsHelper.XmlSchemaDataTypeFloat: //Extract the Float Values and compare float aFloat, bFloat; if (Single.TryParse(a.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out aFloat)) { if (Single.TryParse(b.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out bFloat)) { return(aFloat.CompareTo(bFloat)); } else { return(-1); } } else { if (Single.TryParse(b.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out bFloat)) { return(1); } else { goto default; } } case XmlSpecsHelper.XmlSchemaDataTypeHexBinary: //Extract the numeric value of the Hex encoded Binary and compare long aHex, bHex; if (Int64.TryParse(a.Value, System.Globalization.NumberStyles.HexNumber, null, out aHex)) { if (Int64.TryParse(b.Value, System.Globalization.NumberStyles.HexNumber, null, out bHex)) { return(aHex.CompareTo(bHex)); } else { return(-1); } } else { if (Int64.TryParse(b.Value, System.Globalization.NumberStyles.HexNumber, null, out bHex)) { return(1); } else { goto default; } } case XmlSpecsHelper.XmlSchemaDataTypeBase64Binary: //Extract the numeric value of the Base 64 encoded Binary and compare byte[] aBin, bBin; try { aBin = Convert.FromBase64String(a.Value); try { bBin = Convert.FromBase64String(b.Value); if (aBin.Length > bBin.Length) { return(1); } else if (aBin.Length < bBin.Length) { return(-1); } else { for (int i = 0; i < aBin.Length; i++) { if (aBin[i] != bBin[i]) { return(aBin[i].CompareTo(bBin[i])); } } return(0); } } catch { return(-1); } } catch { try { bBin = Convert.FromBase64String(b.Value); return(1); } catch { goto default; } } case XmlSpecsHelper.XmlSchemaDataTypeString: //String Type //Can use Lexical Ordering for thisgoto default; case XmlSpecsHelper.XmlSchemaDataTypeAnyUri: //Uri Type //Try and convert to a URI and use lexical ordering Uri aUri, bUri; try { aUri = UriFactory.Create(a.Value); try { bUri = UriFactory.Create(b.Value); return(ComparisonHelper.CompareUris(aUri, bUri)); } catch { return(-1); } } catch { try { bUri = UriFactory.Create(b.Value); return(1); } catch { goto default; } } case XmlSpecsHelper.XmlSchemaDataTypeDate: case XmlSpecsHelper.XmlSchemaDataTypeDateTime: //Extract the Date Times and compare DateTimeOffset aDateTimeOffset, bDateTimeOffset; if (DateTimeOffset.TryParse(a.Value, out aDateTimeOffset)) { if (DateTimeOffset.TryParse(b.Value, out bDateTimeOffset)) { return(aDateTimeOffset.CompareTo(bDateTimeOffset)); } else { return(-1); } } else { if (DateTimeOffset.TryParse(b.Value, out bDateTimeOffset)) { return(1); } else { goto default; } } case XmlSpecsHelper.XmlSchemaDataTypeDuration: case XmlSpecsHelper.XmlSchemaDataTypeDayTimeDuration: //Extract the TimeSpan's and compare TimeSpan aTimeSpan, bTimeSpan; try { aTimeSpan = XmlConvert.ToTimeSpan(a.Value); try { bTimeSpan = XmlConvert.ToTimeSpan(b.Value); return(aTimeSpan.CompareTo(bTimeSpan)); } catch { return(-1); } } catch { try { bTimeSpan = XmlConvert.ToTimeSpan(b.Value); return(1); } catch { goto default; } } default: //Don't know how to order so use lexical order return(String.CompareOrdinal(a.Value, b.Value)); } } catch { //There was some error suggesting a non-valid value for a type //e.g. "example"^^xsd:integer //In this case just use Lexical Ordering return(String.CompareOrdinal(a.Value, b.Value)); } } } else { //No way of ordering by value if the Data Types are different //Order by Data Type Uri //This is required or the Value ordering between types won't occur correctly return(ComparisonHelper.CompareUris(a.DataType, b.DataType)); } }
/// <summary> /// Ensures that a specific Object Factory type is registered in a Configuration Graph /// </summary> /// <param name="context">Configuration Serialization Context</param> /// <param name="factoryType">Factory Type</param> internal static void EnsureObjectFactory(this ConfigurationSerializationContext context, Type factoryType) { INode dnrType = context.Graph.CreateUriNode(UriFactory.Create(ConfigurationLoader.PropertyType)); INode rdfType = context.Graph.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfType)); String assm = Assembly.GetAssembly(factoryType).FullName; if (assm.Contains(',')) { assm = assm.Substring(0, assm.IndexOf(',')); } //Firstly need to ensure our object factory has been referenced SparqlParameterizedString factoryCheck = new SparqlParameterizedString(); factoryCheck.Namespaces.AddNamespace("dnr", UriFactory.Create(ConfigurationLoader.ConfigurationNamespace)); factoryCheck.CommandText = "ASK WHERE { ?factory a dnr:ObjectFactory ; dnr:type '" + factoryType.FullName + ", " + assm + "' . }"; SparqlResultSet rset = context.Graph.ExecuteQuery(factoryCheck) as SparqlResultSet; if (!rset.Result) { INode factory = context.Graph.CreateBlankNode(); context.Graph.Assert(new Triple(factory, rdfType, context.Graph.CreateUriNode(UriFactory.Create(ConfigurationLoader.ClassObjectFactory)))); context.Graph.Assert(new Triple(factory, dnrType, context.Graph.CreateLiteralNode(factoryType.FullName + ", " + assm))); } }
public void NodeAsValuedDateTime3() { INode orig = _graph.CreateLiteralNode("2013-06-19T09:58:00-07:00", UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeDateTime)); IValuedNode valued = orig.AsValuedNode(); Assert.Equal(16, valued.AsDateTime().Hour); Assert.Equal(DateTimeKind.Utc, valued.AsDateTime().Kind); }
/// <summary> /// A Function which attempts to reduce a Uri to a QName and issues a Temporary Namespace if required /// </summary> /// <param name="uri">The Uri to attempt to reduce</param> /// <param name="qname">The value to output the QName to if possible</param> /// <param name="tempNamespace">The Temporary Namespace issued (if any)</param> /// <returns></returns> /// <remarks> /// <para> /// This function will always returns a possible QName for the URI if the format of the URI permits it. It doesn't guarentee that the QName will be valid for the syntax it is being written to - it is up to implementers of writers to validate the QNames returned. /// </para> /// <para> /// Where necessary a Temporary Namespace will be issued and the <paramref name="tempNamespace">tempNamespace</paramref> parameter will be set to the prefix of the new temporary namespace /// </para> /// </remarks> public bool ReduceToQName(String uri, out String qname, out String tempNamespace) { tempNamespace = String.Empty; // See if we've cached this mapping QNameMapping mapping; if (_mapping.TryGetValue(uri, out mapping)) { qname = mapping.QName; return(true); } mapping = new QNameMapping(uri); // Try and find a Namespace URI that is the prefix of the URI foreach (Uri u in _uris.Values) { String baseuri = u.AbsoluteUri; // Does the Uri start with the Base Uri if (uri.StartsWith(baseuri)) { // Remove the Base Uri from the front of the Uri qname = uri.Substring(baseuri.Length); // Add the Prefix back onto the front plus the colon to give a QName if (_prefixes.ContainsKey(u.GetEnhancedHashCode())) { qname = _prefixes[u.GetEnhancedHashCode()] + ":" + qname; if (qname.Equals(":")) { continue; } if (qname.Contains("/") || qname.Contains("#")) { continue; } // Cache the Mapping mapping.QName = qname; AddToCache(uri, mapping); return(true); } } } // Try and issue a Temporary Namespace String nsUri, nsPrefix; if (uri.Contains('#')) { nsUri = uri.Substring(0, uri.LastIndexOf('#') + 1); nsPrefix = GetNextTemporaryNamespacePrefix(); } else if (uri.LastIndexOf('/') > 8) { nsUri = uri.Substring(0, uri.LastIndexOf('/') + 1); nsPrefix = GetNextTemporaryNamespacePrefix(); } else { // Failed to find a Reduction and unable to issue a Temporary Namespace qname = String.Empty; return(false); } // Add to Namespace Map AddNamespace(nsPrefix, UriFactory.Create(nsUri)); // Cache mapping and return mapping.QName = nsPrefix + ":" + uri.Replace(nsUri, String.Empty); AddToCache(uri, mapping); qname = mapping.QName; tempNamespace = nsPrefix; return(true); }
/// <summary> /// Helper function for Resolving QNames to URIs /// </summary> /// <param name="qname">QName to resolve to a Uri</param> /// <returns></returns> public virtual Uri ResolveQName(String qname) { return(UriFactory.Create(Tools.ResolveQName(qname, this._nsmapper, this._baseuri))); }
/// <summary> /// Creates a new URI Node that refers to the Base Uri of the Graph /// </summary> /// <returns></returns> public virtual IUriNode CreateUriNode() { return(new UriNode(this, UriFactory.Create(Tools.ResolveUri(String.Empty, this._baseuri.ToSafeString())))); }
/// <summary> /// Generic Helper Function which Resolves Uri References against a Base Uri /// </summary> /// <param name="uriref">Uri Reference to resolve</param> /// <param name="baseUri">Base Uri to resolve against</param> /// <returns>Resolved Uri as a String</returns> /// <exception cref="RdfParseException">RDF Parse Exception if the Uri cannot be resolved for a know reason</exception> /// <exception cref="UriFormatException">Uri Format Exception if one/both of the URIs is malformed</exception> public static String ResolveUri(String uriref, String baseUri) { if (!baseUri.Equals(String.Empty)) { if (uriref.Equals(String.Empty)) { //Empty Uri reference refers to the Base Uri return(UriFactory.Create(Tools.FixMalformedUriStrings(baseUri)).AbsoluteUri); } else { //Resolve the Uri by combining the Absolute/Relative Uri with the in-scope Base Uri Uri u = new Uri(Tools.FixMalformedUriStrings(uriref), UriKind.RelativeOrAbsolute); if (u.IsAbsoluteUri) { //Uri Reference is an Absolute Uri so no need to resolve against Base Uri return(u.AbsoluteUri); } else { Uri b = UriFactory.Create(Tools.FixMalformedUriStrings(baseUri)); //Check that the Base Uri is valid for resolving Relative URIs //If the Uri Reference is a Fragment ID then Base Uri validity is irrelevant //We have to use ToString() here because this is a Relative URI so AbsoluteUri would be invalid here if (u.ToString().StartsWith("#")) { return(Tools.ResolveUri(u, b).AbsoluteUri); } else if (Tools.IsValidBaseUri(b)) { return(Tools.ResolveUri(u, b).AbsoluteUri); } else { throw new RdfParseException("Cannot resolve a URI since the Base URI is not a valid for resolving Relative URIs against"); } } } } else { if (uriref.Equals(String.Empty)) { throw new RdfParseException("Cannot use an Empty URI to refer to the document Base URI since there is no in-scope Base URI!"); } try { return(new Uri(Tools.FixMalformedUriStrings(uriref), UriKind.Absolute).AbsoluteUri); } #if PORTABLE catch (FormatException) #else catch (UriFormatException) #endif { throw new RdfParseException("Cannot resolve a Relative URI Reference since there is no in-scope Base URI!"); } } }