Exemple #1
0
 /**
  * Creates new instance of Navigation
  * 
  * @param ResourceType $resourceType The resource type for this navigation.
  */
 public function __construct($resourceType)
 {
     if ($resourceType->getResourceTypeKind() != ResourceTypeKind::COMPLEX && $resourceType->getResourceTypeKind() != ResourceTypeKind::ENTITY) {
         throw new InvalidArgumentException(Messages::navigationInvalidResourceType());
     }
     $this->_resourceType = $resourceType;
 }
Exemple #2
0
 /**
  * Creates new intstance of ResourceSet
  * 
  * @param string       $name         Name of the resource set (entity set)  
  * @param ResourceType $resourceType ResourceType describing the resource 
  *                                   this entity set holds
  * 
  * @throws InvalidArgumentException
  */
 public function __construct($name, ResourceType $resourceType)
 {
     if ($resourceType->getResourceTypeKind() != ResourceTypeKind::ENTITY) {
         throw new \InvalidArgumentException(Messages::resourceSetContainerMustBeAssociatedWithEntityType());
     }
     $this->_name = $name;
     $this->_resourceType = $resourceType;
 }
Exemple #3
0
 /**
  * Creates a new instance of FilterInfo.
  * 
  * @param array(array(ResourceProperty))/NULL $navigationPropertiesUsedInTheFilterClause Collection of navigation properties specified in the filter
  * 
  * @throws InvalidArgumentException
  */
 public function __construct($navigationPropertiesUsedInTheFilterClause)
 {
     if (!is_null($navigationPropertiesUsedInTheFilterClause)) {
         if (!is_array($navigationPropertiesUsedInTheFilterClause)) {
             throw new \InvalidArgumentException(Messages::filterInfoNaviUsedArgumentShouldBeNullOrNonEmptyArray());
         }
     }
     $this->_navigationPropertiesUsedInTheFilterClause = $navigationPropertiesUsedInTheFilterClause;
 }
 public function handleRequest()
 {
     try {
         $this->createProviders();
         $this->getHost()->validateQueryParameters();
         $requestMethod = $this->getOperationContext()->incomingRequest()->getMethod();
         if ($requestMethod !== ODataConstants::HTTP_METHOD_GET) {
             ODataException::createNotImplementedError(Messages::dataServiceOnlyReadSupport($requestMethod));
         }
     } catch (\Exception $exception) {
         throw $exception;
     }
     $uriProcessor = null;
     try {
         $uriProcessor = UriProcessor::process($this);
         return $uriProcessor;
     } catch (\Exception $exception) {
         throw $exception;
     }
 }
 /**
  * Construct new instance of ResourceAssociationSet
  * 
  * @param string                    $name Name of the association set
  * @param ResourceAssociationSetEnd $end1 First end set participating 
  *                                        in the association set
  * @param ResourceAssociationSetEnd $end2 Second end set participating 
  *                                        in the association set
  * 
  * @throws \InvalidArgumentException
  */
 public function __construct($name, ResourceAssociationSetEnd $end1, ResourceAssociationSetEnd $end2)
 {
     if (is_null($end1->getResourceProperty()) && is_null($end2->getResourceProperty())) {
         throw new \InvalidArgumentException(Messages::resourceAssociationSetResourcePropertyCannotBeBothNull());
     }
     if ($end1->getResourceType() == $end2->getResourceType() && $end1->getResourceProperty() == $end2->getResourceProperty()) {
         throw new \InvalidArgumentException(Messages::resourceAssociationSetSelfReferencingAssociationCannotBeBiDirectional());
     }
     $this->_name = $name;
     $this->_end1 = $end1;
     $this->_end2 = $end2;
 }
 /**
  * Constructs a new instance of OrderByPathSegment
  * 
  * @param array(OrderBySubPathSegment) $orderBySubPathSegments Collection of 
  *                                                             orderby sub path 
  *                                                             segments for
  *                                                             this path segment.
  * @param boolean                      $isAscending            sort order, 
  *                                                             True for 
  *                                                             ascending and 
  *                                                             false
  *                                                             for desending.
  */
 public function __construct($orderBySubPathSegments, $isAscending = true)
 {
     if (!is_array($orderBySubPathSegments)) {
         throw new \InvalidArgumentException(Messages::orderByPathSegmentOrderBySubPathSegmentArgumentShouldBeNonEmptyArray());
     }
     if (empty($orderBySubPathSegments)) {
         throw new \InvalidArgumentException(Messages::orderByPathSegmentOrderBySubPathSegmentArgumentShouldBeNonEmptyArray());
     }
     $this->_orderBySubPathSegments = $orderBySubPathSegments;
     $this->_isAscending = $isAscending;
 }
 /**
  * Checks that the parameter to a function is numeric and is not negative
  * 
  * @param int    $value        The value of parameter to check
  * @param string $functionName The name of the function that receives above value
  * 
  * @throws InvalidOperationException
  * 
  * @return int
  */
 private function _checkIntegerNonNegativeParameter($value, $functionName)
 {
     if (!is_int($value)) {
         throw new \InvalidArgumentException(Messages::commonArgumentShouldBeInteger($value, $functionName));
     }
     if ($value < 0) {
         throw new \InvalidArgumentException(Messages::commonArgumentShouldBeNonNegative($value, $functionName));
     }
     return $value;
 }
 /**
  * Process the given request Uri and creates an instance of 
  * RequestDescription from the processed uri.
  * 
  * @param Url         &$absoluteRequestUri The absolute request uri.
  * @param DataService &$dataService        Reference to the data service
  *                                         instance.
  * 
  * @return RequestDescription
  * 
  * @throws ODataException If any exception occurs while processing the segments
  *                        or incase of any version incompatibility.
  */
 public static function process(Url &$absoluteRequestUri, DataService &$dataService)
 {
     $absoluteRequestUri = $dataService->getHost()->getAbsoluteRequestUri();
     $absoluteServiceUri = $dataService->getHost()->getAbsoluteServiceUri();
     $requestUriSegments = array_slice($absoluteRequestUri->getSegments(), $absoluteServiceUri->getSegmentCount());
     $segmentDescriptors = null;
     try {
         $segmentDescriptors = SegmentParser::parseRequestUriSegements($requestUriSegments, $dataService->getMetadataQueryProviderWrapper(), true);
     } catch (ODataException $odataException) {
         throw $odataException;
     }
     $requestDescription = new RequestDescription($segmentDescriptors, $absoluteRequestUri);
     $requestTargetKind = $requestDescription->getTargetKind();
     if ($requestTargetKind != RequestTargetKind::METADATA && $requestTargetKind != RequestTargetKind::BATCH && $requestTargetKind != RequestTargetKind::SERVICE_DIRECTORY) {
         if ($requestTargetKind != RequestTargetKind::PRIMITIVE_VALUE && $requestTargetKind != RequestTargetKind::MEDIA_RESOURCE) {
             $requestDescription->setContainerName($requestDescription->getIdentifier());
         } else {
             // http://odata/NW.svc/Orders/$count
             // http://odata/NW.svc/Orders(123)/Customer/CustomerID/$value
             // http://odata/NW.svc/Employees(1)/$value
             // http://odata/NW.svc/Employees(1)/ThumbNail_48X48/$value
             $requestDescription->setContainerName($segmentDescriptors[count($segmentDescriptors) - 2]->getIdentifier());
         }
         if ($requestDescription->getIdentifier() === ODataConstants::URI_COUNT_SEGMENT) {
             if (!$dataService->getServiceConfiguration()->getAcceptCountRequests()) {
                 ODataException::createBadRequestError(Messages::dataServiceConfigurationCountNotAccepted());
             }
             $requestDescription->setRequestCountOption(RequestCountOption::VALUE_ONLY);
             // use of $count requires request DataServiceVersion
             // and MaxDataServiceVersion
             // greater than or equal to 2.0
             $requestDescription->raiseResponseVersion(2, 0, $dataService);
             $requestDescription->raiseMinimumVersionRequirement(2, 0, $dataService);
         } else {
             if ($requestDescription->isNamedStream()) {
                 $requestDescription->raiseMinimumVersionRequirement(3, 0, $dataService);
             } else {
                 if ($requestDescription->getTargetKind() == RequestTargetKind::RESOURCE) {
                     if (!$requestDescription->isLinkUri()) {
                         $resourceSetWrapper = $requestDescription->getTargetResourceSetWrapper();
                         //assert($resourceSetWrapper != null)
                         $hasNamedStream = $resourceSetWrapper->hasNamedStreams($dataService->getMetadataQueryProviderWrapper());
                         $hasBagProperty = $resourceSetWrapper->hasBagProperty($dataService->getMetadataQueryProviderWrapper());
                         if ($hasNamedStream || $hasBagProperty) {
                             $requestDescription->raiseResponseVersion(3, 0, $dataService);
                         }
                     }
                 } else {
                     if ($requestDescription->getTargetKind() == RequestTargetKind::BAG) {
                         $requestDescription->raiseResponseVersion(3, 0, $dataService);
                     }
                 }
             }
         }
     }
     return $requestDescription;
 }
 /**
  * Build nextpage link from the given object which will be the last object
  * in the page.
  * 
  * @param mixed $lastObject Entity instance to build next page link from.
  * 
  * @return string
  * 
  * @throws ODataException If reflection exception occurs while accessing 
  *                        property.
  */
 public function buildNextPageLink($lastObject)
 {
     $nextPageLink = null;
     foreach ($this->_internalOrderByInfo->getOrderByPathSegments() as $orderByPathSegment) {
         $index = 0;
         $currentObject = $lastObject;
         $subPathSegments = $orderByPathSegment->getSubPathSegments();
         $subPathCount = count($subPathSegments);
         foreach ($subPathSegments as &$subPathSegment) {
             $isLastSegment = $index == $subPathCount - 1;
             try {
                 $dummyProperty = new \ReflectionProperty($currentObject, $subPathSegment->getName());
                 $currentObject = $dummyProperty->getValue($currentObject);
                 if (is_null($currentObject)) {
                     $nextPageLink .= 'null, ';
                     break;
                 } else {
                     if ($isLastSegment) {
                         $type = $subPathSegment->getInstanceType();
                         $value = $type->convertToOData($currentObject);
                         $nextPageLink .= $value . ', ';
                     }
                 }
             } catch (\ReflectionException $reflectionException) {
                 throw ODataException::createInternalServerError(Messages::internalSkipTokenInfoFailedToAccessOrInitializeProperty($subPathSegment->getName()));
             }
             $index++;
         }
     }
     return rtrim($nextPageLink, ", ");
 }
