/// <summary> /// Try to parse the given text by each parser. /// </summary> /// <param name="text">Part of the Uri which has to be parsed to a value of EdmType <paramref name="targetType"/></param> /// <param name="targetType">The type which the uri text has to be parsed to</param> /// <param name="parsingException">Assign the exception only in case the text could be parsed to the <paramref name="targetType"/> but failed during the parsing process</param> /// <returns>If the parsing proceess has succeeded, returns the parsed object, otherwise returns 'Null'</returns> public object ParseUriStringToType(string text, IEdmTypeReference targetType, out UriLiteralParsingException parsingException) { parsingException = null; object targetValue; // Try to parse the uri text with each parser foreach (IUriLiteralParser uriTypeParser in uriTypeParsers) { targetValue = uriTypeParser.ParseUriStringToType(text, targetType, out parsingException); // Stop in case the parser has returned an excpetion if (parsingException != null) { return null; } // In case of no exception and no value - The parse cannot parse the given text if (targetValue != null) { return targetValue; } } return null; }
public object ParseUriStringToType(string text, IEdmTypeReference targetType, out UriLiteralParsingException parsingException) { object targetValue; if (this.TryUriStringToPrimitive(text, targetType, out targetValue, out parsingException)) { return targetValue; } return null; }
/// <summary> /// Parse the given uri text. /// Try to parse with a specific Uri literal parser regeistered for the target EdmType. /// If no parser is registered, try to parse with the general parsers. /// This method is public becuase of the Interface, but the Singleton instance in internal so it could not be accessed by clients. /// </summary> /// <param name="text">Part of the Uri which has to be parsed to a value of EdmType <paramref name="targetType"/></param> /// <param name="targetType">The type which the uri text has to be parsed to</param> /// <param name="parsingException">Assign the exception only in case the text could be parsed to the <paramref name="targetType"/> but failed during the parsing process</param> /// <returns>If parsing proceess has succeeded, returns the parsed object, otherwise returns 'Null'</returns> public object ParseUriStringToType(string text, IEdmTypeReference targetType, out UriLiteralParsingException parsingException) { object targetValue; lock (Locker) { // Search for Uri literal parser which is registered for the given EdmType IUriLiteralParser uriLiteralParserForEdmType = GetUriLiteralParserByEdmType(targetType); if (uriLiteralParserForEdmType != null) { return uriLiteralParserForEdmType.ParseUriStringToType(text, targetType, out parsingException); } // Parse with all the general parsers // Stop when a parser succeeded parsing the text. foreach (IUriLiteralParser customUriLiteralParser in customUriLiteralParsers) { // Try to parse targetValue = customUriLiteralParser.ParseUriStringToType(text, targetType, out parsingException); // The uriCustomParser could parse the given targetType but failed during the parsing proccess if (parsingException != null) { return null; } // In case of no exception and no value - The parse cannot parse the given text if (targetValue != null) { return targetValue; } } } // No uriCustomParser could parse the requested uri text. parsingException = null; return null; }
/// <summary>Creates an exception for a parse error.</summary> /// <param name="message">Message text.</param> /// <param name="parsingException">Type Parsing exception</param> /// <returns>A new Exception.</returns> private static Exception ParseError(string message, UriLiteralParsingException parsingException) { return new ODataException(message, parsingException); }
private bool TryUriStringToPrimitive(string text, IEdmTypeReference targetType, out object targetValue, out UriLiteralParsingException exception) { Debug.Assert(text != null, "text != null"); Debug.Assert(targetType != null, "targetType != null"); exception = null; try { if (targetType.IsNullable) { // COMPAT 38: Product does not support "null" literals in service operation arguments // check for the 'null' constant for nullable types if (text == ExpressionConstants.KeywordNull) { targetValue = null; return true; } } IEdmPrimitiveTypeReference primitiveTargetType = targetType.AsPrimitiveOrNull(); if (primitiveTargetType == null) { targetValue = null; return false; } EdmPrimitiveTypeKind targetTypeKind = primitiveTargetType.PrimitiveKind(); byte[] byteArrayValue; bool binaryResult = TryUriStringToByteArray(text, out byteArrayValue); if (targetTypeKind == EdmPrimitiveTypeKind.Binary) { targetValue = (object)byteArrayValue; return binaryResult; } else if (binaryResult) { string keyValue = Encoding.UTF8.GetString(byteArrayValue, 0, byteArrayValue.Length); return TryUriStringToPrimitive(keyValue, targetType, out targetValue); } else if (targetTypeKind == EdmPrimitiveTypeKind.Guid) { Guid guidValue; bool result = UriUtils.TryUriStringToGuid(text, out guidValue); targetValue = guidValue; return result; } else if (targetTypeKind == EdmPrimitiveTypeKind.Date) { Date dateValue; bool result = UriUtils.TryUriStringToDate(text, out dateValue); targetValue = dateValue; return result; } else if (targetTypeKind == EdmPrimitiveTypeKind.DateTimeOffset) { DateTimeOffset dateTimeOffsetValue; bool result = UriUtils.ConvertUriStringToDateTimeOffset(text, out dateTimeOffsetValue); targetValue = dateTimeOffsetValue; return result; } else if (targetTypeKind == EdmPrimitiveTypeKind.Duration) { TimeSpan timespanValue; bool result = TryUriStringToDuration(text, out timespanValue); targetValue = timespanValue; return result; } else if (targetTypeKind == EdmPrimitiveTypeKind.Geography) { Geography geographyValue; bool result = TryUriStringToGeography(text, out geographyValue, out exception); targetValue = geographyValue; return result; } else if (targetTypeKind == EdmPrimitiveTypeKind.Geometry) { Geometry geometryValue; bool result = TryUriStringToGeometry(text, out geometryValue, out exception); targetValue = geometryValue; return result; } else if (targetTypeKind == EdmPrimitiveTypeKind.TimeOfDay) { TimeOfDay timeOfDayValue; bool result = UriUtils.TryUriStringToTimeOfDay(text, out timeOfDayValue); targetValue = timeOfDayValue; return result; } bool quoted = targetTypeKind == EdmPrimitiveTypeKind.String; if (quoted != UriParserHelper.IsUriValueQuoted(text)) { targetValue = null; return false; } if (quoted) { text = UriParserHelper.RemoveQuotes(text); } try { switch (targetTypeKind) { case EdmPrimitiveTypeKind.String: targetValue = text; break; case EdmPrimitiveTypeKind.Boolean: targetValue = XmlConvert.ToBoolean(text); break; case EdmPrimitiveTypeKind.Byte: targetValue = XmlConvert.ToByte(text); break; case EdmPrimitiveTypeKind.SByte: targetValue = XmlConvert.ToSByte(text); break; case EdmPrimitiveTypeKind.Int16: targetValue = XmlConvert.ToInt16(text); break; case EdmPrimitiveTypeKind.Int32: targetValue = XmlConvert.ToInt32(text); break; case EdmPrimitiveTypeKind.Int64: UriParserHelper.TryRemoveLiteralSuffix(ExpressionConstants.LiteralSuffixInt64, ref text); targetValue = XmlConvert.ToInt64(text); break; case EdmPrimitiveTypeKind.Single: UriParserHelper.TryRemoveLiteralSuffix(ExpressionConstants.LiteralSuffixSingle, ref text); targetValue = XmlConvert.ToSingle(text); break; case EdmPrimitiveTypeKind.Double: UriParserHelper.TryRemoveLiteralSuffix(ExpressionConstants.LiteralSuffixDouble, ref text); targetValue = XmlConvert.ToDouble(text); break; case EdmPrimitiveTypeKind.Decimal: UriParserHelper.TryRemoveLiteralSuffix(ExpressionConstants.LiteralSuffixDecimal, ref text); try { targetValue = XmlConvert.ToDecimal(text); } catch (FormatException) { // we need to support exponential format for decimals since we used to support them in V1 decimal result; if (Decimal.TryParse(text, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out result)) { targetValue = result; } else { targetValue = default(Decimal); return false; } } break; default: throw new ODataException(ODataErrorStrings.General_InternalError(InternalErrorCodes.UriPrimitiveTypeParser_TryUriStringToPrimitive)); } return true; } catch (FormatException) { targetValue = null; return false; } catch (OverflowException) { targetValue = null; return false; } } catch (Exception primitiveParserException) { exception = new UriLiteralParsingException( string.Format(CultureInfo.InvariantCulture, ODataErrorStrings.UriPrimitiveTypeParsers_FailedToParseTextToPrimitiveValue(text, targetType), primitiveParserException)); targetValue = null; return false; } }
internal bool TryParseUriStringToType(string text, IEdmTypeReference targetType, out object targetValue, out UriLiteralParsingException parsingException) { return this.TryUriStringToPrimitive(text, targetType, out targetValue, out parsingException); }
/// <summary> /// Try to parse the given text to a Geometry object. /// </summary> /// <param name="text">Text to parse.</param> /// <param name="targetValue">Geometry to return.</param> /// <param name="parsingFailureReasonException">The detailed reason of parsing error.</param> /// <returns>True if succeeds, false if not.</returns> private static bool TryUriStringToGeometry(string text, out Geometry targetValue, out UriLiteralParsingException parsingFailureReasonException) { parsingFailureReasonException = null; if (!UriParserHelper.TryRemoveLiteralPrefix(ExpressionConstants.LiteralPrefixGeometry, ref text)) { targetValue = default(Geometry); return false; } if (!UriParserHelper.TryRemoveQuotes(ref text)) { targetValue = default(Geometry); return false; } try { targetValue = LiteralUtils.ParseGeometry(text); return true; } catch (ParseErrorException e) { targetValue = default(Geometry); parsingFailureReasonException = new UriLiteralParsingException(e.Message); return false; } }
public object ParseUriStringToType(string text, IEdmTypeReference targetType, out UriLiteralParsingException parsingException) { parsingException = null; if (!RegisteredTestCases.Exists(testCase => Environment.StackTrace.ToString().Contains(testCase))) { return null; } if (!targetType.IsEquivalentTo(HeartbeatComplexType)) { return null; } if (text == null) { return null; } // Take care of literals if (!text.StartsWith("myCustomHeartbeatTypePrefixLiteral")) { return null; } text = text.Replace("myCustomHeartbeatTypePrefixLiteral", string.Empty); if (!UriParserHelper.IsUriValueQuoted(text)) { parsingException = new UriLiteralParsingException("Edm.Heartbeat value must be quoted"); return null; } text = UriParserHelper.RemoveQuotes(text); double textIntValue; // Simulates a bug in a client Parser if (double.TryParse(text, out textIntValue)) { return new HeatBeat() { Frequency = textIntValue }; } return null; }
public object ParseUriStringToType(string text, IEdmTypeReference targetType, out UriLiteralParsingException parsingException) { parsingException = null; if (!RegisteredTestCases.Exists(testCase => Environment.StackTrace.ToString().Contains(testCase))) { return null; } if (!targetType.IsEquivalentTo(EdmCoreModel.Instance.GetString(true))) { return null; } if (text == null) { return null; } bool isLiteralPrefixExists = false; // Take care of literals if (text.StartsWith(STRING_LITERAL_PREFIX)) { text = text.Replace(STRING_LITERAL_PREFIX, string.Empty); // If Literal exists, not need of quotes isLiteralPrefixExists = true; } if (!isLiteralPrefixExists && !UriParserHelper.IsUriValueQuoted(text)) { parsingException = new UriLiteralParsingException("Edm.String value must be quoted"); return null; } text = UriParserHelper.RemoveQuotes(text); // Simulates a bug in a client Parser if (text == CUSTOM_PARSER_STRING_VALUE_CAUSEBUG) { parsingException = new UriLiteralParsingException("Parsing to Edm.String has failed for some reasons"); return "RetunsAValueButSupposeToBeNull"; } if (text.StartsWith(CUSTOM_PARSER_STRING_VALID_VALUE)) { return text + CUSTOM_PARSER_STRING_ADDED_VALUE; } return null; }
public object ParseUriStringToBoolean(string text, out UriLiteralParsingException parsingException) { parsingException = null; if (!RegisteredTestCases.Exists(testCase => Environment.StackTrace.ToString().Contains(testCase))) { return null; } // Take care of literals if (text.StartsWith(BOOLEAN_LITERAL_PREFIX)) { text = text.Replace(BOOLEAN_LITERAL_PREFIX, string.Empty); text = UriParserHelper.RemoveQuotes(text); } if (text == CUSTOM_PARSER_BOOLEAN_VALID_VALUE_TRUE) { return true; } else if (text == CUSTOM_PARSER_BOOLEAN_VALUE_TRUE_VALID) { parsingException = new UriLiteralParsingException("Failed to convert boolean."); } else if (text == CUSTOM_PARSER_BOOLEAN_INVALID_VALUE) { parsingException = new UriLiteralParsingException("Failed to convert boolean."); return null; } return null; }
private object ParseUriStringToInt(string text, out UriLiteralParsingException parsingException) { parsingException = null; if (!RegisteredTestCases.Exists(testCase => Environment.StackTrace.ToString().Contains(testCase))) { return null; } if (text == CUSTOM_PARSER_INT_VALID_VALUE) { return 55; } return null; }
public object ParseUriStringToType(string text, IEdmTypeReference targetType, out UriLiteralParsingException parsingException) { if (!RegisteredTestCases.Exists(testCase => Environment.StackTrace.ToString().Contains(testCase))) { parsingException = null; return null; } if (targetType.IsEquivalentTo(EdmCoreModel.Instance.GetBoolean(false))) { return this.ParseUriStringToBoolean(text, out parsingException); } if (targetType.IsEquivalentTo(EdmCoreModel.Instance.GetInt32(false))) { return this.ParseUriStringToInt(text, out parsingException); } parsingException = null; return null; }