« The First Entry | Main | DSLs synergy »

May 04, 2006

MPS generators : weaving and mapping rules

One of the most interesting and powerfull parts of MPS is it's generators framework. Many EAP members would want to create their own generator for their languages but we don't have documentation about it now and existing generators aren't very easy to understand.

Recently I worked on support for SemanticWeb in MPS. Now we have language that correspond to OWL and RDF. In RDF all information is stored in triples of subject object and predicate for example MPS-authorIs-JetBrains. But this presenatation isn't very easy to work with from object oriented languages. We need something like OR mapping but instead of relational databases we have RDF triples files. Of course OWL classes are much richer than classes in Java but in simplest cases it's possible to generate stubs from them.

Lets consider the code that we want to generate. We have a RDF schema that looks like this in MPS editor:

schema.png

We want to generate code like this from this schema:

public class Issue {
  public static String ISSUE_PRIORITY = "issuePriority";
  ...

  public Instance myInstance;
  public SModelDescriptor mySchema;

  public Issue(SModelDescriptor schema, Instance instance) {
    this.myInstance = instance;
    this.mySchema = schema;
  }
  
  ...
  public void setTitle(String newValue) {
    SProperty property = OWLModelUtil.getSPropertyDeclaration(Issue.TITLE, this.mySchema.getSModel());
    Triple triple = OWLModelUtil.prepareTripleForSubjectAndPropertyInModel(this.myInstance.getModel(), this.myInstance, property);
    if(newValue == null) {
      newValue = "";
    }
    TextExpression textExpression = TextExpression.newInstance(this.myInstance.getModel());
    textExpression.setText(Parser.parseText(newValue, this.myInstance.getModel()));
    triple.setObject(textExpression);
  }
  public String getTitle() {
    SProperty property = OWLModelUtil.getSPropertyDeclaration(Issue.TITLE,this.mySchema.getSModel());
    Triple triple = OWLModelUtil.getPropertyValueTriple(this.myInstance, property);
    return OWLModelUtil.getTripleObjectString(triple);
  }
  ...
}

We generate stub java class for each OWL class and manager that will help us to create new instances of this class find them, delete them, etc. Instance here is an OWL instance. OWLModelUtil is utility class that helps us to work with triples. This code is trivial but we don't want to write it by hands. Code generation will work very well in this situation.

In MPS generators consist of three kinds of rules:

Lets look at rules of this generator:

rules.png

It has two mapping rules : one to generate OWL classes stubs and one for managers. Also it has two weaving rules to generate getters and setters of different kinds.

Each mapping rule has a query that finds nodes to generate from and template that is applied to each of source nodes. Both of our mapping rules have the same code :

  public static List templateMappingRule_SourceQuery_AllOWLClasses(ITemplateGenerator generator)  {
    List result = new ArrayList();
    result.addAll(SModelUtil.allNodes(generator.getSourceModel(), SClass.class, new Condition() {
      public boolean met(SClass object) {
        return !(object instanceof AnonymousSClass);
      }
    }));
    return result;
  }

Lets look at class stub template:

classStub.png

Lets look at manager template:

classManager.png

In this template some fragments of code marked with the sign $. This means that it'll be replaced with something that depends on context during generation. We have a lot of different kinds of macros but most important of them are property macros, reference macros and link macros.

We also have a weaving rules. Each weaving rule has a template and two queries. One query returns list of nodes that used for changing maing node. In our case it is a OWL property that'll getter and setter methods to class from its domain. Second query finds node that we'll change. It should return instance of INodeBuilder. In our case to each class we have one node builder (that builds java stub). Following code finds it :

  public static INodeBuilder templateWeavingRule_Context_weaving_OWLProperty_context(SNode sourceNode, ITemplateGenerator generator)  {
    SProperty property = (SProperty) sourceNode;
    SClassReference ref = (SClassReference) property.getDomain();
    return generator.findNodeBuilderForSource(ref.getReferentClass(), "classStub");
  }

Lets look closer to weaving rules template. They has slightly different structure than templates of mapping rules.

This is a template for simple property:

owlProperty.png

This is a template for text property:

owlTextProperty.png

Some parts of weaving rules templates are selected with <TF...TF>. This means that this parts of code will be inserted to its context.

Posted by Konstantin Solomatov at May 4, 2006 04:58 PM

Comments

Post a comment




Remember Me?