Skip to main content
Jump to: navigation, search

MWE The Big Picture

The purpose of MWE is to help orchestrate and configure code generation 'workflows'. Just like with compilers a code generator can and should be splitted into several single parts, each part doing a specific job. Such parts could be:

  • parsing / loading model
  • validating model
  • linking model
  • transforming model
  • modifying model
  • generating code out of a model

Typically there are a couple of component fulfilling such jobs included in a generator (compiler-chain), where each needs additional component-specific configuration. Also there are different solutions for each job. For instance modeltransformation can be done using QVT, ATL or Xtend, each need different configuration.

Configuration language

The description of a generator workflow is made of a sequence of declared concrete components (e.g. EMFResourceLoaderComponent, EValidationComponent, JetComponent, XpandComponent, etc.) where each is configured.

For instance an EMFResourceLoaderComponent would need the URIs to the resources to be loaded and optionally respective ResourceFactory configuration, because workflows are run in standalone mode most of the time. XpandComponent needs to know what kind of TypeAdapter to use, where to generate the different files, how to postprocess them, etc.

Essentially such a description is sequence of components where each component, can be configured with arbitrary complex components itself. Example:

EmfResourceLoaderComponent {
  platformRoot = ".."
  uri = "platform:/resource/foo/bar/model.dsl"
  extensionToFactoryMap += { 
     ext="dsl" 
     factory= MySpecialDSLResourceFactory {
        someAdditionalConfig = "foobar"
     }
  } 
}

Previously this has been configured via XML :

<component class="EmfResourceLoaderComponent"
   platformRoot = ".."
   uri = "platform:/resource/foo/bar/model.dsl">
  <extensionToFactoryMap ext="dsl">
      <factory class="MySpecialDSLResourceFactory" 
               someAdditionalConfig="foo"/>
  </extensionToFactoryMap>
</component>

No matter what syntax being used, the core concepts remain. This part (the language) don't need to know anything about what to instantiate. The only interface to the configuration is Java reflection.

Runtime Workflow Model

For a wokflow in order to being executable, we need some kind of interface to the different components. Such an interface defines a main 'execute' method and optionally additional life cycle callback methods (like preconfigure, postconfigure, preExecute,etc.) In the past we used an interface called WorkflowComponent, having two methods : checkConfiguration(), invoke(). Also there is a workflowcontext (essentially a hashmap) being passed into the invoke method, so the different components can communicate some how. One component puts the model into a slot another reads it from there, transforms it and writes the oiutcome to another slot. And so on...

We also introduced a so called CompositeComponent, which is just a composite node being able to hold a sequence of WorkflowComponent.

The runtime workflow model could provide additional things like

  • A way to execute multiple components in parallel
  • A way to conditionally execute components

Contribution from bug

Back to the top