PCM Palladio Factory Builder для преобразования Модель-2-Модель в Xtend - PullRequest
0 голосов
/ 02 октября 2019

Я создал DSL в Xtext, и сейчас я работаю над созданием генератора кода в Xtend. Я реализую этот генератор кода, используя файл Xtend DslGenerator, который автоматически создается при «компиляции» DSL, определенного в Xtext. Пока все хорошо.

Я немного обошелся с языком Xtend и всеми его приятными функциями (включая выражения шаблонов), чтобы посмотреть, на что способен генератор кода. Я сделал несколько простых преобразований Модель-в-текст, и я не пытаюсь реализовать преобразования Модель-в-модель. Я хочу создать генератор кода, который позволит преобразовывать мои модели на основе DSL в модели PCM Palladio. Модель PCM Palladio - это платформа, используемая для моделирования и симуляции программного обеспечения. Частью фреймворка являются некоторые пакеты, которые позволяют программистам создавать экземпляры моделей PCM через фабрики моделей, генерируемые EMF (см. Их site ). Имейте в виду, что пример кода на их сайте в Java. Я скопировал и адаптировал этот код в своем генераторе кода Xtend, как показано ниже.

def builder () {
    var res = new XMLResourceImpl(URI.createFileURI("TestFile.txt"))
    var repository = RepositoryFactory.eINSTANCE.createRepository();
    repository.setEntityName("Repository containing other elements");
    // add root (repository) to resource:
    res.getContents().add(repository);

    var bc = RepositoryFactory.eINSTANCE.createBasicComponent();
    bc.setEntityName("My Basic Component");
    repository.getComponents__Repository().add(bc);  //add first class entity

    var myInterface = RepositoryFactory.eINSTANCE.createOperationInterface();
    myInterface.setEntityName("My Interface");
    repository.getInterfaces__Repository().add(myInterface); //add first class entity

    var opProvRole = RepositoryFactory.eINSTANCE.createOperationProvidedRole();
    opProvRole.setEntityName("Provided Role of Basic Component");

    // set the interface for the role:
    opProvRole.setProvidedInterface__OperationProvidedRole(myInterface);

    // set/add the role for basic component:
    bc.getProvidedRoles_InterfaceProvidingEntity().add(opProvRole);
    return repository
    }

Дело в том, что ожидаемый файл ("TestFile.txt") не появляется. Я пробовал множество способов заставить его работать, но я не уверен, как это реализовать. Преобразования модель-текст больше не являются проблемой, но преобразования модель-модель (с использованием фабрик компоновщика) в действительности еще не работают. Наконец, модель вывода должна выглядеть примерно так:XML-подобный файл, который может быть прочитан платформой Palladio PCM (приведенный ниже код является просто примером файла, который я создал вручную с помощью каркаса Palladio PCM).

