Exemplo n.º 1
0
 /**
  * Create SegmentDescriptors for a set of given segments, optionally 
  * check for rights.
  * 
  * @param array(string) $segments    String array of segments to parse
  * @param boolean       $checkRights Whether to check for rights or not
  * 
  * @return void
  * 
  * @throws ODataException Exception incase of any error found while 
  *                        precessing segments
  */
 private function _createSegmentDescriptors($segments, $checkRights)
 {
     if (empty($segments)) {
         $this->_segmentDescriptors[] = new SegmentDescriptor();
         $this->_segmentDescriptors[0]->setTargetKind(RequestTargetKind::SERVICE_DIRECTORY);
         return;
     }
     $segmentCount = count($segments);
     $identifier = $keyPredicate = null;
     $this->_extractSegmentIdentifierAndKeyPredicate($segments[0], $identifier, $keyPredicate);
     $this->_segmentDescriptors[] = $this->_createFirstSegmentDescriptor($identifier, $keyPredicate, $checkRights);
     $previous = $this->_segmentDescriptors[0];
     for ($i = 1; $i < $segmentCount; $i++) {
         if ($previous->getTargetKind() == RequestTargetKind::METADATA || $previous->getTargetKind() == RequestTargetKind::BATCH || $previous->getTargetKind() == RequestTargetKind::PRIMITIVE_VALUE || $previous->getTargetKind() == RequestTargetKind::BAG || $previous->getTargetKind() == RequestTargetKind::MEDIA_RESOURCE) {
             ODataException::resourceNotFoundError(Messages::segmentParserMustBeLeafSegment($previous->getIdentifier()));
         }
         $identifier = $keyPredicate = null;
         $this->_extractSegmentIdentifierAndKeyPredicate($segments[$i], $identifier, $keyPredicate);
         $hasPredicate = !is_null($keyPredicate);
         $descriptor = null;
         if ($previous->getTargetKind() == RequestTargetKind::PRIMITIVE) {
             if ($identifier !== ODataConstants::URI_VALUE_SEGMENT) {
                 ODataException::resourceNotFoundError(Messages::segmentParserOnlyValueSegmentAllowedAfterPrimitivePropertySegment($identifier, $previous->getIdentifier()));
             }
             $this->_assertion(!$hasPredicate);
             $descriptor = SegmentDescriptor::createFrom($previous);
             $descriptor->setIdentifier(ODataConstants::URI_VALUE_SEGMENT);
             $descriptor->setTargetKind(RequestTargetKind::PRIMITIVE_VALUE);
             $descriptor->setSingleResult(true);
         } else {
             if (!is_null($previous->getPrevious()) && $previous->getPrevious()->getIdentifier() === ODataConstants::URI_LINK_SEGMENT && $identifier !== ODataConstants::URI_COUNT_SEGMENT) {
                 ODataException::createBadRequestError(Messages::segmentParserNoSegmentAllowedAfterPostLinkSegment($identifier));
             } else {
                 if ($previous->getTargetKind() == RequestTargetKind::RESOURCE && $previous->isSingleResult() && $identifier === ODataConstants::URI_LINK_SEGMENT) {
                     $this->_assertion(!$hasPredicate);
                     $descriptor = SegmentDescriptor::createFrom($previous);
                     $descriptor->setIdentifier(ODataConstants::URI_LINK_SEGMENT);
                     $descriptor->setTargetKind(RequestTargetKind::LINK);
                 } else {
                     //Do a sanity check here
                     if ($previous->getTargetKind() != RequestTargetKind::COMPLEX_OBJECT && $previous->getTargetKind() != RequestTargetKind::RESOURCE && $previous->getTargetKind() != RequestTargetKind::LINK) {
                         ODataException::createInternalServerError(Messages::segmentParserInconsistentTargetKindState());
                     }
                     if (!$previous->isSingleResult() && $identifier !== ODataConstants::URI_COUNT_SEGMENT) {
                         ODataException::createBadRequestError(Messages::segmentParserCannotQueryCollection($previous->getIdentifier()));
                     }
                     $descriptor = new SegmentDescriptor();
                     $descriptor->setIdentifier($identifier);
                     $descriptor->setTargetSource(RequestTargetSource::PROPERTY);
                     $projectedProperty = $previous->getTargetResourceType()->tryResolvePropertyTypeByName($identifier);
                     $descriptor->setProjectedProperty($projectedProperty);
                     if ($identifier === ODataConstants::URI_COUNT_SEGMENT) {
                         if ($previous->getTargetKind() != RequestTargetKind::RESOURCE) {
                             ODataException::createBadRequestError(Messages::segmentParserCountCannotBeApplied($previous->getIdentifier()));
                         }
                         if ($previous->isSingleResult()) {
                             ODataException::createBadRequestError(Messages::segmentParserCountCannotFollowSingleton($previous->getIdentifier()));
                         }
                         $descriptor->setTargetKind(RequestTargetKind::PRIMITIVE_VALUE);
                         $descriptor->setSingleResult(true);
                         $descriptor->setTargetResourceSetWrapper($previous->getTargetResourceSetWrapper());
                         $descriptor->setTargetResourceType($previous->getTargetResourceType());
                     } else {
                         if ($identifier === ODataConstants::URI_VALUE_SEGMENT && $previous->getTargetKind() == RequestTargetKind::RESOURCE) {
                             $descriptor->setSingleResult(true);
                             $descriptor->setTargetResourceType($previous->getTargetResourceType());
                             $descriptor->setTargetKind(RequestTargetKind::MEDIA_RESOURCE);
                         } else {
                             if (is_null($projectedProperty)) {
                                 if (!is_null($previous->getTargetResourceType()) && !is_null($previous->getTargetResourceType()->tryResolveNamedStreamByName($identifier))) {
                                     $descriptor->setTargetKind(RequestTargetKind::MEDIA_RESOURCE);
                                     $descriptor->setSingleResult(true);
                                     $descriptor->setTargetResourceType($previous->getTargetResourceType());
                                 } else {
                                     ODataException::createResourceNotFoundError($identifier);
                                 }
                             } else {
                                 $descriptor->setTargetResourceType($projectedProperty->getResourceType());
                                 $descriptor->setSingleResult($projectedProperty->getKind() != ResourcePropertyKind::RESOURCESET_REFERENCE);
                                 if ($previous->getTargetKind() == RequestTargetKind::LINK && $projectedProperty->getTypeKind() != ResourceTypeKind::ENTITY) {
                                     ODataException::createBadRequestError(Messages::segmentParserLinkSegmentMustBeFollowedByEntitySegment($identifier));
                                 }
                                 switch ($projectedProperty->getKind()) {
                                     case ResourcePropertyKind::COMPLEX_TYPE:
                                         $descriptor->setTargetKind(RequestTargetKind::COMPLEX_OBJECT);
                                         break;
                                     case ResourcePropertyKind::BAG | ResourcePropertyKind::PRIMITIVE:
                                     case ResourcePropertyKind::BAG | ResourcePropertyKind::COMPLEX_TYPE:
                                         $descriptor->setTargetKind(RequestTargetKind::BAG);
                                         break;
                                     case ResourcePropertyKind::RESOURCE_REFERENCE:
                                     case ResourcePropertyKind::RESOURCESET_REFERENCE:
                                         $descriptor->setTargetKind(RequestTargetKind::RESOURCE);
                                         $resourceSetWrapper = $this->_providerWrapper->getResourceSetWrapperForNavigationProperty($previous->getTargetResourceSetWrapper(), $previous->getTargetResourceType(), $projectedProperty);
                                         if (is_null($resourceSetWrapper)) {
                                             ODataException::createResourceNotFoundError($projectedProperty->getName());
                                         }
                                         $descriptor->setTargetResourceSetWrapper($resourceSetWrapper);
                                         break;
                                     default:
                                         if (!$projectedProperty->isKindOf(ResourcePropertyKind::PRIMITIVE)) {
                                             ODataException::createInternalServerError(Messages::segmentParserUnExpectedPropertyKind('Primitive'));
                                         }
                                         $descriptor->setTargetKind(RequestTargetKind::PRIMITIVE);
                                         break;
                                 }
                                 if ($hasPredicate) {
                                     $this->_assertion(!$descriptor->isSingleResult());
                                     $keyDescriptor = $this->_createKeyDescriptor($identifier . '(' . $keyPredicate . ')', $projectedProperty->getResourceType(), $keyPredicate);
                                     $descriptor->setKeyDescriptor($keyDescriptor);
                                     if (!$keyDescriptor->isEmpty()) {
                                         $descriptor->setSingleResult(true);
                                     }
                                 }
                                 if ($checkRights && !is_null($descriptor->getTargetResourceSetWrapper())) {
                                     $descriptor->getTargetResourceSetWrapper()->checkResourceSetRightsForRead($descriptor->isSingleResult());
                                 }
                             }
                         }
                     }
                 }
             }
         }
         $descriptor->setPrevious($previous);
         $previous->setNext($descriptor);
         $this->_segmentDescriptors[] = $descriptor;
         $previous = $descriptor;
     }
     if ($previous->getTargetKind() == RequestTargetKind::LINK) {
         ODataException::createBadRequestError(Messages::segmentParserMissingSegmentAfterLink());
     }
 }