/// <summary> /// Get the string representation of <see cref="ODataPath"/>. /// mainly translate Context Url path. /// </summary> /// <param name="path">Path to perform the computation on.</param> /// <returns>The string representation of the Context Url path.</returns> public static string ToContextUrlPathString(this ODataPath path) { StringBuilder pathString = new StringBuilder(); PathSegmentToContextUrlPathTranslator pathTranslator = PathSegmentToContextUrlPathTranslator.DefaultInstance; ODataPathSegment priorSegment = null; foreach (ODataPathSegment segment in path) { OperationSegment operationSegment = segment as OperationSegment; if (operationSegment != null) { bool isBoundPath = false; if (priorSegment != null) { foreach (IEdmOperation operation in operationSegment.Operations) { if (operation.IsBound && operation.Parameters.First().Type.Definition == priorSegment.EdmType) { if (operation.EntitySetPath != null) { foreach (string pathSegment in operation.EntitySetPath.PathSegments.Skip(1)) { pathString.Append('/'); pathString.Append(pathSegment); } isBoundPath = true; } break; } } } if (!isBoundPath) { if (operationSegment.EntitySet != null) { pathString = new StringBuilder(); pathString.Append(operationSegment.EntitySet.Name); } else { return(null); } } } else { pathString.Append(segment.TranslateWith(pathTranslator)); } priorSegment = segment; } return(pathString.ToString().TrimStart('/')); }
/// <summary> /// Check if this segment is equal to another segment. /// </summary> /// <param name="other">the other segment to check.</param> /// <returns>true if the other segment is equal.</returns> /// <exception cref="System.ArgumentNullException">Throws if the input other is null.</exception> internal override bool Equals(ODataPathSegment other) { ExceptionUtils.CheckArgumentNotNull(other, "other"); OperationSegment otherOperation = other as OperationSegment; return(otherOperation != null && otherOperation.Operations.SequenceEqual(this.Operations) && otherOperation.EntitySet == this.entitySet); }
/// <summary> /// Translate a OperationSegment /// </summary> /// <param name="segment">the segment to Translate</param> /// <returns>Defined by the implementer.</returns> public override string Translate(OperationSegment segment) { Debug.Assert(segment != null, "segment != null"); string res = null; NodeToStringBuilder nodeToStringBuilder = new NodeToStringBuilder(); foreach (OperationSegmentParameter operationSegmentParameter in segment.Parameters) { string tmp = nodeToStringBuilder.TranslateNode((QueryNode)operationSegmentParameter.Value); res = String.Concat(res, String.IsNullOrEmpty(res) ? null : ExpressionConstants.SymbolComma, operationSegmentParameter.Name, ExpressionConstants.SymbolEqual, tmp); } return(String.IsNullOrEmpty(res) ? String.Concat("/", segment.Operations.OperationGroupFullName()) : String.Concat("/", segment.Operations.OperationGroupFullName(), ExpressionConstants.SymbolOpenParen, res, ExpressionConstants.SymbolClosedParen)); }
/// <summary> /// Tries to bind a given token as an Operation. /// </summary> /// <param name="pathToken">Token to bind.</param> /// <param name="model">The model.</param> /// <param name="entityType">the current entity type to use as the binding type when looking for operations.</param> /// <param name="segment">Bound segment if the token was bound to an operation successfully, or null.</param> /// <returns>True if the token was bound successfully, or false otherwise.</returns> internal static bool TryBindAsOperation(PathSegmentToken pathToken, IEdmModel model, IEdmStructuredType entityType, out ODataPathSegment segment) { Debug.Assert(pathToken != null, "pathToken != null"); Debug.Assert(entityType != null, "bindingType != null"); IEnumerable <IEdmOperation> possibleFunctions = Enumerable.Empty <IEdmOperation>(); IList <string> parameterNames = new List <string>(); // Catch all catchable exceptions as FindDeclaredBoundOperations is implemented by anyone. // If an exception occurs it will be suppressed and the possible functions will be empty and return false. try { int wildCardPos = pathToken.Identifier.IndexOf("*", StringComparison.Ordinal); if (wildCardPos > -1) { string namespaceName = pathToken.Identifier.Substring(0, wildCardPos - 1); possibleFunctions = model.FindBoundOperations(entityType).Where(o => o.Namespace == namespaceName); } else { NonSystemToken nonSystemToken = pathToken as NonSystemToken; if (nonSystemToken != null && nonSystemToken.NamedValues != null) { parameterNames = nonSystemToken.NamedValues.Select(s => s.Name).ToList(); } if (parameterNames.Count > 0) { // Always force to use fully qualified name when select operation possibleFunctions = model.FindBoundOperations(entityType).FilterByName(true, pathToken.Identifier).FilterOperationsByParameterNames(parameterNames, false); } else { possibleFunctions = model.FindBoundOperations(entityType).FilterByName(true, pathToken.Identifier); } } } catch (Exception exc) { if (!ExceptionUtils.IsCatchableExceptionType(exc)) { throw; } } // Only filter if there is more than one and its needed. if (possibleFunctions.Count() > 1) { possibleFunctions = possibleFunctions.FilterBoundOperationsWithSameTypeHierarchyToTypeClosestToBindingType(entityType); } // If more than one overload matches, try to select based on optional parameters if (possibleFunctions.Count() > 1 && parameterNames.Count > 0) { possibleFunctions = possibleFunctions.FilterOverloadsBasedOnParameterCount(parameterNames.Count); } if (!possibleFunctions.HasAny()) { segment = null; return(false); } possibleFunctions.EnsureOperationsBoundWithBindingParameter(); segment = new OperationSegment(possibleFunctions, null /*entitySet*/); return(true); }
/// <summary> /// Translate an OperationSegment /// </summary> /// <param name="segment">the segment to Translate</param> /// <returns>Defined by the implementer.</returns> public override string Translate(OperationSegment segment) { Debug.Assert(segment != null, "segment != null"); return("/" + segment.Operations.OperationGroupFullName()); }
/// <summary> /// Handle an OperationSegment /// </summary> /// <param name="segment">the segment to Handle</param> public virtual void Handle(OperationSegment segment) { throw new NotImplementedException(); }
/// <summary> /// Get the string representation of <see cref="ODataPath"/>. /// mainly translate Context Url path. /// </summary> /// <param name="path">Path to perform the computation on.</param> /// <returns>The string representation of the Context Url path.</returns> public static string ToContextUrlPathString(this ODataPath path) { StringBuilder pathString = new StringBuilder(); PathSegmentToContextUrlPathTranslator pathTranslator = PathSegmentToContextUrlPathTranslator.DefaultInstance; ODataPathSegment priorSegment = null; bool foundOperationWithoutPath = false; foreach (ODataPathSegment segment in path) { OperationSegment operationSegment = segment as OperationSegment; OperationImportSegment operationImportSegment = segment as OperationImportSegment; if (operationImportSegment != null) { IEdmOperationImport operationImport = operationImportSegment.OperationImports.FirstOrDefault(); Debug.Assert(operationImport != null); EdmPathExpression pathExpression = operationImport.EntitySet as EdmPathExpression; if (pathExpression != null) { Debug.Assert(priorSegment == null); // operation import is always the first segment? pathString.Append(pathExpression.Path); } else { pathString = operationImport.Operation.ReturnType != null ? new StringBuilder(operationImport.Operation.ReturnType.FullName()) : new StringBuilder("Edm.Untyped"); foundOperationWithoutPath = true; } } else if (operationSegment != null) { IEdmOperation operation = operationSegment.Operations.FirstOrDefault(); Debug.Assert(operation != null); if (operation.IsBound && priorSegment != null && operation.Parameters.First().Type.Definition == priorSegment.EdmType) { if (operation.EntitySetPath != null) { foreach (string pathSegment in operation.EntitySetPath.PathSegments.Skip(1)) { pathString.Append('/'); pathString.Append(pathSegment); } } else if (operationSegment.EntitySet != null) { // Is it correct to check EntitySet? pathString = new StringBuilder(operationSegment.EntitySet.Name); } else { pathString = operation.ReturnType != null ? new StringBuilder(operation.ReturnType.FullName()) : new StringBuilder("Edm.Untyped"); foundOperationWithoutPath = true; } } } else { if (foundOperationWithoutPath) { pathString = new StringBuilder(segment.EdmType.FullTypeName()); foundOperationWithoutPath = false; } else { pathString.Append(segment.TranslateWith(pathTranslator)); } } priorSegment = segment; } return(pathString.ToString().TrimStart('/')); }
/// <summary> /// Handle an OperationSegment /// </summary> /// <param name="segment">the segment to Handle</param> public override void Handle(OperationSegment segment) { CommonHandler(segment); }
/// <summary> /// Translate an OperationSegment /// </summary> /// <param name="segment">the segment to Translate</param> /// <returns>Defined by the implementer.</returns> public virtual T Translate(OperationSegment segment) { throw new NotImplementedException(); }
/// <summary> /// Determine the NavigationSource of an OperationSegment /// </summary> /// <param name="segment">The OperationSegment to look in.</param> /// <returns>The IEdmNavigationSource of this OperationSegment</returns> /// <exception cref="System.ArgumentNullException">Throws if the input segment is null.</exception> public override IEdmNavigationSource Translate(OperationSegment segment) { ExceptionUtils.CheckArgumentNotNull(segment, "segment"); return(segment.EntitySet); }