<?xml version="1.0" encoding="UTF-8"?>
<repository:Repository xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:repository="http://palladiosimulator.org/PalladioComponentModel/Repository/5.2" xmlns:seff="http://palladiosimulator.org/PalladioComponentModel/SEFF/5.2" xmlns:stoex="http://sdq.ipd.uka.de/StochasticExpressions/2.2" id="_Gzo5EMuwEeOrXJYSTPO-kw" entityName="PcmStandardRepository" repositoryDescription="This projects holds a repository with a set of standard reusable software components and interfaces. These components and interfaces can be used across multiple projects to ease starting modeling.">
  <components__Repository xsi:type="repository:BasicComponent" id="_li9tIMuwEeOrXJYSTPO-kw" entityName="Cache">
    <providedRoles_InterfaceProvidingEntity xsi:type="repository:OperationProvidedRole" id="_n1kB4MuwEeOrXJYSTPO-kw" entityName="Provided_IRequest_Cache" providedInterface__OperationProvidedRole="_H-m3YMuwEeOrXJYSTPO-kw"/>
    <requiredRoles_InterfaceRequiringEntity xsi:type="repository:OperationRequiredRole" id="_oWqj0MuwEeOrXJYSTPO-kw" entityName="Required_IRequest_Cache" requiredInterface__OperationRequiredRole="_H-m3YMuwEeOrXJYSTPO-kw"/>
    <serviceEffectSpecifications__BasicComponent xsi:type="seff:ResourceDemandingSEFF" id="_n1qIgMuwEeOrXJYSTPO-kw" describedService__SEFF="_JcqJwMuwEeOrXJYSTPO-kw">
      <steps_Behaviour xsi:type="seff:StartAction" id="_n1qIgcuwEeOrXJYSTPO-kw" entityName="start" successor_AbstractAction="_IyWWkMuyEeOrXJYSTPO-kw"/>
      <steps_Behaviour xsi:type="seff:StopAction" id="_n1qIgsuwEeOrXJYSTPO-kw" entityName="stop" predecessor_AbstractAction="__PBwwMuyEeOrXJYSTPO-kw"/>
      <steps_Behaviour xsi:type="seff:InternalAction" id="_IyWWkMuyEeOrXJYSTPO-kw" entityName="CacheLookup" predecessor_AbstractAction="_n1qIgcuwEeOrXJYSTPO-kw" successor_AbstractAction="_Sz5UAMuyEeOrXJYSTPO-kw">
        <resourceDemand_Action>
          <specification_ParametericResourceDemand specification="1"/>
          <requiredResource_ParametricResourceDemand href="pathmap://PCM_MODELS/Palladio.resourcetype#_oro4gG3fEdy4YaaT-RYrLQ"/>
        </resourceDemand_Action>
      </steps_Behaviour>
      <steps_Behaviour xsi:type="seff:BranchAction" id="_Sz5UAMuyEeOrXJYSTPO-kw" entityName="CacheHitMiss" predecessor_AbstractAction="_IyWWkMuyEeOrXJYSTPO-kw" successor_AbstractAction="__PBwwMuyEeOrXJYSTPO-kw">
        <branches_Branch xsi:type="seff:ProbabilisticBranchTransition" id="_WyeCYMuyEeOrXJYSTPO-kw" entityName="CacheHit" branchProbability="0.8">
          <branchBehaviour_BranchTransition id="_WyeCYcuyEeOrXJYSTPO-kw">
            <steps_Behaviour xsi:type="seff:StartAction" id="_WykJAMuyEeOrXJYSTPO-kw" successor_AbstractAction="_WykJAcuyEeOrXJYSTPO-kw"/>
            <steps_Behaviour xsi:type="seff:StopAction" id="_WykJAcuyEeOrXJYSTPO-kw" predecessor_AbstractAction="_WykJAMuyEeOrXJYSTPO-kw"/>
          </branchBehaviour_BranchTransition>
        </branches_Branch>
        <branches_Branch xsi:type="seff:ProbabilisticBranchTransition" id="_ZbkyoMuyEeOrXJYSTPO-kw" entityName="CacheMiss" branchProbability="0.2">
          <branchBehaviour_BranchTransition id="_ZbkyocuyEeOrXJYSTPO-kw">
            <steps_Behaviour xsi:type="seff:StartAction" id="_ZbkyosuyEeOrXJYSTPO-kw" successor_AbstractAction="_ovu5MMuyEeOrXJYSTPO-kw"/>
            <steps_Behaviour xsi:type="seff:StopAction" id="_Zbkyo8uyEeOrXJYSTPO-kw" predecessor_AbstractAction="_ovu5MMuyEeOrXJYSTPO-kw"/>
            <steps_Behaviour xsi:type="seff:ExternalCallAction" id="_ovu5MMuyEeOrXJYSTPO-kw" predecessor_AbstractAction="_ZbkyosuyEeOrXJYSTPO-kw" successor_AbstractAction="_Zbkyo8uyEeOrXJYSTPO-kw" calledService_ExternalService="_JcqJwMuwEeOrXJYSTPO-kw" role_ExternalService="_oWqj0MuwEeOrXJYSTPO-kw">
              <inputVariableUsages__CallAction>
                <variableCharacterisation_VariableUsage type="VALUE">
                  <specification_VariableCharacterisation specification="requestType.VALUE"/>
                </variableCharacterisation_VariableUsage>
                <namedReference__VariableUsage xsi:type="stoex:VariableReference" referenceName="requestType"/>
              </inputVariableUsages__CallAction>
              <returnVariableUsage__CallReturnAction>
                <variableCharacterisation_VariableUsage type="VALUE">
                  <specification_VariableCharacterisation specification="RETURN.VALUE"/>
                </variableCharacterisation_VariableUsage>
                <namedReference__VariableUsage xsi:type="stoex:VariableReference" referenceName="externalCallResponse"/>
              </returnVariableUsage__CallReturnAction>
            </steps_Behaviour>
          </branchBehaviour_BranchTransition>
        </branches_Branch>
      </steps_Behaviour>
      <steps_Behaviour xsi:type="seff:SetVariableAction" id="__PBwwMuyEeOrXJYSTPO-kw" entityName="setReturnValue" predecessor_AbstractAction="_Sz5UAMuyEeOrXJYSTPO-kw" successor_AbstractAction="_n1qIgsuwEeOrXJYSTPO-kw">
        <localVariableUsages_SetVariableAction>
          <variableCharacterisation_VariableUsage type="VALUE">
            <specification_VariableCharacterisation specification="externalCallResponse.VALUE"/>
          </variableCharacterisation_VariableUsage>
          <namedReference__VariableUsage xsi:type="stoex:VariableReference" referenceName="RETURN"/>
        </localVariableUsages_SetVariableAction>
      </steps_Behaviour>
    </serviceEffectSpecifications__BasicComponent>
  </components__Repository>
  <components__Repository xsi:type="repository:BasicComponent" id="_KpCn4MuxEeOrXJYSTPO-kw" entityName="StandardForwardingComponent">
    <providedRoles_InterfaceProvidingEntity xsi:type="repository:OperationProvidedRole" id="_Ljy_8MuxEeOrXJYSTPO-kw" entityName="Provided_IRequest_Forwarder" providedInterface__OperationProvidedRole="_H-m3YMuwEeOrXJYSTPO-kw"/>
    <requiredRoles_InterfaceRequiringEntity xsi:type="repository:OperationRequiredRole" id="_MD1x8MuxEeOrXJYSTPO-kw" entityName="Required_IRequest_Forwarder" requiredInterface__OperationRequiredRole="_H-m3YMuwEeOrXJYSTPO-kw"/>
    <serviceEffectSpecifications__BasicComponent xsi:type="seff:ResourceDemandingSEFF" id="_Ljy_8cuxEeOrXJYSTPO-kw" describedService__SEFF="_JcqJwMuwEeOrXJYSTPO-kw">
      <steps_Behaviour xsi:type="seff:StartAction" id="_Ljy_8suxEeOrXJYSTPO-kw" entityName="start" successor_AbstractAction="_d2mo8MuxEeOrXJYSTPO-kw"/>
      <steps_Behaviour xsi:type="seff:StopAction" id="_Ljy_88uxEeOrXJYSTPO-kw" entityName="stop" predecessor_AbstractAction="_lJaIMMuxEeOrXJYSTPO-kw"/>
      <steps_Behaviour xsi:type="seff:ExternalCallAction" id="_Mps4EMuxEeOrXJYSTPO-kw" predecessor_AbstractAction="_d2mo8MuxEeOrXJYSTPO-kw" successor_AbstractAction="_lJaIMMuxEeOrXJYSTPO-kw" calledService_ExternalService="_JcqJwMuwEeOrXJYSTPO-kw" role_ExternalService="_MD1x8MuxEeOrXJYSTPO-kw">
        <inputVariableUsages__CallAction>
          <variableCharacterisation_VariableUsage type="VALUE">
            <specification_VariableCharacterisation specification="requestType.VALUE"/>
          </variableCharacterisation_VariableUsage>
          <namedReference__VariableUsage xsi:type="stoex:VariableReference" referenceName="requestType"/>
        </inputVariableUsages__CallAction>
        <returnVariableUsage__CallReturnAction>
          <variableCharacterisation_VariableUsage type="VALUE">
            <specification_VariableCharacterisation specification="RETURN.VALUE"/>
          </variableCharacterisation_VariableUsage>
          <namedReference__VariableUsage xsi:type="stoex:VariableReference" referenceName="externalCallResponse"/>
        </returnVariableUsage__CallReturnAction>
      </steps_Behaviour>
      <steps_Behaviour xsi:type="seff:InternalAction" id="_d2mo8MuxEeOrXJYSTPO-kw" entityName="ComponentRessourceUsage" predecessor_AbstractAction="_Ljy_8suxEeOrXJYSTPO-kw" successor_AbstractAction="_Mps4EMuxEeOrXJYSTPO-kw">
        <resourceDemand_Action>
          <specification_ParametericResourceDemand specification="0"/>
          <requiredResource_ParametricResourceDemand href="pathmap://PCM_MODELS/Palladio.resourcetype#_oro4gG3fEdy4YaaT-RYrLQ"/>
        </resourceDemand_Action>
        <resourceDemand_Action>
          <specification_ParametericResourceDemand specification="0"/>
          <requiredResource_ParametricResourceDemand href="pathmap://PCM_MODELS/Palladio.resourcetype#_BIjHoQ3KEdyouMqirZIhzQ"/>
        </resourceDemand_Action>
      </steps_Behaviour>
      <steps_Behaviour xsi:type="seff:SetVariableAction" id="_lJaIMMuxEeOrXJYSTPO-kw" entityName="setReturnValue" predecessor_AbstractAction="_Mps4EMuxEeOrXJYSTPO-kw" successor_AbstractAction="_Ljy_88uxEeOrXJYSTPO-kw">
        <localVariableUsages_SetVariableAction>
          <variableCharacterisation_VariableUsage type="VALUE">
            <specification_VariableCharacterisation specification="externalCallResponse.VALUE"/>
          </variableCharacterisation_VariableUsage>
          <namedReference__VariableUsage xsi:type="stoex:VariableReference" referenceName="RETURN"/>
        </localVariableUsages_SetVariableAction>
      </steps_Behaviour>
      <resourceDemandingInternalBehaviours id="_IXB-DoxVEemBWcwyLC2p7g"/>
    </serviceEffectSpecifications__BasicComponent>
  </components__Repository>
  <components__Repository xsi:type="repository:BasicComponent" id="_SQwdkMxpEeOx-JIRUcYdjg" entityName="LoadBalancer2x">
    <providedRoles_InterfaceProvidingEntity xsi:type="repository:OperationProvidedRole" id="_V0b_sMxpEeOx-JIRUcYdjg" entityName="Provided_IRequest_LoadBalancer2x" providedInterface__OperationProvidedRole="_H-m3YMuwEeOrXJYSTPO-kw"/>
    <requiredRoles_InterfaceRequiringEntity xsi:type="repository:OperationRequiredRole" id="_USYXEMxpEeOx-JIRUcYdjg" entityName="Required_IRequest_LoadBalancer2x_Port01" requiredInterface__OperationRequiredRole="_H-m3YMuwEeOrXJYSTPO-kw"/>
    <requiredRoles_InterfaceRequiringEntity xsi:type="repository:OperationRequiredRole" id="_Ux2hUMxpEeOx-JIRUcYdjg" entityName="Required_IRequest_LoadBalancer2x_Port02" requiredInterface__OperationRequiredRole="_H-m3YMuwEeOrXJYSTPO-kw"/>
    <serviceEffectSpecifications__BasicComponent xsi:type="seff:ResourceDemandingSEFF" id="_V0iGUMxpEeOx-JIRUcYdjg" describedService__SEFF="_JcqJwMuwEeOrXJYSTPO-kw">
      <steps_Behaviour xsi:type="seff:StartAction" id="_V0iGUcxpEeOx-JIRUcYdjg" entityName="start" successor_AbstractAction="_YLD40MxpEeOx-JIRUcYdjg"/>
      <steps_Behaviour xsi:type="seff:StopAction" id="_V0iGUsxpEeOx-JIRUcYdjg" entityName="stop" predecessor_AbstractAction="_YLD40MxpEeOx-JIRUcYdjg"/>
      <steps_Behaviour xsi:type="seff:BranchAction" id="_YLD40MxpEeOx-JIRUcYdjg" entityName="RandomlyChoseRequiredPorts" predecessor_AbstractAction="_V0iGUcxpEeOx-JIRUcYdjg" successor_AbstractAction="_V0iGUsxpEeOx-JIRUcYdjg">
        <branches_Branch xsi:type="seff:ProbabilisticBranchTransition" id="_de5xAMxpEeOx-JIRUcYdjg" entityName="CallPort01" branchProbability="0.5">
          <branchBehaviour_BranchTransition id="_de5xAcxpEeOx-JIRUcYdjg">
            <steps_Behaviour xsi:type="seff:StartAction" id="_de_3oMxpEeOx-JIRUcYdjg" successor_AbstractAction="_ei6LsMxpEeOx-JIRUcYdjg"/>
            <steps_Behaviour xsi:type="seff:StopAction" id="_de_3ocxpEeOx-JIRUcYdjg" predecessor_AbstractAction="_ei6LsMxpEeOx-JIRUcYdjg"/>
            <steps_Behaviour xsi:type="seff:ExternalCallAction" id="_ei6LsMxpEeOx-JIRUcYdjg" predecessor_AbstractAction="_de_3oMxpEeOx-JIRUcYdjg" successor_AbstractAction="_de_3ocxpEeOx-JIRUcYdjg" calledService_ExternalService="_JcqJwMuwEeOrXJYSTPO-kw" role_ExternalService="_USYXEMxpEeOx-JIRUcYdjg">
              <inputVariableUsages__CallAction>
                <variableCharacterisation_VariableUsage type="VALUE">
                  <specification_VariableCharacterisation specification="requestType.VALUE"/>
                </variableCharacterisation_VariableUsage>
                <namedReference__VariableUsage xsi:type="stoex:VariableReference" referenceName="requestType"/>
              </inputVariableUsages__CallAction>
            </steps_Behaviour>
          </branchBehaviour_BranchTransition>
        </branches_Branch>
        <branches_Branch xsi:type="seff:ProbabilisticBranchTransition" id="_lVrgAMxpEeOx-JIRUcYdjg" entityName="CallPort02" branchProbability="0.5">
          <branchBehaviour_BranchTransition id="_lVrgAcxpEeOx-JIRUcYdjg">
            <steps_Behaviour xsi:type="seff:StartAction" id="_lVrgAsxpEeOx-JIRUcYdjg" successor_AbstractAction="_miRO8MxpEeOx-JIRUcYdjg"/>
            <steps_Behaviour xsi:type="seff:StopAction" id="_lVrgA8xpEeOx-JIRUcYdjg" predecessor_AbstractAction="_miRO8MxpEeOx-JIRUcYdjg"/>
            <steps_Behaviour xsi:type="seff:ExternalCallAction" id="_miRO8MxpEeOx-JIRUcYdjg" predecessor_AbstractAction="_lVrgAsxpEeOx-JIRUcYdjg" successor_AbstractAction="_lVrgA8xpEeOx-JIRUcYdjg" calledService_ExternalService="_JcqJwMuwEeOrXJYSTPO-kw" role_ExternalService="_Ux2hUMxpEeOx-JIRUcYdjg">
              <inputVariableUsages__CallAction>
                <variableCharacterisation_VariableUsage type="VALUE">
                  <specification_VariableCharacterisation specification="requestType.VALUE"/>
                </variableCharacterisation_VariableUsage>
                <namedReference__VariableUsage xsi:type="stoex:VariableReference" referenceName="requestType"/>
              </inputVariableUsages__CallAction>
            </steps_Behaviour>
          </branchBehaviour_BranchTransition>
        </branches_Branch>
      </steps_Behaviour>
    </serviceEffectSpecifications__BasicComponent>
  </components__Repository>
  <interfaces__Repository xsi:type="repository:OperationInterface" id="_H-m3YMuwEeOrXJYSTPO-kw" entityName="IRequest">
    <signatures__OperationInterface id="_JcqJwMuwEeOrXJYSTPO-kw" entityName="processRequest">
      <parameters__OperationSignature parameterName="requestType">
        <dataType__Parameter xsi:type="repository:PrimitiveDataType" href="pathmap://PCM_MODELS/PrimitiveTypes.repository#//@dataTypes__Repository.1"/>
      </parameters__OperationSignature>
      <returnType__OperationSignature xsi:type="repository:PrimitiveDataType" href="pathmap://PCM_MODELS/PrimitiveTypes.repository#//@dataTypes__Repository.0"/>
    </signatures__OperationInterface>
  </interfaces__Repository>
