Commit bc58e9ca authored by Guillaume Perréal's avatar Guillaume Perréal
Browse files

Sépare le décorateur inheritance en plusieurs morceaux.

parent 93e12c5d
...@@ -15,7 +15,9 @@ use Irstea\PlantUmlBundle\Model\ClassVisitor; ...@@ -15,7 +15,9 @@ use Irstea\PlantUmlBundle\Model\ClassVisitor;
use Irstea\PlantUmlBundle\Model\Decorator\CompositeDecorator; use Irstea\PlantUmlBundle\Model\Decorator\CompositeDecorator;
use Irstea\PlantUmlBundle\Model\Decorator\FilteringDecorator; use Irstea\PlantUmlBundle\Model\Decorator\FilteringDecorator;
use Irstea\PlantUmlBundle\Model\Decorator\InheritanceDecorator; use Irstea\PlantUmlBundle\Model\Decorator\InheritanceDecorator;
use Irstea\PlantUmlBundle\Model\Decorator\InterfaceDecorator;
use Irstea\PlantUmlBundle\Model\Decorator\NullDecorator; use Irstea\PlantUmlBundle\Model\Decorator\NullDecorator;
use Irstea\PlantUmlBundle\Model\Decorator\TraitDecorator;
use Irstea\PlantUmlBundle\Model\DecoratorInterface; use Irstea\PlantUmlBundle\Model\DecoratorInterface;
use Irstea\PlantUmlBundle\Model\Filter\AcceptAllFilter; use Irstea\PlantUmlBundle\Model\Filter\AcceptAllFilter;
use Irstea\PlantUmlBundle\Model\Filter\Composite\AllFilter; use Irstea\PlantUmlBundle\Model\Filter\Composite\AllFilter;
...@@ -208,6 +210,12 @@ class GenerateCommand extends ContainerAwareCommand ...@@ -208,6 +210,12 @@ class GenerateCommand extends ContainerAwareCommand
case 'inheritance': case 'inheritance':
$decorators[] = new InheritanceDecorator(); $decorators[] = new InheritanceDecorator();
break; break;
case 'interfaces':
$decorators[] = new InterfaceDecorator();
break;
case 'traits':
$decorators[] = new TraitDecorator();
break;
case 'entity': case 'entity':
$decorators[] = new EntityDecorator($this->entityManager->getMetadataFactory()); $decorators[] = new EntityDecorator($this->entityManager->getMetadataFactory());
break; break;
......
...@@ -85,9 +85,9 @@ class Configuration implements ConfigurationInterface ...@@ -85,9 +85,9 @@ class Configuration implements ConfigurationInterface
->addDefaultsIfNotSet() ->addDefaultsIfNotSet()
->children() ->children()
->arrayNode('decorators') ->arrayNode('decorators')
->defaultValue(['inheritance', 'entity', 'associations', 'properties', 'methods']) ->defaultValue(['inheritance', 'traits', 'interfaces', 'entity', 'associations', 'properties', 'methods'])
->prototype('enum') ->prototype('enum')
->values(['inheritance', 'entity', 'associations', 'properties', 'methods']) ->values(['inheritance', 'traits', 'interfaces', 'entity', 'associations', 'properties', 'methods'])
->end() ->end()
->end() ->end()
->append($this->buildFilterNode('include')) ->append($this->buildFilterNode('include'))
......
<?php
/*
* © 2016 IRSTEA
* Guillaume Perréal <guillaume.perreal@irstea.fr>
* Tous droits réservés.
*/
namespace Irstea\PlantUmlBundle\Model\Decorator;
use Irstea\PlantUmlBundle\Model\ArrowInterface;
use Irstea\PlantUmlBundle\Model\ClassVisitorInterface;
use Irstea\PlantUmlBundle\Model\DecoratorInterface;
use Irstea\PlantUmlBundle\Model\NodeInterface;
/**
* Description of InheritanceDecorator
*
* @author Guillaume Perréal <guillaume.perreal@irstea.fr>
*/
abstract class AbstractRelationDecorator implements DecoratorInterface
{
/**
* @param NodeInterface $source
* @param array $classNames
* @param ClassVisitorInterface $visitor
*/
protected function visitRelations(NodeInterface $source, array $classNames, ClassVisitorInterface $visitor)
{
foreach ($classNames as $className) {
$target = $visitor->visitClass($className);
if ($target) {
$source->addArrow($this->buildRelation($source, $target));
}
}
}
/**
* @param NodeInterface $source
* @param NodeInterface $target
* @return ArrowInterface
*/
abstract protected function buildRelation(NodeInterface $source, NodeInterface $target);
}
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace Irstea\PlantUmlBundle\Model\Decorator; namespace Irstea\PlantUmlBundle\Model\Decorator;
use Irstea\PlantUmlBundle\Model\Arrow\ExtendsClass;
use Irstea\PlantUmlBundle\Model\ClassVisitor; use Irstea\PlantUmlBundle\Model\ClassVisitor;
use Irstea\PlantUmlBundle\Model\ClassVisitorInterface; use Irstea\PlantUmlBundle\Model\ClassVisitorInterface;
use Irstea\PlantUmlBundle\Model\DecoratorInterface; use Irstea\PlantUmlBundle\Model\DecoratorInterface;
...@@ -19,45 +20,18 @@ use ReflectionClass; ...@@ -19,45 +20,18 @@ use ReflectionClass;
* *
* @author Guillaume Perréal <guillaume.perreal@irstea.fr> * @author Guillaume Perréal <guillaume.perreal@irstea.fr>
*/ */
class InheritanceDecorator implements DecoratorInterface class InheritanceDecorator extends AbstractRelationDecorator
{ {
public function decorate(ReflectionClass $class, NodeInterface $node, ClassVisitorInterface $visitor) public function decorate(ReflectionClass $class, NodeInterface $node, ClassVisitorInterface $visitor)
{ {
$parent = $class->getParentClass(); $parent = $class->getParentClass();
$traits = $class->getTraitNames();
$interfaces = $class->getInterfaceNames();
$indirectInterfaces = array_filter(
array_map(
function ($i) { return $i->getInterfaceNames(); },
$class->getInterfaces()
)
);
if (!empty($indirectInterfaces)) {
$indirectInterfaces = call_user_func_array('array_merge', $indirectInterfaces);
$interfaces = array_diff($interfaces, $indirectInterfaces);
}
if ($parent) { if ($parent) {
$traits = array_diff($traits, $parent->getTraitNames()); $this->visitRelations($node, [$parent->getName()], $visitor);
$interfaces = array_diff($interfaces, $parent->getInterfaceNames());
$this->visitRelations($node, [$parent->getName()], 'Irstea\PlantUmlBundle\Model\Arrow\ExtendsClass', $visitor);
} }
$this->visitRelations($node, $interfaces, 'Irstea\PlantUmlBundle\Model\Arrow\ImplementsInterface', $visitor);
$this->visitRelations($node, $traits, 'Irstea\PlantUmlBundle\Model\Arrow\UsesTrait', $visitor);
return $this;
} }
protected function visitRelations(NodeInterface $source, array $classNames, $relationClass, ClassVisitorInterface $visitor) protected function buildRelation(NodeInterface $source, NodeInterface $target)
{ {
foreach ($classNames as $className) { return new ExtendsClass($source, $target);
$target = $visitor->visitClass($className);
if ($target) {
$source->addArrow(new $relationClass($source, $target));
}
}
} }
} }
<?php
/*
* © 2016 IRSTEA
* Guillaume Perréal <guillaume.perreal@irstea.fr>
* Tous droits réservés.
*/
namespace Irstea\PlantUmlBundle\Model\Decorator;
use Irstea\PlantUmlBundle\Model\Arrow\ImplementsInterface;
use Irstea\PlantUmlBundle\Model\ClassVisitorInterface;
use Irstea\PlantUmlBundle\Model\DecoratorInterface;
use Irstea\PlantUmlBundle\Model\NodeInterface;
use ReflectionClass;
/**
* Description of InheritanceDecorator
*
* @author Guillaume Perréal <guillaume.perreal@irstea.fr>
*/
class InterfaceDecorator extends AbstractRelationDecorator
{
public function decorate(ReflectionClass $class, NodeInterface $node, ClassVisitorInterface $visitor)
{
$interfaces = $class->getInterfaceNames();
$indirectInterfaces = array_filter(
array_map(
function ($i) { return $i->getInterfaceNames(); },
$class->getInterfaces()
)
);
if (!empty($indirectInterfaces)) {
$indirectInterfaces = call_user_func_array('array_merge', $indirectInterfaces);
$interfaces = array_diff($interfaces, $indirectInterfaces);
}
$parent = $class->getParentClass();
if ($parent) {
$interfaces = array_diff($interfaces, $parent->getInterfaceNames());
}
$this->visitRelations($node, $interfaces, $visitor);
return $this;
}
protected function buildRelation(NodeInterface $source, NodeInterface $target)
{
return new ImplementsInterface($source, $target);
}
}
<?php
/*
* © 2016 IRSTEA
* Guillaume Perréal <guillaume.perreal@irstea.fr>
* Tous droits réservés.
*/
namespace Irstea\PlantUmlBundle\Model\Decorator;
use Irstea\PlantUmlBundle\Model\Arrow\UsesTrait;
use Irstea\PlantUmlBundle\Model\ClassVisitorInterface;
use Irstea\PlantUmlBundle\Model\DecoratorInterface;
use Irstea\PlantUmlBundle\Model\NodeInterface;
use ReflectionClass;
/**
* Description of InheritanceDecorator
*
* @author Guillaume Perréal <guillaume.perreal@irstea.fr>
*/
class TraitDecorator extends AbstractRelationDecorator
{
public function decorate(ReflectionClass $class, NodeInterface $node, ClassVisitorInterface $visitor)
{
$traits = $class->getTraitNames();
$parent = $class->getParentClass();
if ($parent) {
$traits = array_diff($traits, $parent->getTraitNames());
}
$this->visitRelations($node, $traits, $visitor);
return $this;
}
protected function buildRelation(NodeInterface $source, NodeInterface $target)
{
return new UsesTrait($source, $target);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment