Esempio n. 1
0
 /**
  * @param string $ramlFile
  */
 public function generateRest($ramlFile, Local $directoryOutput)
 {
     $parser = new Parser();
     try {
         /*
          * file di routing symfony
          * @var array
          */
         $routing = [];
         /*
          * Mappa delle proprieta dei controller da generare
          * @var array
          */
         $mappaClassDef = [];
         $this->apiDef = $parser->parse($ramlFile);
         $this->logger->info('Title: ' . $this->apiDef->getTitle());
         $baseUrl = $this->apiDef->getBaseUrl();
         $parametriBaseUrl = $this->apiDef->getBaseUriParameters();
         /** @var \Raml\BaseUriParameter $definition */
         foreach ($parametriBaseUrl as $varName => $definition) {
             if (!array_key_exists($varName, $this->mapExternalInfo)) {
                 $this->error('Missing: ' . $varName . ' -> ' . $definition->getDescription());
                 $this->mapExternalInfo[$varName] = 'undefined';
             }
             $baseUrl = str_replace($varName, $this->mapExternalInfo[$varName], $baseUrl);
         }
         $this->info('BaseUrl ' . $baseUrl);
         //corrisponde a host: "{subdomain}.example.com" dentro routing.yml
         $enabledProtocols = $this->apiDef->getProtocols();
         //serve per fare controlli su http/https -> schemes:  [https] dentro routing.yml
         $infoSecuritySchema = $this->apiDef->getSecuredBy();
         // descrive i vari security schema usati nelle varie risorse
         /* @var: \Raml\Resource[] */
         $resources = $this->apiDef->getResources();
         $namespace = $this->bundleName . '\\Controller';
         /** @var: \Raml\Resource $resource */
         foreach ($resources as $resource) {
             $displayName = $resource->getDisplayName();
             $this->info('Controller per path: ' . $displayName);
             $names = explode('/', $displayName);
             preg_match_all("/(\\/{[a-zA-Z]+}(\\/)?)+/i", $displayName, $methodParam);
             array_walk($names, [$this, 'removeGraph']);
             $className = implode('', $names);
             $methods = $resource->getMethods();
             if (count($methods) > 0) {
                 /** @var \Raml\Method $method */
                 foreach ($methods as $method) {
                     $controllerName = ucfirst($className);
                     // Creo $appBundle / $workspace Controller . php
                     $this->info('Genera: ' . $namespace . $controllerName . 'Controller');
                     $controllerProperties = [];
                     $controllerProperties['name'] = $controllerName . 'Controller';
                     $controllerProperties['namespace'] = $namespace;
                     $controllerProperties['extend'] = 'Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller';
                     $methodListParams = implode(',', $methodParam[0]);
                     $type = strtolower($method->getType());
                     $methodCallName = $type . $controllerName;
                     $actionName = $methodCallName . 'Action';
                     $this->info('Call Method: ' . $actionName . '(' . $methodListParams . ')');
                     $controllerProperties['methods'] = [];
                     $controllerProperties['methods'][$actionName] = [];
                     $controllerProperties['methods'][$actionName]['params'] = [];
                     $description = $method->getDescription();
                     $this->info('Description: ' . $description);
                     $entryName = strtolower($className) . '_' . $type;
                     $routing[$entryName]['path'] = $displayName;
                     $routing[$entryName]['defaults']['_controller'] = $this->bundleName . ':' . $controllerName . ':' . $methodCallName;
                     $routing[$entryName]['host'] = $baseUrl;
                     $routing[$entryName]['methods'] = [];
                     $routing[$entryName]['methods'][] = strtoupper($type);
                     $routing[$entryName]['schemas'] = $enabledProtocols;
                     $routing[$entryName]['requirements'] = [];
                     $routing[$entryName]['requirements'][] = 'FIXME';
                     $mappaClassDef[$controllerName . 'Controller'] = $controllerProperties;
                 }
                 //fine methods
             }
             /* @var \Raml\Resource $subResources */
             $subResources = $resource->getResources();
             foreach ($subResources as $subResource) {
                 //$this->analyzeResource($subResource, $directoryOutput);
                 //// SAMPLE:
                 // /Workspace GET => Workspace/GetWorkspace.php
                 // /Workspace POST => Workspace/POSTWorkspace.php
                 // /Workspace/{id} GET => Workspace/GetWorkspaceById.php
             }
         }
         //fine reousrces
         $indent = 4;
         $inline = 2;
         $yaml = new Dumper($indent);
         $this->currentFile = $yaml->dump($routing, $inline, 0, 0);
         $this->_createFileOnDir($directoryOutput, $this->bundleName . '/Resources/config/routing.yml');
         foreach ($mappaClassDef as $className => $controllerProp) {
             $this->info('Devo creare ' . $className);
             $gClassgen = new ClassGenerator($namespace, $className);
             $gClassgen->setLogger($this->logger);
             $config = new ClassConfig();
             $typesReferenceArray = [];
             $typesDescArray = [];
             $gClassgen->generateClassType($controllerProp, $typesReferenceArray, $typesDescArray, $config);
             $gClassgen->createFileOnDir($directoryOutput);
         }
         $this->info('Scrittura su ' . $directoryOutput);
     } catch (InvalidJsonException $e) {
         $this->error('[' . $e->getErrorCode() . '] ' . $e->getMessage());
         $this->error($e->getTraceAsString());
     } catch (RamlParserException $e) {
         $this->error('[' . $e->getErrorCode() . '] ' . $e->getMessage());
     }
 }
