Model Transformations in Practice

Ken Webb 2010-04-26T18:20:38Z

The Model Transformations in Practice Workshop was held at the MoDELS 2005 conference. The workshop specified an example problem that participants were asked to implement using their own favorite tool(s). The description of the example problem, a 'class to RDBMS' transformation is available from the web site.

I am working on a Xholon implementation of this. My approach is to create three separate Xholon models, that can be run individually, or run all at the same time. The three models are:

Class Model

The first step in creating the Class model is to define the Xholon classes in the classmodel_InheritanceHierarchy.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<XholonClass xmlns:xi="http://www.w3.org/2001/XInclude">
  <MtipClassSystem/>
  
  <ClassEntity_c>
    <Association_c/>
    <Classifier_c>
      <Class_c/>
      <PrimitiveDataType_c/>
    </Classifier_c>
    <Attribute_c/>
  </ClassEntity_c>
  
  <!-- Xholon Viewers -->
  <xi:include href="_viewer/XholonViewer.xml"/>
</XholonClass>

The second step is to specify which Java class corresponds to which Xholon class. This is done in the classmodel_ClassDetails.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<xholonClassDetails>
  
  <Association_c implName="org.primordion.user.app.class2rdbms.classmodel.Association"/>
  <Class_c implName="org.primordion.user.app.class2rdbms.classmodel.Class"/>
  <PrimitiveDataType_c implName="org.primordion.user.app.class2rdbms.classmodel.PrimitiveDataType"/>
  <Attribute_c implName="org.primordion.user.app.class2rdbms.classmodel.Attribute"/>
  
  <XholonClass xhType="XhtypePureContainer"/>
</xholonClassDetails>

The third step is to define the composite structure and Java attributes, as detailed in Figure 3 of the workshop specification.

<?xml version="1.0" encoding="UTF-8"?>
<MtipClassSystem>
  
  <!-- PrimitiveDataType instances -->
  <PrimitiveDataType_c>
    <Attribute_String roleName="ClassifierName">int</Attribute_String>
  </PrimitiveDataType_c>
  <PrimitiveDataType_c>
    <Attribute_String roleName="ClassifierName">String</Attribute_String>
  </PrimitiveDataType_c>
  
  <!-- Class and Attribute instances -->
  <Class_c>
    <Attribute_String roleName="ClassifierName">Order</Attribute_String>
    <Attribute_boolean roleName="Is_persistent">true</Attribute_boolean>
    <Attribute_c>
      <Attribute_String roleName="AttributeName">order_no</Attribute_String>
      <Attribute_boolean roleName="Is_primary">true</Attribute_boolean>
    </Attribute_c>
  </Class_c>
  <Class_c>
    <Attribute_String roleName="ClassifierName">Customer</Attribute_String>
    <Attribute_boolean roleName="Is_persistent">true</Attribute_boolean>
    <Attribute_c>
      <Attribute_String roleName="AttributeName">name</Attribute_String>
      <Attribute_boolean roleName="Is_primary">true</Attribute_boolean>
    </Attribute_c>
  </Class_c>
  <Class_c>
    <Attribute_String roleName="ClassifierName">Address</Attribute_String>
    <Attribute_boolean roleName="Is_persistent">false</Attribute_boolean>
    <Attribute_c>
      <Attribute_String roleName="AttributeName">addr</Attribute_String>
      <Attribute_boolean roleName="Is_primary">true</Attribute_boolean>
    </Attribute_c>
  </Class_c>
  
  <!-- Association instances -->
  <Association_c>
    <Attribute_String roleName="AssociationName">customer</Attribute_String>
  </Association_c>
  <Association_c>
    <Attribute_String roleName="AssociationName">address</Attribute_String>
  </Association_c>
  
</MtipClassSystem>

The fourth step is to write the Java code (Xhclassmodel.java) that will create the connections between instances, as detailed in Figure 3 of the workshop specification.

  public void postConfigure() {
    switch (getId()) {
    case 4: // Attribute
      ((Attribute)this).setType(getXPath().evaluate("ancestor::MtipClassSystem/PrimitiveDataType_c[1]", this));
      break;
    case 6: // Attribute
      ((Attribute)this).setType(getXPath().evaluate("ancestor::MtipClassSystem/PrimitiveDataType_c[2]", this));
      break;
    case 8: // Attribute
      ((Attribute)this).setType(getXPath().evaluate("ancestor::MtipClassSystem/PrimitiveDataType_c[2]", this));
      break;
    case 9: // Association
      ((Association)this).setSrc(getXPath().evaluate("ancestor::MtipClassSystem/Class_c[1]", this));
      ((Association)this).setDest(getXPath().evaluate("ancestor::MtipClassSystem/Class_c[2]", this));
      break;
    case 10: // Association
      ((Association)this).setSrc(getXPath().evaluate("ancestor::MtipClassSystem/Class_c[2]", this));
      ((Association)this).setDest(getXPath().evaluate("ancestor::MtipClassSystem/Class_c[3]", this));
      break;
    default:
      break;
    }
    super.postConfigure();
  }

Then the various domain-specific Java classes must be written. The following is the Association class.

package org.primordion.user.app.class2rdbms.classmodel;

import org.primordion.xholon.base.IXholon;

/**
 * See Bezivin et al (2005) "Model Transformations in Practice Workshop".
 * @author <a href="mailto:ken@primordion.com">Ken Webb</a>
 * @see <a href="http://www.primordion.com/Xholon">Xholon Project website</a>
 * @since 0.8.1 (Created on April 26, 2010)
 */
public class Association extends Xhclassmodel {
  
  private String associationName = null;
  private IXholon src = null;
  private IXholon dest = null;

  public String getAssociationName() {
    return associationName;
  }

  public void setAssociationName(String associationName) {
    this.associationName = associationName;
  }

  public IXholon getSrc() {
    return src;
  }

  public void setSrc(IXholon src) {
    this.src = src;
  }

  public IXholon getDest() {
    return dest;
  }

  public void setDest(IXholon dest) {
    this.dest = dest;
  }

  @Override
  public String toString() {
    return "Association [associationName=" + associationName + ", src="
        + src + ", dest=" + dest + "]";
  }
  
}

The Class model can be run under Xholon. Here's how the Xholon GUI displays the example input of the model.

When the Class model is run under Xholon, it can generate a class diagram in Umple format. This text can be copied and pasted into the Umple online page. Umple is then able to generate yUML content, that after some editing, results in the following image. This class diagram is structurally the same as Figure 1 (Class meta-model) in the workshop specification.

The yUML content that generates the above image is:

[Association],
[Attribute],
[Class],
[Classifier]^-[Class],
[Classifier],
[PrimitiveDataType],
[Classifier]^-[PrimitiveDataType],
[Association]1-src >1[Class],
[Association]1-dest >1[Class],
[Attribute]1-type >1[Classifier],
[Class]1-attrs >*[Attribute],

At runtime, Xholon can also automatically generate the following diagram (using JUNG) that matches the structure of Figure 3 (Example input) in the specification. Each node in this diagram is an instance of an entity in the class model.

RDBMS Model

Transformation

return to main page