/**
  * {@inheritDoc}
  */
 public function extractResponse(ActionInterface $action, CallableInterface $callable)
 {
     $response = $action->getResponse();
     if (!$response) {
         return null;
     }
     if (!is_object($response) || !$response instanceof ObjectResponse) {
         throw new ResponseExtractorNotSupportException(sprintf('The response must be ObjectResponse for extract, but "%s" given.'));
     }
     $class = $response->getClass();
     if (substr($class, strlen($class) - 2) == '[]') {
         $type = 'collection';
         $class = substr($class, 0, strlen($class) - 2);
     } else {
         $type = 'object';
     }
     if (!$class) {
         return null;
     }
     if (!class_exists($class)) {
         throw new ResponseExtractException(sprintf('Can not extract response from class "%s" for callable "%s". Class not found.', $class, Reflection::getCalledMethod($callable->getReflection())));
     }
     // Get properties from object
     $properties = $this->getPropertiesForClass($action, $callable, $class);
     $responseProperties = [];
     foreach ($properties as $property) {
         $responseProperties[] = $this->extractResponseProperty($action, $callable, $property);
     }
     return new Response($type, $class, $responseProperties);
 }
 /**
  * Resolve request parameter
  *
  * @param ActionInterface      $action
  * @param CallableInterface    $callable
  * @param array                $inputArguments
  * @param \ReflectionParameter $parameter
  *
  * @return object
  *
  * @throws \Exception
  */
 private function resolveRequest(ActionInterface $action, CallableInterface $callable, array $inputArguments, \ReflectionParameter $parameter)
 {
     $class = $parameter->getClass();
     if ($class->isInterface()) {
         throw new \RuntimeException(sprintf('Could not create instance via interface for parameter "%s" in method "%s". ' . 'You must set the class for type hinting.', $parameter->getName(), Reflection::getCalledMethod($callable->getReflection())));
     }
     if ($class->isAbstract()) {
         throw new \RuntimeException(sprintf('Could not create instance via abstract class for parameter "%s" in method "%s". ' . 'You must set the real class for type hinting.', $parameter->getName(), Reflection::getCalledMethod($callable->getReflection())));
     }
     /** @var RequestInterface $request */
     $request = $class->newInstance();
     // Map arguments
     $this->objectMapper->map($request, $inputArguments, $action->getRequestMappingGroup());
     // First step validation: Strict mode
     if ($this->validator && $action->isStrictValidation()) {
         $this->strictRequestValidate($request);
     }
     // Second step validation: Base validation
     if ($this->validator && $action->getValidationGroups()) {
         $violationList = $this->validator->validate($request, null, $action->getValidationGroups());
         if (count($violationList)) {
             throw ViolationListException::create($violationList);
         }
     }
     // Convert request properties
     if ($this->propertyConverter) {
         try {
             $this->propertyConverter->convertProperties($request, PropertyConverterManagerInterface::GROUP_DEFAULT);
         } catch (InvalidArgumentException $e) {
             $constraintViolation = new ConstraintViolation($e->getMessage(), null, [], null, $e->getName(), $e->getInvalidValue());
             $constraintViolationList = new ConstraintViolationList([$constraintViolation]);
             throw ViolationListException::create($constraintViolationList);
         } catch (ConverterNotFoundException $e) {
             if ($this->logger) {
                 $this->logger->warning(sprintf('Could not convert properties with message: %s.', rtrim($e->getMessage(), '.')));
             }
             // Nothing action
         }
     }
     return $request;
 }
 /**
  * {@inheritDoc}
  */
 public function addAction(ActionInterface $action)
 {
     $this->actions[$action->getName()] = $action;
     return $this;
 }