Ken Webb 2010-04-19T20:08:14Z
The ATLAS Transformation Language (ATL) is "a model transformation language and toolkit".
A good introductory tutorial (Families2Persons) is available, as a presentation, and also described on a web page. To get a better idea of the ATL concepts, I've used Xholon to reimplement the model-to-model (m2m) transformation described in this ATL introductory tutorial. In this example, Xholon functions as a very lightweight modeling and transformation tool. Xholon is able to read the model described in the ATL tutorial (it reads the actual sample-Families.xmi file included in the tutorial). <pre> <?xml version="1.0" encoding="ISO-8859-1"?> <xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
xmlns="platform:/resource/Xholon/src/org/primordion/user/app/AtlFamiliesToPersons/Families.ecore"> <Family lastName="March"> <father firstName="Jim"/> <mother firstName="Cindy"/> <sons firstName="Brandon"/> <daughters firstName="Brenda"/> </Family> <Family lastName="Sailor"> <father firstName="Peter"/> <mother firstName="Jackie"/> <sons firstName="David"/> <sons firstName="Dylan"/> <daughters firstName="Kelly"/> </Family>
</xmi:XMI> </pre>
Once the model has been loaded, Xholon can run the following Xholon transformation script, which is written in Java. <pre> package org.primordion.user.app.AtlFamiliesToPersons;
import org.primordion.xholon.base.IXholon; import org.primordion.xholon.script.XholonScript; import org.primordion.xholon.service.IXholonService; import org.primordion.xholon.service.XholonHelperService;
/**
* This script performs a model-to-model (m2m) transformation, * from a Families model to a Persons model. * This script is based on Families2Persons.atl . * The script should be pasted as a last child of a Families xmi:XMI node. * <p><Families2Persons/></p> */
public class Families2Persons extends XholonScript {
private StringBuffer personsSb = new StringBuffer();
private StringBuffer malesSb = new StringBuffer();
private StringBuffer femalesSb = new StringBuffer();
/*
* @see org.primordion.xholon.base.Xholon#postConfigure()
*/
public void postConfigure() {
personsSb.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
personsSb.append("<xmi:XMI xmi:version=\"2.0\" xmlns:xmi=\"http://www.omg.org/XMI\" xmlns=\"Persons\">\n");
// visit the subtree rooted by the Families xmi:XMI node
getParentNode().visit(this);
// males before females to agree with the ATL example
personsSb.append(malesSb);
personsSb.append(femalesSb);
personsSb.append("</xmi:XMI>\n");
System.out.println(personsSb); // m2t
// paste the Persons model into the Xholon tree
XholonHelperService xholonHelperService = (XholonHelperService)getService(IXholonService.XHSRV_XHOLON_HELPER);
xholonHelperService.pasteAfter(getParentNode(), personsSb.toString());
// remove this script from the Xholon tree
this.removeChild();
}
/*
* @see org.primordion.xholon.base.Xholon#visit(org.primordion.xholon.base.IXholon)
*/
public boolean visit(IXholon visitee) {
if (visitee.getXhc().hasAncestor("Member")) {
boolean isFemale = isFemale(visitee);
StringBuffer sb = isFemale ? sb = femalesSb : malesSb;
sb.append(" <")
.append(isFemale ? ruleMember2Female() : ruleMember2Male())
.append(" fullName=\"")
.append(((Member)visitee).getFirstName())
.append(" ")
.append(((Family)visitee.getParentNode()).getLastName())
.append("\"/>\n");
}
return true;
}
/**
* Is this family member a female?
* Adapted from Families2Persons.atl .
* @param familyMember father, mother, sons, or daughters
* @return true (female) or false (male)
*/
protected boolean isFemale(IXholon familyMember) {
String familyMemberType = familyMember.getXhcName();
if ("mother".equals(familyMemberType)) {
return true;
}
else if ("daughters".equals(familyMemberType)) {
return true;
}
else { // father or sons
return false;
}
}
/**
* Adapted from a rule in Families2Persons.atl .
* @return
*/
protected String ruleMember2Male() {
return "Male";
}
/**
* Adapted from a rule in Families2Persons.atl .
* @return
*/
protected String ruleMember2Female() {
return "Female";
}
} </pre>
The result of running the Xholon transformation script, is the following XML which is exactly the same result in the ATL tutorial (sample-Persons.xmi). <pre> <?xml version="1.0" encoding="ISO-8859-1"?> <xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns="Persons">
<Male fullName="Jim March"/> <Male fullName="Brandon March"/> <Male fullName="Peter Sailor"/> <Male fullName="David Sailor"/> <Male fullName="Dylan Sailor"/> <Female fullName="Cindy March"/> <Female fullName="Brenda March"/> <Female fullName="Jackie Sailor"/> <Female fullName="Kelly Sailor"/>
</xmi:XMI> </pre>
The following image shows the Xholon application running under Eclipse. The Xholon GUI shows the source (Families xmi:XMI subtree), as well as the generated target (Persons xmi:XMI) subtree. The image also shows the Xholon Console window which was opened on the Families xmi:XMI node, and was used to paste-in or apply the transformation script at runtime.