</repository:Repository>

РЕДАКТИРОВАТЬ до первого ответа Лоренцо:

Привет, Лоренцо, спасибо за ответ. Я решил несколько вещей и сумел создать функцию modelBuilder, которая теперь может создавать модели репозитория PCM Palladio. Код функции и модель, сгенерированная с помощью этой функции, показаны ниже. Хорошо, что созданная модель является «допустимой» моделью репозитория (она соответствует синтаксису, как показано на примере модели, которую я первоначально разместил). Тем не менее, PCM Palladio требует другую модель .repository_diagram для редактирования модели в среде графического моделирования. Если теперь я щелкну на сгенерированной модели, чтобы открыть ее в редакторе диаграмм моделей репозитория PCM, я получу сообщение об ошибке: «Не удается открыть элемент ввода, в ресурсе нет диаграммы». Знаете ли вы (или кто-либо еще), как я могу создать «полную» модель хранилища PCM вместе со всеми необходимыми ей моделями, чтобы сгенерированные модели можно было открывать и редактировать с помощью редакторов моделей Graphical PCM?

Код функции modelBuilder:

def modelBuilder () {

        // This part of the code is still a bit unclear for me.
    var injector = new FinalDslStandaloneSetup().createInjectorAndDoEMFRegistration()
    var resourceSet = injector.getInstance(ResourceSet)
    EcoreUtil.resolveAll(resourceSet)

        //Create repository to store Model Elemenents (BasicComponents, Operation Interfaces etc.)
    var repositoryResult = new XMLResourceImpl()
    var repository = RepositoryFactory.eINSTANCE.createRepository
    repository.setEntityName("Repository containing other elements")

        // add root (repository) to resource:
    repositoryResult.getContents().add(repository)

    var bc = RepositoryFactory.eINSTANCE.createBasicComponent()
    bc.setEntityName("My Basic Component")
        //add first class entity
    repository.getComponents__Repository().add(bc)  

    var myInterface = RepositoryFactory.eINSTANCE.createOperationInterface()
    myInterface.setEntityName("My Interface")
        //add first class entity
    repository.getInterfaces__Repository().add(myInterface); 

    var opProvRole = RepositoryFactory.eINSTANCE.createOperationProvidedRole()
    opProvRole.setEntityName("Provided Role of Basic Component")

        // set the interface for the role:
    opProvRole.setProvidedInterface__OperationProvidedRole(myInterface)

        // set/add the role for basic component:
    bc.getProvidedRoles_InterfaceProvidingEntity().add(opProvRole)

        // Save the repositoryResult in
    var location2 = URI.createURI("platform:/resource/finaldsl/TestRepository.repository")
    var xmiResource2 = resourceSet.createResource(location2)
        xmiResource2.getContents().add(repositoryResult.getContents().get(0))
        xmiResource2.save(null)

}

