Example #1
0
 /**
  * Gets the namespace of the given resource type, 
  * if it is null, then default to the container namespace. 
  * 
  * @param ResourceType $resourceType The resource type
  * 
  * @return string The namespace of the resource type.
  */
 protected function getResourceTypeNamespace(ResourceType $resourceType)
 {
     $resourceTypeNamespace = $resourceType->getNamespace();
     if (empty($resourceTypeNamespace)) {
         $resourceTypeNamespace = $this->providersWrapper->getContainerNamespace();
     }
     return $resourceTypeNamespace;
 }
 /**
  * Test search InternalSkipTokenInfo::GetIndexOfFirstEntryInNextPage function
  */
 public function testGetIndexOfFirstEntryInNextPage2()
 {
     $this->markTestSkipped("Skipped because it depends on a query provider that isn't mocked");
     $northWindMetadata = NorthWindMetadata::Create();
     $configuration = new ServiceConfiguration($northWindMetadata);
     $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL);
     $providersWrapper = new ProvidersWrapper($northWindMetadata, $this->mockQueryProvider, $configuration);
     $resourceSetWrapper = $providersWrapper->resolveResourceSet('Orders');
     $resourceType = $resourceSetWrapper->getResourceType();
     $orderBy = 'ShipName asc, Freight';
     //Note: library will add prim key as last sort key
     $orderBy .= ', OrderID';
     $qp = new NorthWindQueryProvider1();
     $orders = $qp->getResourceSet($resourceSetWrapper->getResourceSet());
     $internalOrderByInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $resourceType, $orderBy, $providersWrapper);
     $compFun = $internalOrderByInfo->getSorterFunction();
     $fun = $compFun->getReference();
     usort($orders, $fun);
     $numRecords = count($orders);
     //-----------------------------------------------------------------
     //Search with a key that exactly matches
     $skipToken = utf8_decode(urldecode("'Antonio%20Moreno%20Taquer%C3%ADa',22.0000M,10365"));
     $skipToken = urldecode($skipToken);
     $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
     $nextIndex = $internalSkipTokenInfo->getIndexOfFirstEntryInTheNextPage($orders);
     $this->assertTrue($nextIndex > 1);
     $this->assertTrue($nextIndex < $numRecords);
     //$nextIndex is the index of order record next to the searched record
     $this->assertEquals($orders[$nextIndex - 1]->OrderID, 10365);
     $this->assertEquals($orders[$nextIndex - 1]->Freight, 22.0);
     //-----------------------------------------------------------------
     //Search with a key that partially matches, in the DB there is no
     //order with ShipName 'An', but there are records start with
     //'An', so partial match, since its a parial match other two
     //key wont be used for comparsion
     $skipToken = "'An',22.0000M,10365";
     $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
     $nextIndex = $internalSkipTokenInfo->getIndexOfFirstEntryInTheNextPage($orders);
     $this->assertTrue($nextIndex > 1);
     $this->assertTrue($nextIndex < $numRecords);
     //Make sure this is the most matching record by comparing with previous record
     $prevOrder = $orders[$nextIndex - 1];
     $r = strcmp($prevOrder->ShipName, $orders[$nextIndex]->ShipName);
     $this->assertTrue($r < 0);
     //Make sure this is the most matching record by comparing with next record
     $nextOrder = $orders[$nextIndex + 1];
     $r = strcmp($nextOrder->ShipName, $orders[$nextIndex]->ShipName);
     $this->assertTrue($r >= 0);
     //-----------------------------------------------------------------
     //Search with a key that does not exists
     $skipToken = "'XXX',11,10365";
     $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
     $nextIndex = $internalSkipTokenInfo->getIndexOfFirstEntryInTheNextPage($orders);
     $this->assertTrue($nextIndex == -1);
     //-----------------------------------------------------------------
 }
Example #3
0
 public function testWriteMetadata()
 {
     $northWindMetadata = NorthWindMetadata::Create();
     $configuration = new ServiceConfiguration($northWindMetadata);
     $configuration->setEntitySetAccessRule("*", EntitySetRights::ALL);
     $configuration->setMaxDataServiceVersion(ProtocolVersion::V3());
     $providersWrapper = new ProvidersWrapper($northWindMetadata, $this->mockQueryProvider, $configuration, false);
     $metadataWriter = new MetadataWriter($providersWrapper);
     $metadata = $metadataWriter->writeMetadata();
     $this->assertNotNull($metadata);
     $this->assertEquals($providersWrapper->getContainerName(), 'NorthWindEntities');
     $this->assertEquals($providersWrapper->getContainerNamespace(), 'NorthWind');
     $this->assertStringStartsWith('<edmx:Edmx Version="1.0"', $metadata);
     $customerResourceSet = $providersWrapper->resolveResourceSet('Customers');
     $this->assertEquals($customerResourceSet->getName(), 'Customers');
     $this->assertEquals($customerResourceSet->getResourceType()->getName(), 'Customer');
     $customerEntityType = $providersWrapper->resolveResourceType('Customer');
     $this->assertEquals($customerEntityType->getResourceTypeKind(), ResourceTypeKind::ENTITY);
 }
