PCM Palladio Factory Builder for Model-2-Model transformation in Xtend - xtext

I have created a DSL in Xtext and I am now working on creating a code generator in Xtend. I implement this code generator using the DslGenerator Xtend file which is automatically created when 'compiling' the DSL defined in Xtext. So far so good.
I screwed around a bit with the Xtend language and all it's nice features (including template expressions) to see what the code generator is capable of. I did some simple Model-to-Text transformations, and I am not trying to implement Model-to-Model transformations. I want to create a code generator that allows to transform my DSL-based models to PCM Palladio Models. The PCM Palladio model is a framework used for modelling and simulating software. Part of the framework are some packages which allow programmers to instantiate PCM models through EMF-generated model factories (see their site). Mind that the code example on their site is in Java. I have copied and adapted this code in my Xtend code generator as can be seen below.
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
}
The thing is that the file I expect to appear ("TestFile.txt") does not appear. I have tried numerous ways to get it to work, but I am not sure on how to implement this. Model-to-Text transformations are not a problem anymore, but Model-to-Model transformations (using builder factories) are not really working yet. The output model finally has to be something like the code below; an XML-like file which can be read by Palladio PCM framework (the code below is just an example of a file I created manually with the Palladio PCM framework).
<?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>
EDIT to Lorenzo's first answer:
Hi Lorenzo thanks for answering. I have solved a few things and have managed to create a modelBuilder function now which can create PCM Palladio repository models now. The code of the function, and the model that is generated through this function are shown below. The good thing is that the created model is a 'valid' repository model (it complies with the syntax as illustrated by the example model that I initially posted). However, PCM Palladio requires another .repository_diagram model to edit the model in the graphical modelling environment. If I now click on the generated model to open it with the PCM Repository Model Diagram editor, I get the error message: 'Cannot open input element, Resource contains no diagram'. Do you know (or anyone else) how I can create a 'full' PCM repository model together with all of its required models, so that the generated models can be opened and edited with the Graphical PCM model editors?
Code of modelBuilder function:
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 repository model that is generated through the modelBuilder function:
<?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>
Edit to Lorzenzo's second answer:
/*
* 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)
}
}

Related

Which settings should be used for TokensregexNER

When I try regexner it works as expected with the following settings and data;
props.setProperty("annotators", "tokenize, cleanxml, ssplit, pos, lemma, regexner");
Bachelor of Laws DEGREE
Bachelor of (Arts|Laws|Science|Engineering|Divinity) DEGREE
What I would like to do is that using TokenRegex. For example
Bachelor of Laws DEGREE
Bachelor of ([{tag:NNS}] [{tag:NNP}]) DEGREE
I read that to do this, I should use TokensregexNERAnnotator.
I tried to use it as follows, but it did not work.
Pipeline.addAnnotator(new TokensRegexNERAnnotator("expressions.txt", true));
Or I tried setting annotator in another way,
props.setProperty("annotators", "tokenize, cleanxml, ssplit, pos, lemma, tokenregexner");
props.setProperty("customAnnotatorClass.tokenregexner", "edu.stanford.nlp.pipeline.TokensRegexNERAnnotator");
I tried to different TokenRegex formats but either annotator could not find the expression or I got SyntaxException.
What is the proper way to use TokenRegex (query on tokens with tags) on NER data file ?
BTW I just see a comment in TokensRegexNERAnnotator.java file. Not sure if it is related pos tags does not work with RegexNerAnnotator.
if (entry.tokensRegex != null) {
// TODO: posTagPatterns...
pattern = TokenSequencePattern.compile(env, entry.tokensRegex);
}
First you need to make a TokensRegex rule file (sample_degree.rules). Here is an example:
ner = { type: "CLASS", value: "edu.stanford.nlp.ling.CoreAnnotations$NamedEntityTagAnnotation" }
{ pattern: (/Bachelor/ /of/ [{tag:NNP}]), action: Annotate($0, ner, "DEGREE") }
To explain the rule a bit, the pattern field is specifying what type of pattern to match. The action field is saying to annotate every token in the overall match (that is what $0 represents), annotate the ner field (note that we specified ner = ... in the rule file as well, and the third parameter is saying set the field to the String "DEGREE").
Then make this .props file (degree_example.props) for the command:
customAnnotatorClass.tokensregex = edu.stanford.nlp.pipeline.TokensRegexAnnotator
tokensregex.rules = sample_degree.rules
annotators = tokenize,ssplit,pos,lemma,ner,tokensregex
Then run this command:
java -Xmx8g edu.stanford.nlp.pipeline.StanfordCoreNLP -props degree_example.props -file sample-degree-sentence.txt -outputFormat text
You should see that the three tokens you wanted tagged as "DEGREE" will be tagged.
I think I will push a change to the code to make tokensregex link to the TokensRegexAnnotator so you won't have to specify it as a custom annotator.
But for now you need to add that line in the .props file.
This example should help in implementing this. Here are some more resources if you want to learn more:
http://nlp.stanford.edu/software/tokensregex.shtml#TokensRegexRules
http://nlp.stanford.edu/nlp/javadoc/javanlp/edu/stanford/nlp/ling/tokensregex/SequenceMatchRules.html
http://nlp.stanford.edu/nlp/javadoc/javanlp/edu/stanford/nlp/ling/tokensregex/types/Expressions.html

how to create project hierarchical view in pyqt inside main window

I'm trying to implement a project structure viewer to view the structure of a specific programming language. and this project structure view should look like a the tree widget in PyQT , like project explorer in Eclipse.
Example:
if my code is :
rule Adzok
{
meta:
author = " Kevin Breen <kevin#techanarchy.net>"
Description = "Adzok Rat"
Versions = "Free 1.0.0.3,"
strings:
$a1 = "config.xmlPK"
$a2 = "key.classPK"
$a3 = "svd$1.classPK"
condition:
7 of ($a*)
}
Check the figure below.

Porting old MDX code

I'm porting some old MDX code to SharpDX using Direct3D9 assemblies.
I was able to 'convert' most of the code to SharpDX but I'm stuck at the following:
Mesh result = Mesh.Cylinder(_device, _arrowRadius1, _arrowRadius2, _arrowLength, _arrowNumberOfSlices, _arrowNumberOfStacks);
Mesh result = Mesh.Box(_device, _axisLength, _axisThick, _axisThick);
Mesh.TextFromFont(_device, new System.Drawing.Font("Berlin Sans FB", 12), text, 5f, 0.2f);
The mesh class exists but does not contain the Cylinder or Box methods. I've gone through tons of documentation and could not find a solution.
Apart from the problem with the Mesh class I could not find matching classes and methods for the following in SharpDX:
using (Surface backbuffer = _device.GetBackBuffer(0, 0))
{
GraphicsStream stream = SurfaceLoader.SaveToStream(ImageFileFormat.Bmp, backbuffer);
return new Bitmap(stream);
}
GraphicStream and SurfaceLoader do not exist.
i had similar problem proting from old Managed Microsoft.DirectX to SharpDx9.
For Meshes we had to implement our own Mesh classes since there are no pritives like cylinder, sphere or box in SharpDx.Mesh (its just a mock class i guess).
But for SurfaceLoader check Surface class itself it has static methods that will probably match your needs. For example:
Surface.ToStream()

Rails Microsoft Word, XML databinding, repeat rows

Those willing to jump straight to my questions can go to the paragraph "Please help with". You will find there my beginning of implementation, along with short XML samples
The story
The famous problem of inserting repeating content, like table rows, into a word template, using the rails framework.
I decided to implement a 'cleaner' solution for replacing some variables in a Word document with rails, using XML databinding. This solution works very well for non-repetitive content, but for repetitive content, a little extra dirty work must be done and I need help with it.
No C#, No Visual, just plain olde ruby on rails & XML
The databinded document
I have a Word document with some content controls, tagged with "human-readable" text, so my users know what should be inside.
I have used Word 2007 Content Control Toolkit to add some custom XML to a .docx file. Therefore in each .docx I have some customXml/itemsx.xml that contains my custom XML.
I have manually databinded this XML to text content control I have in my word template, using drag & drop with Word 2007 Content Control Toolkit.
The replacing process with nokogiri
Basically I already have some code that replaces every XML node by the corresponding value from a hash. For example if I provide this hash to my function :
variables = {
"some_xml-node" => "some_value"
}
It will properly replace XML in customXml/itemsx.xml of .docx file :
<root> <some> <xml-node>some_value</xml-node></some> </root>
So this is taken care of !
The repetitive content
Now as I said, this works perfectly for non-repetitive content. For repetitive content (in my case I want to repeat some <w:tr> in a document), the solution I'd like to go with, is
Manually insert some tags in word/document.xml of .docx file (this is dirty, but hell I can't think of anything else) before every <tr> that needs to be duplicated
In rails, parse the XML and locate the <tr> that needs duplicating using Nokogiri
Copy the tr as many times as I need
Look at some text inside this <tr>, find the databinding (which looks like <w:dataBinding w:xpath="/root[1]/movies[1]/movie[1]/name[1]"
Replace movie[1] by movie[index]
Repeat for every table that needs <tr> duplication
With this solution Therefore I ensure 100% compatibility with my existing system ! It's some kind of preprocessing...
Please help with
Finding an XML comment containing a custom string, and selecting the node just below it (using Nokogiri)
Changing attributes in many sub-nodes of the node found in 1.
XML/Hash samples that could be used (my beginning of implementation after that):
Sample of .docx word/document.xml
<w:document>
<!-- My_Custom_Tag_ID -->
<w:tr someparam="something">
<w:td></w:td>
<w:td><w:sthelse></w:sthelse><w:dataBinding w:xpath="/root[1]/movies[1]/movie[1]/name[1]><w:sth>Value</w:sth></w:td>
<w:td></<:td>
</w:tr>
</w:document>
Sample of input parameter repeat_tag hash
repeat_tags_sample = [
{
"tag" => "My_Custom_Tag_ID",
"repeatable-content" => "movie"
},
{
"tag" => "My_Custom_Tag_ID_2",
"repeatable-content" => "cartoons"
}
]
Sample of input parameter contents hash
contents_sample =
{
"movies" => [{"name" => "X-Men",
"year" => 1998,
"property-xxx" => 42
}, { "name" => "X-Men-4",
"year" => 2007,
"property-xxx" => 42
}],
"cartoons" => [{"name" => "Tom_Jerry",
"year" => 1995,
"property-yyy" => "cat"
}, { "name" => "Random_name",
"year" => 2008,
"property-yyy" => 42
}]
}
My beginning of implementation :
def dynamic_table_content(zip, repeat_tags, contents)
doc = zip.find_entry("word/document.xml")
xml = Nokogiri::XML.parse(doc.get_input_dtream)
# repeat_tags_sample = [ {
# "tag" => My_Custom_Tag_ID",
# "repeatable-content" => "movie"},
# ...]
repeat_tags.each do |rpt|
content = contents[rpt[:repeatable-content]]
# content now looks like [
# {"name" => "X-Men",
# "year" => 1998,
# "property-xxx" => 42, ...},
# ...]
content_name = rpt[:repeateable_content].to_s
# the 'movie' of '/root[1]/movies[1]/movie[1]/name[1]' (see below)
puts "Processing #{rpt[:tag]}, adding #{content_name}s"
# Word document.xml sample code looks like this :
# <!-- My_Custom_Tag_ID_inserted_manually -->
# <w:tr ...>
# ...
# <w:dataBinding w:xpath="/root[1]/movies[1]/movie[1]/name[1]>
# ...
# </w:tr>
Find a comment containing a custom string, and select the node just below
# Find starting <w:tr > tag located after <!-- rpt[:tag] -->
base_tr_node = find the node after
# Duplicate it as many times as we want.
content.each_with_index do |content, index|
puts "Adding #{content_name} : #{content}.to_s"
new_tr_node = base_tr_node.add_next_sibling(base_tr_node)
# inside this new node there are many
# <w:dataBinding w:xpath="/root[1]/movies[1]/movie[1]/name[1]>
# <w:dataBinding w:xpath="/root[1]/movies[1]/movie[1]/year[1]>
# ..../movie[1]/property-xxx[1]
# GOAL : replace every movie[1] by movie[index]
Change attributes in many sub-nodes of the node found in 1.
new_tr_node.change_attributes as shown in (see GOAL in previous comments)
# Maybe, it would be something like
# new_tr_node.gsub("(#{content_name})\[([1-9]+)\]", "\1\[#{index}\]")
# ... But new_tr_node is a nokogiri element so .gsub doesn't exist
end
end
#replace["word/document.xml"] = xml.serialize :save_zip_with => 0
end
I have looked at the DoPE extension for Word documents. It looks great ! But alas I had already done a lot of work, and just now I (almost) finished building my own preprocessor.
What I needed was more complicated than what I originally asked. But nevertheless, the answers would be :
EDIT : fixed bad regex/xpath
# 1. Find a comment containing a custom string, and select the node just below
comment_nodes = doc.xpath("//comment()")
# Loop like comment_nodes.each do |comment|
base_tr_node = comment.next_sibling.next_sibling
# For some reason, need to apply next_sibling twice, thought the comment is indeed just above the <w:tr> node
# 2. Change attributes in many sub-nodes of the node found in 1.
matches = tr_node.search('.//*[name()='w:dataBinding']')
matches.each do |databinding_node|
# replace '.*phase[1].*' by '.*phase[index].*'
databinding_node['w:xpath'].gsub("#{comment.text}\[1\]", "#{comment.text}\[#{index}\]")
end

Unable to append a sheet using OpenXml with F# (FSharp)

The CreateSpreadsheetWorkbook example method from the OpenXml documentation does translate directly to F#. The problem seems to be the Append method of the Sheets object. The code executes without error, but the resulting xlsx file is missing the inner Xml which should have been appended, and the file is unreadable by Excel. I suspect the problem stems from the conversion of functional F# structures into a System.Collections type, but I do not have direct evidence for this.
I have run similar code in C# and VB.NET (i.e. the documentation example) and it executes perfectly and creates a readable, complete xlsx file.
I know that I could deal with the XML directly, but I would like to understand the nature of the mismatch between F# and OpenXml. Any suggestions?
The code is almost directly from the example:
namespace OpenXmlLib
open System
open DocumentFormat
open DocumentFormat.OpenXml
open DocumentFormat.OpenXml.Packaging
open DocumentFormat.OpenXml.Spreadsheet
module OpenXmlXL =
// this function overwrites an existing file without warning!
let CreateSpreadsheetWorkbook (filepath: string) =
// Create a spreadsheet document by supplying the filepath.
// By default, AutoSave = true, Editable = true, and Type = xlsx.
let spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook)
// Add a WorkbookPart to the document.
let workbookpart = spreadsheetDocument.AddWorkbookPart()
workbookpart.Workbook <- new Workbook()
// Add a WorksheetPart to the WorkbookPart.
let worksheetPart = workbookpart.AddNewPart<WorksheetPart>()
worksheetPart.Worksheet <- new Worksheet(new SheetData())
// Add Sheets to the Workbook.
let sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets())
// Append a new worksheet and associate it with the workbook.
let sheet = new Sheet()
sheet.Id <- stringValue(spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart))
//Console.WriteLine(sheet.Id.Value)
sheet.SheetId <- UInt32Value(1u)
// Console.WriteLine(sheet.SheetId.Value)
sheet.Name <- StringValue("TestSheet")
//Console.WriteLine(sheet.Name.Value)
sheets.Append (sheet)
// Console.WriteLine("Sheets: {0}", sheets.InnerXml.ToString())
workbookpart.Workbook.Save()
spreadsheetDocument.Close()
The sheet is created, but empty:
sheet.xml:
<?xml version="1.0" encoding="utf-8" ?>
<x:worksheet xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main" />
workbook.xml:
<?xml version="1.0" encoding="utf-8" ?>
- <x:workbook xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
- <x:sheets>
<x:sheet name="TestSheet" sheetId="1" r:id="R263eb6f245a2497e" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" />
</x:sheets>
</x:workbook>
The problem is very subtle, and is in your calls to the Worksheet constructor and the Sheets.Append method. Both of these methods are overloaded, and can take either a seq<OpenXmlElement> or any number of individual OpenXmlElements (via a [<System.ParamArray>]/params array). The twist is that the OpenXmlElement type itself implements the seq<OpenXmlElement> interface.
In C#, when you call new Worksheet(new SheetData()), the compiler's overload resolution picks the second of the overloads, implicitly creating a one-element array containing the SheetData value. However, in F#, since the SheetData class implements IEnumerable<OpenXmlElement>, the first overload is chosen, which creates a new WorkSheet by enumerating the contents of the SheetData, which is not what you want.
To fix this, you need to set up your calls so that they use the other overload (first example below) or explicitly create a singleton sequence (second example below):
worksheetPart.Worksheet <- new Worksheet(new SheetData() :> OpenXmlElement)
...
sheets.Append([sheet :> OpenXmlElement])

Resources