Exemple #10
0
 /**
  * Constructs new instance of OrderByInfo
  * 
  * @param array $orderByPathSegments                        Order by 
  *                                                          path segments
  * array(OrderByPathSegment)
  * @param array $navigationPropertiesUsedInTheOrderByClause navigation
  *                                                          properties used
  *                                                          in the order 
  *                                                          by clause
  * array(array(ResourceProperty))/NULL
  * 
  * @throws InvalidArgumentException
  */
 public function __construct($orderByPathSegments, $navigationPropertiesUsedInTheOrderByClause)
 {
     if (!is_array($orderByPathSegments)) {
         throw new \InvalidArgumentException(Messages::orderByInfoPathSegmentsArgumentShouldBeNonEmptyArray());
     }
     if (empty($orderByPathSegments)) {
         throw new \InvalidArgumentException(Messages::orderByInfoPathSegmentsArgumentShouldBeNonEmptyArray());
     }
     if (!is_null($navigationPropertiesUsedInTheOrderByClause)) {
         if (!is_array($navigationPropertiesUsedInTheOrderByClause)) {
             throw new \InvalidArgumentException(Messages::orderByInfoNaviUSedArgumentShouldBeNullOrNonEmptyArray());
         }
         if (empty($navigationPropertiesUsedInTheOrderByClause)) {
             throw new \InvalidArgumentException(Messages::orderByInfoNaviUSedArgumentShouldBeNullOrNonEmptyArray());
         }
     }
     $this->_orderByPathSegments = $orderByPathSegments;
     $this->_navigationPropertiesUsedInTheOrderByClause = $navigationPropertiesUsedInTheOrderByClause;
 }
 /**
  * Gets and validate the ResourceAssociationSet instance for the 
  * given source resource association end
  * This function first searches the ResourceAssociationSet cache, 
  * if found return it otherwise 
  * get the association set from metadata wrapper, 
  * validate, cache and return it.
  * 
  * @param ResourceSetWrapper $resourceSet        Resource set of the 
  *                                               source association end
  * @param ResourceType       $resourceType       Resource type of the 
  *                                               source association end
  * @param ResourceProperty   $navigationProperty Resource property of the 
  *                                               source association end
  * 
  * @return ResourceAssociationSet/NULL The association set instance for the 
  *                                     given association set end,
  *                                     NULL if the metadata wrapper 
  *                                     returns NULL 
  *                                     (either IDSMP implementation
  *                                     returns null or 
  *                                     target resource set is invisible)
  *                                  
  * @throws InvalidOperationException If validation of AssociationSet fails
  * @throws ODataException If validation fails at 
  * MetadataQueryProviderWrapper::getResourceAssociationSet
  */
 private function _getResourceAssociationSet(ResourceSetWrapper $resourceSet, ResourceType $resourceType, ResourceProperty $navigationProperty)
 {
     $associationSetLookupKey = $resourceSet->getName() . '_' . $resourceType->getFullName() . '_' . $navigationProperty->getName();
     if (array_key_exists($associationSetLookupKey, $this->_resourceAssociationSets)) {
         return $this->_resourceAssociationSets[$associationSetLookupKey];
     }
     $resourceAssociationSet = $this->metadataQueryproviderWrapper->getResourceAssociationSet($resourceSet, $resourceType, $navigationProperty);
     if (is_null($resourceAssociationSet)) {
         //Either the related ResourceSet is invisible or IDSMP implementation returns null
         return null;
     }
     /**
      * @var ResourceAssociationSetEnd
      */
     $relatedEnd = $resourceAssociationSet->getRelatedResourceAssociationSetEnd($resourceSet->getResourceSet(), $resourceType, $navigationProperty);
     //For bidirectional relationship IDSMP::getResourceAssociationSet should
     //return same association set when called from either end
     if (!is_null($relatedEnd->getResourceProperty())) {
         //No need to check whether the following call returns NULL,
         //because the above call
         //MetadataQueryproviderWrapper::getResourceAssociationSet
         //causes the metadata wrapper to check the visibility of
         //related resource set and cache the corrosponding wrapper.
         //If found invisible it would have return NULL,
         //which we are any way handling above.
         $relatedResourceSetWrapper = $this->metadataQueryproviderWrapper->validateResourceSetAndGetWrapper($relatedEnd->getResourceSet());
         $reverseResourceAssociationSet = $this->metadataQueryproviderWrapper->getResourceAssociationSet($relatedResourceSetWrapper, $relatedEnd->getResourceType(), $relatedEnd->getResourceProperty());
         if (is_null($reverseResourceAssociationSet) || !is_null($reverseResourceAssociationSet) && $resourceAssociationSet->getName() != $reverseResourceAssociationSet->getName()) {
             throw new InvalidOperationException(Messages::metadataAssociationTypeSetBidirectionalAssociationMustReturnSameResourceAssociationSetFromBothEnd());
         }
     }
     $reverseAssociationSetLookupKey = null;
     if (!is_null($relatedEnd->getResourceProperty())) {
         $reverseAssociationSetLookupKey = $relatedEnd->getResourceSet()->getName() . '_' . $relatedEnd->getResourceProperty()->getResourceType()->getFullName() . '_' . $relatedEnd->getResourceProperty()->getName();
     } else {
         $reverseAssociationSetLookupKey = $relatedEnd->getResourceSet()->getName() . '_Null_' . $resourceType->getFullName() . '_' . $navigationProperty->getName();
     }
     if (array_key_exists($reverseAssociationSetLookupKey, $this->_resourceAssociationSets)) {
         throw new InvalidOperationException(Messages::metadataAssociationTypeSetMultipleAssociationSetsForTheSameAssociationTypeMustNotReferToSameEndSets($this->_resourceAssociationSets[$reverseAssociationSetLookupKey]->getName(), $resourceAssociationSet->getName(), $relatedEnd->getResourceSet()->getName()));
     }
     $this->_resourceAssociationSets[$associationSetLookupKey] = $resourceAssociationSet;
     $this->_resourceAssociationSets[$reverseAssociationSetLookupKey] = $resourceAssociationSet;
     return $resourceAssociationSet;
 }
