Merge remote-tracking branch 'origin/request_headers'

This commit is contained in:
Francis Besset
2011-08-17 08:35:49 +02:00
18 changed files with 303 additions and 122 deletions

View File

@ -0,0 +1,22 @@
<?php
/*
* This file is part of the BeSimpleSoapBundle.
*
* (c) Christian Kerl <christian-kerl@web.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace BeSimple\SoapBundle\ServiceDefinition\Annotation;
/**
* @Annotation
*/
class Header extends Param
{
public function getAliasName()
{
return 'header';
}
}

View File

@ -0,0 +1,37 @@
<?php
/*
* This file is part of the BeSimpleSoapBundle.
*
* (c) Christian Kerl <christian-kerl@web.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace BeSimple\SoapBundle\ServiceDefinition\Dumper;
use Zend\Soap\Wsdl as BaseWsdl;
/**
* @author Francis Besset <francis.besset@gmail.com>
*/
class Wsdl extends BaseWsdl
{
public function addBindingOperationHeader(\DOMElement $bindingOperation, array $headers, array $baseBinding)
{
foreach ($headers as $header) {
$inputNode = $bindingOperation->getElementsByTagName('input')->item(0);
$headerNode = $this->toDomDocument()->createElement('soap:header');
$headerNode->setAttribute('part', $header);
foreach ($baseBinding as $name => $value) {
$headerNode->setAttribute($name, $value);
}
$inputNode->appendChild($headerNode);
}
return $bindingOperation;
}
}

View File

