/** * @param string $content * * @return Model * */ public static function parse($content) { $content = Yaml::parse($content); $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('model'); $rootNode->normalizeKeys(false)->children()->scalarNode('name')->end()->scalarNode('desc')->defaultNull()->end()->arrayNode('internal-systems')->normalizeKeys(false)->prototype('array')->children()->scalarNode('name')->end()->scalarNode('desc')->defaultNull()->end()->arrayNode('containers')->normalizeKeys(false)->prototype('array')->children()->scalarNode('name')->end()->scalarNode('desc')->defaultNull()->end()->scalarNode('type')->defaultNull()->end()->arrayNode('uses')->normalizeKeys(false)->prototype('array')->children()->scalarNode('for')->defaultNull()->end()->scalarNode('type')->defaultNull()->end()->end()->end()->end()->end()->end()->end()->end()->end()->end()->arrayNode('external-systems')->normalizeKeys(false)->prototype('array')->children()->scalarNode('name')->end()->scalarNode('desc')->defaultNull()->end()->arrayNode('uses')->normalizeKeys(false)->prototype('array')->children()->scalarNode('for')->defaultNull()->end()->scalarNode('type')->defaultNull()->end()->end()->end()->end()->end()->end()->end()->arrayNode('internal-users')->normalizeKeys(false)->prototype('array')->children()->scalarNode('name')->end()->scalarNode('desc')->defaultNull()->end()->arrayNode('uses')->normalizeKeys(false)->prototype('array')->children()->scalarNode('for')->defaultNull()->end()->scalarNode('type')->defaultNull()->end()->end()->end()->end()->end()->end()->end()->arrayNode('external-users')->normalizeKeys(false)->prototype('array')->children()->scalarNode('name')->end()->scalarNode('desc')->defaultNull()->end()->arrayNode('uses')->normalizeKeys(false)->prototype('array')->children()->scalarNode('for')->defaultNull()->end()->scalarNode('type')->defaultNull()->end()->end()->end()->end()->end()->end()->end()->end(); $processor = new Processor(); $modelContent = $processor->process($treeBuilder->buildTree(), $content); /** @var ElementInterface[] $elements */ $elements = []; // create model $model = new Model($modelContent['name'], $modelContent['desc']); // parse internal systems foreach ($modelContent['internal-systems'] as $internalSystemId => $internalSystemContent) { $internalSystem = new InternalSystem($internalSystemId, $internalSystemContent['name'], $internalSystemContent['desc']); foreach ($internalSystemContent['containers'] as $containerId => $containerContent) { $container = new Container($containerId, $containerContent['name'], $containerContent['desc'], $containerContent['type']); $internalSystem->addContainer($container); $elements[$container->getId()] = $container; } $model->addInternalSystem($internalSystem); } // parse external systems foreach ($modelContent['external-systems'] as $externalSystemId => $externalSystemContent) { $externalSystem = new ExternalSystem($externalSystemId, $externalSystemContent['name'], $externalSystemContent['desc']); $model->addExternalSystem($externalSystem); $elements[$externalSystem->getId()] = $externalSystem; } // parse internal users foreach ($modelContent['internal-users'] as $internalUserId => $internalUserContent) { $internalUser = new InternalUser($internalUserId, $internalUserContent['name'], $internalUserContent['desc']); $model->addInternalUser($internalUser); $elements[$internalUser->getId()] = $internalUser; } // parse external users foreach ($modelContent['external-users'] as $externalUserId => $externalUserContent) { $externalUser = new ExternalUser($externalUserId, $externalUserContent['name'], $externalUserContent['desc']); $model->addExternalUser($externalUser); $elements[$externalUser->getId()] = $externalUser; } // parse usages in internal systems foreach ($modelContent['internal-systems'] as $internalSystemId => $internalSystemContent) { foreach ($internalSystemContent['containers'] as $containerId => $containerContent) { foreach ($containerContent['uses'] as $targetId => $usageContent) { $usage = new Usage($elements[$targetId], $usageContent['for'], $usageContent['type']); $elements[$containerId]->uses($usage); } } } // parse usages in external systems foreach ($modelContent['external-systems'] as $externalSystemId => $externalSystemContent) { foreach ($externalSystemContent['uses'] as $targetId => $usageContent) { $usage = new Usage($elements[$targetId], $usageContent['for'], $usageContent['type']); $elements[$externalSystemId]->uses($usage); } } // parse usages in internal users foreach ($modelContent['internal-users'] as $internalUserId => $internalUserContent) { foreach ($internalUserContent['uses'] as $targetId => $usageContent) { $usage = new Usage($elements[$targetId], $usageContent['for'], $usageContent['type']); $elements[$internalUserId]->uses($usage); } } // parse usages in external users foreach ($modelContent['external-users'] as $externalUserId => $externalUserContent) { foreach ($externalUserContent['uses'] as $targetId => $usageContent) { $usage = new Usage($elements[$targetId], $usageContent['for'], $usageContent['type']); $elements[$externalUserId]->uses($usage); } } return $model; }
/** * @param Model $model * @param string $mode * @param array $internalSystemIds * @param array $highlights * * @return Graph */ public function generate(Model $model, $mode = self::MODE_ALL, array $internalSystemIds = [], array $highlights = []) { $elementsNodes = []; $requiredElementsIds = []; $connections = []; $graph = Graph::create('model'); // add internal systems with container view foreach ($model->getInternalSystems() as $internalSystem) { if (self::MODE_SELECTIVE === $mode && !in_array($internalSystem->getId(), $internalSystemIds)) { continue; } $internalSystemGraph = $this->createInternalSystemGraph($internalSystem); $graph->addGraph($internalSystemGraph); foreach ($internalSystem->getContainers() as $container) { $highlight = false; if (in_array($container->getId(), $highlights)) { $highlight = true; } $containerNode = $this->createContainerNode($container, $highlight); $elementsNodes[$container->getId()] = $containerNode; $internalSystemGraph->setNode($containerNode); foreach ($container->getUsages() as $usage) { $connections[$container->getId()][$usage->getTarget()->getId()][] = $usage; } } } // collect connections from external systems foreach ($model->getExternalSystems() as $externalSystem) { foreach ($externalSystem->getUsages() as $usage) { if (in_array($usage->getTarget()->getId(), array_keys($elementsNodes))) { $connections[$externalSystem->getId()][$usage->getTarget()->getId()][] = $usage; } } } // collect connections from internal systems foreach ($model->getInternalSystems() as $internalSystem) { foreach ($internalSystem->getContainers() as $container) { if (in_array($container->getId(), array_keys($elementsNodes))) { continue; } foreach ($container->getUsages() as $usage) { if (in_array($usage->getTarget()->getId(), array_keys($elementsNodes))) { $connections[$container->getId()][$usage->getTarget()->getId()][] = $usage; } } } } // collect connections from external users foreach ($model->getExternalUsers() as $externalUser) { foreach ($externalUser->getUsages() as $usage) { if (in_array($usage->getTarget()->getId(), array_keys($elementsNodes))) { $connections[$externalUser->getId()][$usage->getTarget()->getId()][] = $usage; } } } // collect connections from internal users foreach ($model->getInternalUsers() as $internalUser) { foreach ($internalUser->getUsages() as $usage) { if (in_array($usage->getTarget()->getId(), array_keys($elementsNodes))) { $connections[$internalUser->getId()][$usage->getTarget()->getId()][] = $usage; } } } // summarise required elements foreach ($connections as $elementId => $usages) { $requiredElementsIds = array_merge($requiredElementsIds, [$elementId], array_keys($usages)); } // add nodes for internal users foreach ($model->getInternalUsers() as $internalUser) { if (in_array($internalUser->getId(), $requiredElementsIds)) { $highlight = false; if (in_array($internalUser->getId(), $highlights)) { $highlight = true; } $internalUserNode = $this->createInternalUserNode($internalUser, $highlight); $graph->setNode($internalUserNode); $elementsNodes[$internalUser->getId()] = $internalUserNode; } } // add nodes for external users foreach ($model->getExternalUsers() as $externalUser) { if (in_array($externalUser->getId(), $requiredElementsIds)) { $highlight = false; if (in_array($externalUser->getId(), $highlights)) { $highlight = true; } $externalUserNode = $this->createExternalUserNode($externalUser, $highlight); $graph->setNode($externalUserNode); $elementsNodes[$externalUser->getId()] = $externalUserNode; } } // add nodes for external systems foreach ($model->getExternalSystems() as $externalSystem) { if (in_array($externalSystem->getId(), $requiredElementsIds)) { $highlight = false; if (in_array($externalSystem->getId(), $highlights)) { $highlight = true; } $externalSystemNode = $this->createExternalSystemNode($externalSystem, $highlight); $graph->setNode($externalSystemNode); $elementsNodes[$externalSystem->getId()] = $externalSystemNode; } } // add nodes for internal systems foreach ($model->getInternalSystems() as $internalSystem) { $createInternalSystemNode = null; $highlight = false; foreach ($internalSystem->getContainers() as $container) { if (in_array($container->getId(), array_keys($elementsNodes))) { continue; } if (in_array($container->getId(), $requiredElementsIds)) { $createInternalSystemNode = true; if (in_array($container->getId(), $highlights)) { $highlight = true; } } if (true === $createInternalSystemNode) { $internalSystemNode = $this->createInternalSystemNode($internalSystem, $highlight); $graph->setNode($internalSystemNode); $elementsNodes[$container->getId()] = $internalSystemNode; } } } // create edges foreach ($connections as $sourceElementId => $targetElements) { foreach ($targetElements as $targetElementId => $usages) { $highlight = false; if (in_array($sourceElementId, $highlights) || in_array($targetElementId, $highlights)) { $highlight = true; } $edge = $this->createConnectionEdge($elementsNodes[$sourceElementId], $elementsNodes[$targetElementId], $usages, $highlight); $graph->link($edge); } } return $graph; }