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.