@ -17,8 +17,6 @@ use BeSimple\SoapBundle\ServiceDefinition\Loader\AnnotationComplexTypeLoader;
use BeSimple\SoapBundle\Util\Assert;
use BeSimple\SoapBundle\Util\QName;
use Zend\Soap\Wsdl;
/**
* @author Christian Kerl <christian-kerl@web.de>
*/
@ -49,8 +47,13 @@ class WsdlDumper implements DumperInterface
$this->wsdl->addService($this->getServiceName(), $this->getPortName(), $this->qualify($this->getBindingName()), $endpoint);
foreach ($definition->getMethods() as $method) {
$requestParts = array();
$responseParts = array();
$requestHeaderParts =
$requestParts =
$responseParts = array();
foreach ($method->getHeaders() as $header) {
$requestHeaderParts[$header->getName()] = $this->wsdl->getType($header->getType()->getPhpType());
}
foreach ($method->getArguments() as $argument) {
$requestParts[$argument->getName()] = $this->wsdl->getType($argument->getType()->getPhpType());
@ -60,26 +63,38 @@ class WsdlDumper implements DumperInterface
$responseParts['return'] = $this->wsdl->getType($method->getReturn()->getPhpType());
}
if (!empty($requestHeaderParts)) {
$this->wsdl->addMessage($this->getRequestHeaderMessageName($method), $requestHeaderParts);
}
$this->wsdl->addMessage($this->getRequestMessageName($method), $requestParts);
$this->wsdl->addMessage($this->getResponseMessageName($method), $responseParts);
$portOperation = $this->wsdl->addPortOperation($port, $method->getName(), $this->qualify($this->getRequestMessageName($method)), $this->qualify($this->getResponseMessageName($method)));
$portOperation = $this->wsdl->addPortOperation(
$port,
$method->getName(),
$this->qualify($this->getRequestMessageName($method)),
$this->qualify($this->getResponseMessageName($method))
);
$portOperation->setAttribute('parameterOrder', implode(' ', array_keys($requestParts)));
$bindingInput = array(
'parts' => implode(' ', array_keys($requestParts)),
'use' => 'literal',
'namespace' => $definition->getNamespace(),
'encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/',
);
$bindingOutput = array(
'parts' => implode(' ', array_keys($responseParts)),
$baseBinding = array(
'use' => 'literal',
'namespace' => $definition->getNamespace(),
'encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/',
);
$bindingOperation = $this->wsdl->addBindingOperation($binding, $method->getName(), $bindingInput, $bindingOutput);
$bindingOperation = $this->wsdl->addBindingOperation(
$binding,
$method->getName(),
array_merge(array('parts' => implode(' ', array_keys($requestParts))), $baseBinding),
array_merge(array('parts' => implode(' ', array_keys($responseParts))), $baseBinding)
);
$bindingOperation = $this->wsdl->addBindingOperationHeader(
$bindingOperation,
array_keys($requestHeaderParts),
array_merge(array('message' => $this->qualify($this->getRequestHeaderMessageName($method))), $baseBinding)
);
$this->wsdl->addSoapOperation($bindingOperation, $this->getSoapOperationName($method));
}
@ -126,6 +141,11 @@ class WsdlDumper implements DumperInterface
return $this->definition->getName().'Service';
}
protected function getRequestHeaderMessageName(Method $method)
{
return $method->getName().'Header';
}
protected function getRequestMessageName(Method $method)
{
return $method->getName().'Request';

View File

@ -16,7 +16,7 @@ use BeSimple\SoapBundle\ServiceDefinition\Strategy\ComplexType;
use BeSimple\SoapBundle\Util\String;
use Zend\Soap\Exception;
use Zend\Soap\Wsdl;
use Zend\Soap\Wsdl as BaseWsdl;
use Zend\Soap\Wsdl\Strategy;
use Zend\Soap\Wsdl\Strategy\ArrayOfTypeSequence;
@ -46,7 +46,7 @@ class WsdlTypeStrategy implements Strategy
*
* @param \Zend\Soap\Wsdl $context
*/
public function setContext(Wsdl $context)
public function setContext(BaseWsdl $context)
{
$this->context = $context;

View File

@ -10,13 +10,8 @@
namespace BeSimple\SoapBundle\ServiceDefinition\Loader;
use BeSimple\SoapBundle\ServiceDefinition\Argument;
use BeSimple\SoapBundle\ServiceDefinition\Method;
use BeSimple\SoapBundle\ServiceDefinition\Type;
use BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition;
use BeSimple\SoapBundle\ServiceDefinition\Annotation\Method as MethodAnnotation;
use BeSimple\SoapBundle\ServiceDefinition\Annotation\Param as ParamAnnotation;
use BeSimple\SoapBundle\ServiceDefinition\Annotation\Result as ResultAnnotation;
use BeSimple\SoapBundle\ServiceDefinition as Definition;
use BeSimple\SoapBundle\ServiceDefinition\Annotation;
use Doctrine\Common\Annotations\Reader;
@ -50,7 +45,7 @@ class AnnotationClassLoader implements LoaderInterface
* @param string $class A class name
* @param string $type The resource type
*
* @return ServiceDefinition A ServiceDefinition instance
* @return \BeSimple\SoapBundle\ServiceDefinition\ServiceDefinition A ServiceDefinition instance
*
* @throws \InvalidArgumentException When route can't be parsed
*/
@ -61,48 +56,57 @@ class AnnotationClassLoader implements LoaderInterface
}
$class = new \ReflectionClass($class);
$definition = new ServiceDefinition();
$definition = new Definition\ServiceDefinition();
foreach ($class->getMethods() as $method) {
$serviceArguments = array();
$serviceArguments =
$serviceHeaders = array();
$serviceMethod =
$serviceReturn = null;
foreach ($this->reader->getMethodAnnotations($method) as $i => $annotation) {
if ($annotation instanceof ParamAnnotation) {
$serviceArguments[] = new Argument(
if ($annotation instanceof Annotation\Header) {
$serviceHeaders[] = new Definition\Header(
$annotation->getValue(),
$this->getArgumentType($method, $annotation)
);
} elseif ($annotation instanceof MethodAnnotation) {
} elseif ($annotation instanceof Annotation\Param) {
$serviceArguments[] = new Definition\Argument(
$annotation->getValue(),
$this->getArgumentType($method, $annotation)
);
} elseif ($annotation instanceof Annotation\Method) {
if ($serviceMethod) {
throw new \LogicException(sprintf('@Method defined twice for "%s".', $method->getName()));
throw new \LogicException(sprintf('@Soap\Method defined twice for "%s".', $method->getName()));
}
$serviceMethod = new Method(
$serviceMethod = new Definition\Method(
$annotation->getValue(),
$this->getController($method, $annotation)
);
} elseif ($annotation instanceof ResultAnnotation) {
} elseif ($annotation instanceof Annotation\Result) {
if ($serviceReturn) {
throw new \LogicException(sprintf('@Result defined twice for "%s".', $method->getName()));
throw new \LogicException(sprintf('@Soap\Result defined twice for "%s".', $method->getName()));
}
$serviceReturn = new Type($annotation->getPhpType(), $annotation->getXmlType());
$serviceReturn = new Definition\Type($annotation->getPhpType(), $annotation->getXmlType());
}
}
if (!$serviceMethod && (!empty($serviceArguments) || $serviceReturn)) {
throw new \LogicException(sprintf('@Method non-existent for "%s".', $method->getName()));
throw new \LogicException(sprintf('@Soap\Method non-existent for "%s".', $method->getName()));
}
if ($serviceMethod) {
$serviceMethod->setArguments($serviceArguments);
$serviceMethod->setHeaders($serviceHeaders);
if ($serviceReturn) {
$serviceMethod->setReturn($serviceReturn);
if (!$serviceReturn) {
throw new \LogicException(sprintf('@Soap\Result non-existent for "%s".', $method->getName()));
}
$serviceMethod->setReturn($serviceReturn);
$definition->getMethods()->add($serviceMethod);
}
}
@ -110,7 +114,13 @@ class AnnotationClassLoader implements LoaderInterface
return $definition;
}
private function getController(\ReflectionMethod $method, MethodAnnotation $annotation)
/**
* @param \ReflectionMethod $method
* @param \BeSimple\SoapBundle\ServiceDefinition\Annotation\Method $annotation
*
* @return string
*/
private function getController(\ReflectionMethod $method, Annotation\Method $annotation)
{
if(null !== $annotation->getService()) {
return $annotation->getService() . ':' . $method->name;
@ -121,11 +131,11 @@ class AnnotationClassLoader implements LoaderInterface
/**
* @param \ReflectionMethod $method
* @param ParamAnnotation $annotation
* @param \BeSimple\SoapBundle\ServiceDefinition\Annotation\Param $annotation
*
* @return \BeSimple\SoapBundle\ServiceDefinition\Type
*/
private function getArgumentType(\ReflectionMethod $method, ParamAnnotation $annotation)
private function getArgumentType(\ReflectionMethod $method, Annotation\Param $annotation)
{
$phpType = $annotation->getPhpType();
$xmlType = $annotation->getXmlType();
@ -140,7 +150,7 @@ class AnnotationClassLoader implements LoaderInterface
}
}
return new Type($phpType, $xmlType);
return new Definition\Type($phpType, $xmlType);
}
/**

View File

@ -17,12 +17,14 @@ class Method
private $name;
private $controller;
private $arguments;
private $headers;
private $return;
public function __construct($name = null, $controller = null, array $arguments = array(), Type $return = null)
public function __construct($name = null, $controller = null, array $headers = array(), array $arguments = array(), Type $return = null)
{
$this->setName($name);
$this->setController($controller);
$this->setHeaders($headers);
$this->setArguments($arguments);
if ($return) {
@ -50,6 +52,17 @@ class Method
$this->controller = $controller;
}
public function getHeaders()
{
return $this->headers;
}
public function setHeaders(array $headers)
{
$this->headers = new Collection('getName', 'BeSimple\SoapBundle\ServiceDefinition\Header');
$this->headers->addAll($headers);
}
public function getArguments()
{
return $this->arguments;

View File

@ -29,23 +29,16 @@ class ServiceDefinition
*/
private $methods;
/**
* @var \BeSimple\SoapBundle\Util\Collection
*/
private $headers;
private $complexTypes = array();
public function __construct($name = null, $namespace = null, array $methods = array(), array $headers = array())
public function __construct($name = null, $namespace = null, array $methods = array())
{
$this->setName($name);
$this->setNamespace($namespace);
$this->methods = new Collection('getName', 'BeSimple\SoapBundle\ServiceDefinition\Method');
$this->headers = new Collection('getName', 'BeSimple\SoapBundle\ServiceDefinition\Header');
$this->setMethods($methods);
$this->setHeaders($headers);
}
/**
@ -96,22 +89,6 @@ class ServiceDefinition
$this->methods->addAll($methods);
}
/**
* @return \BeSimple\SoapBundle\Util\Collection
*/
public function getHeaders()
{
return $this->headers;
}
/**
* @param array $headers
*/
public function setHeaders(array $headers)
{
$this->headers->addAll($headers);
}
/**
* @return array
*/
@ -119,11 +96,15 @@ class ServiceDefinition
{
$types = array();
foreach($this->methods as $method) {
foreach($method->getArguments() as $argument) {
foreach ($this->methods as $method) {
foreach ($method->getArguments() as $argument) {
$types[] = $argument->getType();
}
foreach ($method->getHeaders() as $header) {
$types[] = $header->getType();
}
$types[] = $method->getReturn();
}