Example #4
0
 /**
  * Write entity container 
  * 
  * @return void
  */
 private function _writeEntityContainer()
 {
     $this->_xmlWriter->startElement(ODataConstants::ENTITY_CONTAINER);
     $this->_xmlWriter->writeAttribute(ODataConstants::NAME, $this->providersWrapper->getContainerName());
     $this->_xmlWriter->writeAttributeNs(ODataConstants::ODATA_METADATA_NAMESPACE_PREFIX, ODataConstants::ISDEFAULT_ENTITY_CONTAINER_ATTRIBUTE, null, "true");
     foreach ($this->_metadataManager->getResourceSets() as $resourceSet) {
         $this->_xmlWriter->startElement(ODataConstants::ENTITY_SET);
         $this->_xmlWriter->writeAttribute(ODataConstants::NAME, $resourceSet->getName());
         $this->_xmlWriter->writeAttribute(ODataConstants::ENTITY_TYPE, $resourceSet->getResourceType()->getFullName());
         $this->_xmlWriter->endElement();
     }
     $this->_writeAssociationSets();
     $this->_xmlWriter->endElement();
 }
 /**
  * Build 'Projection Tree' from the given expand path segments
  * 
  * @param array(array(string)) $expandPathSegments Collection of expand paths.
  *
  * 
  * @return void
  * 
  * @throws ODataException If any error occurs while processing the expand path segments
  *                        .
  */
 private function _buildProjectionTree($expandPathSegments)
 {
     foreach ($expandPathSegments as $expandSubPathSegments) {
         $currentNode = $this->_rootProjectionNode;
         foreach ($expandSubPathSegments as $expandSubPathSegment) {
             $resourceSetWrapper = $currentNode->getResourceSetWrapper();
             $resourceType = $currentNode->getResourceType();
             $resourceProperty = $resourceType->resolveProperty($expandSubPathSegment);
             if (is_null($resourceProperty)) {
                 throw ODataException::createSyntaxError(Messages::expandProjectionParserPropertyNotFound($resourceType->getFullName(), $expandSubPathSegment, false));
             } else {
                 if ($resourceProperty->getTypeKind() != ResourceTypeKind::ENTITY) {
                     throw ODataException::createBadRequestError(Messages::expandProjectionParserExpandCanOnlyAppliedToEntity($resourceType->getFullName(), $expandSubPathSegment));
                 }
             }
             $resourceSetWrapper = $this->_providerWrapper->getResourceSetWrapperForNavigationProperty($resourceSetWrapper, $resourceType, $resourceProperty);
             if (is_null($resourceSetWrapper)) {
                 throw ODataException::createBadRequestError(Messages::badRequestInvalidPropertyNameSpecified($resourceType->getFullName(), $expandSubPathSegment));
             }
             $singleResult = $resourceProperty->isKindOf(ResourcePropertyKind::RESOURCE_REFERENCE);
             $resourceSetWrapper->checkResourceSetRightsForRead($singleResult);
             $pageSize = $resourceSetWrapper->getResourceSetPageSize();
             $internalOrderByInfo = null;
             if ($pageSize != 0 && !$singleResult) {
                 $this->_rootProjectionNode->setPagedExpandedResult(true);
                 $rt = $resourceSetWrapper->getResourceType();
                 //assert($rt != null)
                 $keys = array_keys($rt->getKeyProperties());
                 //assert(!empty($keys))
                 $orderBy = null;
                 foreach ($keys as $key) {
                     $orderBy = $orderBy . $key . ', ';
                 }
                 $orderBy = rtrim($orderBy, ', ');
                 $internalOrderByInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $rt, $orderBy, $this->_providerWrapper);
             }
             $node = $currentNode->findNode($expandSubPathSegment);
             if (is_null($node)) {
                 $maxResultCount = $this->_providerWrapper->getConfiguration()->getMaxResultsPerCollection();
                 $node = new ExpandedProjectionNode($expandSubPathSegment, $resourceProperty, $resourceSetWrapper, $internalOrderByInfo, null, $pageSize == 0 ? null : $pageSize, $maxResultCount == PHP_INT_MAX ? null : $maxResultCount);
                 $currentNode->addNode($node);
             }
             $currentNode = $node;
         }
     }
 }