Модель репозитория PCM Palladio, сгенерированная с помощью функции modelBuilder:

<?xml version="1.0" encoding="ASCII"?>
<repository:Repository xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:repository="http://palladiosimulator.org/PalladioComponentModel/Repository/5.2" id="_urk-0OYtEem_g6oW0m4J9A" entityName="Repository containing other elements">
  <components__Repository xsi:type="repository:BasicComponent" id="_urk-0eYtEem_g6oW0m4J9A" entityName="My Basic Component">
    <providedRoles_InterfaceProvidingEntity xsi:type="repository:OperationProvidedRole" id="_urk-0-YtEem_g6oW0m4J9A" entityName="Provided Role of Basic Component" providedInterface__OperationProvidedRole="_urk-0uYtEem_g6oW0m4J9A"/>
  </components__Repository>
  <interfaces__Repository xsi:type="repository:OperationInterface" id="_urk-0uYtEem_g6oW0m4J9A" entityName="My Interface"/>
</repository:Repository>

Правка второго ответа Лорценцо:

/*
 * generated by Xtext 2.17.1
 */
package org.xtext.example.mydsl.generator

import org.eclipse.emf.common.util.URI
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.emf.ecore.resource.ResourceSet
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl
import org.eclipse.emf.ecore.util.EcoreUtil
import org.eclipse.xtext.generator.AbstractGenerator
import org.eclipse.xtext.generator.IFileSystemAccess2
import org.eclipse.xtext.generator.IGeneratorContext
import org.palladiosimulator.pcm.repository.RepositoryFactory
import org.xtext.example.mydsl.FinalDslStandaloneSetup

