From 5e7877282cee3063ea26473ce4cbfd9a5a2a955b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Guillaume=20Perr=C3=A9al?= <guillaume.perreal@irstea.fr>
Date: Wed, 9 Mar 2016 17:34:40 +0100
Subject: [PATCH] Refactoring des namespaces.

---
 Command/EntitySchemaCommand.php               |  6 ++-
 Doctrine/AssociationDecorator.php             |  2 +-
 Doctrine/DoctrineNamespace.php                | 28 +++++++++++
 Model/ClassVisitor.php                        | 12 ++---
 Model/NamespaceInterface.php                  | 10 +++-
 Model/Namespace_/BundleNamespace.php          | 29 ++++++++++++
 Model/Namespace_/FlatNamespace.php            | 11 ++++-
 Model/Namespace_/MappedNamespace.php          | 46 +++++++++++++++++++
 .../AbstractNamespace.php}                    | 11 +++--
 Model/Namespace_/{ => Php}/Namespace_.php     |  2 +-
 Model/Namespace_/{ => Php}/RootNamespace.php  |  4 +-
 Model/Node/BaseNode.php                       |  9 ++--
 Model/Node/Class_.php                         |  4 +-
 Model/Node/Interface_.php                     |  4 +-
 Model/Node/Trait_.php                         |  4 +-
 15 files changed, 151 insertions(+), 31 deletions(-)
 create mode 100644 Doctrine/DoctrineNamespace.php
 create mode 100644 Model/Namespace_/BundleNamespace.php
 create mode 100644 Model/Namespace_/MappedNamespace.php
 rename Model/Namespace_/{AbstractHierachicalNamespace.php => Php/AbstractNamespace.php} (87%)
 rename Model/Namespace_/{ => Php}/Namespace_.php (96%)
 rename Model/Namespace_/{ => Php}/RootNamespace.php (90%)

diff --git a/Command/EntitySchemaCommand.php b/Command/EntitySchemaCommand.php
index 46782c7..6edbc7c 100644
--- a/Command/EntitySchemaCommand.php
+++ b/Command/EntitySchemaCommand.php
@@ -9,12 +9,14 @@ namespace Irstea\PlantUmlBundle\Command;
 use Doctrine\ORM\EntityManagerInterface;
 use Doctrine\ORM\Mapping\ClassMetadata;
 use Irstea\PlantUmlBundle\Doctrine\AssociationDecorator;
+use Irstea\PlantUmlBundle\Doctrine\DoctrineNamespace;
 use Irstea\PlantUmlBundle\Doctrine\EntityDecorator;
 use Irstea\PlantUmlBundle\Model\ClassVisitor;
 use Irstea\PlantUmlBundle\Model\Decorator\CompositeDecorator;
 use Irstea\PlantUmlBundle\Model\Decorator\FilteringDecorator;
 use Irstea\PlantUmlBundle\Model\Decorator\InheritanceDecorator;
 use Irstea\PlantUmlBundle\Model\Filter\Whitelist;
+use Irstea\PlantUmlBundle\Model\Namespace_\BundleNamespace;
 use Irstea\PlantUmlBundle\Model\Namespace_\FlatNamespace;
 use Irstea\PlantUmlBundle\Writer\OutputWriter;
 use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
@@ -56,6 +58,8 @@ class EntitySchemaCommand extends ContainerAwareCommand
             $allMetadata
         );
 