Example #6
0
 /**
  * Create SegmentDescriptor for the first segment
  * 
  * @param string $segmentIdentifier The identifier part of the first segment
  * @param string $keyPredicate The predicate part of the first segment if any else NULL
  * @param boolean $checkRights Whether to check the rights on this segment
  *
  * @return SegmentDescriptor Descriptor for the first segment
  * 
  * @throws ODataException Exception if any validation fails
  */
 private function _createFirstSegmentDescriptor($segmentIdentifier, $keyPredicate, $checkRights)
 {
     $descriptor = new SegmentDescriptor();
     $descriptor->setIdentifier($segmentIdentifier);
     if ($segmentIdentifier === ODataConstants::URI_METADATA_SEGMENT) {
         $this->_assertion(is_null($keyPredicate));
         $descriptor->setTargetKind(TargetKind::METADATA());
         return $descriptor;
     }
     if ($segmentIdentifier === ODataConstants::URI_BATCH_SEGMENT) {
         $this->_assertion(is_null($keyPredicate));
         $descriptor->setTargetKind(TargetKind::BATCH());
         return $descriptor;
     }
     if ($segmentIdentifier === ODataConstants::URI_COUNT_SEGMENT) {
         throw ODataException::createBadRequestError(Messages::segmentParserSegmentNotAllowedOnRoot(ODataConstants::URI_COUNT_SEGMENT));
     }
     if ($segmentIdentifier === ODataConstants::URI_LINK_SEGMENT) {
         throw ODataException::createBadRequestError(Messages::segmentParserSegmentNotAllowedOnRoot(ODataConstants::URI_LINK_SEGMENT));
     }
     $resourceSetWrapper = $this->providerWrapper->resolveResourceSet($segmentIdentifier);
     if ($resourceSetWrapper === null) {
         throw ODataException::createResourceNotFoundError($segmentIdentifier);
     }
     $descriptor->setTargetResourceSetWrapper($resourceSetWrapper);
     $descriptor->setTargetResourceType($resourceSetWrapper->getResourceType());
     $descriptor->setTargetSource(TargetSource::ENTITY_SET);
     $descriptor->setTargetKind(TargetKind::RESOURCE());
     if ($keyPredicate !== null) {
         $keyDescriptor = $this->_createKeyDescriptor($segmentIdentifier . '(' . $keyPredicate . ')', $resourceSetWrapper->getResourceType(), $keyPredicate);
         $descriptor->setKeyDescriptor($keyDescriptor);
         if (!$keyDescriptor->isEmpty()) {
             $descriptor->setSingleResult(true);
         }
     }
     if ($checkRights) {
         $resourceSetWrapper->checkResourceSetRightsForRead($descriptor->isSingleResult());
     }
     return $descriptor;
 }
Example #7
0
 /**
  * Execute queries for expansion.
  * 
  * @param array(mixed)/mixed $result Resource(s) whose navigation properties needs to be expanded.
  *
  *
  * @return void
  */
 private function _executeExpansion($result)
 {
     $expandedProjectionNodes = $this->_getExpandedProjectionNodes();
     foreach ($expandedProjectionNodes as $expandedProjectionNode) {
         $isCollection = $expandedProjectionNode->getResourceProperty()->getKind() == ResourcePropertyKind::RESOURCESET_REFERENCE;
         $expandedPropertyName = $expandedProjectionNode->getResourceProperty()->getName();
         if (is_array($result)) {
             foreach ($result as $entry) {
                 // Check for null entry
                 if ($isCollection) {
                     $currentResourceSet = $this->_getCurrentResourceSetWrapper()->getResourceSet();
                     $resourceSetOfProjectedProperty = $expandedProjectionNode->getResourceSetWrapper()->getResourceSet();
                     $projectedProperty1 = $expandedProjectionNode->getResourceProperty();
                     $result1 = $this->providers->getRelatedResourceSet(QueryType::ENTITIES(), $currentResourceSet, $entry, $resourceSetOfProjectedProperty, $projectedProperty1, null, null, null, null)->results;
                     if (!empty($result1)) {
                         $internalOrderByInfo = $expandedProjectionNode->getInternalOrderByInfo();
                         if (!is_null($internalOrderByInfo)) {
                             $orderByFunction = $internalOrderByInfo->getSorterFunction()->getReference();
                             usort($result1, $orderByFunction);
                             unset($internalOrderByInfo);
                             $takeCount = $expandedProjectionNode->getTakeCount();
                             if (!is_null($takeCount)) {
                                 $result1 = array_slice($result1, 0, $takeCount);
                             }
                         }
                         $entry->{$expandedPropertyName} = $result1;
                         $projectedProperty = $expandedProjectionNode->getResourceProperty();
                         $needPop = $this->_pushSegmentForNavigationProperty($projectedProperty);
                         $this->_executeExpansion($result1);
                         $this->_popSegment($needPop);
                     } else {
                         $entry->{$expandedPropertyName} = array();
                     }
                 } else {
                     $currentResourceSet1 = $this->_getCurrentResourceSetWrapper()->getResourceSet();
                     $resourceSetOfProjectedProperty1 = $expandedProjectionNode->getResourceSetWrapper()->getResourceSet();
                     $projectedProperty2 = $expandedProjectionNode->getResourceProperty();
                     $result1 = $this->providers->getRelatedResourceReference($currentResourceSet1, $entry, $resourceSetOfProjectedProperty1, $projectedProperty2);
                     $entry->{$expandedPropertyName} = $result1;
                     if (!is_null($result1)) {
                         $projectedProperty3 = $expandedProjectionNode->getResourceProperty();
                         $needPop = $this->_pushSegmentForNavigationProperty($projectedProperty3);
                         $this->_executeExpansion($result1);
                         $this->_popSegment($needPop);
                     }
                 }
             }
         } else {
             if ($isCollection) {
                 $currentResourceSet2 = $this->_getCurrentResourceSetWrapper()->getResourceSet();
                 $resourceSetOfProjectedProperty2 = $expandedProjectionNode->getResourceSetWrapper()->getResourceSet();
                 $projectedProperty4 = $expandedProjectionNode->getResourceProperty();
                 $result1 = $this->providers->getRelatedResourceSet(QueryType::ENTITIES(), $currentResourceSet2, $result, $resourceSetOfProjectedProperty2, $projectedProperty4, null, null, null, null)->results;
                 if (!empty($result1)) {
                     $internalOrderByInfo = $expandedProjectionNode->getInternalOrderByInfo();
                     if (!is_null($internalOrderByInfo)) {
                         $orderByFunction = $internalOrderByInfo->getSorterFunction()->getReference();
                         usort($result1, $orderByFunction);
                         unset($internalOrderByInfo);
                         $takeCount = $expandedProjectionNode->getTakeCount();
                         if (!is_null($takeCount)) {
                             $result1 = array_slice($result1, 0, $takeCount);
                         }
                     }
                     $result->{$expandedPropertyName} = $result1;
                     $projectedProperty7 = $expandedProjectionNode->getResourceProperty();
                     $needPop = $this->_pushSegmentForNavigationProperty($projectedProperty7);
                     $this->_executeExpansion($result1);
                     $this->_popSegment($needPop);
                 } else {
                     $result->{$expandedPropertyName} = array();
                 }
             } else {
                 $currentResourceSet3 = $this->_getCurrentResourceSetWrapper()->getResourceSet();
                 $resourceSetOfProjectedProperty3 = $expandedProjectionNode->getResourceSetWrapper()->getResourceSet();
                 $projectedProperty5 = $expandedProjectionNode->getResourceProperty();
                 $result1 = $this->providers->getRelatedResourceReference($currentResourceSet3, $result, $resourceSetOfProjectedProperty3, $projectedProperty5);
                 $result->{$expandedPropertyName} = $result1;
                 if (!is_null($result1)) {
                     $projectedProperty6 = $expandedProjectionNode->getResourceProperty();
                     $needPop = $this->_pushSegmentForNavigationProperty($projectedProperty6);
                     $this->_executeExpansion($result1);
                     $this->_popSegment($needPop);
                 }
             }
         }
     }
 }
