/// <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"); DynamicPathSegment otherDynamicPathSegment = other as DynamicPathSegment; return(otherDynamicPathSegment != null && otherDynamicPathSegment.Identifier == this.Identifier && otherDynamicPathSegment.EdmType == this.EdmType && otherDynamicPathSegment.TargetEdmNavigationSource == this.TargetEdmNavigationSource && otherDynamicPathSegment.SingleResult == this.SingleResult); }
/// <summary> /// Translate an OpenPropertySegment /// </summary> /// <param name="segment">the segment to Translate</param> /// <returns>Defined by the implementer.</returns> public override string Translate(DynamicPathSegment segment) { Debug.Assert(segment != null, "segment != null"); return("/" + segment.Identifier); }
/// <summary> /// Process a <see cref="PathSegmentToken"/> following any type segments if necessary. /// </summary> /// <param name="tokenIn">the path token to process.</param> private List <ODataPathSegment> ProcessSelectTokenPath(PathSegmentToken tokenIn) { Debug.Assert(tokenIn != null, "tokenIn != null"); List <ODataPathSegment> pathSoFar = new List <ODataPathSegment>(); IEdmStructuredType currentLevelType = this.edmType; // first, walk through all type segments in a row, converting them from tokens into segments. if (tokenIn.IsNamespaceOrContainerQualified() && !UriParserHelper.IsAnnotation(tokenIn.Identifier)) { PathSegmentToken firstNonTypeToken; pathSoFar.AddRange(SelectExpandPathBinder.FollowTypeSegments(tokenIn, this.Model, this.Settings.SelectExpandLimit, this.configuration.Resolver, ref currentLevelType, out firstNonTypeToken)); Debug.Assert(firstNonTypeToken != null, "Did not get last token."); tokenIn = firstNonTypeToken as NonSystemToken; if (tokenIn == null) { throw new ODataException(ODataErrorStrings.SelectExpandBinder_SystemTokenInSelect(firstNonTypeToken.Identifier)); } } // next, create a segment for the first non-type segment in the path. ODataPathSegment lastSegment = SelectPathSegmentTokenBinder.ConvertNonTypeTokenToSegment(tokenIn, this.Model, currentLevelType, this.configuration.Resolver, this.state); // next, create an ODataPath and add the segments to it. if (lastSegment != null) { pathSoFar.Add(lastSegment); // try create a complex type property path. while (true) { // no need to go on if the current property is not of complex type or collection of complex type, // unless the segment is a primitive type cast or a property on an open complex property. currentLevelType = lastSegment.EdmType as IEdmStructuredType; IEdmCollectionType collectionType = lastSegment.EdmType as IEdmCollectionType; IEdmPrimitiveType primitiveType = lastSegment.EdmType as IEdmPrimitiveType; DynamicPathSegment dynamicPath = lastSegment as DynamicPathSegment; if ((currentLevelType == null || currentLevelType.TypeKind != EdmTypeKind.Complex) && (collectionType == null || collectionType.ElementType.TypeKind() != EdmTypeKind.Complex) && (primitiveType == null || primitiveType.TypeKind != EdmTypeKind.Primitive) && (dynamicPath == null || tokenIn.NextToken == null)) { break; } NonSystemToken nextToken = tokenIn.NextToken as NonSystemToken; if (nextToken == null) { break; } if (UriParserHelper.IsAnnotation(nextToken.Identifier)) { lastSegment = SelectPathSegmentTokenBinder.ConvertNonTypeTokenToSegment(nextToken, this.Model, currentLevelType, this.configuration.Resolver, null); } else if (primitiveType == null && dynamicPath == null) { // This means last segment a collection of complex type, // current segment can only be type cast and cannot be property name. if (currentLevelType == null) { currentLevelType = collectionType.ElementType.Definition as IEdmStructuredType; } // If there is no collection type in the path yet, will try to bind property for the next token // first try bind the segment as property. lastSegment = SelectPathSegmentTokenBinder.ConvertNonTypeTokenToSegment(nextToken, this.Model, currentLevelType, this.configuration.Resolver, null); } else { // determine whether we are looking at a type cast or a dynamic path segment. EdmPrimitiveTypeKind nextTypeKind = EdmCoreModel.Instance.GetPrimitiveTypeKind(nextToken.Identifier); IEdmPrimitiveType castType = EdmCoreModel.Instance.GetPrimitiveType(nextTypeKind); if (castType != null) { lastSegment = new TypeSegment(castType, castType, null); } else if (dynamicPath != null) { lastSegment = new DynamicPathSegment(nextToken.Identifier); } else { throw new ODataException(ODataErrorStrings.SelectBinder_MultiLevelPathInSelect); } } // then try bind the segment as type cast. if (lastSegment == null) { IEdmStructuredType typeFromNextToken = UriEdmHelpers.FindTypeFromModel(this.Model, nextToken.Identifier, this.configuration.Resolver) as IEdmStructuredType; if (typeFromNextToken.IsOrInheritsFrom(currentLevelType)) { lastSegment = new TypeSegment(typeFromNextToken, /*entitySet*/ null); } } // type cast failed too. if (lastSegment == null) { break; } // try move to and add next path segment. tokenIn = nextToken; pathSoFar.Add(lastSegment); } } // non-navigation cases do not allow further segments in $select. if (tokenIn.NextToken != null) { throw new ODataException(ODataErrorStrings.SelectBinder_MultiLevelPathInSelect); } // Later, we can consider to create a "DynamicOperationSegment" to handle this. // But now, Let's throw exception. if (lastSegment == null) { throw new ODataException(ODataErrorStrings.MetadataBinder_InvalidIdentifierInQueryOption(tokenIn.Identifier)); } // navigation property is not allowed to append sub path in the selection. NavigationPropertySegment navPropSegment = pathSoFar.LastOrDefault() as NavigationPropertySegment; if (navPropSegment != null && tokenIn.NextToken != null) { throw new ODataException(ODataErrorStrings.SelectBinder_MultiLevelPathInSelect); } return(pathSoFar); }
/// <summary> /// Translate an OpenPropertySegment /// </summary> /// <param name="segment">the segment to Translate</param> /// <returns>UserDefinedValue</returns> /// <exception cref="System.ArgumentNullException">Throws if the input segment is null.</exception> public override bool Translate(DynamicPathSegment segment) { ExceptionUtils.CheckArgumentNotNull(segment, "segment"); return(false); }
/// <summary> /// Handle an OpenPropertySegment /// </summary> /// <param name="segment">the segment to Handle</param> public virtual void Handle(DynamicPathSegment segment) { throw new NotImplementedException(); }
/// <summary> /// Handle an OpenPropertySegment /// </summary> /// <param name="segment">the segment to Handle</param> public override void Handle(DynamicPathSegment segment) { CommonHandler(segment); }
private void ProcessTokenAsPath(NonSystemToken tokenIn) { Debug.Assert(tokenIn != null, "tokenIn != null"); List <ODataPathSegment> pathSoFar = new List <ODataPathSegment>(); IEdmStructuredType currentLevelType = this.edmType; // first, walk through all type segments in a row, converting them from tokens into segments. if (tokenIn.IsNamespaceOrContainerQualified() && !UriParserHelper.IsAnnotation(tokenIn.Identifier)) { PathSegmentToken firstNonTypeToken; pathSoFar.AddRange(SelectExpandPathBinder.FollowTypeSegments(tokenIn, this.model, this.maxDepth, this.resolver, ref currentLevelType, out firstNonTypeToken)); Debug.Assert(firstNonTypeToken != null, "Did not get last token."); tokenIn = firstNonTypeToken as NonSystemToken; if (tokenIn == null) { throw new ODataException(ODataErrorStrings.SelectPropertyVisitor_SystemTokenInSelect(firstNonTypeToken.Identifier)); } } // next, create a segment for the first non-type segment in the path. ODataPathSegment lastSegment = SelectPathSegmentTokenBinder.ConvertNonTypeTokenToSegment(tokenIn, this.model, currentLevelType, resolver, this.state); // next, create an ODataPath and add the segments to it. if (lastSegment != null) { pathSoFar.Add(lastSegment); // try create a complex type property path. while (true) { // no need to go on if the current property is not of complex type or collection of complex type, // unless the segment is a primitive type cast or a property on an open complex property. currentLevelType = lastSegment.EdmType as IEdmStructuredType; IEdmCollectionType collectionType = lastSegment.EdmType as IEdmCollectionType; IEdmPrimitiveType primitiveType = lastSegment.EdmType as IEdmPrimitiveType; DynamicPathSegment dynamicPath = lastSegment as DynamicPathSegment; if ((currentLevelType == null || currentLevelType.TypeKind != EdmTypeKind.Complex) && (collectionType == null || collectionType.ElementType.TypeKind() != EdmTypeKind.Complex) && (primitiveType == null || primitiveType.TypeKind != EdmTypeKind.Primitive) && (dynamicPath == null || tokenIn.NextToken == null)) { break; } NonSystemToken nextToken = tokenIn.NextToken as NonSystemToken; if (nextToken == null) { break; } if (UriParserHelper.IsAnnotation(nextToken.Identifier)) { lastSegment = SelectPathSegmentTokenBinder.ConvertNonTypeTokenToSegment(nextToken, this.model, currentLevelType, resolver, null); } else if (primitiveType == null && dynamicPath == null) { // This means last segment a collection of complex type, // current segment can only be type cast and cannot be property name. if (currentLevelType == null) { currentLevelType = collectionType.ElementType.Definition as IEdmStructuredType; } // If there is no collection type in the path yet, will try to bind property for the next token // first try bind the segment as property. lastSegment = SelectPathSegmentTokenBinder.ConvertNonTypeTokenToSegment(nextToken, this.model, currentLevelType, resolver, null); } else { // determine whether we are looking at a type cast or a dynamic path segment. EdmPrimitiveTypeKind nextTypeKind = EdmCoreModel.Instance.GetPrimitiveTypeKind(nextToken.Identifier); IEdmPrimitiveType castType = EdmCoreModel.Instance.GetPrimitiveType(nextTypeKind); if (castType != null) { lastSegment = new TypeSegment(castType, castType, null); } else if (dynamicPath != null) { lastSegment = new DynamicPathSegment(nextToken.Identifier); } else { throw new ODataException(ODataErrorStrings.SelectBinder_MultiLevelPathInSelect); } } // then try bind the segment as type cast. if (lastSegment == null) { IEdmStructuredType typeFromNextToken = UriEdmHelpers.FindTypeFromModel(this.model, nextToken.Identifier, this.resolver) as IEdmStructuredType; if (typeFromNextToken.IsOrInheritsFrom(currentLevelType)) { lastSegment = new TypeSegment(typeFromNextToken, /*entitySet*/ null); } } // type cast failed too. if (lastSegment == null) { break; } // try move to and add next path segment. tokenIn = nextToken; pathSoFar.Add(lastSegment); } } ODataSelectPath selectedPath = new ODataSelectPath(pathSoFar); var selectionItem = new PathSelectItem(selectedPath); // non-navigation cases do not allow further segments in $select. if (tokenIn.NextToken != null) { throw new ODataException(ODataErrorStrings.SelectBinder_MultiLevelPathInSelect); } // if the selected item is a nav prop, then see if its already there before we add it. NavigationPropertySegment trailingNavPropSegment = selectionItem.SelectedPath.LastSegment as NavigationPropertySegment; if (trailingNavPropSegment != null) { if (this.expandClauseToDecorate.SelectedItems.Any(x => x is PathSelectItem && ((PathSelectItem)x).SelectedPath.Equals(selectedPath))) { return; } } this.expandClauseToDecorate.AddToSelectedItems(selectionItem); }
/// <summary> /// Translate an OpenPropertySegment /// </summary> /// <param name="segment">the segment to Translate</param> /// <returns>Defined by the implementer.</returns> public virtual T Translate(DynamicPathSegment segment) { throw new NotImplementedException(); }
/// <summary> /// Determine the NavigationSource of a OpenPropertySegment /// </summary> /// <param name="segment">The OpenPropertySegment to look in.</param> /// <returns>null, since an OpenProperty doesn't have an navigation source</returns> /// <exception cref="System.ArgumentNullException">Throws if the input segment is null.</exception> public override IEdmNavigationSource Translate(DynamicPathSegment segment) { ExceptionUtils.CheckArgumentNotNull(segment, "segment"); return(null); }