diff --git a/Converter/ConverterRepository.php b/Converter/ConverterRepository.php
index b1691f1..2a31a95 100644
--- a/Converter/ConverterRepository.php
+++ b/Converter/ConverterRepository.php
@@ -31,25 +31,9 @@ class ConverterRepository
$this->typeConverters[] = $converter;
}
- public function toSoapServerTypemap(SoapKernel $kernel)
+ public function getTypeConverters()
{
- $result = array();
-
- foreach($this->typeConverters as $typeConverter)
- {
- $result[] = array(
- 'type_name' => $typeConverter->getTypeName(),
- 'type_ns' => $typeConverter->getTypeNamespace(),
- 'from_xml' => function($input) use ($kernel, $typeConverter) {
- return $typeConverter->convertXmlToPhp($kernel->getRequest(), $input);
- },
- 'to_xml' => function($input) use ($kernel, $typeConverter) {
- return $typeConverter->convertPhpToXml($kernel->getResponse(), $input);
- }
- );
- }
-
- return $result;
+ return $this->typeConverters;
}
public function registerTypeConverterServices(ContainerInterface $container)
diff --git a/Resources/config/services.xml b/Resources/config/services.xml
index e0eb394..4cb4bf6 100644
--- a/Resources/config/services.xml
+++ b/Resources/config/services.xml
@@ -11,7 +11,7 @@
Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition
Bundle\WebServiceBundle\ServiceDefinition\Loader\XmlFileLoader
- Bundle\WebServiceBundle\Tests\StaticFileDumper
+ Bundle\WebServiceBundle\ServiceDefinition\Dumper\WsdlFileDumper
@@ -23,14 +23,12 @@
-
+
-
-
@@ -39,6 +37,12 @@
+
+
+
+
+
+
@@ -47,6 +51,8 @@
%webservice.definition.name%
+ %webservice.definition.namespace%
+
%webservice.definition.resource%
diff --git a/ServiceBinding/ServiceBinder.php b/ServiceBinding/ServiceBinder.php
index 375e2f5..abf0430 100644
--- a/ServiceBinding/ServiceBinder.php
+++ b/ServiceBinding/ServiceBinder.php
@@ -10,6 +10,8 @@
namespace Bundle\WebServiceBundle\ServiceBinding;
+use Bundle\WebServiceBundle\Util\QName;
+
use Bundle\WebServiceBundle\ServiceDefinition\Type;
use Bundle\WebServiceBundle\Soap\SoapHeader;
@@ -43,60 +45,16 @@ class ServiceBinder
public function __construct(
ServiceDefinition $definition,
- LoaderInterface $loader,
- DumperInterface $dumper,
MessageBinderInterface $requestMessageBinder,
MessageBinderInterface $responseMessageBinder
)
{
- $loader->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 getSoapServerClassmap()
- {
- $result = array();
-
- foreach($this->definition->getHeaders() as $header)
- {
- $this->addSoapServerClassmapEntry($result, $header->getType());
- }
-
- foreach($this->definition->getMethods() as $method)
- {
- foreach($method->getArguments() as $arg)
- {
- $this->addSoapServerClassmapEntry($result, $arg->getType());
- }
- }
-
- return $result;
- }
-
- private function addSoapServerClassmapEntry(&$classmap, Type $type)
- {
- list($namespace, $xmlType) = $this->parsePackedQName($type->getXmlType());
- $phpType = $type->getPhpType();
-
- if(isset($classmap[$xmlType]) && $classmap[$xmlType] != $phpType)
- {
- // log warning
- }
-
- $classmap[$xmlType] = $phpType;
- }
-
public function isServiceHeader($name)
{
return $this->definition->getHeaders()->has($name);
@@ -134,18 +92,8 @@ class ServiceBinder
protected function createSoapHeader(Header $headerDefinition, $data)
{
- list($namespace, $name) = $this->parsePackedQName($headerDefinition->getType()->getXmlType());
+ $qname = QName::fromPackedQName($headerDefinition->getType()->getXmlType());
- return new SoapHeader($namespace, $name, $data);
- }
-
- private function parsePackedQName($qname)
- {
- if(!preg_match('/^\{(.+)\}(.+)$/', $qname, $matches))
- {
- throw new \InvalidArgumentException();
- }
-
- return array($matches[1], $matches[2]);
+ return new SoapHeader($qname->getNamespace(), $qname->getName(), $data);
}
}
\ No newline at end of file
diff --git a/Soap/SoapServerFactory.php b/Soap/SoapServerFactory.php
new file mode 100644
index 0000000..983a07c
--- /dev/null
+++ b/Soap/SoapServerFactory.php
@@ -0,0 +1,111 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Bundle\WebServiceBundle\Soap;
+
+/**
+ *
+ * @author Christian Kerl
+ */
+use Bundle\WebServiceBundle\ServiceDefinition\Type;
+
+use Bundle\WebServiceBundle\ServiceDefinition\Dumper\FileDumper;
+
+use Bundle\WebServiceBundle\Converter\ConverterRepository;
+
+use Bundle\WebServiceBundle\SoapKernel;
+
+use Bundle\WebServiceBundle\Util\QName;
+
+use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition;
+
+class SoapServerFactory
+{
+ private $definition;
+ private $converters;
+ private $dumper;
+
+ public function __construct(ServiceDefinition $definition, ConverterRepository $converters, FileDumper $dumper)
+ {
+ $this->definition = $definition;
+ $this->converters = $converters;
+ $this->dumper = $dumper;
+ }
+
+ public function create(&$request, &$response)
+ {
+ $file = $this->dumper->dumpServiceDefinition($this->definition);
+
+ $server = new \SoapServer(
+ $file,
+ array(
+ 'classmap' => $this->createSoapServerClassmap(),
+ 'typemap' => $this->createSoapServerTypemap($request, $response),
+ 'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
+ )
+ );
+
+ return $server;
+ }
+
+ private function createSoapServerTypemap(&$request, &$response)
+ {
+ $result = array();
+
+ foreach($this->converters->getTypeConverters() as $typeConverter)
+ {
+ $result[] = array(
+ 'type_name' => $typeConverter->getTypeName(),
+ 'type_ns' => $typeConverter->getTypeNamespace(),
+ 'from_xml' => function($input) use (&$request, $typeConverter) {
+ return $typeConverter->convertXmlToPhp($request, $input);
+ },
+ 'to_xml' => function($input) use (&$response, $typeConverter) {
+ return $typeConverter->convertPhpToXml($response, $input);
+ }
+ );
+ }
+
+ return $result;
+ }
+
+ private function createSoapServerClassmap()
+ {
+ $result = array();
+
+ foreach($this->definition->getHeaders() as $header)
+ {
+ $this->addSoapServerClassmapEntry($result, $header->getType());
+ }
+
+ foreach($this->definition->getMethods() as $method)
+ {
+ foreach($method->getArguments() as $arg)
+ {
+ $this->addSoapServerClassmapEntry($result, $arg->getType());
+ }
+ }
+
+ return $result;
+ }
+
+ private function addSoapServerClassmapEntry(&$classmap, Type $type)
+ {
+ $xmlType = QName::fromPackedQName($type->getXmlType())->getName();
+ $phpType = $type->getPhpType();
+
+ if(isset($classmap[$xmlType]) && $classmap[$xmlType] != $phpType)
+ {
+ // log warning
+ }
+
+ $classmap[$xmlType] = $phpType;
+ }
+}
diff --git a/SoapKernel.php b/SoapKernel.php
index e939583..aedd9bd 100644
--- a/SoapKernel.php
+++ b/SoapKernel.php
@@ -11,6 +11,8 @@
namespace Bundle\WebServiceBundle;
+use Bundle\WebServiceBundle\Soap\SoapServerFactory;
+
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -61,21 +63,13 @@ class SoapKernel implements HttpKernelInterface
*/
protected $kernel;
- public function __construct(ServiceBinder $serviceBinder, ConverterRepository $converterRepository, HttpKernelInterface $kernel)
+ public function __construct(ServiceBinder $serviceBinder, SoapServerFactory $soapServerFactory, HttpKernelInterface $kernel)
{
$this->serviceBinder = $serviceBinder;
-
- $this->soapServer = new \SoapServer(
- $this->serviceBinder->getSerializedServiceDefinition(),
- array(
- 'classmap' => $this->serviceBinder->getSoapServerClassmap(),
- 'typemap' => $converterRepository->toSoapServerTypemap($this),
- 'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
- )
- );
+ $this->soapServer = $soapServerFactory->create($this->soapRequest, $this->soapResponse);
$this->soapServer->setObject($this);
-
$this->kernel = $kernel;
+
}
public function getRequest()
diff --git a/Tests/SoapKernelTest.php b/Tests/SoapKernelTest.php
index 21d4490..bb6dc5c 100644
--- a/Tests/SoapKernelTest.php
+++ b/Tests/SoapKernelTest.php
@@ -10,6 +10,8 @@
namespace Bundle\WebServiceBundle\Tests;
+use Bundle\WebServiceBundle\Soap\SoapServerFactory;
+
use Bundle\WebServiceBundle\Converter\ConverterRepository;
use Symfony\Component\HttpFoundation\Request;
@@ -42,20 +44,20 @@ class SoapKernelTest extends \PHPUnit_Framework_TestCase
{
$serviceDefinition = new ServiceDefinition('api');
$serviceDefinitionLoader = new XmlFileLoader(__DIR__ . '/fixtures/api-servicedefinition.xml');
+ $serviceDefinitionLoader->loadServiceDefinition($serviceDefinition);
$serviceDefinitionDumper = new StaticFileDumper(__DIR__ . '/fixtures/api.wsdl');
$requestMessageBinder = new RpcLiteralRequestMessageBinder();
$responseMessageBinder = new RpcLiteralResponseMessageBinder();
- $serviceBinder = new ServiceBinder($serviceDefinition, $serviceDefinitionLoader, $serviceDefinitionDumper, $requestMessageBinder, $responseMessageBinder);
-
+ $serviceBinder = new ServiceBinder($serviceDefinition, $requestMessageBinder, $responseMessageBinder);
$converterRepository = new ConverterRepository();
-
+ $soapServerFactory = new SoapServerFactory($serviceDefinition, $converterRepository, $serviceDefinitionDumper);
$httpKernel = $this->getMock('Symfony\\Component\\HttpKernel\\HttpKernelInterface');
$httpKernel->expects($this->any())
->method('handle')
->will($this->returnValue(new SoapResponse(200)));
- $this->soapKernel = new SoapKernel($serviceBinder, $converterRepository, $httpKernel);
+ $this->soapKernel = new SoapKernel($serviceBinder, $soapServerFactory, $httpKernel);
}
public function testHandle()
diff --git a/Tests/StaticFileDumper.php b/Tests/StaticFileDumper.php
index 82675ed..3d91744 100644
--- a/Tests/StaticFileDumper.php
+++ b/Tests/StaticFileDumper.php
@@ -10,18 +10,13 @@
namespace Bundle\WebServiceBundle\Tests;
+use Bundle\WebServiceBundle\ServiceDefinition\Dumper\FileDumper;
+
use Bundle\WebServiceBundle\ServiceDefinition\ServiceDefinition;
use Bundle\WebServiceBundle\ServiceDefinition\Dumper\DumperInterface;
-class StaticFileDumper implements DumperInterface
+class StaticFileDumper extends FileDumper
{
- private $file;
-
- public function __construct($file)
- {
- $this->file = $file;
- }
-
public function dumpServiceDefinition(ServiceDefinition $definition)
{
return $this->file;
diff --git a/Util/QName.php b/Util/QName.php
new file mode 100644
index 0000000..d2bf3f2
--- /dev/null
+++ b/Util/QName.php
@@ -0,0 +1,49 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Bundle\WebServiceBundle\Util;
+
+/**
+ *
+ * @author Christian Kerl
+ */
+class QName
+{
+ public static function fromPackedQName($qname)
+ {
+ Assert::thatArgument('qname', preg_match('/^\{(.+)\}(.+)$/', $qname, $matches));
+
+ return new self($matches[1], $matches[2]);
+ }
+
+ private $namespace;
+ private $name;
+
+ public function __construct($namespace, $name)
+ {
+ $this->namespace = $namespace;
+ $this->name = $name;
+ }
+
+ public function getNamespace()
+ {
+ return $this->namespace;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function __toString()
+ {
+ return sprintf('{%s}%s', $this->getNamespace(), $this->getName());
+ }
+}