Ejemplo n.º 1
0
        public MaximoResult Execute(ApplicationMetadata application, JObject json, string id, string operation)
        {
            var entityMetadata   = MetadataProvider.Entity(application.Entity);
            var operationWrapper = new OperationWrapper(application, entityMetadata, operation, json, id);

            return(_maximoConnectorEngine.Execute(operationWrapper));
        }
Ejemplo n.º 2
0
        public OperationSerializerTests()
        {
            ResourceType intType = ResourceType.GetPrimitiveResourceType(typeof(int));

            var customerType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "FQ.NS", "Customer", false);

            customerType.CanReflectOnInstanceType = false;
            customerType.AddProperty(new ResourceProperty("Id", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, intType)
            {
                CanReflectOnInstanceTypeProperty = false
            });
            customerType.SetReadOnly();

            var operation = new ServiceAction("Action", intType, OperationParameterBindingKind.Sometimes, new[] { new ServiceActionParameter("P1", customerType), new ServiceActionParameter("P2", intType) }, null);

            operation.SetReadOnly();
            this.baseTypeOperation = new OperationWrapper(operation);

            var bestCustomerType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, customerType, "FQ.NS", "BestCustomer", false);

            bestCustomerType.SetReadOnly();

            operation = new ServiceAction("Action", intType, OperationParameterBindingKind.Sometimes, new[] { new ServiceActionParameter("P1", bestCustomerType) }, null);
            operation.SetReadOnly();
            this.derivedTypeOperation = new OperationWrapper(operation);

            operation = new ServiceAction("Unambiguous", intType, OperationParameterBindingKind.Sometimes, new[] { new ServiceActionParameter("P1", customerType) }, null);
            operation.SetReadOnly();
            this.unambiguousOperation = new OperationWrapper(operation);

            this.entityToSerialize = EntityToSerialize.CreateFromExplicitValues(new object(), bestCustomerType, new TestSerializedEntityKey("http://odata.org/Service.svc/Customers(0)/", bestCustomerType.FullName));

            this.testSubject = CreateOperationSerializer(AlwaysAdvertiseActions);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates a segment for a service operation
        /// </summary>
        /// <param name="serviceOperation">The service operation for the segment.</param>
        /// <returns>A fully populated PathSegment representing the service operation</returns>
        private static SegmentInfo CreateSegmentForServiceOperation(OperationWrapper serviceOperation)
        {
            Debug.Assert(serviceOperation != null, "serviceOperation != null");
            WebUtil.DebugEnumIsDefined(serviceOperation.ResultKind);

            SegmentInfo segment = new SegmentInfo
            {
                Identifier        = serviceOperation.Name,
                Operation         = serviceOperation,
                TargetSource      = RequestTargetSource.ServiceOperation,
                TargetResourceSet = serviceOperation.ResourceSet
            };

            if (serviceOperation.ResultKind != ServiceOperationResultKind.Void)
            {
                segment.TargetResourceType = serviceOperation.ResultType;
                segment.TargetKind         = TargetKindFromType(segment.TargetResourceType);

                // this service operation returns results
                // we should check service operation rights
                // SingleResult operations are service operations defined with [SingleResult] attribute, returns a DirectValue
                // or a service operation returning multiple results, but contains key predicates in the query portion.
                // For these operations, you MUST have ReadSingle defined
                // For multiple-result-operations(IQueryable/IEnumerable), you MUST have ReadMultiple defined.
                segment.SingleResult = (serviceOperation.ResultKind == ServiceOperationResultKind.QueryWithSingleResult || serviceOperation.ResultKind == ServiceOperationResultKind.DirectValue);
            }
            else
            {
                segment.TargetResourceType = null;
                segment.TargetKind         = RequestTargetKind.VoidOperation;
            }

            return(segment);
        }
