diff --git a/DependencyInjection/WebServiceExtension.php b/DependencyInjection/WebServiceExtension.php
index 015591c..e4b4d9e 100644
--- a/DependencyInjection/WebServiceExtension.php
+++ b/DependencyInjection/WebServiceExtension.php
@@ -31,12 +31,19 @@ class WebServiceExtension extends Extension
$configuration->setAlias('http_kernel', 'webservice.kernel');
}
- if(!isset($config['definition']))
+ if(isset($config['definition']))
+ {
+ $this->registerServiceDefinitionConfig($config['definition'], $configuration);
+ }
+ else
{
throw new \InvalidArgumentException();
}
- $this->registerServiceDefinitionConfig($config['definition'], $configuration);
+ if(isset($config['binding']))
+ {
+ $this->registerServiceBindingConfig($config['binding'], $configuration);
+ }
}
protected function registerServiceDefinitionConfig(array $config, ContainerBuilder $configuration)
@@ -50,6 +57,30 @@ class WebServiceExtension extends Extension
$configuration->setParameter('webservice.definition.resource', isset($config['resource']) ? $config['resource'] : null);
}
+ protected function registerServiceBindingConfig(array $config, ContainerBuilder $configuration)
+ {
+ $style = isset($config['style']) ? $config['style'] : 'document-literal-wrapped';
+
+ if(!in_array($style, array('document-literal-wrapped', 'rpc-literal')))
+ {
+ throw new \InvalidArgumentException();
+ }
+
+ $binderNamespace = 'Bundle\\WebServiceBundle\\ServiceBinding\\';
+
+ switch ($style)
+ {
+ case 'document-literal-wrapped':
+ $configuration->setParameter('webservice.binder.request.class', $binderNamespace . 'DocumentLiteralWrappedRequestMessageBinder');
+ $configuration->setParameter('webservice.binder.response.class', $binderNamespace . 'DocumentLiteralWrappedResponseMessageBinder');
+ break;
+ case 'rpc-literal':
+ $configuration->setParameter('webservice.binder.request.class', $binderNamespace . 'RpcLiteralRequestMessageBinder');
+ $configuration->setParameter('webservice.binder.response.class', $binderNamespace . 'RpcLiteralResponseMessageBinder');
+ break;
+ }
+ }
+
public function getXsdValidationBasePath()
{
return null;
diff --git a/Resources/config/services.xml b/Resources/config/services.xml
index 896ec68..accd3c7 100644
--- a/Resources/config/services.xml
+++ b/Resources/config/services.xml
@@ -6,9 +6,12 @@
Bundle\WebServiceBundle\Soap\SoapRequest
+ Bundle\WebServiceBundle\ServiceBinding\DocumentLiteralWrappedRequestMessageBinder
+ Bundle\WebServiceBundle\ServiceBinding\DocumentLiteralWrappedResponseMessageBinder
+
Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition
Bundle\WebServiceBundle\ServiceDefinition\Loader\XmlFileLoader
- Bundle\WebServiceBundle\ServiceDefinition\Dumper\Wsdl11DocumentLiteralFileDumper
+ Bundle\WebServiceBundle\ServiceDefinition\Dumper\Wsdl11DocumentLiteralWrappedFileDumper
@@ -19,12 +22,22 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
%webservice.definition.name%
diff --git a/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php b/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php
new file mode 100644
index 0000000..6401d19
--- /dev/null
+++ b/ServiceBinding/DocumentLiteralWrappedRequestMessageBinder.php
@@ -0,0 +1,26 @@
+ 1)
+ {
+ throw new \InvalidArgumentException();
+ }
+
+ $result = array();
+ $message = $message[0];
+
+ foreach($messageDefinition->getArguments() as $argument)
+ {
+ $result[$argument->getName()] = $message->{$argument->getName()};
+ }
+
+ return $result;
+ }
+}
\ No newline at end of file
diff --git a/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php b/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php
new file mode 100644
index 0000000..7ff4910
--- /dev/null
+++ b/ServiceBinding/DocumentLiteralWrappedResponseMessageBinder.php
@@ -0,0 +1,16 @@
+{$messageDefinition->getName() . 'Result'} = $message;
+
+ return $result;
+ }
+}
\ No newline at end of file
diff --git a/ServiceBinding/MessageBinderInterface.php b/ServiceBinding/MessageBinderInterface.php
new file mode 100644
index 0000000..867c781
--- /dev/null
+++ b/ServiceBinding/MessageBinderInterface.php
@@ -0,0 +1,18 @@
+getArguments() as $argument)
+ {
+ $result[$argument->getName()] = $message[$i];
+ $i++;
+ }
+
+ return $result;
+ }
+}
\ No newline at end of file
diff --git a/ServiceBinding/RpcLiteralResponseMessageBinder.php b/ServiceBinding/RpcLiteralResponseMessageBinder.php
new file mode 100644
index 0000000..b04c14f
--- /dev/null
+++ b/ServiceBinding/RpcLiteralResponseMessageBinder.php
@@ -0,0 +1,13 @@
+loadServiceDefinition($definition);
+
+ $this->definition = $definition;
+ $this->definitionDumper = $dumper;
+
+ $this->requestMessageBinder = $requestMessageBinder;
+ $this->responseMessageBinder = $responseMessageBinder;
+ }
+
+ public function getSerializedServiceDefinition()
+ {
+ // TODO: add caching
+ return $this->definitionDumper->dumpServiceDefinition($this->definition);
+ }
+
+ public function isServiceHeader($name)
+ {
+ return $this->definition->getHeaders()->has($name);
+ }
+
+ public function isServiceMethod($name)
+ {
+ return $this->definition->getMethods()->has($name);
+ }
+
+ public function processServiceHeader($name, $data)
+ {
+ $headerDefinition = $this->definition->getHeaders()->get($name);
+
+ return $this->createSoapHeader($headerDefinition, $data);
+ }
+
+ public function processServiceMethodArguments($name, $arguments)
+ {
+ $methodDefinition = $this->definition->getMethods()->get($name);
+
+ $result = array();
+ $result['_controller'] = $methodDefinition->getController();
+ $result = array_merge($result, $this->requestMessageBinder->processMessage($methodDefinition, $arguments));
+
+ return $result;
+ }
+
+ public function processServiceMethodReturnValue($name, $return)
+ {
+ $methodDefinition = $this->definition->getMethods()->get($name);
+
+ return $this->responseMessageBinder->processMessage($methodDefinition, $return);
+ }
+
+ protected function createSoapHeader(Header $headerDefinition, $data)
+ {
+ if(!preg_match('/^\{(.+)\}(.+)$/', $headerDefinition->getType()->getXmlType(), $matches))
+ {
+ throw new \InvalidArgumentException();
+ }
+
+ return new SoapHeader($matches[1], $matches[2], $data);
+ }
+}
\ No newline at end of file
diff --git a/ServiceDefinition/ServiceHeader.php b/ServiceDefinition/Argument.php
similarity index 83%
rename from ServiceDefinition/ServiceHeader.php
rename to ServiceDefinition/Argument.php
index 8df73fb..4f812ec 100644
--- a/ServiceDefinition/ServiceHeader.php
+++ b/ServiceDefinition/Argument.php
@@ -2,12 +2,12 @@
namespace Bundle\WebServiceBundle\ServiceDefinition;
-class ServiceHeader
+class Argument
{
private $name;
private $type;
- public function __construct($name = null, ServiceType $type = null)
+ public function __construct($name = null, Type $type = null)
{
$this->setName($name);
$this->setType($type);
diff --git a/ServiceDefinition/Header.php b/ServiceDefinition/Header.php
new file mode 100644
index 0000000..42ef3e2
--- /dev/null
+++ b/ServiceDefinition/Header.php
@@ -0,0 +1,35 @@
+setName($name);
+ $this->setType($type);
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ public function setType($type)
+ {
+ $this->type = $type;
+ }
+}
\ No newline at end of file
diff --git a/ServiceDefinition/Loader/XmlFileLoader.php b/ServiceDefinition/Loader/XmlFileLoader.php
index af3cdfd..b35a265 100644
--- a/ServiceDefinition/Loader/XmlFileLoader.php
+++ b/ServiceDefinition/Loader/XmlFileLoader.php
@@ -2,13 +2,11 @@
namespace Bundle\WebServiceBundle\ServiceDefinition\Loader;
-use Bundle\WebServiceBundle\ServiceDefinition\ServiceType;
-
use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition;
-
-use Bundle\WebServiceBundle\ServiceDefinition\ServiceMethod;
-
-use Bundle\WebServiceBundle\ServiceDefinition\ServiceHeader;
+use Bundle\WebServiceBundle\ServiceDefinition\Header;
+use Bundle\WebServiceBundle\ServiceDefinition\Method;
+use Bundle\WebServiceBundle\ServiceDefinition\Argument;
+use Bundle\WebServiceBundle\ServiceDefinition\Type;
class XmlFileLoader extends FileLoader
{
@@ -35,11 +33,11 @@ class XmlFileLoader extends FileLoader
/**
* @param \SimpleXMLElement $node
*
- * @return \Bundle\WebServiceBundle\ServiceDefinition\ServiceHeader
+ * @return \Bundle\WebServiceBundle\ServiceDefinition\Header
*/
protected function parseHeader(\SimpleXMLElement $node)
{
- $header = new ServiceHeader((string)$node['name'], $this->parseType($node->type));
+ $header = new Header((string)$node['name'], $this->parseType($node->type));
return $header;
}
@@ -47,11 +45,16 @@ class XmlFileLoader extends FileLoader
/**
* @param \SimpleXMLElement $node
*
- * @return \Bundle\WebServiceBundle\ServiceDefinition\ServiceMethod
+ * @return \Bundle\WebServiceBundle\ServiceDefinition\Method
*/
protected function parseMethod(\SimpleXMLElement $node)
{
- $method = new ServiceMethod((string)$node['name'], (string)$node['controller']);
+ $method = new Method((string)$node['name'], (string)$node['controller']);
+
+ foreach($node->argument as $argument)
+ {
+ $method->getArguments()->add($this->parseArgument($argument));
+ }
return $method;
}
@@ -59,7 +62,19 @@ class XmlFileLoader extends FileLoader
/**
* @param \SimpleXMLElement $node
*
- * @return \Bundle\WebServiceBundle\ServiceDefinition\ServiceType
+ * @return \Bundle\WebServiceBundle\ServiceDefinition\Argument
+ */
+ protected function parseArgument(\SimpleXMLElement $node)
+ {
+ $argument = new Argument((string)$node['name'], $this->parseType($node->type));
+
+ return $argument;
+ }
+
+ /**
+ * @param \SimpleXMLElement $node
+ *
+ * @return \Bundle\WebServiceBundle\ServiceDefinition\Type
*/
protected function parseType(\SimpleXMLElement $node)
{
@@ -67,7 +82,7 @@ class XmlFileLoader extends FileLoader
$qname = explode(':', $node['xml-type'], 2);
$xmlType = sprintf('{%s}%s', $namespaces[$qname[0]], $qname[1]);
- $type = new ServiceType((string)$node['php-type'], $xmlType, (string)$node['converter']);
+ $type = new Type((string)$node['php-type'], $xmlType, (string)$node['converter']);
return $type;
}
diff --git a/ServiceDefinition/ServiceMethod.php b/ServiceDefinition/Method.php
similarity index 59%
rename from ServiceDefinition/ServiceMethod.php
rename to ServiceDefinition/Method.php
index d78ead6..1a157fe 100644
--- a/ServiceDefinition/ServiceMethod.php
+++ b/ServiceDefinition/Method.php
@@ -2,15 +2,19 @@
namespace Bundle\WebServiceBundle\ServiceDefinition;
-class ServiceMethod
+use Bundle\WebServiceBundle\Util\Collection;
+
+class Method
{
private $name;
private $controller;
+ private $arguments;
- public function __construct($name = null, $controller = null)
+ public function __construct($name = null, $controller = null, array $arguments = array())
{
$this->setName($name);
$this->setController($controller);
+ $this->setArguments($arguments);
}
public function getName()
@@ -32,4 +36,15 @@ class ServiceMethod
{
$this->controller = $controller;
}
+
+ public function getArguments()
+ {
+ return $this->arguments;
+ }
+
+ public function setArguments($arguments)
+ {
+ $this->arguments = new Collection('getName');
+ $this->arguments->addAll($arguments);
+ }
}
\ No newline at end of file
diff --git a/ServiceDefinition/ServiceType.php b/ServiceDefinition/Type.php
similarity index 97%
rename from ServiceDefinition/ServiceType.php
rename to ServiceDefinition/Type.php
index bcf0699..f4e33de 100644
--- a/ServiceDefinition/ServiceType.php
+++ b/ServiceDefinition/Type.php
@@ -2,7 +2,7 @@
namespace Bundle\WebServiceBundle\ServiceDefinition;
-class ServiceType
+class Type
{
private $phpType;
private $xmlType;
diff --git a/Soap/SoapRequest.php b/Soap/SoapRequest.php
index da0d99b..cbc8b89 100644
--- a/Soap/SoapRequest.php
+++ b/Soap/SoapRequest.php
@@ -46,7 +46,6 @@ class SoapRequest extends Request
parent::__construct($query, null, $attributes, $cookies, null, $server);
$this->rawContent = $rawContent != null ? $rawContent : $this->loadRawContent();
-
$this->soapHeaders = new Collection('getName');
}
diff --git a/Soap/SoapResponse.php b/Soap/SoapResponse.php
index 4d7cc34..46042cc 100644
--- a/Soap/SoapResponse.php
+++ b/Soap/SoapResponse.php
@@ -26,6 +26,9 @@ class SoapResponse extends Response
*/
protected $soapHeaders;
+ /**
+ * @var mixed
+ */
protected $soapReturnValue;
public function __construct($returnValue = null)
diff --git a/SoapKernel.php b/SoapKernel.php
index 36b1514..ba80ca4 100644
--- a/SoapKernel.php
+++ b/SoapKernel.php
@@ -10,12 +10,6 @@
namespace Bundle\WebServiceBundle;
-use Bundle\WebServiceBundle\Soap\SoapHeader;
-
-use Bundle\WebServiceBundle\ServiceDefinition\ServiceHeader;
-
-use Bundle\WebServiceBundle\ServiceDefinition\Dumper\DumperInterface;
-
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -23,9 +17,9 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
use Bundle\WebServiceBundle\Soap\SoapRequest;
use Bundle\WebServiceBundle\Soap\SoapResponse;
+use Bundle\WebServiceBundle\Soap\SoapHeader;
-use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition;
-use Bundle\WebServiceBundle\ServiceDefinition\Loader\LoaderInterface;
+use Bundle\WebServiceBundle\ServiceBinding\ServiceBinder;
use Bundle\WebServiceBundle\Util\String;
@@ -55,24 +49,20 @@ class SoapKernel implements HttpKernelInterface
protected $soapResponse;
/**
- * @var \Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition
+ * @var \Bundle\WebServiceBundle\ServiceBinding\ServiceBinder
*/
- protected $serviceDefinition;
+ protected $serviceBinder;
/**
* @var \Symfony\Component\HttpKernel\HttpKernelInterface
*/
protected $kernel;
- public function __construct(ServiceDefinition $definition, LoaderInterface $loader, DumperInterface $dumper, HttpKernelInterface $kernel)
+ public function __construct(ServiceBinder $serviceBinder, HttpKernelInterface $kernel)
{
- $this->serviceDefinition = $definition;
- $loader->loadServiceDefinition($this->serviceDefinition);
+ $this->serviceBinder = $serviceBinder;
- // assume $dumper creates WSDL 1.1 file
- $wsdl = $dumper->dumpServiceDefinition($this->serviceDefinition);
-
- $this->soapServer = new \SoapServer($wsdl);
+ $this->soapServer = new \SoapServer($this->serviceBinder->getSerializedServiceDefinition());
$this->soapServer->setObject($this);
$this->kernel = $kernel;
@@ -107,19 +97,21 @@ class SoapKernel implements HttpKernelInterface
*/
public function __call($method, $arguments)
{
- if($this->serviceDefinition->getHeaders()->has($method))
+ if($this->serviceBinder->isServiceHeader($method))
{
// collect request soap headers
- $headerDefinition = $this->serviceDefinition->getHeaders()->get($method);
- $this->soapRequest->getSoapHeaders()->add($this->createSoapHeader($headerDefinition, $arguments[0]));
+ $this->soapRequest->getSoapHeaders()->add(
+ $this->serviceBinder->processServiceHeader($method, $arguments[0])
+ );
return;
}
- if($this->serviceDefinition->getMethods()->has($method))
+ if($this->serviceBinder->isServiceMethod($method))
{
- $methodDefinition = $this->serviceDefinition->getMethods()->get($method);
- $this->soapRequest->attributes->set('_controller', $methodDefinition->getController());
+ $this->soapRequest->attributes->add(
+ $this->serviceBinder->processServiceMethodArguments($method, $arguments)
+ );
// delegate to standard http kernel
$response = $this->kernel->handle($this->soapRequest, self::MASTER_REQUEST, true);
@@ -133,7 +125,10 @@ class SoapKernel implements HttpKernelInterface
}
// return operation return value to soap server
- return $this->soapResponse->getReturnValue();
+ return $this->serviceBinder->processServiceMethodReturnValue(
+ $method,
+ $this->soapResponse->getReturnValue()
+ );
}
}
@@ -180,14 +175,4 @@ class SoapKernel implements HttpKernelInterface
return $response;
}
-
- protected function createSoapHeader(ServiceHeader $headerDefinition, $data)
- {
- if(!preg_match('/^\{(.+)\}(.+)$/', $headerDefinition->getType()->getXmlType(), $matches))
- {
- throw new \InvalidArgumentException();
- }
-
- return new SoapHeader($matches[1], $matches[2], $data);
- }
}
\ No newline at end of file
diff --git a/Tests/SoapKernelTest.php b/Tests/SoapKernelTest.php
index 890259f..49e8727 100644
--- a/Tests/SoapKernelTest.php
+++ b/Tests/SoapKernelTest.php
@@ -10,17 +10,20 @@
namespace Bundle\WebServiceBundle\Tests;
-
-use Bundle\WebServiceBundle\ServiceDefinition\ServiceMethod;
-
-use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition;
-
use Symfony\Component\HttpFoundation\Request;
use Bundle\WebServiceBundle\SoapKernel;
use Bundle\WebServiceBundle\Soap\SoapRequest;
use Bundle\WebServiceBundle\Soap\SoapResponse;
+use Bundle\WebServiceBundle\ServiceBinding\ServiceBinder;
+use Bundle\WebServiceBundle\ServiceBinding\RpcLiteralResponseMessageBinder;
+use Bundle\WebServiceBundle\ServiceBinding\RpcLiteralRequestMessageBinder;
+
+use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition;
+use Bundle\WebServiceBundle\ServiceDefinition\Method;
+use Bundle\WebServiceBundle\ServiceDefinition\Loader\XmlFileLoader;
+
/**
* UnitTest for \Bundle\WebServiceBundle\SoapKernel.
*
@@ -36,17 +39,19 @@ class SoapKernelTest extends \PHPUnit_Framework_TestCase
public function setUp()
{
$serviceDefinition = new ServiceDefinition('api');
- $serviceDefinition->getMethods()->add(new ServiceMethod('math_multiply', 'MathController::multiply'));
-
- $serviceDefinitionLoader = null;
+ $serviceDefinitionLoader = new XmlFileLoader(__DIR__ . '/fixtures/api-servicedefinition.xml');
$serviceDefinitionDumper = new StaticFileDumper(__DIR__ . '/fixtures/api.wsdl');
+ $requestMessageBinder = new RpcLiteralRequestMessageBinder();
+ $responseMessageBinder = new RpcLiteralResponseMessageBinder();
+
+ $serviceBinder = new ServiceBinder($serviceDefinition, $serviceDefinitionLoader, $serviceDefinitionDumper, $requestMessageBinder, $responseMessageBinder);
$httpKernel = $this->getMock('Symfony\\Component\\HttpKernel\\HttpKernelInterface');
$httpKernel->expects($this->any())
->method('handle')
->will($this->returnValue(new SoapResponse(200)));
- $this->soapKernel = new SoapKernel($serviceDefinition, $serviceDefinitionLoader, $serviceDefinitionDumper, $httpKernel);
+ $this->soapKernel = new SoapKernel($serviceBinder, $httpKernel);
}
public function testHandle()
diff --git a/Tests/fixtures/api-servicedefinition.xml b/Tests/fixtures/api-servicedefinition.xml
new file mode 100644
index 0000000..30fd286
--- /dev/null
+++ b/Tests/fixtures/api-servicedefinition.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file