Example #8
0
 /**
  * @param ProvidersWrapper $providers
  * @return IODataWriter
  */
 public function writeServiceDocument(ProvidersWrapper $providers)
 {
     $writer = $this->xmlWriter;
     $writer->startElementNs(null, ODataConstants::ATOM_PUBLISHING_SERVICE_ELEMENT_NAME, ODataConstants::APP_NAMESPACE);
     $writer->writeAttributeNs(ODataConstants::XML_NAMESPACE_PREFIX, ODataConstants::XML_BASE_ATTRIBUTE_NAME, null, $this->baseUri);
     $writer->writeAttributeNs(ODataConstants::XMLNS_NAMESPACE_PREFIX, self::ATOM_NAMESPACE_PREFIX, null, ODataConstants::ATOM_NAMESPACE);
     $writer->writeAttributeNs(ODataConstants::XMLNS_NAMESPACE_PREFIX, self::APP_NAMESPACE_PREFIX, null, ODataConstants::APP_NAMESPACE);
     $writer->startElement(ODataConstants::ATOM_PUBLISHING_WORKSPACE_ELEMNT_NAME);
     $writer->startElementNs(self::ATOM_NAMESPACE_PREFIX, ODataConstants::ATOM_TITLE_ELELMET_NAME, null);
     $writer->text(ODataConstants::ATOM_PUBLISHING_WORKSPACE_DEFAULT_VALUE);
     $writer->endElement();
     foreach ($providers->getResourceSets() as $resourceSetWrapper) {
         //start collection node
         $writer->startElement(ODataConstants::ATOM_PUBLISHING_COLLECTION_ELEMENT_NAME);
         $writer->writeAttribute(ODataConstants::ATOM_HREF_ATTRIBUTE_NAME, $resourceSetWrapper->getName());
         //start title node
         $writer->startElementNs(self::ATOM_NAMESPACE_PREFIX, ODataConstants::ATOM_TITLE_ELELMET_NAME, null);
         $writer->text($resourceSetWrapper->getName());
         //end title node
         $writer->endElement();
         //end collection node
         $writer->endElement();
     }
     //End workspace and service nodes
     $writer->endElement();
     $writer->endElement();
     return $this;
 }