Ejemplo n.º 4
0
 private static bool AlwaysAdvertiseActions(OperationWrapper serviceAction, object resourceInstance, bool resourceInstanceInFeed, ref ODataAction actionToSerialize)
 {
     // the links should always be provided and always be absolute, even if they will be written relative in JSON-Light.
     actionToSerialize.Metadata.Should().NotBeNull().And.Subject.As <Uri>().IsAbsoluteUri.Should().BeTrue();
     actionToSerialize.Target.Should().NotBeNull().And.Subject.As <Uri>().IsAbsoluteUri.Should().BeTrue();
     return(true);
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Gets the IEdmOperationI for a specified <paramref name="serviceOperation"/>.
        /// </summary>
        /// <param name="serviceOperation">The service action or function to get the function import for.</param>
        /// <returns>The function import.</returns>
        protected IEdmOperation GetOperation(OperationWrapper serviceOperation)
        {
            var model = this.Service.Provider.GetMetadataProviderEdmModel();

            model.EnsureDefaultEntityContainer().EnsureOperationImport(serviceOperation);
            return(model.GetRelatedOperation(serviceOperation));
        }
Ejemplo n.º 6
0
 internal static void CheckServiceOperationRights(OperationWrapper operation, bool singleResult)
 {
     if (operation.ResultKind != ServiceOperationResultKind.Void)
     {
         ServiceOperationRights requiredRights = singleResult ? ServiceOperationRights.ReadSingle : ServiceOperationRights.ReadMultiple;
         CheckServiceOperationRights(operation, requiredRights);
     }
 }
Ejemplo n.º 7
0
        internal static void CheckServiceOperationRights(OperationWrapper operation, ServiceOperationRights requiredRights)
        {
            ServiceOperationRights serviceOperationRights = operation.ServiceOperationRights;

            if ((requiredRights & serviceOperationRights) == ServiceOperationRights.None)
            {
                throw DataServiceException.CreateForbidden();
            }
        }
        /// <summary>
        /// Determines if the previous segment can be composed upon.
        /// </summary>
        /// <param name="previous">previous segment info.</param>
        /// <returns>
        ///   <c>true</c> if the segment can be composed upon; otherwise, <c>false</c>.
        /// </returns>
        private static bool IsSegmentComposable(SegmentInfo previous)
        {
            OperationWrapper op = previous.Operation;

            return(op == null ||
                   (op.ResultKind != ServiceOperationResultKind.Enumeration &&
                    op.ResultKind != ServiceOperationResultKind.DirectValue &&
                    (op.ResultKind != ServiceOperationResultKind.QueryWithSingleResult ||
                     op.ResultType.ResourceTypeKind == ResourceTypeKind.EntityType)));
        }
Ejemplo n.º 9
0
        /// <summary>Checks whether this request has the specified rights.</summary>
        /// <param name="operation">Operation to check.</param>
        /// <param name="requiredRights">Required rights.</param>
        /// <exception cref="DataServiceException">Thrown if <paramref name="requiredRights"/> aren't available.</exception>
        internal static void CheckServiceOperationRights(OperationWrapper operation, ServiceOperationRights requiredRights)
        {
            Debug.Assert(operation != null, "operation != null");
            Debug.Assert(requiredRights != ServiceOperationRights.None, "requiredRights != EntitySetRights.None");

            ServiceOperationRights effectiveRights = operation.ServiceOperationRights;

            if ((requiredRights & effectiveRights) == 0)
            {
                throw DataServiceException.CreateForbidden();
            }
        }
Ejemplo n.º 10
0
        /// <summary>Writes multiple top-level elements, possibly none.</summary>
        /// <param name="expanded">Expanded results for elements.</param>
        /// <param name="elements">Enumerator for elements to write.</param>
        protected override void WriteTopLevelElements(IExpandedResult expanded, QueryResultInfo elements)
        {
            Debug.Assert(
                !this.RequestDescription.IsSingleResult,
                "!this.RequestDescription.IsSingleResult -- otherwise WriteTopLevelElement should have been called");

            if (this.RequestDescription.LinkUri)
            {
                bool needPop = this.PushSegmentForRoot();
                this.WriteLinkCollection(elements);
                this.PopSegmentName(needPop);
            }
            else
            {
                MetadataProviderEdmModel model     = this.Service.Provider.GetMetadataProviderEdmModel();
                OperationWrapper         operation = this.RequestDescription.LastSegmentInfo.Operation;

                IEdmOperation edmOperation = model.GetRelatedOperation(operation);
                Debug.Assert(edmOperation != null, "edmOperation != null");

                IEdmCollectionTypeReference collectionType = (IEdmCollectionTypeReference)edmOperation.ReturnType;
                bool isJsonLightResponse = ContentTypeUtil.IsResponseMediaTypeJsonLight(this.Service, /*isEntryOrFeed*/ false);
                this.collectionWriter = this.writer.CreateODataCollectionWriter(isJsonLightResponse ? null : collectionType.ElementType());

                ODataCollectionStart collectionStart = new ODataCollectionStart {
                    Name = this.ComputeContainerName()
                };
                collectionStart.SetSerializationInfo(new ODataCollectionStartSerializationInfo {
                    CollectionTypeName = collectionType.FullName()
                });

                this.collectionWriter.WriteStart(collectionStart);
                while (elements.HasMoved)
                {
                    object       element      = elements.Current;
                    ResourceType resourceType = element == null ?
                                                this.RequestDescription.TargetResourceType : WebUtil.GetResourceType(this.Provider, element);
                    if (resourceType == null)
                    {
                        throw new InvalidOperationException(Microsoft.OData.Service.Strings.Serializer_UnsupportedTopLevelType(element.GetType()));
                    }

                    this.collectionWriter.WriteItem(this.GetPropertyValue(XmlConstants.XmlCollectionItemElementName, resourceType, element, false /*openProperty*/).FromODataValue());
                    elements.MoveNext();
                }

                this.collectionWriter.WriteEnd();
                this.collectionWriter.Flush();
            }
        }
Ejemplo n.º 11
0
        internal Uri BuildMetadataLink(OperationWrapper operation, bool entityHasMultipleActionsWithSameName)
        {
            Debug.Assert(!String.IsNullOrEmpty(operation.Name), "!string.IsNullOrEmpty(operation.Name)");

            StringBuilder builder = new StringBuilder();

            builder.Append(UriUtil.UriToString(this.metadataUri));
            builder.Append('#');
            builder.Append(Uri.EscapeDataString(namespaceName));
            builder.Append('.');
            builder.Append(Uri.EscapeDataString(operation.Name));

            return(new Uri(builder.ToString()));
        }
Ejemplo n.º 12
0
        public OperationLinkBuilderTests()
        {
            ResourceType intType = ResourceType.GetPrimitiveResourceType(typeof(int));

            var customerType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "FQ.NS", "Customer", false);

            customerType.CanReflectOnInstanceType = false;
            customerType.AddProperty(new ResourceProperty("Id", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, intType)
            {
                CanReflectOnInstanceTypeProperty = false
            });
            customerType.SetReadOnly();

            var operation = new ServiceAction("Action", intType, OperationParameterBindingKind.Sometimes, new[] { new ServiceActionParameter("P1", customerType), new ServiceActionParameter("P2", intType) }, null);

            operation.SetReadOnly();
            this.operationWithParameters = new OperationWrapper(operation);

            var typeWithEscapedName = new ResourceType(typeof(object), ResourceTypeKind.ComplexType, null, "FQ NS", "+ /", false);

            typeWithEscapedName.CanReflectOnInstanceType = false;
            typeWithEscapedName.AddProperty(new ResourceProperty("Number", ResourcePropertyKind.Primitive, intType)
            {
                CanReflectOnInstanceTypeProperty = false
            });
            typeWithEscapedName.SetReadOnly();

            operation = new ServiceAction("Action", intType, OperationParameterBindingKind.Sometimes, new[] { new ServiceActionParameter("P1", customerType), new ServiceActionParameter("P2", typeWithEscapedName) }, null);
            operation.SetReadOnly();
            this.operationWithEscapedParameter = new OperationWrapper(operation);

            var bestCustomerType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, customerType, "FQ.NS", "BestCustomer", false);

            bestCustomerType.SetReadOnly();

            operation = new ServiceAction("Action", intType, OperationParameterBindingKind.Sometimes, new[] { new ServiceActionParameter("P1", customerType) }, null);
            operation.SetReadOnly();
            this.operationBoundToBaseType = new OperationWrapper(operation);

            this.entityToSerialize = EntityToSerialize.CreateFromExplicitValues(new object(), bestCustomerType, new TestSerializedEntityKey("http://odata.org/Service.svc/Customers/", bestCustomerType.FullName));

            var metadataUri = new Uri("http://odata.org/Service.svc/$metadata");

            this.testSubject = new OperationLinkBuilder("MyContainer", metadataUri);
        }
