Serializer.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <?php
  2. /*
  3. * Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. namespace JMS\SerializerBundle\Serializer;
  18. use JMS\SerializerBundle\Serializer\Normalizer\NormalizableInterface;
  19. use JMS\SerializerBundle\Exception\RuntimeException;
  20. use JMS\SerializerBundle\Serializer\SerializerAwareInterface;
  21. use JMS\SerializerBundle\Serializer\Normalizer\NormalizerInterface;
  22. /**
  23. * Serializer implementation.
  24. *
  25. * This serializer distinuishes three different types of normalizers, one
  26. * normalizer for native php types, one default normalizer for objects, and an
  27. * arbitrary amount of specialized normalizers for specific object classes.
  28. *
  29. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  30. */
  31. class Serializer implements SerializerInterface
  32. {
  33. private $nativePhpTypeNormalizer;
  34. private $customObjectNormalizers;
  35. private $defaultObjectNormalizer;
  36. private $encoderMap;
  37. public function __construct(NormalizerInterface $nativePhpNormalizer, NormalizerInterface $defaultObjectNormalizer, array $customObjectNormalizers = array(), array $encoderMap = array())
  38. {
  39. if ($nativePhpNormalizer instanceof SerializerAwareInterface) {
  40. $nativePhpNormalizer->setSerializer($this);
  41. }
  42. $this->nativePhpTypeNormalizer = $nativePhpNormalizer;
  43. if ($defaultObjectNormalizer instanceof SerializerAwareInterface) {
  44. $defaultObjectNormalizer->setSerializer($this);
  45. }
  46. $this->defaultObjectNormalizer = $defaultObjectNormalizer;
  47. foreach ($customObjectNormalizers as $normalizer) {
  48. if ($normalizer instanceof SerializerAwareInterface) {
  49. $normalizer->setSerializer($this);
  50. }
  51. }
  52. $this->customObjectNormalizers = $customObjectNormalizers;
  53. foreach ($encoderMap as $encoder) {
  54. if ($encoder instanceof SerializerAwareInterface) {
  55. $encoder->setSerializer($this);
  56. }
  57. }
  58. $this->encoderMap = $encoderMap;
  59. }
  60. /**
  61. * {@inheritDoc}
  62. */
  63. public final function normalize($data, $format = null)
  64. {
  65. // needs to run first so that users can override the behavior for built-in
  66. // interface like \Traversable, see #10
  67. if ($this->customObjectNormalizers && is_object($data)) {
  68. foreach ($this->customObjectNormalizers as $normalizer) {
  69. if ($normalizer->supportsNormalization($data, $format)) {
  70. return $normalizer->normalize($data, $format);
  71. }
  72. }
  73. }
  74. if ($this->nativePhpTypeNormalizer->supportsNormalization($data, $format)) {
  75. return $this->nativePhpTypeNormalizer->normalize($data, $format);
  76. }
  77. return $this->defaultObjectNormalizer->normalize($data, $format);
  78. }
  79. /**
  80. * {@inheritDoc}
  81. */
  82. public final function denormalize($data, $type, $format = null)
  83. {
  84. if ($this->nativePhpTypeNormalizer->supportsDenormalization($data, $type, $format)) {
  85. return $this->nativePhpTypeNormalizer->denormalize($data, $type, $format);
  86. }
  87. if ($this->customObjectNormalizers) {
  88. foreach ($this->customObjectNormalizers as $normalizer) {
  89. if ($normalizer->supportsDenormalization($data, $type, $format)) {
  90. return $normalizer->denormalize($data, $type, $format);
  91. }
  92. }
  93. }
  94. return $this->defaultObjectNormalizer->denormalize($data, $type, $format);
  95. }
  96. /**
  97. * {@inheritDoc}
  98. */
  99. public final function serialize($data, $format)
  100. {
  101. $data = $this->normalize($data, $format);
  102. return $this->encode($data, $format);
  103. }
  104. /**
  105. * {@inheritDoc}
  106. */
  107. public final function deserialize($data, $type, $format)
  108. {
  109. $data = $this->decode($data, $format);
  110. return $this->denormalize($data, $type, $format);
  111. }
  112. /**
  113. * {@inheritDoc}
  114. */
  115. public final function encode($data, $format)
  116. {
  117. return $this->getEncoder($format)->encode($data, $format);
  118. }
  119. /**
  120. * {@inheritDoc}
  121. */
  122. public final function decode($data, $format)
  123. {
  124. return $this->getEncoder($format)->decode($data, $format);
  125. }
  126. protected function getEncoder($format)
  127. {
  128. if (!isset($this->encoderMap[$format])) {
  129. throw new RuntimeException(sprintf('No encoder found for format "%s".', $format));
  130. }
  131. return $this->encoderMap[$format];
  132. }
  133. }