Example #9
0
 /**
  * Test whether order by parser identify and remove path duplication
  */
 public function testOrderByWithPathDuplication()
 {
     $northWindMetadata = NorthWindMetadata::Create();
     $configuration = new ServiceConfiguration($northWindMetadata);
     $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL);
     $providersWrapper = new ProvidersWrapper($northWindMetadata, $this->mockQueryProvider, $configuration, false);
     $resourceSetWrapper = $providersWrapper->resolveResourceSet('Order_Details');
     $resourceType = $resourceSetWrapper->getResourceType();
     $orderBy = 'Order/Price desc, Product/ProductName asc, Order/Price asc';
     $internalOrderInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $resourceType, $orderBy, $providersWrapper);
     //The orderby path Order/Price appears twice, but parser will consider only first path
     $orderByInfo = $internalOrderInfo->getOrderByInfo();
     //There are navigation (resource reference) properties in the orderby path so getNavigationPropertiesUsed should
     //not be null
     $naviUsed = $orderByInfo->getNavigationPropertiesUsed();
     $this->assertFalse(is_null($naviUsed));
     //3 path segment are there, but last one is duplicate of first one, so parser removes last one
     $this->assertEquals(count($naviUsed), 2);
     $this->assertTrue(is_array($naviUsed[0]));
     $this->assertTrue(is_array($naviUsed[1]));
     //one navgations used in first orderby 'Order'
     $this->assertEquals(count($naviUsed[0]), 1);
     //one navgations used in second orderby 'Prodcut'
     $this->assertEquals(count($naviUsed[1]), 1);
     $this->assertEquals($naviUsed[0][0]->getName(), 'Order');
     $this->assertEquals($naviUsed[1][0]->getName(), 'Product');
     $orderByPathSegments = $orderByInfo->getOrderByPathSegments();
     $this->assertEquals(count($orderByPathSegments), 2);
 }
Example #10
0
 /**
  * Check wrapped resource set's resource type or any of the resource type derived
  * from the this resource type has bag property associated with it.
  * 
  * @param ProvidersWrapper $provider Metadata query provider wrapper
  * 
  * @return boolean
  */
 public function hasBagProperty(ProvidersWrapper $provider)
 {
     $arrayToDetectLoop = array();
     $hasBagProperty = $this->_resourceSet->getResourceType()->hasBagProperty($arrayToDetectLoop);
     unset($arrayToDetectLoop);
     // This will check only the resource type associated with
     // the resource set, we need to check presence of bag property
     // in resource type which is derived form this resource type also.
     if (!$hasBagProperty) {
         $derivedTypes = $provider->getDerivedTypes($this->_resourceSet->getResourceType());
         foreach ($derivedTypes as $derivedType) {
             $arrayToDetectLoop = array();
             if ($derivedType->hasBagProperty($arrayToDetectLoop)) {
                 return true;
             }
         }
     }
     return false;
 }
Example #11
0
 /**
  * One can expand a navigation property only if corresponding resource set is visible
  * 
  */
 public function testExpandWithNonVisibleResourceSet()
 {
     $northWindMetadata = NorthWindMetadata::Create();
     $queryProvider = new NorthWindQueryProvider();
     $configuration = new ServiceConfiguration($northWindMetadata);
     //Make 'Customers' and 'Orders' visible, make 'Order_Details' invisible
     $configuration->setEntitySetAccessRule('Customers', EntitySetRights::ALL);
     $configuration->setEntitySetAccessRule('Orders', EntitySetRights::ALL);
     $providersWrapper = new ProvidersWrapper($northWindMetadata, $queryProvider, $configuration, false);
     $customersResourceSetWrapper = $providersWrapper->resolveResourceSet('Customers');
     $customerResourceType = $customersResourceSetWrapper->getResourceType();
     $exceptionThrown = false;
     try {
         $projectionTree = ExpandProjectionParser::parseExpandAndSelectClause($customersResourceSetWrapper, $customerResourceType, null, null, null, 'Orders/Order_Details', null, $providersWrapper);
         $this->fail('An expected ODataException for navigation to invisible resource set has not been thrown');
     } catch (ODataException $odataException) {
         $this->assertStringEndsWith("(Check the resource set of the navigation property 'Order_Details' is visible)", $odataException->getMessage());
     }
 }
Example #12
0
    public function testGetOutputTwoResourceSets()
    {
        $fakeResourceSet1 = Phockito::mock('POData\\Providers\\Metadata\\ResourceSetWrapper');
        Phockito::when($fakeResourceSet1->getName())->return("Name 1");
        $fakeResourceSet2 = Phockito::mock('POData\\Providers\\Metadata\\ResourceSetWrapper');
        //TODO: this certainly doesn't seem right...see #73
        Phockito::when($fakeResourceSet2->getName())->return("XML escaped stuff \" ' <> & ?");
        $fakeResourceSets = array($fakeResourceSet1, $fakeResourceSet2);
        Phockito::when($this->mockProvider->getResourceSets())->return($fakeResourceSets);
        $fakeBaseURL = "http://some/place/some/where/" . uniqid();
        $writer = new AtomODataWriter($fakeBaseURL);
        $actual = $writer->writeServiceDocument($this->mockProvider)->getOutput();
        $expected = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<service xml:base="' . $fakeBaseURL . '" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app">
 <workspace>
  <atom:title>Default</atom:title>
  <collection href="Name 1">
   <atom:title>Name 1</atom:title>
  </collection>
  <collection href="XML escaped stuff &quot; \' &lt;&gt; &amp; ?">
   <atom:title>XML escaped stuff &quot; \' &lt;&gt; &amp; ?</atom:title>
  </collection>
 </workspace>
</service>
';
        $this->assertEquals($expected, $actual);
    }