+        $namespace = new BundleNamespace($this->getContainer()->getParameter('kernel.bundles'));
+
         $decorator = new FilteringDecorator(
             new CompositeDecorator([
                 new InheritanceDecorator(),
@@ -65,7 +69,7 @@ class EntitySchemaCommand extends ContainerAwareCommand
             new Whitelist($classes)
         );
 
-        $visitor = new ClassVisitor($decorator, null, new FlatNamespace());
+        $visitor = new ClassVisitor($decorator, null, $namespace);
 
         array_walk($classes, [$visitor, 'visitClass']);
 
diff --git a/Doctrine/AssociationDecorator.php b/Doctrine/AssociationDecorator.php
index a5027fd..9d15b70 100644
--- a/Doctrine/AssociationDecorator.php
+++ b/Doctrine/AssociationDecorator.php
@@ -44,7 +44,7 @@ class AssociationDecorator extends AbstractDoctrineDecorator
             return;
         }
 
-        $link = "-->";
+        $link = "->";
         if ($association["isCascadeRemove"]) {
             $link = "o".$link;
         }
diff --git a/Doctrine/DoctrineNamespace.php b/Doctrine/DoctrineNamespace.php
new file mode 100644
index 0000000..6281536
--- /dev/null
+++ b/Doctrine/DoctrineNamespace.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * © 2016 IRSTEA
+ * Guillaume Perréal <guillaume.perreal@irstea.fr>
+ * Tous droits réservés.
+ */
+
+namespace Irstea\PlantUmlBundle\Doctrine;
+
+/**
+ * Description of DoctrineNamespace
+ *
+ * @author Guillaume Perréal <guillaume.perreal@irstea.fr>
+ */
+class DoctrineNamespace extends \Irstea\PlantUmlBundle\Model\Namespace_\MappedNamespace
+{
+    const SEPARATOR = '::';
+
+    public function __construct(array $entityNamespaces)
+    {
+        $mapping = [];
+        foreach($entityNamespaces as $alias => $namespace) {
+            $mapping[$namespace.'\\'] = $alias.'::';
+        }
+        parent::__construct($mapping);
+    }
+}
diff --git a/Model/ClassVisitor.php b/Model/ClassVisitor.php
index 5821f91..75730ae 100644
--- a/Model/ClassVisitor.php
+++ b/Model/ClassVisitor.php
@@ -10,12 +10,11 @@ namespace Irstea\PlantUmlBundle\Model;
 
 use Irstea\PlantUmlBundle\Model\Decorator\NullDecorator;
 use Irstea\PlantUmlBundle\Model\Filter\AcceptAllFilter;
-use Irstea\PlantUmlBundle\Model\Namespace_\RootNamespace;
+use Irstea\PlantUmlBundle\Model\Namespace_\Php\RootNamespace;
 use Irstea\PlantUmlBundle\Model\Node\Class_;
 use Irstea\PlantUmlBundle\Model\Node\Interface_;
 use Irstea\PlantUmlBundle\Model\Node\Trait_;
 use Irstea\PlantUmlBundle\Writer\WritableInterface;
-use Irstea\PlantUmlBundle\Writer\WritableNodeInterface;
 use Irstea\PlantUmlBundle\Writer\WriterInterface;
 use ReflectionClass;
 
@@ -103,18 +102,15 @@ class ClassVisitor implements ClassVisitorInterface, WritableInterface
     {
         $className = $class->getName();
 
-        $id = str_replace('\\', '.', $className).'_node';
-        $label = $namespace->getShortName($className);
-
         if ($class->isTrait()) {
-            return new Trait_($namespace, $id, $label);
+            return new Trait_($namespace, $className);
         }
 
         if ($class->isInterface()) {
-            return new Interface_($namespace, $id, $label, $class->getName());
+            return new Interface_($namespace, $className);
         }
 
-        return new Class_($namespace, $id, $label, $class->isAbstract(), $class->isFinal());
+        return new Class_($namespace, $className, $class->isAbstract(), $class->isFinal());
     }
 
     public function outputTo(WriterInterface $writer)
diff --git a/Model/NamespaceInterface.php b/Model/NamespaceInterface.php
index ed69141..5fbabf0 100644
--- a/Model/NamespaceInterface.php
+++ b/Model/NamespaceInterface.php
@@ -23,10 +23,16 @@ interface NamespaceInterface extends WritableInterface
     public function getNamespace($namespaceName);
 
     /**
-     * @param string $name
+     * @param string $className
      * @return string
      */
-    public function getShortName($name);
+    public function getNodeId($className);
+
+    /**
+     * @param string $className
+     * @return string
+     */
+    public function getNodeLabel($className);
 
     /**
      * @param NodeInterface $node
diff --git a/Model/Namespace_/BundleNamespace.php b/Model/Namespace_/BundleNamespace.php
new file mode 100644
index 0000000..63aa185
--- /dev/null
+++ b/Model/Namespace_/BundleNamespace.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * © 2016 IRSTEA
+ * Guillaume Perréal <guillaume.perreal@irstea.fr>
+ * Tous droits réservés.
+ */
+
+namespace Irstea\PlantUmlBundle\Model\Namespace_;
+
+/**
+ * Description of BundleNamespace
+ *
+ * @author Guillaume Perréal <guillaume.perreal@irstea.fr>
+ */
+class BundleNamespace extends MappedNamespace
+{
+    const SEPARATOR = '::';
+
+    public function __construct(array $bundles)
+    {
+        $mapping = [];
+        foreach($bundles as $bundle => $php) {
+            $mapping[substr($php, 0, 1+strrpos($php, '\\'))] = $bundle.'::';
+        }
+
+        parent::__construct($mapping);
+    }
+}
diff --git a/Model/Namespace_/FlatNamespace.php b/Model/Namespace_/FlatNamespace.php
index 0eab38e..587fb8d 100644
--- a/Model/Namespace_/FlatNamespace.php
+++ b/Model/Namespace_/FlatNamespace.php
@@ -18,6 +18,8 @@ use Irstea\PlantUmlBundle\Writer\WriterInterface;
  */
 class FlatNamespace extends AbstractNamespace
 {
+    const SEPARATOR = 'none';
+
     /**
      * @var ArrowInterface[]
      */
@@ -31,7 +33,7 @@ class FlatNamespace extends AbstractNamespace
 
     public function outputTo(WriterInterface $writer)
     {
-        $writer->write("set namespaceSeparator none\n");
+        $writer->printf("set namespaceSeparator %s\n", static::SEPARATOR);
         $this
             ->outputNodesTo($writer)
             ->outputArrowsTo($writer);
@@ -51,7 +53,12 @@ class FlatNamespace extends AbstractNamespace
         return $this;
     }
 
-    public function getShortName($name)
+    public function getNodeId($name)
+    {
+        return str_replace('\\', '_', $name);
+    }
+
+    public function getNodeLabel($name)
     {
         return $name;
     }
diff --git a/Model/Namespace_/MappedNamespace.php b/Model/Namespace_/MappedNamespace.php
new file mode 100644
index 0000000..c395f08
--- /dev/null
+++ b/Model/Namespace_/MappedNamespace.php
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * © 2016 IRSTEA
+ * Guillaume Perréal <guillaume.perreal@irstea.fr>
+ * Tous droits réservés.
+ */
+
+namespace Irstea\PlantUmlBundle\Model\Namespace_;
+
+/**
+ * Description of BundleNamespace
+ *
+ * @author Guillaume Perréal <guillaume.perreal@irstea.fr>
+ */
+class MappedNamespace extends FlatNamespace
+{
+    const SEPARATOR = '::';
+
+    /**
+     * @var string[]
+     */
+    private $mappedNamespaces = [];
+
+    /**
+     * @var string[]
+     */
+    private $phpNamespaces = [];
+
+    public function __construct(array $mapping)
+    {
+        $this->phpNamespaces = array_keys($mapping);
+        $this->mappedNamespaces = array_values($mapping);
+    }
+
+    public function getNodeId($name)
+    {
+        return str_replace('\\', '__', str_replace($this->phpNamespaces, $this->mappedNamespaces, $name));
+    }
+
+    public function getNodeLabel($name)
+    {
+        return str_replace($this->phpNamespaces, '', $name);
+    }
+
+}
diff --git a/Model/Namespace_/AbstractHierachicalNamespace.php b/Model/Namespace_/Php/AbstractNamespace.php
similarity index 87%
rename from Model/Namespace_/AbstractHierachicalNamespace.php
rename to Model/Namespace_/Php/AbstractNamespace.php
index 9aac536..2d591ee 100644
--- a/Model/Namespace_/AbstractHierachicalNamespace.php
+++ b/Model/Namespace_/Php/AbstractNamespace.php
@@ -6,7 +6,7 @@
  * Tous droits réservés.
  */
 
-namespace Irstea\PlantUmlBundle\Model\Namespace_;
+namespace Irstea\PlantUmlBundle\Model\Namespace_\Php;
 
 use Irstea\PlantUmlBundle\Model\NamespaceInterface;
 use Irstea\PlantUmlBundle\Model\NodeInterface;
@@ -18,7 +18,7 @@ use Irstea\PlantUmlBundle\Writer\WriterInterface;
  *
  * @author Guillaume Perréal <guillaume.perreal@irstea.fr>
  */
-abstract class AbstractHierachicalNamespace extends AbstractNamespace
+abstract class AbstractNamespace extends AbstractNamespace
 {
     /**
      * @var NamespaceInterface
@@ -50,7 +50,7 @@ abstract class AbstractHierachicalNamespace extends AbstractNamespace
      */
     abstract protected function getNamespacePrefix();
 
-    public function getShortName($name)
+    public function getNodeLabel($name)
     {
         $prefix = $this->getNamespacePrefix();
         if (0 === strpos($name, $prefix)) {
@@ -59,6 +59,11 @@ abstract class AbstractHierachicalNamespace extends AbstractNamespace
         return $name;
     }
 
+    public function getNodeId($name)
+    {
+        return str_replace('\\', '.', $name).'_node';
+    }
+
     /**
      * @param WriterInterface $writer
      * @return self
diff --git a/Model/Namespace_/Namespace_.php b/Model/Namespace_/Php/Namespace_.php
similarity index 96%
rename from Model/Namespace_/Namespace_.php
rename to Model/Namespace_/Php/Namespace_.php
index 89fceef..8c6da0b 100644
--- a/Model/Namespace_/Namespace_.php
+++ b/Model/Namespace_/Php/Namespace_.php
@@ -6,7 +6,7 @@
  * Tous droits réservés.
  */
 
-namespace Irstea\PlantUmlBundle\Model\Namespace_;
+namespace Irstea\PlantUmlBundle\Model\Namespace_\Php;
 
 use Irstea\PlantUmlBundle\Model\ArrowInterface;
 use Irstea\PlantUmlBundle\Model\NamespaceInterface;
diff --git a/Model/Namespace_/RootNamespace.php b/Model/Namespace_/Php/RootNamespace.php
similarity index 90%
rename from Model/Namespace_/RootNamespace.php
rename to Model/Namespace_/Php/RootNamespace.php
index 0b87754..90c5f1a 100644
--- a/Model/Namespace_/RootNamespace.php
+++ b/Model/Namespace_/Php/RootNamespace.php
@@ -6,7 +6,7 @@
  * Tous droits réservés.
  */
 
-namespace Irstea\PlantUmlBundle\Model\Namespace_;
+namespace Irstea\PlantUmlBundle\Model\Namespace_\Php;
 
 use Irstea\PlantUmlBundle\Model\ArrowInterface;
 use Irstea\PlantUmlBundle\Writer\WriterInterface;
@@ -16,7 +16,7 @@ use Irstea\PlantUmlBundle\Writer\WriterInterface;
  *
  * @author Guillaume Perréal <guillaume.perreal@irstea.fr>
  */
-class RootNamespace extends AbstractHierachicalNamespace
+class RootNamespace extends AbstractNamespace
 {
     /**
      * @var ArrowInterface[]
diff --git a/Model/Node/BaseNode.php b/Model/Node/BaseNode.php
index dcc73a7..1be3396 100644
--- a/Model/Node/BaseNode.php
+++ b/Model/Node/BaseNode.php
@@ -52,17 +52,16 @@ class BaseNode implements NodeInterface
 
     /**
      * @param NamespaceInterface $namespace
-     * @param string $id
-     * @param string $label
+     * @param string $name
      * @param string $nodeType
      * @param array $classifiers
      * @param array $stereotypes
      */
-    function __construct(NamespaceInterface $namespace, $id, $label, $nodeType, array $classifiers = [], array $stereotypes = [])
+    function __construct(NamespaceInterface $namespace, $name, $nodeType, array $classifiers = [], array $stereotypes = [])
     {
         $this->namespace   = $namespace;
-        $this->id          = $id;
-        $this->label       = $label;
+        $this->id          = $namespace->getNodeId($name);
+        $this->label       = $namespace->getNodeLabel($name);
 
         $this->nodeType    = $nodeType;
         $this->classifiers = $classifiers;
diff --git a/Model/Node/Class_.php b/Model/Node/Class_.php
index c4b0a52..d9e5477 100644
--- a/Model/Node/Class_.php
+++ b/Model/Node/Class_.php
@@ -17,7 +17,7 @@ use Irstea\PlantUmlBundle\Model\NamespaceInterface;
  */
 class Class_ extends BaseNode
 {
-    public function __construct(NamespaceInterface $namespace, $id, $label, $isAbstract, $isFinal)
+    public function __construct(NamespaceInterface $namespace, $name, $isAbstract, $isFinal)
     {
         $classifiers = [];
         if ($isAbstract) {
@@ -25,6 +25,6 @@ class Class_ extends BaseNode
         } elseif ($isFinal) {
             $classifiers[] = 'final';
         }
-        parent::__construct($namespace, $id, $label, "class", $classifiers, []);
+        parent::__construct($namespace, $name, "class", $classifiers, []);
     }
 }
diff --git a/Model/Node/Interface_.php b/Model/Node/Interface_.php
index f1926a6..6d36ccf 100644
--- a/Model/Node/Interface_.php
+++ b/Model/Node/Interface_.php
@@ -17,8 +17,8 @@ use Irstea\PlantUmlBundle\Model\NamespaceInterface;
  */
 class Interface_ extends BaseNode
 {
-    public function __construct(NamespaceInterface $namespace, $id, $label)
+    public function __construct(NamespaceInterface $namespace, $name)
     {
-        parent::__construct($namespace, $id, $label, 'interface', [], []);
+        parent::__construct($namespace, $name, 'interface', [], []);
     }
 }
diff --git a/Model/Node/Trait_.php b/Model/Node/Trait_.php
index 2f682a3..62a50dc 100644
--- a/Model/Node/Trait_.php
+++ b/Model/Node/Trait_.php
@@ -17,8 +17,8 @@ use Irstea\PlantUmlBundle\Model\NamespaceInterface;
  */
 class Trait_ extends BaseNode
 {
-    public function __construct(NamespaceInterface $namespace, $id, $label)
+    public function __construct(NamespaceInterface $namespace, $name)
     {
-        parent::__construct($namespace, $id, $label, 'class', [], ['trait']);
+        parent::__construct($namespace, $name, 'class', [], ['trait']);
     }
 }
-- 
GitLab