/**
 * Generates code from your model files on save.
 * 
 * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation
 */
class FinalDslGenerator extends AbstractGenerator {


override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context ) {

    // Method call to build and store PCM Palladio repository. Rigt click on the repository file
    // to create a .repository_diagram file to 'graphically' view and edit the repostiry accordingly.
    RepositoryBuilder()

    // Method call to build and store your modelled DSL instance accordingly. Mind that this has nothing
    // to do with the creation of the PCM Palladio repository above, but it might come in handy if you want
    // to export your DSL instances (for use outside of the xText IDE environment).
    ModelXMLBuilder(resource)

    }

def RepositoryBuilder () {

    var repository = RepositoryFactory.eINSTANCE.createRepository
    repository.setEntityName("Repository containing other elements")

    // add root (repository) to resource:
    var bc = RepositoryFactory.eINSTANCE.createBasicComponent()
    bc.setEntityName("My Basic Component")
    repository.getComponents__Repository().add(bc)  //add first class entity

    var myInterface = RepositoryFactory.eINSTANCE.createOperationInterface()
    myInterface.setEntityName("My Interface")
    repository.getInterfaces__Repository().add(myInterface); //add first class entity

    var opProvRole = RepositoryFactory.eINSTANCE.createOperationProvidedRole()
    opProvRole.setEntityName("Provided Role of Basic Component")

    // set the interface for the role:
    opProvRole.setProvidedInterface__OperationProvidedRole(myInterface)

    // set/add the role for basic component:
    bc.getProvidedRoles_InterfaceProvidingEntity().add(opProvRole)

    var storeURI = URI.createURI("platform:/resource/finaldsl/src-gen/TestRepository.repository")
    var result = new ResourceSetImpl().createResource(storeURI)
        result.getContents().add(repository)
        result.save(null)
    }


def ModelXMLBuilder (Resource dslInstance) {
    var injector = new FinalDslStandaloneSetup().createInjectorAndDoEMFRegistration()
    var resourceSet = injector.getInstance(ResourceSet)

    dslInstance.load(null)
    EcoreUtil.resolveAll(resourceSet)

    var location = URI.createURI("platform:/resource/finaldsl/src-gen/DSL-XMI-Model.xmi")       
    var xmiResource = resourceSet.createResource(location)
        xmiResource.getContents().add(dslInstance.getContents().get(0))
        xmiResource.save(null)
    }
}
...