Example #13
0
 /**
  * test the creation of nextlink from an object.
  * Test building of link with guid sub-value
  */
 public function testCreationOfNextLink4()
 {
     $northWindMetadata = NorthWindMetadata::Create();
     $configuration = new ServiceConfiguration($northWindMetadata);
     $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL);
     $providersWrapper = new ProvidersWrapper($northWindMetadata, $this->mockQueryProvider, $configuration, false);
     $resourceSetWrapper = $providersWrapper->resolveResourceSet('Customers');
     $resourceType = $resourceSetWrapper->getResourceType();
     $orderBy = 'CustomerID, CustomerGuid';
     $internalOrderByInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $resourceType, $orderBy, $providersWrapper);
     $skipToken = "null, guid'05b242e752eb46bd8f0e6568b72cd9a5'";
     $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
     $keyObject = $internalSkipTokenInfo->getKeyObject();
     $lastObject = new Customer2();
     $lastObject->CustomerID = 'ABC';
     $lastObject->CustomerGuid = '{05b242e7-52eb-46bd-8f0e-6568b72cd9a5}';
     $nextLink = $internalSkipTokenInfo->buildNextPageLink($lastObject);
     $this->assertEquals($nextLink, "'ABC', guid'%7B05b242e7-52eb-46bd-8f0e-6568b72cd9a5%7D'");
 }