Exemple #12
0
 /**
  * Assert that the given condition is true, if false throw 
  * ODataException for syntax error
  * 
  * @param boolean $condition The condition to assert
  * 
  * @return void
  * 
  * @throws ODataException
  */
 private function _assertion($condition)
 {
     if (!$condition) {
         ODataException::createSyntaxError(Messages::syntaxError());
     }
 }
 /**
  * Construct new instance of ResourceAssociationTypeEnd
  * 
  * @param string                $name             name of the end
  * @param ResourceType          $resourceType     resource type that the end 
  *                                                refers to
  * @param ResourceProperty/NULL $resourceProperty property of the end, can be 
  *                                                NULL if relationship is 
  *                                                uni-directional
  * @param ResourceProperty/NULL $fromProperty     Property on the related end 
  *                                                that points to this end, can 
  *                                                be NULL if relationship is 
  *                                                uni-directional
  */
 public function __construct($name, ResourceType $resourceType, $resourceProperty, $fromProperty)
 {
     if (is_null($resourceProperty) && is_null($fromProperty)) {
         throw new \InvalidArgumentException(Messages::resourceAssociationTypeEndBothPropertyCannotBeNull());
     }
     if (!is_null($fromProperty) && !$fromProperty instanceof ResourceProperty) {
         throw new \InvalidArgumentException(Messages::resourceAssociationTypeEndPropertyMustBeNullOrInsatnceofResourceProperty('$fromProperty'));
     }
     if (!is_null($resourceProperty) && !$resourceProperty instanceof ResourceProperty) {
         throw new \InvalidArgumentException(Messages::resourceAssociationTypeEndPropertyMustBeNullOrInsatnceofResourceProperty('$$resourceProperty'));
     }
     $this->_name = $name;
     $this->_resourceType = $resourceType;
     $this->_resourceProperty = $resourceProperty;
     $this->_fromProperty = $fromProperty;
 }
 /**
  * Process the resource path and query options of client's request uri.
  * 
  * @param DataService &$dataService Reference to the data service instance.
  * 
  * @return void
  * 
  * @throws ODataException
  */
 public static function process(DataService &$dataService)
 {
     $absoluteRequestUri = $dataService->getHost()->getAbsoluteRequestUri();
     $absoluteServiceUri = $dataService->getHost()->getAbsoluteServiceUri();
     if (!$absoluteServiceUri->isBaseOf($absoluteRequestUri)) {
         ODataException::createInternalServerError(Messages::uriProcessorRequestUriDoesNotHaveTheRightBaseUri($absoluteRequestUri->getUrlAsString(), $absoluteServiceUri->getUrlAsString()));
     }
     $uriProcessor = new UriProcessor($dataService);
     //Parse the resource path part of the request Uri.
     try {
         $uriProcessor->_requestDescription = ResourcePathProcessor::process($absoluteRequestUri, $dataService);
         $uriProcessor->_requestDescription->setUriProcessor($uriProcessor);
     } catch (ODataException $odataException) {
         throw $odataException;
     }
     //Parse the query string options of the request Uri.
     try {
         QueryProcessor::process($uriProcessor->_requestDescription, $dataService);
     } catch (ODataException $odataException) {
         throw $odataException;
     }
     return $uriProcessor;
 }
 /**
  * Parse the given skiptoken, validate it using the given InternalOrderByInfo 
  * and generates instance of InternalSkipTokenInfo.
  * 
  * @param ResourceType        &$resourceType        The resource type of the
  *                                                  resource targetted by the
  *                                                  resource path.
  * @param InternalOrderByInfo &$internalOrderByInfo The $orderby details.
  * @param string              $skipToken            The $skiptoken value.
  * 
  * @return InternalSkipTokenInfo
  * 
  * @throws ODataException
  */
 public static function parseSkipTokenClause(ResourceType &$resourceType, InternalOrderByInfo &$internalOrderByInfo, $skipToken)
 {
     $tokenValueDescriptor = null;
     if (!KeyDescriptor::tryParseValuesFromSkipToken($skipToken, $tokenValueDescriptor)) {
         ODataException::createSyntaxError(Messages::skipTokenParserSyntaxError($skipToken));
     }
     $orderByPathSegments = null;
     //$positionalValues are of type array(int, array(string, IType))
     $positionalValues =& $tokenValueDescriptor->getPositionalValuesByRef();
     $count = count($positionalValues);
     $orderByPathSegments = $internalOrderByInfo->getOrderByPathSegments();
     $orderByPathCount = count($orderByPathSegments);
     if ($count != $orderByPathCount) {
         ODataException::createBadRequestError(Messages::skipTokenParserSkipTokenNotMatchingOrdering($count, $skipToken, $orderByPathCount));
     }
     $i = 0;
     foreach ($orderByPathSegments as $orderByPathSegment) {
         $typeProvidedInSkipToken = $positionalValues[$i][1];
         if (!$typeProvidedInSkipToken instanceof Null1) {
             $orderBySubPathSegments = $orderByPathSegment->getSubPathSegments();
             $j = count($orderBySubPathSegments) - 1;
             $expectedType = $orderBySubPathSegments[$j]->getInstanceType();
             if (!$expectedType->isCompatibleWith($typeProvidedInSkipToken)) {
                 ODataException::createSyntaxError(Messages::skipTokenParserInCompatibleTypeAtPosition($skipToken, $expectedType->getFullTypeName(), $i, $typeProvidedInSkipToken->getFullTypeName()));
             }
         }
         $i++;
     }
     return new InternalSkipTokenInfo($internalOrderByInfo, $positionalValues, $resourceType);
 }
 /**
  * Validate this KeyDescriptor, If valid, this function populates
  * _validatedNamedValues array with key as keyName and value as an array of
  * key value and key type.
  *
  * @param string       $segmentAsString The segment in the form identifer
  *                                      (keyPredicate) which this descriptor
  *                                      represents
  * @param ResourceType $resourceType    The type of the idenfier in the segment
  *
  * @return void
  *
  * @throws ODataException If validation fails.
  */
 public function validate($segmentAsString, ResourceType $resourceType)
 {
     if ($this->isEmpty()) {
         $this->_validatedNamedValues = array();
         return;
     }
     $keyProperties = $resourceType->getKeyProperties();
     $keyPropertiesCount = count($keyProperties);
     if (!empty($this->_namedValues)) {
         if (count($this->_namedValues) != $keyPropertiesCount) {
             ODataException::createSyntaxError(Messages::keyDescriptorKeyCountNotMatching($segmentAsString, $keyPropertiesCount, count($this->_namedValues)));
         }
         foreach ($keyProperties as $keyName => $keyResourceProperty) {
             if (!array_key_exists($keyName, $this->_namedValues)) {
                 $keysAsString = null;
                 foreach (array_keys($keyProperties) as $key) {
                     $keysAsString .= $key . ', ';
                 }
                 $keysAsString = rtrim($keysAsString, ' ,');
                 ODataException::createSyntaxError(Messages::keyDescriptorMissingKeys($segmentAsString, $keysAsString));
             }
             $typeProvided = $this->_namedValues[$keyName][1];
             $expectedType = $keyResourceProperty->getInstanceType();
             if (!$expectedType->isCompatibleWith($typeProvided)) {
                 ODataException::createSyntaxError(Messages::keyDescriptorInCompatibleKeyType($segmentAsString, $keyName, $expectedType->getFullTypeName(), $typeProvided->getFullTypeName()));
             }
             $this->_validatedNamedValues[$keyName] = $this->_namedValues[$keyName];
         }
     } else {
         if (count($this->_positionalValues) != $keyPropertiesCount) {
             ODataException::createSyntaxError(Messages::keyDescriptorKeyCountNotMatching($segmentAsString, $keyPropertiesCount, count($this->_positionalValues)));
         }
         $i = 0;
         foreach ($keyProperties as $keyName => $keyResourceProperty) {
             $typeProvided = $this->_positionalValues[$i][1];
             $expectedType = $keyResourceProperty->getInstanceType();
             if (!$expectedType->isCompatibleWith($typeProvided)) {
                 ODataException::createSyntaxError(Messages::keyDescriptorInCompatibleKeyTypeAtPosition($segmentAsString, $keyResourceProperty->getName(), $i, $expectedType->getFullTypeName(), $typeProvided->getFullTypeName()));
             }
             $this->_validatedNamedValues[$keyName] = $this->_positionalValues[$i];
             $i++;
         }
     }
 }
 /**
  * Validate current character is a digit.
  * 
  * @return void
  */
 private function _validateDigit()
 {
     if (!Char::isDigit($this->_ch)) {
         throw $this->_parseError(Messages::expressionLexerDigitExpected($this->_textPos));
     }
 }
 /**
  * Returns the etag for the given resource.
  * Note: This function will not add W\" prefix and " suffix, its callers
  * repsonsability.
  *
  * @param mixed        &$entryObject  Resource for which etag value needs to 
  *                                    be returned
  * @param ResourceType &$resourceType Resource type of the $entryObject
  * 
  * @return string/NULL ETag value for the given resource (with values encoded 
  *                     for use in a URI) there are etag properties, NULL if 
  *                     there is no etag property.
  */
 protected function getETagForEntry(&$entryObject, ResourceType &$resourceType)
 {
     $eTag = null;
     $comma = null;
     foreach ($resourceType->getETagProperties() as $eTagProperty) {
         $type = $eTagProperty->getInstanceType();
         self::assert(!is_null($type) && array_search('ODataProducer\\Providers\\Metadata\\Type\\IType', class_implements($type)) !== false, '!is_null($type) 
             && array_search(\'ODataProducer\\Providers\\Metadata\\Type\\IType\', class_implements($type)) !== false');
         $value = null;
         try {
             $reflectionProperty = new \ReflectionProperty($entryObject, $eTagProperty->getName());
             $value = $reflectionProperty->getValue($entryObject);
         } catch (\ReflectionException $reflectionException) {
             throw ODataException::createInternalServerError(Messages::dataServiceFailedToAccessProperty($eTagProperty->getName(), $resourceType->getName()));
         }
         if (is_null($value)) {
             $eTag = $eTag . $comma . 'null';
         } else {
             $eTag = $eTag . $comma . $type->convertToOData($value);
         }
         $comma = ',';
     }
     if (!is_null($eTag)) {
         // If eTag is made up of datetime or string properties then the above
         // IType::converToOData will perform utf8 and url encode. But we don't
         // want this for eTag value.
         $eTag = urldecode(utf8_decode($eTag));
         return rtrim($eTag, ',');
     }
     return null;
 }
 /**
  * Write value of a complex object.
  * Note: This method will not handle null complex value.
  *
  * @param mixed                &$complexValue         Complex object to write.
  * @param string               $propertyName          Name of the
  *                                                    complex property
  *                                                    whose value
  *                                                    need to be written.
  * @param ResourceType         &$resourceType         Expected type of the
  *                                                    property.
  * @param string               $relativeUri           Relative uri for the
  *                                                    complex type element.
  * @param ODataPropertyContent &$odataPropertyContent Content to write to.
  *
  * @return ResourceType The actual type of the complex object.
  *
  * @return void
  */
 private function _complexObjectToContent(&$complexValue, $propertyName, ResourceType &$resourceType, $relativeUri, ODataPropertyContent &$odataPropertyContent)
 {
     $count = count($this->complexTypeInstanceCollection);
     for ($i = 0; $i < $count; $i++) {
         if ($this->complexTypeInstanceCollection[$i] === $complexValue) {
             throw new InvalidOperationException(Messages::objectModelSerializerLoopsNotAllowedInComplexTypes($propertyName));
         }
     }
     $this->complexTypeInstanceCollection[$count] =& $complexValue;
     //TODO function to resolve actual type from $resourceType
     $actualType = $resourceType;
     $odataEntry = null;
     $this->_writeObjectProperties($complexValue, $actualType, null, $relativeUri, $odataEntry, $odataPropertyContent);
     unset($this->complexTypeInstanceCollection[$count]);
     return $actualType;
 }
 /**
  * Retrieve the complex type(s) used in the given resource type and cache them.
  * 
  * @param ResourceType $resourceType The resource type to inspect
  * 
  * @return void
  * 
  * @throws InvalidOperationException If found any complex type bag property 
  * with derived type(s) 
  */
 private function _populateComplexTypes(ResourceType $resourceType)
 {
     foreach ($resourceType->getPropertiesDeclaredOnThisType() as $property) {
         if ($property->isKindOf(ResourcePropertyKind::COMPLEX_TYPE)) {
             if ($property->isKindOf(ResourcePropertyKind::BAG)) {
                 //Validate the bag complex type
                 //as it should not have derived type
                 if ($this->metadataQueryproviderWrapper->hasDerivedTypes($resourceType)) {
                     throw new InvalidOperationException(Messages::metadataResourceTypeSetBagOfComplexTypeWithDerivedTypes($resourceType->getFullName()));
                 }
             }
             if ($this->_populateResourceTypes($property->getResourceType())) {
                 $this->_populateComplexTypes($property->getResourceType());
             }
         }
     }
 }
 /**
  * Converts the specified character from the ASCII range to a digit.
  * 
  * @param char $c Character to convert
  *
  * @return int The Int32 value for $c, or -1 if it is an element separator.
  *
  * @throws HttpHeaderFailure If $c is not ASCII value for digit or element
  *                           seperator.
  */
 public static function digitToInt32($c)
 {
     if ($c >= '0' && $c <= '9') {
         return intval($c);
     } else {
         if (self::isHttpElementSeparator($c)) {
             return -1;
         } else {
             throw new HttpHeaderFailure(Messages::httpProcessUtilityMalformedHeaderValue(), 400);
         }
     }
 }
 /**
  * Validate the given entity instance.
  * 
  * @param object        $entityInstance Entity instance to validate
  * @param ResourceSet   &$resourceSet   Resource set to which the entity 
  *                                      instance belongs to.
  * @param KeyDescriptor &$keyDescriptor The key descriptor.
  * @param string        $methodName     Method from which this function 
  *                                      invoked.
  *
  * @return void
  * 
  * @throws ODataException
  */
 private function _validateEntityInstance($entityInstance, ResourceSet &$resourceSet, KeyDescriptor &$keyDescriptor, $methodName)
 {
     if (is_null($entityInstance)) {
         ODataException::createResourceNotFoundError($resourceSet->getName());
     }
     $entityName = $resourceSet->getResourceType()->getInstanceType()->getName();
     if (!is_object($entityInstance) || !$entityInstance instanceof $entityName) {
         ODataException::createInternalServerError(Messages::metadataQueryProviderWrapperIDSQPMethodReturnsUnExpectedType($entityName, $methodName));
     }
     foreach ($keyDescriptor->getValidatedNamedValues() as $keyName => $valueDescription) {
         try {
             $keyProperty = new \ReflectionProperty($entityInstance, $keyName);
             $keyValue = $keyProperty->getValue($entityInstance);
             if (is_null($keyValue)) {
                 ODataException::createInternalServerError(Messages::metadataQueryProviderWrapperIDSQPMethodReturnsInstanceWithNullKeyProperties($methodName));
             }
             $convertedValue = $valueDescription[1]->convert($valueDescription[0]);
             if ($keyValue != $convertedValue) {
                 ODataException::createInternalServerError(Messages::metadataQueryProviderWrapperIDSQPMethodReturnsInstanceWithNonMatchingKeys($methodName));
             }
         } catch (\ReflectionException $reflectionException) {
             //throw ODataException::createInternalServerError(
             //  Messages::orderByParserFailedToAccessOrInitializeProperty(
             //      $resourceProperty->getName(), $resourceType->getName()
             //  )
             //);
         }
     }
 }
 /**
  * To add a child node to the list of child nodes.
  * 
  * @param ProjectionNode $node Node to add.
  * 
  * @return void 
  * 
  * @throws InvalidArgumentException
  */
 public function addNode($node)
 {
     if (!$node instanceof ProjectionNode && !$node instanceof ExpandedProjectionNode) {
         throw new \InvalidArgumentException(Messages::expandedProjectionNodeArgumentTypeShouldbeProjection());
     }
     $this->_childNodes[$node->getPropertyName()] = $node;
 }
Exemple #24
0
 /**
  * To check whether the the query options $select, $expand
  * is applicable for the current requested resource.
  * 
  * @param string $queryItem The query option to check.
  * 
  * @return void
  * 
  * @throws ODataException Throws bad request error if the query 
  *                        options $select, $expand cannot be 
  *                        applied to the requested resource. 
  */
 private function _checkExpandOrSelectApplicable($queryItem)
 {
     if (!$this->_expandSelectApplicable) {
         ODataException::createBadRequestError(Messages::queryProcessorSelectOrExpandOptionNotApplicable($queryItem));
     }
 }
 /**
  * Write a navigation property
  * 
  * @param ResourceType     $resourceType                            Resource type
  * @param array            $associationTypesInResourceTypeNamespace Collection 
  * of association types for the given resource types
  * array(ResourceAssociatedType)
  * @param ResourceProperty $navigationProperty                      Navigation 
  * property
  * 
  * @throws InvalidOperationException
  * @return nothing
  */
 private function _writeNavigationProperty(ResourceType $resourceType, $associationTypesInResourceTypeNamespace, ResourceProperty $navigationProperty)
 {
     $associationTypeLookupName = $resourceType->getName() . '_' . $navigationProperty->getName();
     if (!array_key_exists($associationTypeLookupName, $associationTypesInResourceTypeNamespace)) {
         throw new InvalidOperationException(Messages::metadataWriterNoResourceAssociationSetForNavigationProperty($navigationProperty->getName(), $resourceType->getName()));
     }
     $associationType = $associationTypesInResourceTypeNamespace[$associationTypeLookupName];
     $thisEnd = $associationType->getResourceAssociationTypeEnd($resourceType, $navigationProperty);
     $relatedEnd = $associationType->getRelatedResourceAssociationSetEnd($resourceType, $navigationProperty);
     $this->_iOdataWriter->startElement(ODataConstants::NAVIGATION_PROPERTY);
     $this->_iOdataWriter->writeAttribute(ODataConstants::NAME, $navigationProperty->getName());
     $this->_iOdataWriter->writeAttribute(ODataConstants::RELATIONSHIP, $associationType->getFullName());
     $this->_iOdataWriter->writeAttribute(ODataConstants::FROM_ROLE, $thisEnd->getName());
     $this->_iOdataWriter->writeAttribute(ODataConstants::TO_ROLE, $relatedEnd->getName());
     $this->_iOdataWriter->endElement();
 }
Exemple #26
0
 /**
  * This function perform the following steps:
  * 1) Resolve and validate the service
  * 2) Creates the instance of requested service
  * 3) Calls the handleRequest() to process the request
  * 4) Calls the handleresponse() to sendback the o/p to the client
  *
  * @return void
  */
 public function dispatch()
 {
     $dataService = null;
     include_once $this->_serviceInfo['SERVICE_PATH'];
     try {
         $reflectionClass = new \ReflectionClass($this->_serviceInfo['SERVICE_CLASS']);
         $dataService = $reflectionClass->newInstance();
     } catch (\Exception $exception) {
         $this->_handleException($exception->getMessage(), HttpStatus::CODE_INTERNAL_SERVER_ERROR);
     }
     $interfaces = class_implements($dataService);
     if (array_key_exists('ODataProducer\\IDataService', $interfaces)) {
         $dataService->setHost($this->_dataServiceHost);
         if (array_key_exists('ODataProducer\\IRequestHandler', $interfaces)) {
             // DataService::handleRequest will never throw an error
             // All exception that can occur while parsing the request and
             // serializing the result will be handled by
             // DataService::handleRequest
             $dataService->handleRequest();
         } else {
             $this->_handleException(Messages::dispatcherServiceClassShouldImplementIRequestHandler(), HttpStatus::CODE_INTERNAL_SERVER_ERROR);
         }
     } else {
         $this->_handleException(Messages::dispatcherServiceClassShouldImplementIDataService(), HttpStatus::CODE_INTERNAL_SERVER_ERROR);
     }
     $this->_writeResponse($dataService->getHost()->getWebOperationContext()->outgoingResponse());
 }
 /**
  * Get predefined ResourceType for a primitive type
  *
  * @param EdmPrimitiveType $typeCode Typecode of primitive type
  *
  * @return ResourceType
  *
  * @throws InvalidArgumentException
  */
 public static function getPrimitiveResourceType($typeCode)
 {
     switch ($typeCode) {
         case EdmPrimitiveType::BINARY:
             return new ResourceType(new Binary(), ResourceTypeKind::PRIMITIVE, 'Binary', 'Edm');
             break;
         case EdmPrimitiveType::BOOLEAN:
             return new ResourceType(new Boolean(), ResourceTypeKind::PRIMITIVE, 'Boolean', 'Edm');
             break;
         case EdmPrimitiveType::BYTE:
             return new ResourceType(new Byte(), ResourceTypeKind::PRIMITIVE, 'Byte', 'Edm');
             break;
         case EdmPrimitiveType::DATETIME:
             return new ResourceType(new DateTime(), ResourceTypeKind::PRIMITIVE, 'DateTime', 'Edm');
             break;
         case EdmPrimitiveType::DECIMAL:
             return new ResourceType(new Decimal(), ResourceTypeKind::PRIMITIVE, 'Decimal', 'Edm');
             break;
         case EdmPrimitiveType::DOUBLE:
             return new ResourceType(new Double(), ResourceTypeKind::PRIMITIVE, 'Double', 'Edm');
             break;
         case EdmPrimitiveType::GUID:
             return new ResourceType(new Guid(), ResourceTypeKind::PRIMITIVE, 'Guid', 'Edm');
             break;
         case EdmPrimitiveType::INT16:
             return new ResourceType(new Int16(), ResourceTypeKind::PRIMITIVE, 'Int16', 'Edm');
             break;
         case EdmPrimitiveType::INT32:
             return new ResourceType(new Int32(), ResourceTypeKind::PRIMITIVE, 'Int32', 'Edm');
             break;
         case EdmPrimitiveType::INT64:
             return new ResourceType(new Int64(), ResourceTypeKind::PRIMITIVE, 'Int64', 'Edm');
             break;
         case EdmPrimitiveType::SBYTE:
             return new ResourceType(new SByte(), ResourceTypeKind::PRIMITIVE, 'SByte', 'Edm');
             break;
         case EdmPrimitiveType::SINGLE:
             return new ResourceType(new Single(), ResourceTypeKind::PRIMITIVE, 'Single', 'Edm');
             break;
         case EdmPrimitiveType::STRING:
             return new ResourceType(new OString(), ResourceTypeKind::PRIMITIVE, 'String', 'Edm');
             break;
         default:
             throw new \InvalidArgumentException(Messages::commonNotValidPrimitiveEDMType('$typeCode', 'getPrimitiveResourceType'));
     }
 }
 /**
  * Construct a new instance of ResouceProperty
  * 
  * @param string               $name                  Name of the property
  * @param string               $mimeType              Mime type of the property
  * @param ResourcePropertyKind $kind                  The kind of property
  * @param ResourceType         &$propertyResourceType ResourceType of the 
  *                                                    property
  * 
  * @throws InvalidOperationException
  */
 public function __construct($name, $mimeType, $kind, ResourceType &$propertyResourceType)
 {
     if (!$this->_isValidResourcePropertyKind($kind)) {
         throw new \InvalidArgumentException(Messages::resourcePropertyInvalidKindParameter('$kind'));
     }
     if (!$this->_isResourceKindValidForPropertyKind($kind, $propertyResourceType->getResourceTypeKind())) {
         throw new \InvalidArgumentException(Messages::resourcePropertyPropertyKindAndResourceTypeKindMismatch('$kind', '$propertyResourceType'));
     }
     $this->_name = $name;
     $this->_mimeType = $mimeType;
     $this->_kind = $kind;
     $this->_propertyResourceType = $propertyResourceType;
 }
 /**
  * Create newinstance of AnonymousFunction
  * 
  * @param array  $parameters Array of parameters
  * @param string $code       Body of the function
  */
 public function __construct($parameters, $code)
 {
     $this->_parameters = $parameters;
     foreach ($this->_parameters as $parameter) {
         if (strpos($parameter, '$') !== 0) {
             throw new \InvalidArgumentException(Messages::anonymousFunctionParameterShouldStartWithDollorSymbol());
         }
     }
     $this->_parametersAsString = implode(', ', $this->_parameters);
     $this->_code = $code;
 }
 /**
  *  Populate map table 
  *
  * @param AbstractExpression $nullCheckExpTree The expression to verfiy.
  * 
  * @return void
  * 
  * @throws ODataException
  */
 private function _map($nullCheckExpTree)
 {
     if ($nullCheckExpTree instanceof LogicalExpression) {
         $this->_map($nullCheckExpTree->getLeft());
         $this->_map($nullCheckExpTree->getRight());
     } else {
         if ($nullCheckExpTree instanceof UnaryExpression) {
             $this->_map($nullCheckExpTree->getChild());
         } else {
             if ($nullCheckExpTree instanceof FunctionCallExpression) {
                 $param = $nullCheckExpTree->getParamExpressions();
                 $this->_map($param[0]);
             } else {
                 if ($nullCheckExpTree instanceof PropertyAccessExpression) {
                     $parent = $nullCheckExpTree;
                     $key = null;
                     do {
                         $key = $parent->getResourceProperty()->getName() . '_' . $key;
                         $parent = $parent->getParent();
                     } while ($parent != null);
                     $this->_mapTable[$key] = $nullCheckExpTree;
                 } else {
                     ODataException::createSyntaxError(Messages::expressionParser2UnexpectedExpression(get_class($expTree)));
                 }
             }
         }
     }
 }