Esempio n. 2
0
 private function compareFileGenerated($resourcesDir, $namespace, $className, ClassGenerator $gClassgen)
 {
     $directoryOutput = $this->generateDestDir($namespace);
     $gClassgen->createFileOnDir(new VfsAdapter($directoryOutput, 0));
     $this->compareClassPhp($resourcesDir, $namespace, $className, $directoryOutput);
 }
Esempio n. 3
0
 /**
  * [generate description].
  *
  * @param Local $directoryOutput directory where write generated class
  */
 public function generate(Local $directoryOutput)
 {
     //$is_constructor_enable = true;
     //$ddd_is_root_aggregate = false;
     $specListClasses = $this->rym->getClassesDefinition();
     foreach ($specListClasses as $className => $properties) {
         $this->info('Generate class', ['class' => $className]);
         //, 'properties' => $properties
         if (!array_key_exists('ddd', $properties)) {
             $this->error('missing ddd section into yml for class', ['class' => $className]);
             $this->errors[] = 'missing ddd section into yml for class ' . $className;
             $this->info('force ' . $className . ' to type class');
             $properties['ddd'] = [];
             $properties['ddd']['type'] = 'class';
         }
         $namespace = '';
         if (array_key_exists('namespace', $properties)) {
             $namespace = $properties['namespace'];
         }
         $classComments = 'No comment found on ddd model';
         if (array_key_exists('description', $properties)) {
             $classComments = $properties['description'];
             $this->info('Found description :' . $classComments);
         }
         //FIXME: switch with $dddType as key
         $generated = false;
         $dddType = $properties['ddd']['type'];
         if (in_array($dddType, ['interface'])) {
             $g = new ClassGenerator($namespace, $className, $classComments);
             $g->setLogger($this->logger);
             $config = new ClassConfig();
             $config->isInterface = true;
             $g->generateClassType($properties, $this->modelClass, $this->modelComments, $config);
             $g->createFileOnDir($directoryOutput);
             $generated = true;
             //FIXME: use $g for determinate! -> take error from generator
             if ($generated) {
                 $this->fieldsClass[$namespace . '\\' . $className] = $properties['fields'];
                 //ONLY IF VALID!!!
             }
             // DOMANDA: perche' non passarle tutte??
             // if (array_key_exists('fields', $properties)) {
             //     $types_field[$className] = $properties['fields'];
             // }
             // $this->generateClassType($fileInterface, $interface, $properties, $types_reference, $types_description, false, true, true, false, false, $filesystem, $io);
         }
         // NOTE: class aren't ddd type, we haven't section on ddd definition
         if (in_array($dddType, ['class'])) {
             $g = new ClassGenerator($namespace, $className, $classComments);
             $g->setLogger($this->logger);
             $config = new ClassConfig();
             $config->isInterface = false;
             $config->haveConstructor = true;
             $g->generateClassType($properties, $this->modelClass, $this->modelComments, $config);
             $g->createFileOnDir($directoryOutput);
             $generated = true;
             //FIXME: use $g for determinate! -> take error from generator
             if ($generated) {
                 $this->fieldsClass[$namespace . '\\' . $className] = $properties['fields'];
                 //ONLY IF VALID!!!
             }
             // DOMANDA: perche' non passarle tutte??
             // if (array_key_exists('fields', $properties)) {
             //     $types_field[$className] = $properties['fields'];
             // }
             // $this->generateClassType($fileInterface, $interface, $properties, $types_reference, $types_description, false, true, true, false, false, $filesystem, $io);
         }
         if (in_array($dddType, ['events'])) {
             //FIXME: impossible! events exist in relation on aggregateRoot
             $this->error('events exist in relation on aggregateRoot', ['class' => $className]);
             $this->errors[] = 'events exist in relation on aggregateRoot, event class ' . $className . ' cannot exist!';
         }
         if (!$generated) {
             $dddDefinition = $this->rym->getDomainDefinitionAttributes($dddType);
             if (is_null($dddDefinition)) {
                 $this->error('Missing ddd reference for : ' . $dddType . ' into ' . $className, ['class' => $className]);
                 $this->errors[] = 'Missing ddd reference for : ' . $dddType . ' into ' . $className;
             } else {
                 if (array_key_exists('package', $dddDefinition)) {
                     $namespace = $dddDefinition['package'];
                 }
                 if (empty($namespace)) {
                     $this->error('Missing namespace', ['class' => $className]);
                     $this->errors[] = 'Missing namespace for ' . $className;
                 }
                 $createGetter = false;
                 $createSetter = false;
                 if (array_key_exists('getter', $dddDefinition)) {
                     $createGetter = $dddDefinition['getter'];
                 }
                 if (array_key_exists('setter', $dddDefinition)) {
                     $createSetter = $dddDefinition['setter'];
                 }
                 $isRootAggregate = $dddType == 'aggregate' && isset($properties['ddd']['root']) && boolval($properties['ddd']['root']) ? true : false;
                 $this->info('Method required', ['class' => $className, 'getter' => $createGetter, 'setter' => $createSetter, 'aggregateRoot' => $isRootAggregate]);
                 if (array_key_exists('extend', $dddDefinition)) {
                     $dddExtendDefinition = $dddDefinition['extend'];
                     if (!array_key_exists('extend', $properties)) {
                         $properties['extend'] = $dddExtendDefinition;
                         //No multi-inheritance
                     }
                 }
                 $dddReferenceFields = [];
                 if (array_key_exists('fields', $dddDefinition)) {
                     foreach ($dddDefinition['fields'] as $key => $value) {
                         $dddReferenceFields[$key] = $value;
                     }
                 }
                 //TODO: gestire gli [] dentro la definizione del modello se serve...
                 //TODO: aggiungere le validazioni
                 // validationRule:
                 //   events:
                 //     create:
                 //       fields: [ id, sessione, tipologiaCampo]
                 //     delete:
                 //       fields: [ id ]
                 //     addDocument:
                 //       fields: [ id, documentoCorrelato ]
                 if (array_key_exists('events', $properties)) {
                     //genero altre classi per ogni evento!
                     $eventsProperties = $this->rym->getDomainDefinitionAttributes('events');
                     $eventsNamespace = $eventsProperties['package'];
                     $eventsImplement = '';
                     if (array_key_exists('implement', $eventsProperties)) {
                         $eventsImplement = $eventsProperties['implement'];
                     }
                     $eventsExtend = '';
                     if (array_key_exists('extend', $eventsProperties)) {
                         $eventsExtend = $eventsProperties['extend'];
                     }
                     if (!array_key_exists($eventsImplement, $this->modelClass)) {
                         $this->error('Missing implement class ' . $eventsImplement, ['class' => $className]);
                         $this->errors[] = 'Missing implement ' . $eventsImplement . ' for ' . $className;
                         continue;
                     }
                     $namespaceImplementClass = $this->modelClass[$eventsImplement];
                     $eventsImplementFull = $namespaceImplementClass . '\\' . $eventsImplement;
                     $eventsField = [];
                     if (array_key_exists('fields', $eventsProperties)) {
                         foreach ($eventsProperties['fields'] as $key => $value) {
                             $eventsField[$key] = $value;
                         }
                     }
                     //field's inheritance
                     if (array_key_exists($eventsImplementFull, $this->fieldsClass)) {
                         $fieldsImplementClass = $this->fieldsClass[$eventsImplementFull];
                         foreach ($fieldsImplementClass as $key => $value) {
                             $eventsField[$key] = $value;
                         }
                     }
                     $eventsToCreate = [];
                     if (array_key_exists('events', $properties)) {
                         $eventsToCreate = $properties['events'];
                     }
                     if (array_key_exists('events', $dddDefinition)) {
                         $eventsToCreate = array_merge($dddDefinition['events'], $eventsToCreate);
                     }
                     foreach ($eventsToCreate as $event) {
                         $eventClassName = $className . str_replace('_', '', ucwords($event, '_')) . 'Event';
                         $eventClassComments = 'Event ' . $event . ' for Aggregate Root ' . $className;
                         $propertiesEventClass = [];
                         if (!empty($eventsExtend)) {
                             $propertiesEventClass['extend'] = $eventsExtend;
                         }
                         if (!empty($eventsImplement)) {
                             $propertiesEventClass['implements'] = $eventsImplementFull;
                         }
                         $propertiesEventClass['fields'] = $eventsField;
                         $this->info('Create Event', ['event' => $event, 'class' => $className, 'extend' => $eventsExtend, 'implement' => $eventsImplementFull, 'fields' => $eventsField]);
                         $g = new ClassGenerator($eventsNamespace, $eventClassName, $eventClassComments);
                         $g->setLogger($this->logger);
                         $config = new ClassConfig();
                         $config->isInterface = false;
                         $config->haveConstructor = true;
                         $config->isFinalClass = true;
                         //don't wnat cycle dependency
                         $config->haveGetter = true;
                         $config->haveSetter = false;
                         $g->generateClassType($propertiesEventClass, $this->modelClass, $this->modelComments, $config);
                         $g->createFileOnDir($directoryOutput);
                         $generated = true;
                     }
                     if ($generated) {
                         $this->fieldsClass[$namespace . '\\' . $className] = $eventsField;
                         //ONLY IF VALID!!!
                     }
                 }
                 if (array_key_exists('enum', $properties)) {
                     $enumClassList = $properties['enum'];
                     foreach ($enumClassList as $enumClassName) {
                         $enumNamespace = $namespace . '\\' . $className;
                         $propertiesEnumClass = ['extend' => $namespace . '\\' . $className];
                         $actionName = 'instance';
                         $propertiesEnumClass['methods'] = [];
                         $propertiesEnumClass['methods'][$actionName] = [];
                         $propertiesEnumClass['methods'][$actionName]['params'] = [];
                         $propertiesEnumClass['methods'][$actionName]['static'] = true;
                         $propertiesEnumClass['methods'][$actionName]['@return'] = $enumNamespace . '\\' . $enumClassName;
                         $body = 'self::$instance = new ' . $enumClassName . '();';
                         $body .= 'return self::$instance;';
                         $propertiesEnumClass['methods'][$actionName]['body'] = $body;
                         //TODO: pensare se qui va bene cosi... potrebbe il ClassGenerator sapere come fare questo costruttore?
                         $actionName = '__construct';
                         $propertiesEnumClass['methods'][$actionName] = [];
                         $propertiesEnumClass['methods'][$actionName]['visibility'] = 'private';
                         $propertiesEnumClass['methods'][$actionName]['params'] = [];
                         $propertiesEnumClass['methods'][$actionName]['static'] = false;
                         $propertiesEnumClass['methods'][$actionName]['description'] = 'costruttore';
                         $body = '$this->name = \'' . $enumClassName . '\';';
                         $propertiesEnumClass['methods'][$actionName]['body'] = $body;
                         $enumClassComments = 'Child of ' . $className . ' ' . $enumClassName;
                         $g = new ClassGenerator($enumNamespace, $enumClassName, $enumClassComments);
                         $g->setLogger($this->logger);
                         $configEnum = new ClassConfig();
                         $configEnum->isInterface = false;
                         $configEnum->haveConstructor = true;
                         $configEnum->isFinalClass = true;
                         //don't wnat cycle dependency
                         $configEnum->haveGetter = true;
                         $configEnum->haveSetter = false;
                         $g->generateClassType($propertiesEnumClass, $this->modelClass, $this->modelComments, $configEnum);
                         $g->createFileOnDir($directoryOutput);
                         $generated = true;
                     }
                     $properties['fields']['name'] = ['primitive' => 'string', 'description' => 'nome esplicativo della enum', 'getter' => true];
                     $config = new ClassConfig();
                     $config->isInterface = false;
                     $config->haveConstructor = false;
                     $config->isFinalClass = false;
                     $config->isEnum = true;
                     $config->haveGetter = $createGetter;
                     $config->haveSetter = $createSetter;
                 } else {
                     $config = new ClassConfig();
                     $config->isInterface = false;
                     $config->haveConstructor = true;
                     $config->isFinalClass = true;
                     //don't wnat cycle dependency
                     $config->haveGetter = $createGetter;
                     $config->haveSetter = $createSetter;
                 }
                 //NORMAL GENERATION
                 $g = new ClassGenerator($namespace, $className, $classComments);
                 $g->setLogger($this->logger);
                 $g->generateClassType($properties, $this->modelClass, $this->modelComments, $config);
                 $g->createFileOnDir($directoryOutput);
                 $generated = true;
             }
         }
         if ($generated) {
             $this->modelClass[$className] = $namespace;
             $this->modelComments[$className] = $classComments;
         }
     }
     //end class generation
 }