/** * Call-back for property access expression * * @param PropertyAccessExpression $expression The property access expression * * @return string */ public function onPropertyAccessExpression($expression) { $parent = $expression; $variable = null; $entityTypeName = $this->resourceType->getName(); $propertyName = $parent->getResourceProperty()->getName(); if (is_array($this->entityMapping)) { if (array_key_exists($entityTypeName, $this->entityMapping)) { if (array_key_exists($propertyName, $this->entityMapping[$entityTypeName])) { return $this->entityMapping[$entityTypeName][$propertyName]; } } } return $propertyName; }
public function testGetResourceAssociationSetEndIsNotVisible() { $fakePropName = "Fake Prop"; Phockito::when($this->mockResourceProperty->getName())->return($fakePropName); Phockito::when($this->mockResourceType->resolvePropertyDeclaredOnThisType($fakePropName))->return($this->mockResourceProperty); $fakeTypeName = "Fake Type"; Phockito::when($this->mockResourceType->getName())->return($fakeTypeName); $fakeSetName = "Fake Set"; Phockito::when($this->mockResourceSet->getName())->return($fakeSetName); Phockito::when($this->mockResourceSet->getResourceType())->return($this->mockResourceType); Phockito::when($this->mockResourceSet2->getResourceType())->return($this->mockResourceType2); //Indicate the resource set is visible Phockito::when($this->mockServiceConfig->getEntitySetAccessRule($this->mockResourceSet))->return(EntitySetRights::READ_SINGLE); //Indicate the resource set is visible Phockito::when($this->mockServiceConfig->getEntitySetAccessRule($this->mockResourceSet2))->return(EntitySetRights::NONE); Phockito::when($this->mockMetadataProvider->getResourceAssociationSet($this->mockResourceSet, $this->mockResourceType, $this->mockResourceProperty))->return($this->mockResourceAssociationSet); Phockito::when($this->mockResourceAssociationSet->getResourceAssociationSetEnd($this->mockResourceSet, $this->mockResourceType, $this->mockResourceProperty))->return($this->mockResourceAssociationSetEnd); Phockito::when($this->mockResourceAssociationSet->getRelatedResourceAssociationSetEnd($this->mockResourceSet, $this->mockResourceType, $this->mockResourceProperty))->return($this->mockResourceAssociationSetEnd); Phockito::when($this->mockResourceAssociationSetEnd->getResourceSet())->return($this->mockResourceSet2); Phockito::when($this->mockResourceAssociationSetEnd->getResourceType())->return($this->mockResourceType2); $wrapper = $this->getMockedWrapper(); $actual = $wrapper->getResourceAssociationSet($this->mockResourceSet, $this->mockResourceType, $this->mockResourceProperty); $this->assertNull($actual); }
/** * 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) && $type instanceof IType, '!is_null($type) && $type instanceof IType'); $value = null; try { //TODO #88...also this seems like dupe work $reflectionProperty = new \ReflectionProperty($entryObject, $eTagProperty->getName()); $value = $reflectionProperty->getValue($entryObject); } catch (\ReflectionException $reflectionException) { throw ODataException::createInternalServerError(Messages::failedToAccessProperty($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::convertToOData 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 a navigation property * * @param ResourceType $resourceType Resource type * @param ResourceAssociationType[] $associationTypesInResourceTypeNamespace Collection of association types for the given resource types * @param ResourceProperty $navigationProperty Navigation property * * @throws InvalidOperationException * @return void */ 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->_xmlWriter->startElement(ODataConstants::NAVIGATION_PROPERTY); $this->_xmlWriter->writeAttribute(ODataConstants::NAME, $navigationProperty->getName()); $this->_xmlWriter->writeAttribute(ODataConstants::RELATIONSHIP, $associationType->getFullName()); $this->_xmlWriter->writeAttribute(ODataConstants::FROM_ROLE, $thisEnd->getName()); $this->_xmlWriter->writeAttribute(ODataConstants::TO_ROLE, $relatedEnd->getName()); $this->_xmlWriter->endElement(); }
/** * Write values of properties of given entry (resource) or complex object. * * @param mixed $customObject Entity or complex object * with properties * to write out. * @param ResourceType &$resourceType Resource type describing * the metadata of * the custom object. * @param string $absoluteUri Absolute uri for the given * entry object * NULL for complex object. * @param string $relativeUri Relative uri for the given * custom object. * @param ODataEntry &$odataEntry ODataEntry instance to * place links and * expansion of the * entry object, * NULL for complex object. * @param ODataPropertyContent &$odataPropertyContent ODataPropertyContent * instance in which * to place the values. * * @return void */ private function _writeObjectProperties($customObject, ResourceType &$resourceType, $absoluteUri, $relativeUri, &$odataEntry, ODataPropertyContent &$odataPropertyContent) { // lion: if ($_SERVER['REQUEST_METHOD'] == HTTPRequestMethod::DELETE()) { $odataEntry = (object) array(); return; } // --- $resourceTypeKind = $resourceType->getResourceTypeKind(); if (is_null($absoluteUri) == ($resourceTypeKind == ResourceTypeKind::ENTITY)) { throw ODataException::createInternalServerError(Messages::badProviderInconsistentEntityOrComplexTypeUsage($resourceType->getName())); } $this->assert($resourceTypeKind == ResourceTypeKind::ENTITY && $odataEntry instanceof ODataEntry || $resourceTypeKind == ResourceTypeKind::COMPLEX && is_null($odataEntry), '(($resourceTypeKind == ResourceTypeKind::ENTITY) && ($odataEntry instanceof ODataEntry)) || (($resourceTypeKind == ResourceTypeKind::COMPLEX) && is_null($odataEntry))'); $projectionNodes = null; $navigationProperties = null; if ($resourceTypeKind == ResourceTypeKind::ENTITY) { $projectionNodes = $this->getProjectionNodes(); $navigationProperties = array(); } if (is_null($projectionNodes)) { //This is the code path to handle properties of Complex type //or Entry without projection (i.e. no expansion or selection) $resourceProperties = array(); if ($resourceTypeKind == ResourceTypeKind::ENTITY) { // If custom object is an entry then it can contain navigation // properties which are invisible (because the corresponding // resource set is invisible). // IDSMP::getResourceProperties will give collection of properties // which are visible. $currentResourceSetWrapper1 = $this->getCurrentResourceSetWrapper(); $resourceProperties = $this->service->getProvidersWrapper()->getResourceProperties($currentResourceSetWrapper1, $resourceType); } else { $resourceProperties = $resourceType->getAllProperties(); } //First write out primitve types foreach ($resourceProperties as $name => $resourceProperty) { if ($resourceProperty->getKind() == ResourcePropertyKind::PRIMITIVE || $resourceProperty->getKind() == (ResourcePropertyKind::PRIMITIVE | ResourcePropertyKind::KEY) || $resourceProperty->getKind() == (ResourcePropertyKind::PRIMITIVE | ResourcePropertyKind::ETAG) || $resourceProperty->getKind() == (ResourcePropertyKind::PRIMITIVE | ResourcePropertyKind::KEY | ResourcePropertyKind::ETAG)) { $odataProperty = new ODataProperty(); $primitiveValue = $this->getPropertyValue($customObject, $resourceType, $resourceProperty); $this->_writePrimitiveValue($primitiveValue, $resourceProperty, $odataProperty); $odataPropertyContent->properties[] = $odataProperty; } } //Write out bag and complex type $i = 0; foreach ($resourceProperties as $resourceProperty) { if ($resourceProperty->isKindOf(ResourcePropertyKind::BAG)) { //Handle Bag Property (Bag of Primitive or complex) $propertyValue = $this->getPropertyValue($customObject, $resourceType, $resourceProperty); $resourceType2 = $resourceProperty->getResourceType(); $this->_writeBagValue($propertyValue, $resourceProperty->getName(), $resourceType2, $relativeUri . '/' . $resourceProperty->getName(), $odataPropertyContent); } else { $resourcePropertyKind = $resourceProperty->getKind(); if ($resourcePropertyKind == ResourcePropertyKind::COMPLEX_TYPE) { $propertyValue = $this->getPropertyValue($customObject, $resourceType, $resourceProperty); $resourceType1 = $resourceProperty->getResourceType(); $this->_writeComplexValue($propertyValue, $resourceProperty->getName(), $resourceType1, $relativeUri . '/' . $resourceProperty->getName(), $odataPropertyContent); } else { if ($resourceProperty->getKind() == ResourcePropertyKind::PRIMITIVE || $resourceProperty->getKind() == (ResourcePropertyKind::PRIMITIVE | ResourcePropertyKind::KEY) || $resourceProperty->getKind() == (ResourcePropertyKind::PRIMITIVE | ResourcePropertyKind::ETAG) || $resourceProperty->getKind() == (ResourcePropertyKind::PRIMITIVE | ResourcePropertyKind::KEY | ResourcePropertyKind::ETAG)) { continue; } else { $this->assert($resourcePropertyKind == ResourcePropertyKind::RESOURCE_REFERENCE || $resourcePropertyKind == ResourcePropertyKind::RESOURCESET_REFERENCE, '($resourcePropertyKind == ResourcePropertyKind::RESOURCE_REFERENCE) || ($resourcePropertyKind == ResourcePropertyKind::RESOURCESET_REFERENCE)'); $navigationProperties[$i] = new NavigationPropertyInfo($resourceProperty, $this->shouldExpandSegment($resourceProperty->getName())); if ($navigationProperties[$i]->expanded) { $navigationProperties[$i]->value = $this->getPropertyValue($customObject, $resourceType, $resourceProperty); } $i++; } } } } } else { //This is the code path to handle projected properties of Entry $i = 0; foreach ($projectionNodes as $projectionNode) { $propertyName = $projectionNode->getPropertyName(); $resourceProperty = $resourceType->resolveProperty($propertyName); $this->assert(!is_null($resourceProperty), '!is_null($resourceProperty)'); if ($resourceProperty->getTypeKind() == ResourceTypeKind::ENTITY) { $currentResourceSetWrapper2 = $this->getCurrentResourceSetWrapper(); $resourceProperties = $this->service->getProvidersWrapper()->getResourceProperties($currentResourceSetWrapper2, $resourceType); //Check for the visibility of this navigation property if (array_key_exists($resourceProperty->getName(), $resourceProperties)) { $navigationProperties[$i] = new NavigationPropertyInfo($resourceProperty, $this->shouldExpandSegment($propertyName)); if ($navigationProperties[$i]->expanded) { $navigationProperties[$i]->value = $this->getPropertyValue($customObject, $resourceType, $resourceProperty); } $i++; continue; } } //Primitve, complex or bag property $propertyValue = $this->getPropertyValue($customObject, $resourceType, $resourceProperty); $propertyTypeKind = $resourceProperty->getKind(); $propertyResourceType = $resourceProperty->getResourceType(); $this->assert(!is_null($propertyResourceType), '!is_null($propertyResourceType)'); if (ResourceProperty::sIsKindOf($propertyTypeKind, ResourcePropertyKind::BAG)) { $bagResourceType = $resourceProperty->getResourceType(); $this->_writeBagValue($propertyValue, $propertyName, $bagResourceType, $relativeUri . '/' . $propertyName, $odataPropertyContent); } else { if (ResourceProperty::sIsKindOf($propertyTypeKind, ResourcePropertyKind::PRIMITIVE)) { $odataProperty = new ODataProperty(); $this->_writePrimitiveValue($propertyValue, $resourceProperty, $odataProperty); $odataPropertyContent->properties[] = $odataProperty; } else { if ($propertyTypeKind == ResourcePropertyKind::COMPLEX_TYPE) { $complexResourceType = $resourceProperty->getResourceType(); $this->_writeComplexValue($propertyValue, $propertyName, $complexResourceType, $relativeUri . '/' . $propertyName, $odataPropertyContent); } else { //unexpected $this->assert(false, '$propertyTypeKind = Primitive or Bag or ComplexType'); } } } } } if (!is_null($navigationProperties)) { //Write out navigation properties (deferred or inline) foreach ($navigationProperties as $navigationPropertyInfo) { $propertyName = $navigationPropertyInfo->resourceProperty->getName(); $type = $navigationPropertyInfo->resourceProperty->getKind() == ResourcePropertyKind::RESOURCE_REFERENCE ? 'application/atom+xml;type=entry' : 'application/atom+xml;type=feed'; $link = new ODataLink(); $link->name = ODataConstants::ODATA_RELATED_NAMESPACE . $propertyName; $link->title = $propertyName; $link->type = $type; $link->url = $relativeUri . '/' . $propertyName; if ($navigationPropertyInfo->expanded) { $propertyRelativeUri = $relativeUri . '/' . $propertyName; $propertyAbsoluteUri = trim($absoluteUri, '/') . '/' . $propertyName; $needPop = $this->pushSegmentForNavigationProperty($navigationPropertyInfo->resourceProperty); $navigationPropertyKind = $navigationPropertyInfo->resourceProperty->getKind(); $this->assert($navigationPropertyKind == ResourcePropertyKind::RESOURCESET_REFERENCE || $navigationPropertyKind == ResourcePropertyKind::RESOURCE_REFERENCE, '$navigationPropertyKind == ResourcePropertyKind::RESOURCESET_REFERENCE || $navigationPropertyKind == ResourcePropertyKind::RESOURCE_REFERENCE'); $currentResourceSetWrapper = $this->getCurrentResourceSetWrapper(); $this->assert(!is_null($currentResourceSetWrapper), '!is_null($currentResourceSetWrapper)'); $link->isExpanded = true; if (!is_null($navigationPropertyInfo->value)) { if ($navigationPropertyKind == ResourcePropertyKind::RESOURCESET_REFERENCE) { $inlineFeed = new ODataFeed(); $link->isCollection = true; $currentResourceType = $currentResourceSetWrapper->getResourceType(); $this->_writeFeedElements($navigationPropertyInfo->value, $currentResourceType, $propertyName, $propertyAbsoluteUri, $propertyRelativeUri, $inlineFeed); $link->expandedResult = $inlineFeed; } else { $link->isCollection = false; $currentResourceType1 = $currentResourceSetWrapper->getResourceType(); $link->expandedResult = $this->_writeEntryElement($navigationPropertyInfo->value, $currentResourceType1, $propertyAbsoluteUri, $propertyRelativeUri); } } else { $link->expandedResult = null; } $this->popSegment($needPop); } $odataEntry->links[] = $link; } } }
/** * To add a navigation property (resource set or resource reference) * to a resource type * * @param ResourceType $resourceType The resource type to add * the resource reference * or resource * reference set property to * @param string $name The name of the * property to add * @param ResourceSet $targetResourceSet The resource set the * resource reference * or reference * set property * ponits to * @param ResourcePropertyKind $resourcePropertyKind The property kind * * @return void */ private function _addReferencePropertyInternal(ResourceType $resourceType, $name, ResourceSet $targetResourceSet, $resourcePropertyKind) { try { $resourceType->getInstanceType()->getProperty($name); } catch (\ReflectionException $exception) { throw new InvalidOperationException('Can\'t add a property which does not exist on the instance type.'); } if (!($resourcePropertyKind == ResourcePropertyKind::RESOURCESET_REFERENCE || $resourcePropertyKind == ResourcePropertyKind::RESOURCE_REFERENCE)) { throw new InvalidOperationException('Property kind should be ResourceSetReference or ResourceReference'); } $targetResourceType = $targetResourceSet->getResourceType(); $resourceProperty = new ResourceProperty($name, null, $resourcePropertyKind, $targetResourceType); $resourceType->addProperty($resourceProperty); //Create instance of AssociationSet for this relationship $sourceResourceSet = $resourceType->getCustomState(); if (is_null($sourceResourceSet)) { throw new InvalidOperationException('Failed to retrieve the custom state from ' . $resourceType->getName()); } //Customer_Orders_Orders, Order_Customer_Customers //(source type::name _ source property::name _ target set::name) $setKey = $resourceType->getName() . '_' . $name . '_' . $targetResourceSet->getName(); $set = new ResourceAssociationSet($setKey, new ResourceAssociationSetEnd($sourceResourceSet, $resourceType, $resourceProperty), new ResourceAssociationSetEnd($targetResourceSet, $targetResourceSet->getResourceType(), null)); $this->associationSets[$setKey] = $set; }
/** * test ResourceType class */ public function testResourceType() { $exceptionThrown = false; try { ResourceType::getPrimitiveResourceType(TypeCode::VOID); $this->fail('An expected InvalidArgumentException for \'EdmPrimitiveType\' has not been raised'); } catch (\InvalidArgumentException $exception) { $this->assertStringEndsWith('is not a valid EdmPrimitiveType Enum value', $exception->getMessage()); } $int16ResType = new ResourceType(new Int16(), ResourceTypeKind::PRIMITIVE, 'Int16', 'Edm'); try { $int32ResType = new ResourceType(new Int32(), ResourceTypeKind::PRIMITIVE, 'Int32', 'Edm', $int16ResType); $this->fail('An expected InvalidArgumentException for \'basetype\' has not been raised'); } catch (\InvalidArgumentException $exception) { $this->AssertEquals('Primitive type cannot have base type', $exception->getMessage()); } try { $int32ResType = new ResourceType(new Int32(), ResourceTypeKind::PRIMITIVE, 'Int32', 'Edm', null, true); $this->fail('An expected InvalidArgumentException for \'abstract\' has not been raised'); } catch (\InvalidArgumentException $exception) { $this->AssertEquals('Primitive type cannot be abstract', $exception->getMessage()); } try { $int32ResType = new ResourceType(null, ResourceTypeKind::PRIMITIVE, 'Int32', 'Edm'); $this->fail('An expected InvalidArgumentException for \'IType\' has not been raised'); } catch (\InvalidArgumentException $exception) { $this->assertStringEndsWith('should be an \'IType\' implementor instance', $exception->getMessage()); } try { $customerResType = new ResourceType(null, ResourceTypeKind::ENTITY, 'Customer', 'Northwind'); $this->fail('An expected InvalidArgumentException for \'ReflectionClass\' has not been raised'); } catch (\InvalidArgumentException $exception) { $this->assertStringEndsWith('argument should be an \'ReflectionClass\' instance', $exception->getMessage()); } $customerResType = new ResourceType(new \ReflectionClass('UnitTests\\POData\\Facets\\NorthWind1\\Customer2'), ResourceTypeKind::ENTITY, 'Customer', 'Northwind'); $this->AssertEquals($customerResType->getName(), 'Customer'); $this->AssertEquals($customerResType->getFullName(), 'Northwind.Customer'); $this->assertTrue($customerResType->getInstanceType() instanceof \ReflectionClass); $this->AssertEquals($customerResType->getNamespace(), 'Northwind'); $this->AssertEquals($customerResType->getResourceTypeKind(), ResourceTypeKind::ENTITY); $this->AssertEquals($customerResType->isMediaLinkEntry(), false); try { $customerResType->validateType(); $this->fail('An expected InvalidOperationException for \'No key defined\' has not been raised'); } catch (InvalidOperationException $exception) { $this->assertStringEndsWith('Please make sure the key properties are defined for this entity type', $exception->getMessage()); } $int32ResourceType = ResourceType::getPrimitiveResourceType(EdmPrimitiveType::INT32); $primitiveResourceType = ResourceType::getPrimitiveResourceType(EdmPrimitiveType::STRING); $testProperty = new ResourceProperty('test', null, ResourcePropertyKind::PRIMITIVE, $primitiveResourceType); try { $int32ResourceType->addProperty($testProperty); $this->fail('An expected InvalidOperationException for \'property on primitive\' has not been raised'); } catch (InvalidOperationException $exception) { $this->assertStringEndsWith('ResourceType instances with a ResourceTypeKind equal to \'Primitive\'', $exception->getMessage()); } $stringResourceType = ResourceType::getPrimitiveResourceType(EdmPrimitiveType::STRING); $customerIDPrimProperty = new ResourceProperty('CustomerID', null, ResourcePropertyKind::PRIMITIVE | ResourcePropertyKind::KEY, $stringResourceType); $customerNamePrimProperty = new ResourceProperty('CustomerName', null, ResourcePropertyKind::PRIMITIVE, $stringResourceType); $intResourceType = ResourceType::getPrimitiveResourceType(EdmPrimitiveType::INT32); $ratingPrimProperty = new ResourceProperty('Rating', null, ResourcePropertyKind::PRIMITIVE, $intResourceType); $addressResType = new ResourceType(new \ReflectionClass('UnitTests\\POData\\Facets\\NorthWind1\\Address2'), ResourceTypeKind::COMPLEX, 'Address', 'Northwind'); $booleanResourceType = ResourceType::getPrimitiveResourceType(EdmPrimitiveType::BOOLEAN); $isPrimaryPrimProperty = new ResourceProperty('IsPrimary', null, ResourcePropertyKind::PRIMITIVE | ResourcePropertyKind::KEY, $booleanResourceType); try { $addressResType->addProperty($isPrimaryPrimProperty); $this->fail('An expected InvalidOperationException for \'Key on non-entity\' has not been raised'); } catch (InvalidOperationException $exception) { $this->assertStringEndsWith('ResourceType instances with a ResourceTypeKind equal to \'EntityType\'', $exception->getMessage()); } $booleanResourceType = ResourceType::getPrimitiveResourceType(EdmPrimitiveType::BOOLEAN); $isPrimaryPrimProperty = new ResourceProperty('IsPrimary', null, ResourcePropertyKind::PRIMITIVE, $booleanResourceType); $addressResType->addProperty($isPrimaryPrimProperty); try { $addressResType->addProperty($isPrimaryPrimProperty); $this->fail('An expected InvalidArgumentException for \'Property duplication\' has not been raised'); } catch (InvalidOperationException $exception) { $this->assertStringStartsWith('Property with same name \'IsPrimary\' already exists in type \'Address\'', $exception->getMessage()); } try { $addressResType->setMediaLinkEntry(true); $this->fail('An expected InvalidOperationException for \'MLE on non-entity\' has not been raised'); } catch (InvalidOperationException $exception) { $this->assertStringStartsWith('Cannot apply the HasStreamAttribute', $exception->getMessage()); } $customerAdrComplexType = new ResourceProperty('Address', null, ResourcePropertyKind::COMPLEX_TYPE, $addressResType); $customerResType->addProperty($customerIDPrimProperty); $customerResType->addProperty($customerNamePrimProperty); $customerResType->addProperty($ratingPrimProperty); $customerResType->addProperty($customerAdrComplexType); $customerResType->validateType(); $customerProperties = $customerResType->getPropertiesDeclaredOnThisType(); $this->AssertEquals(count($customerProperties), 4); $customerAllProperties = $customerResType->getAllProperties(); $this->AssertEquals(count($customerProperties), count($customerAllProperties)); $keys = array('CustomerID', 'CustomerName', 'Rating', 'Address'); $i = 0; foreach ($customerAllProperties as $key => $customerProperty) { $this->AssertEquals($key, $keys[$i++]); } $entityKeys = array('CustomerID'); $customerKeyProperties = $customerResType->getKeyProperties(); $i = 0; foreach ($customerKeyProperties as $key => $customerKeyProperty) { $this->AssertEquals($key, $entityKeys[$i++]); } $this->AssertEquals(count($customerResType->getETagProperties()), 0); $this->AssertEquals($customerResType->resolveProperty('PropNotExists'), null); $property = $customerResType->resolveProperty('CustomerName'); $this->AssertNotEquals($property, null); $this->AssertEquals($property->getName(), 'CustomerName'); $employeeResType = new ResourceType(new \ReflectionClass('UnitTests\\POData\\Facets\\NorthWind1\\Employee2'), ResourceTypeKind::ENTITY, 'Employee', 'Northwind'); $stringResourceType = ResourceType::getPrimitiveResourceType(EdmPrimitiveType::STRING); $employeeResType->addProperty(new ResourceProperty('EmployeeID', null, ResourcePropertyKind::PRIMITIVE | ResourcePropertyKind::KEY, $stringResourceType)); $employeeResType->addProperty(new ResourceProperty('Emails', null, ResourcePropertyKind::PRIMITIVE | ResourcePropertyKind::BAG, $stringResourceType)); $employeeResType->setMediaLinkEntry(true); $employeeResType->addNamedStream(new ResourceStreamInfo('ThumNail_64X64')); try { $employeeResType->addNamedStream(new ResourceStreamInfo('ThumNail_64X64')); $this->fail('An expected InvalidOperationException for \'named stream duplication\' has not been raised'); } catch (InvalidOperationException $exception) { $this->assertStringStartsWith('Named stream with the name \'ThumNail_64X64\' already exists in type \'Employee\'', $exception->getMessage()); } $this->AssertEquals($employeeResType->hasNamedStream(), true); $b = array(); $this->AssertEquals($employeeResType->hasBagProperty($b), true); $namedStreams = $employeeResType->getAllNamedStreams(); $this->AssertEquals(count($namedStreams), 1); $this->AssertTrue(array_key_exists('ThumNail_64X64', $namedStreams)); $name = $employeeResType->tryResolveNamedStreamByName('ThumNail_64X64')->getName(); $this->AssertEquals($name, 'ThumNail_64X64'); }
/** * Get the value of a given property from an instance. * * @param mixed $entity Instance of a type which contains this property. * @param ResourceType $resourceType Resource type instance containing metadata about the instance. * @param ResourceProperty $resourceProperty Resource property instance containing metadata about the property whose value to be retrieved. * * @return mixed The value of the given property. * * @throws ODataException If reflection exception occurred while trying to access the property. * */ protected function getPropertyValue($entity, ResourceType $resourceType, ResourceProperty $resourceProperty) { try { //Is this slow? See #88 $reflectionProperty = new \ReflectionProperty($entity, $resourceProperty->getName()); return $reflectionProperty->getValue($entity); } catch (\ReflectionException $reflectionException) { throw ODataException::createInternalServerError(Messages::objectModelSerializerFailedToAccessProperty($resourceProperty->getName(), $resourceType->getName())); } }
/** * Validates the given instance of ResourceType * * @param ResourceType $resourceType The ResourceType to validate * * @return ResourceType * * @throws ODataException Exception if $resourceType is invalid */ private function _validateResourceType(ResourceType $resourceType) { $cacheKey = $resourceType->getName(); if (array_key_exists($cacheKey, $this->typeCache)) { return $this->typeCache[$cacheKey]; } //TODO: Do validation if any for the ResourceType $this->typeCache[$cacheKey] = $resourceType; return $resourceType; }