Ejemplo n.º 13
0
        public OperationCacheTests()
        {
            this.entityType1 = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "My.Namespace", "Entity1", false);
            this.entityType2 = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "My.Namespace", "Entity2", false);

            var intType = ResourceType.GetPrimitiveResourceType(typeof(int));

            this.actionWithBindingParameter1 = CreateAction("SameName", intType, this.entityType1);
            this.actionWithBindingParameter2 = CreateAction("SameName", intType, this.entityType2);
            this.serviceOperation            = CreateServiceOperation("SameName", intType);

            this.actionWithBindingParameter1.SetReadOnly();
            this.actionWithBindingParameter2.SetReadOnly();
            this.serviceOperation.SetReadOnly();

            this.actionWithBindingParameterWrapper1 = new OperationWrapper(this.actionWithBindingParameter1);
            this.actionWithBindingParameterWrapper2 = new OperationWrapper(this.actionWithBindingParameter2);
            this.serviceOperationWrapper            = new OperationWrapper(this.serviceOperation);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Gets the target link value for an <see cref="ODataOperation"/>
        /// </summary>
        /// <param name="entityToSerialize">The current entity being serialized.</param>
        /// <param name="operation">The operation to generate the link for.</param>
        /// <param name="entityHasMultipleActionsWithSameName">Whether or not there are multiple operations in the current scope with the same name as the current operation.</param>
        /// <returns>Uri representing link to use for invoking this operation.</returns>
        internal Uri BuildTargetLink(EntityToSerialize entityToSerialize, OperationWrapper operation, bool entityHasMultipleActionsWithSameName)
        {
            Debug.Assert(entityToSerialize != null, "entityToSerialize != null");
            Debug.Assert(operation != null, "operation != null");
            Debug.Assert(operation.BindingParameter != null, "operation.BindingParameter != null");
            Debug.Assert(operation.BindingParameter.ParameterType != null, "operation.BindingParameter.ParameterType != null");

            string targetSegment = operation.GetActionTargetSegmentByResourceType(entityToSerialize.ResourceType, this.namespaceName);

            // If there are multiple operations with the same name, then using the edit link of the entry would cause the target to potentially resolve to the wrong
            // operation. Instead, use the actual binding type of the specific operation.
            if (entityHasMultipleActionsWithSameName)
            {
                Uri editLinkWithBindingType = RequestUriProcessor.AppendUnescapedSegment(entityToSerialize.SerializedKey.AbsoluteEditLinkWithoutSuffix, operation.BindingParameter.ParameterType.FullName);
                return(RequestUriProcessor.AppendUnescapedSegment(editLinkWithBindingType, targetSegment));
            }

            return(RequestUriProcessor.AppendUnescapedSegment(entityToSerialize.SerializedKey.AbsoluteEditLink, targetSegment));
        }
        public MaximoResult InvokeCustomOperation(OperationWrapper operationWrapper)
        {
            var operationName  = operationWrapper.OperationName;
            var entityMetadata = operationWrapper.EntityMetadata;

            try {
                var mi = ReflectionUtil.GetMethodNamed(_connectorTemplate, operationName);
                if (mi == null)
                {
                    throw new InvalidOperationException(String.Format("operation {0} not found on entity {1}",
                                                                      operationName,
                                                                      entityMetadata.Name));
                }
                if (mi.GetParameters().Count() != 1)
                {
                    throw new InvalidOperationException(
                              String.Format(ErrorParameter, operationName, entityMetadata.Name));
                }
                var fp = mi.GetParameters().First();
                if (!typeof(OperationData).IsAssignableFrom(fp.ParameterType))
                {
                    throw new InvalidOperationException(
                              String.Format(ErrorParameter, operationName, entityMetadata.Name));
                }
                var param = operationWrapper.OperationData(fp.ParameterType);
                if (mi.ReturnType == typeof(void))
                {
                    mi.Invoke(_connectorTemplate, new object[] { param });
                    return(null);
                }
                var ob = mi.Invoke(_connectorTemplate, new object[] { param });
                if (ob is MaximoResult)
                {
                    return((MaximoResult)ob);
                }
                return(new MaximoResult(param.Id, ob));
            } catch (AmbiguousMatchException e) {
                throw new InvalidOperationException(
                          String.Format("multiples methods found for operation {0} on entity {1}. Unable to decide", operationName,
                                        entityMetadata.Name));
            }
        }
        public void Init()
        {
            this.baseType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Fake.NS", "BaseType", false)
            {
                CanReflectOnInstanceType = false
            };
            this.baseType.AddProperty(new ResourceProperty("Id", ResourcePropertyKind.Key | ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(int)))
            {
                CanReflectOnInstanceTypeProperty = false
            });
            this.baseType.SetReadOnly();

            this.entityType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, this.baseType, "Fake.NS", "Type", false)
            {
                CanReflectOnInstanceType = false
            };
            this.entityType.SetReadOnly();

            this.derivedType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, this.entityType, "Fake.NS", "DerivedType", false)
            {
                CanReflectOnInstanceType = false
            };
            this.derivedType.SetReadOnly();

            var resourceSet = new ResourceSet("Set", this.entityType);

            resourceSet.SetReadOnly();
            this.resourceSetWrapper = ResourceSetWrapper.CreateForTests(resourceSet);

            this.action = new ServiceAction("Fake", ResourceType.GetPrimitiveResourceType(typeof(int)), OperationParameterBindingKind.Sometimes, new[] { new ServiceActionParameter("p1", this.entityType) }, null);
            this.action.SetReadOnly();
            this.actionWrapper = new OperationWrapper(action);

            this.derivedAction = new ServiceAction("Fake", ResourceType.GetPrimitiveResourceType(typeof(int)), OperationParameterBindingKind.Sometimes, new[] { new ServiceActionParameter("p1", this.derivedType) }, null);
            this.derivedAction.SetReadOnly();
            this.derivedActionWrapper = new OperationWrapper(derivedAction);

            this.testSubject = new SelectedOperationsCache();
        }
        /// <summary>
        /// Creates a segment for the given service action.
        /// </summary>
        /// <param name="previousSegment">The previous segment before the operation to be invoked.</param>
        /// <param name="serviceAction">The service action to create the segment for.</param>
        /// <returns>A fully populated PathSegment representing the service action</returns>
        private SegmentInfo CreateSegmentForServiceAction(SegmentInfo previousSegment, OperationWrapper serviceAction)
        {
            Debug.Assert(serviceAction != null && serviceAction.Kind == OperationKind.Action, "serviceAction != null && serviceAction.Kind == OperationKind.Action");

            SegmentInfo segment = new SegmentInfo()
            {
                Identifier = serviceAction.Name, Operation = serviceAction
            };

            WebUtil.DebugEnumIsDefined(serviceAction.ResultKind);
            Debug.Assert(segment.IsServiceActionSegment, "IsServiceActionSegment(segment)");

            if (previousSegment != null && previousSegment.TargetKind == RequestTargetKind.Link)
            {
                throw DataServiceException.CreateBadRequestError(Strings.RequestUriProcessor_LinkSegmentMustBeFollowedByEntitySegment(serviceAction.Name, XmlConstants.UriLinkSegment));
            }

            segment.TargetSource = RequestTargetSource.ServiceOperation;

            if (serviceAction.ResultKind != ServiceOperationResultKind.Void)
            {
                segment.TargetResourceSet  = serviceAction.GetResultSet(this.providerWrapper, previousSegment == null ? null : previousSegment.TargetResourceSet);
                segment.TargetResourceType = serviceAction.ReturnType;
                segment.TargetKind         = TargetKindFromType(segment.TargetResourceType);
                if (segment.TargetKind == RequestTargetKind.Resource && segment.TargetResourceSet == null)
                {
                    // Service actions are either visible (ServiceActionRights.Invoke) or not (ServiceActionRight.None). The fact that
                    // DataServiceActionProviderWrapper.TryResolveServiceAction() returns a non-null value means the action is visible.
                    // If the result of the action is of entity type, we need to make sure the target set is visible or else the self
                    // and edit links of the entities in the response payload would not be usable.
                    Debug.Assert(serviceAction.IsVisible, "serviceAction.IsVisible");
                    throw DataServiceException.CreateForbidden();
                }

                segment.SingleResult = serviceAction.ResultKind == ServiceOperationResultKind.DirectValue;
                Debug.Assert(serviceAction.ResultKind != ServiceOperationResultKind.QueryWithSingleResult, "QueryWithSingleResult is not applicable for Actions.");
            }
            else
            {
                segment.TargetResourceSet  = null;
                segment.TargetResourceType = null;
                segment.TargetKind         = RequestTargetKind.VoidOperation;
            }

            return(segment);
        }