Example #14
0
 /**
  * Build 'OrderBy Tree' from the given orderby path segments, also build 
  * comparsion function for each path segment.
  * 
  * @param array(array) &$orderByPathSegments Collection of orderby path segments,
  *                                           this is passed by reference
  *                                           since we need this function to 
  *                                           modify this array in two cases:
  *                                           1. if asc or desc present, then the 
  *                                              corresponding sub path segment 
  *                                              should be removed
  *                                           2. remove duplicate orderby path 
  *                                              segment
  * 
  * @return void
  * 
  * @throws ODataException If any error occurs while processing the orderby path 
  *                        segments
  */
 private function _buildOrderByTree(&$orderByPathSegments)
 {
     foreach ($orderByPathSegments as $index1 => &$orderBySubPathSegments) {
         $currentNode = $this->_rootOrderByNode;
         $currentObject = $this->_dummyObject;
         $ascending = true;
         $subPathCount = count($orderBySubPathSegments);
         // Check sort order is specified in the path, if so set a
         // flag and remove that segment
         if ($subPathCount > 1) {
             if ($orderBySubPathSegments[$subPathCount - 1] === '*desc') {
                 $ascending = false;
                 unset($orderBySubPathSegments[$subPathCount - 1]);
                 $subPathCount--;
             } else {
                 if ($orderBySubPathSegments[$subPathCount - 1] === '*asc') {
                     unset($orderBySubPathSegments[$subPathCount - 1]);
                     $subPathCount--;
                 }
             }
         }
         $ancestors = array($this->_rootOrderByNode->getResourceSetWrapper()->getName());
         foreach ($orderBySubPathSegments as $index2 => $orderBySubPathSegment) {
             $isLastSegment = $index2 == $subPathCount - 1;
             $resourceSetWrapper = null;
             $resourceType = $currentNode->getResourceType();
             $resourceProperty = $resourceType->resolveProperty($orderBySubPathSegment);
             if (is_null($resourceProperty)) {
                 throw ODataException::createSyntaxError(Messages::orderByParserPropertyNotFound($resourceType->getFullName(), $orderBySubPathSegment));
             }
             if ($resourceProperty->isKindOf(ResourcePropertyKind::BAG)) {
                 throw ODataException::createBadRequestError(Messages::orderByParserBagPropertyNotAllowed($resourceProperty->getName()));
             } else {
                 if ($resourceProperty->isKindOf(ResourcePropertyKind::PRIMITIVE)) {
                     if (!$isLastSegment) {
                         throw ODataException::createBadRequestError(Messages::orderByParserPrimitiveAsIntermediateSegment($resourceProperty->getName()));
                     }
                     $type = $resourceProperty->getInstanceType();
                     if ($type instanceof Binary) {
                         throw ODataException::createBadRequestError(Messages::orderByParserSortByBinaryPropertyNotAllowed($resourceProperty->getName()));
                     }
                 } else {
                     if ($resourceProperty->getKind() == ResourcePropertyKind::RESOURCESET_REFERENCE || $resourceProperty->getKind() == ResourcePropertyKind::RESOURCE_REFERENCE) {
                         $this->_assertion($currentNode instanceof OrderByRootNode || $currentNode instanceof OrderByNode);
                         $resourceSetWrapper = $currentNode->getResourceSetWrapper();
                         $this->_assertion(!is_null($resourceSetWrapper));
                         $resourceSetWrapper = $this->_providerWrapper->getResourceSetWrapperForNavigationProperty($resourceSetWrapper, $resourceType, $resourceProperty);
                         if (is_null($resourceSetWrapper)) {
                             throw ODataException::createBadRequestError(Messages::badRequestInvalidPropertyNameSpecified($resourceType->getFullName(), $orderBySubPathSegment));
                         }
                         if ($resourceProperty->getKind() == ResourcePropertyKind::RESOURCESET_REFERENCE) {
                             throw ODataException::createBadRequestError(Messages::orderByParserResourceSetReferenceNotAllowed($resourceProperty->getName(), $resourceType->getFullName()));
                         }
                         $resourceSetWrapper->checkResourceSetRightsForRead(true);
                         if ($isLastSegment) {
                             throw ODataException::createBadRequestError(Messages::orderByParserSortByNavigationPropertyIsNotAllowed($resourceProperty->getName()));
                         }
                         $ancestors[] = $orderBySubPathSegment;
                     } else {
                         if ($resourceProperty->isKindOf(ResourcePropertyKind::COMPLEX_TYPE)) {
                             if ($isLastSegment) {
                                 throw ODataException::createBadRequestError(Messages::orderByParserSortByComplexPropertyIsNotAllowed($resourceProperty->getName()));
                             }
                             $ancestors[] = $orderBySubPathSegment;
                         } else {
                             throw ODataException::createInternalServerError(Messages::orderByParserUnexpectedPropertyType());
                         }
                     }
                 }
             }
             $node = $currentNode->findNode($orderBySubPathSegment);
             if (is_null($node)) {
                 if ($resourceProperty->isKindOf(ResourcePropertyKind::PRIMITIVE)) {
                     $node = new OrderByLeafNode($orderBySubPathSegment, $resourceProperty, $ascending);
                     $this->_comparisonFunctions[] = $node->buildComparisonFunction($ancestors);
                 } else {
                     if ($resourceProperty->getKind() == ResourcePropertyKind::RESOURCE_REFERENCE) {
                         $node = new OrderByNode($orderBySubPathSegment, $resourceProperty, $resourceSetWrapper);
                         // Initialize this member variable (identified by
                         // $resourceProperty) of parent object.
                         try {
                             $dummyProperty = new \ReflectionProperty($currentObject, $resourceProperty->getName());
                             $object = $resourceProperty->getInstanceType()->newInstance();
                             $dummyProperty->setValue($currentObject, $object);
                             $currentObject = $object;
                         } catch (\ReflectionException $reflectionException) {
                             throw ODataException::createInternalServerError(Messages::orderByParserFailedToAccessOrInitializeProperty($resourceProperty->getName(), $resourceType->getName()));
                         }
                     } else {
                         if ($resourceProperty->getKind() == ResourcePropertyKind::COMPLEX_TYPE) {
                             $node = new OrderByNode($orderBySubPathSegment, $resourceProperty, null);
                             // Initialize this member variable
                             // (identified by $resourceProperty)of parent object.
                             try {
                                 $dummyProperty = new \ReflectionProperty($currentObject, $resourceProperty->getName());
                                 $object = $resourceProperty->getInstanceType()->newInstance();
                                 $dummyProperty->setValue($currentObject, $object);
                                 $currentObject = $object;
                             } catch (\ReflectionException $reflectionException) {
                                 throw ODataException::createInternalServerError(Messages::orderByParserFailedToAccessOrInitializeProperty($resourceProperty->getName(), $resourceType->getName()));
                             }
                         }
                     }
                 }
                 $currentNode->addNode($node);
             } else {
                 try {
                     $reflectionClass = new \ReflectionClass(get_class($currentObject));
                     $reflectionProperty = $reflectionClass->getProperty($resourceProperty->getName());
                     $reflectionProperty->setAccessible(true);
                     $currentObject = $reflectionProperty->getValue($currentObject);
                     //$dummyProperty = new \ReflectionProperty(
                     //    $currentObject, $resourceProperty->getName()
                     //);
                     //$currentObject = $dummyProperty->getValue($currentObject);
                 } catch (\ReflectionException $reflectionException) {
                     throw ODataException::createInternalServerError(Messages::orderByParserFailedToAccessOrInitializeProperty($resourceProperty->getName(), $resourceType->getName()));
                 }
                 if ($node instanceof OrderByLeafNode) {
                     //remove duplicate orderby path
                     unset($orderByPathSegments[$index1]);
                 }
             }
             $currentNode = $node;
         }
     }
 }
Example #15
0
 /**
  * Gets resource sets which are visible
  * 
  * @return ResourceSetWrapper[]
  */
 public function getResourceSets()
 {
     return $this->providersWrapper->getResourceSets();
 }
Example #16
0
 /**
  * @param ProvidersWrapper $providers
  * @return IODataWriter
  */
 public function writeServiceDocument(ProvidersWrapper $providers)
 {
     $writer = $this->_writer;
     $writer->startObjectScope()->writeName("d")->startObjectScope()->writeName(ODataConstants::ENTITY_SET)->startArrayScope();
     foreach ($providers->getResourceSets() as $resourceSetWrapper) {
         $writer->writeValue($resourceSetWrapper->getName());
     }
     $writer->endScope()->endScope()->endScope();
     return $this;
 }
