Browse Source

Merge pull request #28 from adrienbrault/navigator-context-metadata-stack

The NavigatorContext now holds a metadata stack
Johannes 12 years ago
parent
commit
8ec7b14234

+ 40 - 0
src/JMS/Serializer/Context.php

@@ -18,10 +18,13 @@
 
 namespace JMS\Serializer;
 
+use JMS\Serializer\Exception\RuntimeException;
 use JMS\Serializer\Exclusion\DisjunctExclusionStrategy;
 use JMS\Serializer\Exclusion\ExclusionStrategyInterface;
 use JMS\Serializer\Exclusion\GroupsExclusionStrategy;
 use JMS\Serializer\Exclusion\VersionExclusionStrategy;
+use JMS\Serializer\Metadata\ClassMetadata;
+use JMS\Serializer\Metadata\PropertyMetadata;
 use Metadata\MetadataFactory;
 use Metadata\MetadataFactoryInterface;
 use PhpCollection\Map;
@@ -52,6 +55,9 @@ abstract class Context
 
     private $initialized = false;
 
+    /** @var \SplStack */
+    private $metadataStack;
+
     public function __construct()
     {
         $this->attributes = new Map();
@@ -68,6 +74,7 @@ abstract class Context
         $this->visitor = $visitor;
         $this->navigator = $navigator;
         $this->metadataFactory = $factory;
+        $this->metadataStack = new \SplStack();
     }
 
     public function accept($data, array $type = null)
@@ -183,6 +190,39 @@ abstract class Context
         return $this->format;
     }
 
+    public function pushClassMetadata(ClassMetadata $metadata)
+    {
+        $this->metadataStack->push($metadata);
+    }
+
+    public function pushPropertyMetadata(PropertyMetadata $metadata)
+    {
+        $this->metadataStack->push($metadata);
+    }
+
+    public function popPropertyMetadata()
+    {
+        $metadata = $this->metadataStack->pop();
+
+        if (!$metadata instanceof PropertyMetadata) {
+            throw new RuntimeException('Context metadataStack not working well');
+        }
+    }
+
+    public function popClassMetadata()
+    {
+        $metadata = $this->metadataStack->pop();
+
+        if (!$metadata instanceof ClassMetadata) {
+            throw new RuntimeException('Context metadataStack not working well');
+        }
+    }
+
+    public function getMetadataStack()
+    {
+        return $this->metadataStack;
+    }
+
     abstract public function getDepth();
     abstract public function getDirection();
 }

+ 5 - 0
src/JMS/Serializer/GraphNavigator.php

@@ -184,6 +184,8 @@ final class GraphNavigator
                     $metadata = $this->resolveMetadata($context, $data, $metadata);
                 }
 
+                $context->pushClassMetadata($metadata);
+
                 if (null !== $exclusionStrategy && $exclusionStrategy->shouldSkipClass($metadata, $context)) {
                     $this->leaveScope($context, $data);
 
@@ -222,7 +224,9 @@ final class GraphNavigator
                         continue;
                     }
 
+                    $context->pushPropertyMetadata($propertyMetadata);
                     $visitor->visitProperty($propertyMetadata, $data, $context);
+                    $context->popPropertyMetadata();
                 }
 
                 if ($context instanceof SerializationContext) {
@@ -281,6 +285,7 @@ final class GraphNavigator
     private function afterVisitingObject(ClassMetadata $metadata, $object, array $type, Context $context)
     {
         $this->leaveScope($context, $object);
+        $context->popClassMetadata();
 
         if ($context instanceof SerializationContext) {
             foreach ($metadata->postSerializeMethods as $method) {

+ 11 - 1
src/JMS/Serializer/SerializationContext.php

@@ -95,4 +95,14 @@ class SerializationContext extends Context
     {
         return !$this->visitingStack->isEmpty() ? $this->visitingStack->top() : null;
     }
-}
+
+    public function getVisitingStack()
+    {
+        return $this->visitingStack;
+    }
+
+    public function getVisitingSet()
+    {
+        return $this->visitingSet;
+    }
+}