Ejemplo n.º 18
0
 private static bool AppendToLinks(OperationWrapper serviceAction, object resourceInstance, bool resourceInstanceInFeed, ref ODataAction actionToSerialize)
 {
     actionToSerialize.Metadata = new Uri(actionToSerialize.Metadata.OriginalString + "/SomethingThatWasAppended");
     actionToSerialize.Target   = new Uri(actionToSerialize.Target.OriginalString + "/SomethingThatWasAppended");
     return(true);
 }
 protected IEdmFunctionImport GetFunctionImport(OperationWrapper serviceOperation)
 {
     return(base.Service.Provider.GetMetadataProviderEdmModel(base.Service.OperationContext).EnsureDefaultEntityContainer().EnsureFunctionImport(serviceOperation));
 }
        /// <summary>
        /// Creates the next segment.
        /// </summary>
        /// <param name="previous">The previous segment.</param>
        /// <param name="segment">The the next segment.</param>
        /// <returns>The newly created next segment.</returns>
        private SegmentInfo CreateNextSegment(SegmentInfo previous, ODataPathSegment segment)
        {
            if (segment is ValueSegment)
            {
                return(CreateValueSegment(previous));
            }

            SegmentInfo segmentInfo;

            if (segment is CountSegment)
            {
                segmentInfo = CreateCountSegment(previous);

                // DEVNOTE: Prior to refactor, $count was handled alongside properties. See more detailed comment in HandleCountSegment
                Debug.Assert(segmentInfo.TargetSource == RequestTargetSource.Property, "segment.TargetSource == RequestTargetSource.Property");
                return(segmentInfo);
            }

            // if its not one of the recognized special segments, then it must be a property, type-segment, or key value.
            Debug.Assert(
                previous.TargetKind == RequestTargetKind.ComplexObject ||
                previous.TargetKind == RequestTargetKind.Resource ||
                previous.TargetKind == RequestTargetKind.OpenProperty ||
                previous.TargetKind == RequestTargetKind.Link,
                "previous.TargetKind(" + previous.TargetKind + ") can have properties");

            CheckSegmentIsComposable(previous);

            // if the segment corresponds to a declared property, handle it
            // otherwise, fall back to type-segments, actions, and dynamic/open properties
            ResourceProperty projectedProperty;

            if (TryGetPropertyFromSegment(segment, out projectedProperty))
            {
                CheckSingleResult(previous.SingleResult, previous.Identifier);

                if (projectedProperty.IsOfKind(ResourcePropertyKind.Stream))
                {
                    segmentInfo = CreateNamedStreamSegment(previous, projectedProperty);
                    Debug.Assert(segmentInfo.TargetSource == RequestTargetSource.Property, "segment.TargetSource == RequestTargetSource.Property");
                    return(segmentInfo);
                }

                segmentInfo = this.CreatePropertySegment(previous, projectedProperty);
                Debug.Assert(segmentInfo.TargetSource == RequestTargetSource.Property, "segment.TargetSource == RequestTargetSource.Property");
                return(segmentInfo);
            }

            // If the property resolution failed, and the previous segment was targeting an entity, then we should
            // try and resolve the identifier as type name.
            SegmentInfo typeNameSegment;

            if (this.TryCreateTypeNameSegment(previous, segment, out typeNameSegment))
            {
                Debug.Assert(typeNameSegment.TargetSource == previous.TargetSource, "segment.TargetSource == previous.TargetSource");
                return(typeNameSegment);
            }

            OperationWrapper serviceAction = null;
            var actionSegment = segment as OperationSegment;

            if (actionSegment != null)
            {
                Debug.Assert(actionSegment.Operations.Count() == 1, "Operation segment should only ever have exactly one operation. Was a change made to how MetadataProviderEdmModel finds actions/service operations");
                serviceAction = ((MetadataProviderEdmOperation)actionSegment.Operations.Single()).ServiceOperation;
                Debug.Assert(serviceAction != null, "serviceAction != null");
                Debug.Assert(serviceAction.Kind == OperationKind.Action, "serviceAction.Kind == OperationKind.Action");
            }

            if (serviceAction != null)
            {
                Debug.Assert(serviceAction.Kind == OperationKind.Action, "serviceAction.Kind == OperationKind.Action");

                // Service Actions can bind to a set with any ResourceSetRights except ResourceSetRights.None.
                segmentInfo = this.CreateSegmentForServiceAction(previous, serviceAction);
                Debug.Assert(segmentInfo.TargetSource == RequestTargetSource.ServiceOperation, "segment.TargetSource == RequestTargetSource.ServiceOperation");
                return(segmentInfo);
            }

            CheckSingleResult(previous.SingleResult, previous.Identifier);
            segmentInfo = CreateOpenPropertySegment(previous, ((DynamicPathSegment)segment).Identifier);
            Debug.Assert(segmentInfo.TargetSource == RequestTargetSource.Property, "segment.TargetSource == RequestTargetSource.Property");
            return(segmentInfo);
        }
 public bool TryGetCachedOperationWrapper(string serviceActionName, ResourceType bindingType, out OperationWrapper actionWrapper)
 {
     actionWrapper = null;
     return(false);
 }
 public void AddOperationToEdmModel(OperationWrapper actionWrapper)
 {
 }