Example #17
0
 public function testProcessRequestForCollectionWithInlineCountProviderHandlesPaging()
 {
     $requestURI = new Url('http://host.com/data.svc/Collection/?$inlinecount=allpages');
     Phockito::when($this->mockServiceHost->getAbsoluteRequestUri())->return($requestURI);
     //mock inline count as all pages
     Phockito::when($this->mockServiceHost->getQueryStringItem(ODataConstants::HTTPQUERY_STRING_INLINECOUNT))->return("allpages");
     $this->fakeServiceConfig->setAcceptCountRequests(true);
     $this->fakeServiceConfig->setMaxDataServiceVersion(ProtocolVersion::V2());
     $uriProcessor = UriProcessor::process($this->mockService);
     $fakeQueryResult = new QueryResult();
     $fakeQueryResult->results = array(1, 2, 3);
     $fakeQueryResult->count = 10;
     Phockito::when($this->mockProvidersWrapper->getResourceSet(QueryType::ENTITIES_WITH_COUNT(), $this->mockCollectionResourceSetWrapper, null, null, null, null))->return($fakeQueryResult);
     //indicate that the Provider performs the paging (thus it will use the count in the QueryResult)
     Phockito::when($this->mockProvidersWrapper->handlesOrderedPaging())->return(true);
     $uriProcessor->execute();
     $request = $uriProcessor->getRequest();
     $actual = $request->getTargetResult();
     $this->assertEquals(array(1, 2, 3), $actual);
     $this->assertEquals(10, $request->getCountValue());
 }
    public function testGetOutputTwoResourceSets()
    {
        $fakeResourceSet1 = Phockito::mock('POData\\Providers\\Metadata\\ResourceSetWrapper');
        Phockito::when($fakeResourceSet1->getName())->return("Name 1");
        $fakeResourceSet2 = Phockito::mock('POData\\Providers\\Metadata\\ResourceSetWrapper');
        //TODO: this certainly doesn't seem right...see #73
        Phockito::when($fakeResourceSet2->getName())->return("XML escaped stuff \" ' <> & ?");
        $fakeResourceSets = array($fakeResourceSet1, $fakeResourceSet2);
        Phockito::when($this->mockProvider->getResourceSets())->return($fakeResourceSets);
        $writer = new JsonLightODataWriter(JsonLightMetadataLevel::FULL(), $this->serviceBase);
        $actual = $writer->writeServiceDocument($this->mockProvider)->getOutput();
        $expected = '{
    "d":{
        "EntitySet":[
            "Name 1","XML escaped stuff \\" \' <> & ?"
        ]
    }
}';
        $this->assertEquals($expected, $actual);
    }
Example #19
0
 /**
  * If last sub path segment specified in the select clause does not appear in the prjection tree,
  * then parser will create 'ProjectionNode' for them
  */
 public function testProjectionNodeCreation()
 {
     $northWindMetadata = NorthWindMetadata::Create();
     $queryProvider = new NorthWindQueryProvider();
     $configuration = new ServiceConfiguration($northWindMetadata);
     $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL);
     $providersWrapper = new ProvidersWrapper($northWindMetadata, $queryProvider, $configuration, false);
     $ordersResourceSetWrapper = $providersWrapper->resolveResourceSet('Orders');
     $orderResourceType = $ordersResourceSetWrapper->getResourceType();
     //test selection of properties which is not included in expand clause
     //1 primitve ('Order_Details/UnitPrice') and 1 link to navigation 'Customer'
     $projectionTreeRoot = ExpandProjectionParser::parseExpandAndSelectClause($ordersResourceSetWrapper, $orderResourceType, null, null, null, 'Order_Details', 'Order_Details/UnitPrice, Customer', $providersWrapper);
     //expand option is absent
     $this->assertTrue($projectionTreeRoot->isExpansionSpecified());
     //select is applied
     $this->assertTrue($projectionTreeRoot->isSelectionSpecified());
     $this->assertFalse($projectionTreeRoot->canSelectAllImmediateProperties());
     $this->assertFalse($projectionTreeRoot->canSelectAllProperties());
     //there are 2 child nodes for the root
     $this->assertEquals(count($projectionTreeRoot->getChildNodes()), 2);
     //The child nodes one 'ProjectionNode' Customer and one 'ExpandedProjectionNode' for 'Order'
     $childNodes = $projectionTreeRoot->getChildNodes();
     $this->assertTrue(array_key_exists('Order_Details', $childNodes));
     $this->assertTrue(array_key_exists('Customer', $childNodes));
     $this->assertTrue($childNodes['Order_Details'] instanceof ExpandedProjectionNode);
     $this->assertTrue($childNodes['Customer'] instanceof ProjectionNode);
     //'Order_Detials' has a child node
     $childNodes = $childNodes['Order_Details']->getChildNodes();
     $this->assertEquals(count($childNodes), 1);
     $this->assertTrue(array_key_exists('UnitPrice', $childNodes));
     $this->assertTrue($childNodes['UnitPrice'] instanceof ProjectionNode);
 }