/**
  * {@inheritDoc}
  */
 public function denormalize($data, ContextInterface $context)
 {
     if (!is_array($data)) {
         throw DenormalizationFailedException::unexpected($data, 'array');
     }
     $collectionClass = $context->getAttribute('collection_class');
     $class = $context->getAttribute('class');
     if (!$class) {
         throw new DenormalizationFailedException('Undefined denormalizer class.');
     }
     try {
         $this->normalizerManager->getNormalizerForClass($class);
     } catch (UnsupportedClassException $e) {
         throw new DenormalizationFailedException(sprintf('Not found normalizer for denormalize collection. Collection class "%s". Denormalizer class "%s".', $collectionClass, $class), 0, $e);
     }
     if ($collectionClass) {
         $reflection = Reflection::loadClassReflection($collectionClass);
         $collection = $reflection->newInstanceWithoutConstructor();
     } else {
         $collection = [];
     }
     if (is_object($collection) && !$collection instanceof \ArrayAccess) {
         throw new DenormalizationFailedException(sprintf('The collection instance for denormalize data should implement "ArrayAccess", but "%s" given.', get_class($collection)));
     }
     foreach ($data as $key => $childData) {
         $denormalized = $this->normalizerManager->denormalize($class, $childData);
         $collection[$key] = $denormalized;
     }
     return $collection;
 }
 /**
  * {@inheritDoc}
  */
 public function load($object, $group)
 {
     $reflection = Reflection::loadClassReflection($object);
     $objectMappingAnnotation = $this->getObjectMappingAnnotation($reflection, $group);
     if ($objectMappingAnnotation && $objectMappingAnnotation->allProperties) {
         // Include all properties
         $propertiesMappingAnnotation = $this->getAllPropertiesMapping($reflection, $objectMappingAnnotation->group);
     } else {
         $propertiesMappingAnnotation = $this->getPropertiesMappingAnnotation($reflection, $group);
     }
     if (!$objectMappingAnnotation && !$propertiesMappingAnnotation) {
         return null;
     }
     if (!$objectMappingAnnotation) {
         $strategy = 'reflection';
     } else {
         $strategy = $objectMappingAnnotation->strategy;
     }
     $properties = array();
     foreach ($propertiesMappingAnnotation as $propertyName => $propertyAnnotation) {
         $fieldName = $propertyAnnotation->fieldName ?: $propertyName;
         if ($propertyAnnotation->collection) {
             $collection = new CollectionMetadata($propertyAnnotation->collection->class, $propertyAnnotation->collection->saveKeys);
         } else {
             $collection = null;
         }
         $property = new PropertyMetadata($propertyName, $fieldName, $propertyAnnotation->class, $collection);
         $properties[] = $property;
     }
     $objectMetadata = new ObjectMetadata($strategy, $properties);
     return $objectMetadata;
 }
 /**
  * {@inheritDoc}
  */
 public function loadForClass($class, $group)
 {
     $reflectionClass = Reflection::loadClassReflection($class);
     $classAnnotations = $this->reader->getClassAnnotations($reflectionClass);
     $securityClassAnnotation = null;
     $rules = array();
     foreach ($classAnnotations as $classAnnotation) {
         if ($classAnnotation instanceof ClassSecurityAnnotation && $group == $classAnnotation->group) {
             if ($securityClassAnnotation) {
                 throw new \RuntimeException(sprintf('The @ClassSecurity annotation already defined in class "%s".', $reflectionClass->getName()));
             }
             $securityClassAnnotation = $classAnnotation;
         }
         if ($rule = $this->transformAnnotationToRule($classAnnotation, $group, $class)) {
             $rules[] = $rule;
         }
     }
     if (!$securityClassAnnotation && !count($rules)) {
         return null;
     }
     if ($securityClassAnnotation) {
         $strategy = $securityClassAnnotation->strategy;
     } else {
         $strategy = Security::STRATEGY_AFFIRMATIVE;
     }
     $securityClass = new ClassSecurity($reflectionClass->getName(), $strategy, $rules, $group);
     return $securityClass;
 }
 /**
  * {@inheritDoc}
  */
 public function loadActions()
 {
     $actions = new ActionCollection();
     foreach ($this->classes as $id => $class) {
         $reflection = Reflection::loadClassReflection($class);
         // Get all methods from class
         $methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC);
         foreach ($methods as $method) {
             $methodAnnotations = $this->reader->getMethodAnnotations($method);
             foreach ($methodAnnotations as $annotation) {
                 if ($annotation instanceof ActionAnnotation) {
                     if ($method->isStatic()) {
                         throw new \RuntimeException('The static method not supported (@todo).');
                     }
                     if ($annotation->response) {
                         $response = new ObjectResponse($annotation->response->class);
                     } else {
                         $response = null;
                     }
                     $action = new ServiceAction($annotation->name, $id, $method->getName(), $annotation->validationGroups, $annotation->securityGroups, $annotation->requestMappingGroup, $annotation->useStrictValidation, $annotation->checkEnabled, $response);
                     $actions->addAction($action);
                 }
             }
         }
     }
     return $actions;
 }
 /**
  * {@inheritDoc}
  */
 public function resolve(ActionInterface $action)
 {
     if (!$action instanceof ServiceAction) {
         throw UnexpectedTypeException::create($action, 'FivePercent\\Bundle\\ApiBundle\\SMD\\Action\\ServiceAction');
     }
     $serviceId = $action->getServiceId();
     $method = $action->getMethod();
     $service = $this->container->get($serviceId);
     $reflectionService = Reflection::loadClassReflection($service);
     $reflectionMethod = $reflectionService->getMethod($method);
     return new BaseCallable($reflectionMethod, $service);
 }
 /**
  * {@inheritDoc}
  */
 protected function getPropertiesForClass(ActionInterface $action, CallableInterface $callable, $class)
 {
     if (!$this->metadataFactory->supportsClass($class)) {
         return [];
     }
     $metadata = $this->metadataFactory->loadMetadata($class);
     $reflectionClass = Reflection::loadClassReflection($class);
     $properties = [];
     foreach ($metadata->getProperties() as $propertyName => $property) {
         $properties[] = $reflectionClass->getProperty($propertyName);
     }
     return $properties;
 }
 /**
  * {@inheritDoc}
  */
 public function convertProperties($object, $group)
 {
     if (!is_object($object)) {
         throw UnexpectedTypeException::create($object, 'object');
     }
     $converter = $this->getConverter($group);
     $classReflection = Reflection::loadClassReflection($object);
     $properties = $classReflection->getProperties();
     foreach ($properties as $property) {
         if ($converter->isSupported($property)) {
             $this->convertPropertyReflection($object, $property, $group);
         }
     }
 }
 /**
  * {@inheritDoc}
  */
 public function transform($object, ContextInterface $context)
 {
     $metadata = $this->metadataFactory->loadMetadata(get_class($object));
     // Get properties for transformation
     if (!$context->getGroups()) {
         $transformProperties = $metadata->getProperties();
     } else {
         $transformProperties = $metadata->getPropertiesForGroups($context->getGroups());
     }
     // Try create transformed
     $transformedClass = $metadata->getTransformedClass();
     $transformedReflection = Reflection::loadClassReflection($transformedClass);
     $transformed = $transformedReflection->newInstanceWithoutConstructor();
     $objectReflection = Reflection::loadClassReflection($object);
     foreach ($transformProperties as $transformPropertyName => $propertyMetadata) {
         try {
             $objectPropertyReflection = $objectReflection->getProperty($transformPropertyName);
         } catch (\ReflectionException $e) {
             throw new \RuntimeException(sprintf('Error transform property: Not found property "%s" in class "%s".', $transformPropertyName, $objectReflection->getName()), 0, $e);
         }
         try {
             $transformedPropertyReflection = $transformedReflection->getProperty($propertyMetadata->getPropertyName());
         } catch (\ReflectionException $e) {
             throw new \RuntimeException(sprintf('Error transform property: Not found property "%s" in class "%s".', $propertyMetadata->getPropertyName(), $transformedReflection->getName()));
         }
         if (!$transformedPropertyReflection->isPublic()) {
             $transformedPropertyReflection->setAccessible(true);
         }
         if (!$objectPropertyReflection->isPublic()) {
             $objectPropertyReflection->setAccessible(true);
         }
         $objectPropertyValue = $objectPropertyReflection->getValue($object);
         $transformedValue = $this->transformValue($object, $objectPropertyValue, $propertyMetadata, $transformedPropertyReflection);
         $transformedPropertyReflection->setValue($transformed, $transformedValue);
     }
     return $transformed;
 }
 /**
  * {@inheritDoc}
  */
 public function denormalize($data, ContextInterface $context)
 {
     $class = $context->getAttribute('_class');
     if (!$class) {
         throw new DenormalizationFailedException('Undefined class for denormalization');
     }
     $metadata = $this->metadataFactory->loadMetadata($class);
     if ($context->getGroups()) {
         $denormalizeProperties = $metadata->getPropertiesForGroups($context->getGroups());
     } else {
         $denormalizeProperties = $metadata->getProperties();
     }
     $classReflection = Reflection::loadClassReflection($class);
     if ($object = $context->getAttribute('_object')) {
         if (!is_object($object)) {
             throw UnexpectedTypeException::create($object, 'object');
         }
         if (get_class($object) != $classReflection && !is_a($object, $class)) {
             throw UnexpectedTypeException::create($object, $class);
         }
     } else {
         $object = $classReflection->newInstanceWithoutConstructor();
     }
     foreach ($denormalizeProperties as $denormalizePropertyName => $propertyMetadata) {
         $fieldName = $propertyMetadata->getFieldName();
         if (!isset($data[$fieldName])) {
             continue;
         }
         $objectPropertyReflection = $classReflection->getProperty($denormalizePropertyName);
         if (!$objectPropertyReflection->isPublic()) {
             $objectPropertyReflection->setAccessible(true);
         }
         $denormalizedValue = $this->denormalizeValue($data[$fieldName], $propertyMetadata, $objectPropertyReflection);
         $objectPropertyReflection->setValue($object, $denormalizedValue);
     }
     return $object;
 }
 /**
  * Create a new object by class
  *
  * @param string $class
  *
  * @return object
  */
 protected function createObjectFromClass($class)
 {
     $reflection = Reflection::loadClassReflection($class);
     if (!$reflection->isUserDefined()) {
         // PHP System class
         return $reflection->newInstance();
     }
     $constructor = $reflection->getConstructor();
     if (!$constructor) {
         // Constructor not found
         return $reflection->newInstanceWithoutConstructor();
     }
     $constructorParameters = $constructor->getParameters();
     // Is constructor has required parameter
     $constructorHasRequiredParameter = false;
     foreach ($constructorParameters as $constructorParameter) {
         if (!$constructorParameter->isOptional()) {
             $constructorHasRequiredParameter = true;
             break;
         }
     }
     if ($constructorHasRequiredParameter) {
         return $reflection->newInstanceWithoutConstructor();
     } else {
         return $reflection->newInstance();
     }
 }
 /**
  * Validate property value by types
  *
  * @param object $object
  * @param string $propertyName
  * @param array  $types
  *
  * @return null|\Symfony\Component\Validator\ConstraintViolationInterface[]
  */
 private function validatePropertyValueByTypes($object, $propertyName, array $types)
 {
     $classReflection = Reflection::loadClassReflection($object);
     $property = $classReflection->getProperty($propertyName);
     if (!$property->isPublic()) {
         $property->setAccessible(true);
     }
     $value = $property->getValue($object);
     if (!$value) {
         return null;
     }
     $firstViolationList = null;
     foreach ($types as $type) {
         try {
             $varTagConstraint = $this->constraintFactoryRegistry->getConstraintFactory($type)->getVarTagConstraint();
         } catch (ConstraintFactoryNotFoundException $e) {
             continue;
         }
         $constraints = $varTagConstraint->getConstraints();
         $groupSequence = $varTagConstraint->getGroupSequence();
         if (count($constraints)) {
             $violationList = $this->validator->validate($value, $constraints, $groupSequence);
             if (count($violationList)) {
                 if (!$firstViolationList) {
                     $firstViolationList = $violationList;
                 }
             } else {
                 return null;
             }
         }
     }
     return $firstViolationList;
 }