Ejemplo n.º 23
0
 private void ApplyProjectionsToExpandTree(List <List <string> > selectPathsAsText)
 {
     for (int i = selectPathsAsText.Count - 1; i >= 0; i--)
     {
         List <string>          list = selectPathsAsText[i];
         ExpandedProjectionNode rootProjectionNode = this.GetRootProjectionNode();
         ResourceType           type = null;
         for (int j = 0; j < list.Count; j++)
         {
             bool   flag2;
             string containerQualifiedName = list[j];
             bool   lastPathSegment        = j == (list.Count - 1);
             rootProjectionNode.ProjectionFound = true;
             if (containerQualifiedName == "*")
             {
                 rootProjectionNode.ProjectAllImmediateProperties = true;
                 break;
             }
             if (this.service.Provider.GetNameFromContainerQualifiedName(containerQualifiedName, out flag2) == "*")
             {
                 rootProjectionNode.ProjectAllImmediateOperations = true;
                 break;
             }
             ResourceType     previousSegmentResourceType = type ?? rootProjectionNode.ResourceType;
             ResourceProperty property = previousSegmentResourceType.TryResolvePropertyName(containerQualifiedName);
             if (property == null)
             {
                 type = WebUtil.ResolveTypeIdentifier(this.service.Provider, containerQualifiedName, previousSegmentResourceType, type != null);
                 if (type != null)
                 {
                     this.description.VerifyProtocolVersion(RequestDescription.Version3Dot0, this.service);
                     continue;
                 }
                 Func <OperationWrapper, bool> predicate = null;
                 string           serviceActionName      = this.service.Provider.GetNameFromContainerQualifiedName(containerQualifiedName, out flag2);
                 OperationWrapper operation = null;
                 if (!previousSegmentResourceType.IsOpenType || flag2)
                 {
                     if (predicate == null)
                     {
                         predicate = o => o.Name == serviceActionName;
                     }
                     operation = this.service.ActionProvider.GetServiceActionsByBindingParameterType(this.service.OperationContext, previousSegmentResourceType).SingleOrDefault <OperationWrapper>(predicate);
                 }
                 if (operation != null)
                 {
                     rootProjectionNode.AddOperation(operation);
                     if (!lastPathSegment)
                     {
                         throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.RequestQueryProcessor_ServiceActionMustBeLastSegmentInSelect(containerQualifiedName));
                     }
                     continue;
                 }
                 if (!previousSegmentResourceType.IsOpenType)
                 {
                     throw DataServiceException.CreateSyntaxError(System.Data.Services.Strings.RequestUriProcessor_PropertyNotFound(previousSegmentResourceType.FullName, containerQualifiedName));
                 }
                 if (!lastPathSegment)
                 {
                     throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.OpenNavigationPropertiesNotSupportedOnOpenTypes(containerQualifiedName));
                 }
             }
             rootProjectionNode = ApplyProjectionForProperty(rootProjectionNode, containerQualifiedName, property, previousSegmentResourceType, lastPathSegment);
             type = null;
         }
         if (type != null)
         {
             throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.RequestQueryProcessor_QueryParametersPathCannotEndInTypeIdentifier("$select", type.FullName));
         }
     }
 }
Ejemplo n.º 24
0
        /// <summary>
        /// Asks the provider if the action should be advertised in payloads.
        /// </summary>
        /// <param name="entityToSerialize">The entity to serialize.</param>
        /// <param name="resourceInstanceInFeed">Whether or not the entity is being serialized in a feed.</param>
        /// <param name="serviceOperationWrapper">The service operation wrapper.</param>
        /// <param name="lazyActionTargetUri">Target uri of the action, which will only be generated if needed.</param>
        /// <param name="entityHasMultipleActionsWithSameName">Whether or not there are multiple operations in the current scope with the same name as the current operation.</param>
        /// <param name="odataAction">The ODL object-model representation of the action.</param>
        /// <returns>Whether or not the action should be advertised.</returns>
        private bool AskProviderIfActionShouldBeAdvertised(EntityToSerialize entityToSerialize, bool resourceInstanceInFeed, OperationWrapper serviceOperationWrapper, SimpleLazy <Uri> lazyActionTargetUri, bool entityHasMultipleActionsWithSameName, ref ODataAction odataAction)
        {
            if (this.advertiseServiceAction(serviceOperationWrapper, entityToSerialize.Entity, resourceInstanceInFeed, ref odataAction))
            {
                if (odataAction == null)
                {
                    throw new DataServiceException(500, Microsoft.OData.Service.Strings.DataServiceActionProviderWrapper_AdvertiseServiceActionCannotReturnNullActionToSerialize);
                }

                // Always set target and title if there are overloaded actions.
                if (!entityHasMultipleActionsWithSameName)
                {
                    this.metadataPropertyManager.CheckForUnmodifiedTitle(odataAction, serviceOperationWrapper.Name);
                    this.metadataPropertyManager.CheckForUnmodifiedTarget(odataAction, () => lazyActionTargetUri.Value);
                }

                // make the target link relative
                this.MakeOperationTargetRelativeFromMetadataUriIfJsonLight(odataAction);

                return(true);
            }

            odataAction = null;
            return(false);
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Tries to serialize the operation.
        /// </summary>
        /// <param name="entityToSerialize">The entity to serialize.</param>
        /// <param name="resourceInstanceInFeed">Whether or not the entity is being serialized in a feed.</param>
        /// <param name="entityHasMultipleActionsWithSameName">Whether or not there are multiple operations in the current scope with the same name as the current operation.</param>
        /// <param name="serviceOperationWrapper">The service operation wrapper.</param>
        /// <param name="odataAction">The ODL object-model representation of the action.</param>
        /// <returns>Whether or not to serialize the operation.</returns>
        private bool TrySerializeOperation(EntityToSerialize entityToSerialize, bool resourceInstanceInFeed, bool entityHasMultipleActionsWithSameName, OperationWrapper serviceOperationWrapper, out ODataAction odataAction)
        {
            Debug.Assert(serviceOperationWrapper != null, "serviceOperationWrapper != null");

            // We only advertise actions. This is a debug assert because GetServiceOperationsByResourceType only returns actions.
            Debug.Assert(serviceOperationWrapper.Kind == OperationKind.Action, "Only actions can be advertised");

            Uri metadata = this.operationLinkBuilder.BuildMetadataLink(serviceOperationWrapper, entityHasMultipleActionsWithSameName);

            // If the action has OperationParameterBindingKind set to "Always" then we advertise the action without calling "AdvertiseServiceAction".
            bool isAlwaysAvailable = serviceOperationWrapper.OperationParameterBindingKind == OperationParameterBindingKind.Always;

            odataAction = new ODataAction {
                Metadata = metadata
            };

            // There is some subtlety to the interaction between action advertisement and whether or not to include title/target on the wire.
            //
            // 1) If an action is always available:
            //    The provider author does not get a chance to customize the title/target values...
            //    so the values will be based on conventions...
            //    so by default do not write them on the wire
            // 2) If it is only sometimes available:
            //    The values need to be computed to provide them on the instance given to the provider...
            //    but they might not be changed by the provider author...
            //    so compare them to the computed values, and do not write them if they match.

            // TODO: Action provider should be able to customize title/target even if the action is 'always' advertised
            // If this gets fixed, then all the behavior should collapse to emulate case #2 above

            // Create a lazy Uri for the target, because we may need it more than once (see case #2 above).
            SimpleLazy <Uri> lazyActionTargetUri = new SimpleLazy <Uri>(() => this.operationLinkBuilder.BuildTargetLink(entityToSerialize, serviceOperationWrapper, entityHasMultipleActionsWithSameName));

            this.metadataPropertyManager.SetTitle(odataAction, isAlwaysAvailable, serviceOperationWrapper.Name);
            this.metadataPropertyManager.SetTarget(odataAction, isAlwaysAvailable, () => lazyActionTargetUri.Value);

            // If the operation is always available,
            // 1. Return true for MetadataQueryOption.All.
            // 2. Return false for MetadataQueryOption.None.
            // 3. Return false for MetadataQueryOption.Default.
            if (isAlwaysAvailable)
            {
                return(this.payloadMetadataParameterInterpreter.ShouldIncludeAlwaysAvailableOperation());
            }

            return(this.AskProviderIfActionShouldBeAdvertised(entityToSerialize, resourceInstanceInFeed, serviceOperationWrapper, lazyActionTargetUri, entityHasMultipleActionsWithSameName, ref odataAction));
        }