[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Newsgroup Home]
[news.eclipse.modeling.m2m] Re: [ATL] ATLTransformations

Hello,

We are currently working on redefining a correct API to launch transformations programmatically. Actually there are no "simple" way to do that, and the class you use (ATLTransformations) has been created with an old ATL version.

There is an up-to-date non-regression test in ATL which launch transformations programmatically. I advise you to take a look on it, you may find some reusable classes to do your intent.

Here is a link :
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.m2m/org.eclipse.m2m.atl/tests/org.eclipse.m2m.atl.tests/src/org/eclipse/m2m/atl/tests/util/TransfoLauncher.java?root=Modeling_Project&sortdir=down&view=markup

Best regards,

William

John Bravus a écrit :
Hello,

I'm trying to execute a transformation programmatically through the ATLTransformations class. I've modified that class to lauch the Public2Private example, but I didn't have success.
Thanks for any help.


The code is:

package atl;

import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.util.*;
import javax.jmi.reflect.*;

import org.atl.eclipse.engine.*;
import org.atl.engine.extractors.*;
import org.atl.engine.extractors.ebnf.*;
import org.atl.engine.injectors.ebnf.*;
import org.atl.engine.extractors.xml.*;
import org.atl.engine.injectors.xml.*;
import org.atl.engine.repositories.emf4atl.*;
import org.atl.engine.vm.nativelib.*;
import org.eclipse.core.runtime.*;
import org.atl.engine.repositories.mdr4atl.*;
import org.atl.engine.vm.*;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

/**
* Main class for running ATL transformations programatically (template)
* TODO: Add support for running AM3 Ant tasks
* @author Milan Milanovic (milan [at] milanovic.org)
* @version 2.3
*/
public class ATLTransformations {

    // Stop on error in EBNF Injection
    private final static boolean stopOnError = !false;

    // Relative location of transformations
    String transformationsLocation = "";

    // Relative location of metamodels
    String transformationsMetamodels = "";

// URL's to compiled ATL transformations (an example of OneMM to OtherMM transformation)
private URL OneMM2OtherMMurl = ATLTransformations.class.getResource("Public2Private.asm");
// Add here URL's to your other compiled transformations...


// TCS specific (MM is pseudoname for some your metamodel which is used for TCS injection/extraction)
//private URL MM_tcs = ATLTransformations.class.getResource("MOF-1.4.xmi");
//private URL TCS = ATLTransformations.class.getResource("TCS.xmi"); // uses MDR (change to .ecore for EMF)


    // MDR model handler
    private AtlModelHandler mdramh = null;

    // EMF model handler
    private AtlModelHandler emfamh = null;

// MDR meta-metamodels
private ASMModel oneMM_MDR = null;
private ASMModel otherMM_MDR = null;
private ASMModel xmlMDRmm = null; // XML metamodel is needed because of XML injection/extraction
// Add here objects for you metamodels (MDR - MOF-1.4)...


    // For TCS (MDR) support
    //private ASMModel tcsMDRmm = null;
    //private ASMModel mmTcsMDRmm = null;

    // Used for keeping metamodel names
    Map MDRMetaModels = new HashMap();

    // EMF meta-metamodels
    private ASMModel oneMM_EMF = null;
    private ASMModel otherMM_EMF = null;
    private ASMModel xmlEMFmm = null;
    // Add here objects for you metamodels (EMF - Ecore)

    // For TCS (EMF) support
    //private ASMModel tcsEMFmm = null;
    //private ASMModel mmTcsEMFmm = null;

    // General meta-models
    private ASMModel pbmm = null;

    // Instance of ATLTransformations class (Singleton)
   private static ATLTransformations atlTransformations = null;

    // Markers for Problem metamodel
    private MarkerMaker markerMaker;

    // Constructor
    public ATLTransformations() {
        initMDR(); // Initialize MDR based metamodels
        //initEMF(); // Initialize EMF based metamodels - if needed
    } // -- end of constructor

/////////////////////////////////////////////////////////////////////////////////////////////

//// General ATL transformation initialization with domain metamodels specific initialization
/////////////////////////////////////////////////////////////////////////////////////////////



/** * Initialize MDR model handler and MOF based metamodels */ private void initMDR() {

        if(mdramh == null) { // if MDR is not initialized

            // Initialize MDR model handler
            mdramh = getDefaultHandler("MDR");

// URL's to MOF-1.4 (XMI) metamodels
URL onemmurl = ATLTransformations.class.getResource("UMLDI.xmi");
URL xmlmmurl = ATLTransformations.class.getResource("xml.xmi");
URL othermmurl = ATLTransformations.class.getResource("UMLDI.xmi");
// Add here URL's to your metamodels (MDR - MOF-1.4)...


try {
// Get metamodels
oneMM_MDR = mdramh.loadModel("UMLDI", mdramh.getMof(), onemmurl.openStream()); // ONE MM
xmlMDRmm = mdramh.loadModel("xml", mdramh.getMof(), xmlmmurl.openStream()); // XML MM
otherMM_MDR = mdramh.loadModel("UMLDI", mdramh.getMof(), othermmurl.openStream()); // Other MM
// Load your metamodels here...


// Only for TCS output!!
//tcsMDRmm = mdramh.loadModel("TCS", mdramh.getMof(), TCS.openStream()); // TCS MM
//mmTcsMDRmm = mdramh.loadModel("MOF-1.4", tcsMDRmm, MM_tcs.openStream()); // MM-TCS MM


                // Put metamodels in map for easy lookup
                MDRMetaModels.put("OneMM", oneMM_MDR);
                MDRMetaModels.put("XML", xmlMDRmm);
                MDRMetaModels.put("OtherMM", otherMM_MDR);
                //MDRMetaModels.put("TCS", tcsMDRmm);
                //MDRMetaModels.put("MOF-1.4", mmTcsMDRmm);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    } // -- end of initMDR

    /**
     * Initialize EMF model handler and Ecore based metamodels
    */
    private void initEMF() {

        if(emfamh == null) { // if EMF is not initialized

            // Initialize EMF model handler
            emfamh = AtlModelHandler.getDefault(AtlModelHandler.AMH_EMF);

// URL's to Ecore (XMI) metamodels
URL onemmurl = ATLTransformations.class.getResource(transformationsMetamodels + "oneMM/oneMM.ecore");
URL xmlmmurl = ATLTransformations.class.getResource(transformationsMetamodels + "xml/xml.ecore");
URL othermmurl = ATLTransformations.class.getResource(transformationsMetamodels + "otherMM/otherMM.ecore");
// Add here URL's to your metamodels (EMF - Ecore)...


try {
// Get metamodels
oneMM_EMF = emfamh.loadModel("OneMM", emfamh.getMof(), onemmurl.openStream());
xmlEMFmm = emfamh.loadModel("XML", emfamh.getMof(), xmlmmurl.openStream());
otherMM_EMF = emfamh.loadModel("OtherMM", emfamh.getMof(), othermmurl.openStream());
// Load your metamodels here...


// Only for TCS output!!
//tcsEMFmm = emfamh.loadModel("TCS", emfamh.getMof(), TCS.openStream()); // TCS MM
//mmTcsEMFmm = emfamh.loadModel("MM.tcs", tcsEMFmm, MM_tcs.openStream()); // MM-TCS MM


            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        pbmm = emfamh.getBuiltInMetaModel("Problem");
        markerMaker = new MarkerMaker();
    } // -- end of initEMF

/**
* Returns default model handler (currently supported MDR and EMF)
* @param repository String which represents model handler
* @return default repository for input (EMF or MDR)
*/
private AtlModelHandler getDefaultHandler(String repository) {
AtlModelHandler amh = null;
try {
amh = AtlModelHandler.getDefault(repository);
} catch (Throwable e) {
if ("MDR".equals(repository)) {
AtlModelHandler.registerDefaultHandler("MDR", new AtlMDRModelHandler()); // register
amh = AtlModelHandler.getDefault(repository);
} else {
throw new RuntimeException(e);
}
}
return amh;
} // -- end of getDefaultHandler


  /**
     * Returns static instance of ATLTransformations class (Singleton)
     * @return default repository for input (EMF or MDR)
     */
   public static ATLTransformations getATLTransformations() {
        if(atlTransformations  == null)
            atlTransformations = new ATLTransformations();

        return atlTransformations;
    }

/**
* Check if input XML file is well-formed - helper method
* @param file path to input XML file or XML code
* @param isFile if it is true then it is path to file, otherwise it is String that contains XML code
* @return true if input XML file is well formed, otherwise is false
*/
private boolean checkForWellFormedness(String file, boolean isFile)
{
SAXParser saxParser = null;
DefaultHandler dh = null;
InputStream in = null;


        // init parser
        try {
            SAXParserFactory spfactory = SAXParserFactory.newInstance();
            saxParser = spfactory.newSAXParser();
            dh = new DefaultHandler();
        }
        catch(Exception e) {
            System.out.println("Cannot initialize SAX parser.");
            e.printStackTrace();
            return false;
        }

// parse the XML document using SAX parser
try {
if (isFile == true) { // it is file
in = new FileInputStream(file);
}
else { // it is String that contains XML code
byte currentXMLBytes[] = file.getBytes(); // Get bytes from input String
in = new ByteArrayInputStream(currentXMLBytes);
}
saxParser.parse(in, dh); // SAXException, IOException
}
catch(SAXParseException spe) { // Document is not well-formed: Error
System.out.println("Document is not well-formed.");
return false;
}
catch(SAXException se) { // (*)
System.out.println("Error while parsing input XML file: " + file);
se.printStackTrace();
return false;
}
catch(FileNotFoundException f) {
System.out.println("Error: File is not found-1");
return false;
}
catch(IOException ioe) {
System.out.println("Cannot read file.");
return false;
}
return true;
} // -- end of checkForWellFormedness


/**
* Inject input XML file to XML model (instance of XML metamodel - MOF 1.4)
* Note: if you want to use EMF, just change 'mdramh' to 'emfamh' and 'xmlMDRmm' to 'xmlEMFmm'
* in this method, and also in other methods if needed.
* @param file name of file from which XML model will be created
* @return created XML model from input file
*/
public ASMModel injectXMLModelFromFile(String file) {
initMDR(); // if MDR is not initialized, do it now !


ASMModel ret = mdramh.newModel("IN", xmlMDRmm); // create new output model with XML metamodel (MOF-1.4)

        XMLInjector xmli = new XMLInjector(); // create XML injector

        Map parameters = Collections.EMPTY_MAP; // no parameters

        InputStream in = null;

        try {
            in = new FileInputStream(file);

            xmli.inject(ret, in, parameters); // Do injection !

        } catch(FileNotFoundException f) {
            System.out.println("Error: File is not found-2");
        } catch(IOException io) {
            System.out.println("Error: in injection of XML file");
        }

        return ret;
    } // -- end of injectXMLModelFromFile

/**
* Convert input String which contains XML code to XML model (instance of XML metamodel - MOF 1.4)
* @param inputString String which contains XML
* @return created XML model from in XML code
*/
public ASMModel injectXMLModelFromString(String inputString) {
initMDR(); // if MDR is not initialized, do it now !


        // Get bytes from input String
        byte currentXMLBytes[] = inputString.getBytes();

        InputStream in = new ByteArrayInputStream(currentXMLBytes);

ASMModel ret = mdramh.newModel("IN", xmlMDRmm); // create new output model with XML metamodel (MOF-1.4)

        XMLInjector xmli = new XMLInjector(); // create XML injector

        Map parameters = Collections.EMPTY_MAP; // no parameters

        try {
            xmli.inject(ret, in, parameters); // Do injection !
        } catch(IOException io){
            io.printStackTrace();
        }

        return ret;
    } // -- end of injectXMLModelFromFile

/**
* Extract input XML model (instance of XML metamodel - MOF 1.4) to XML file
* @param model input XML model which will be extracted to XML file
* @param file output XML file in which input XML model will be extracted
*/
public void extractXMLModelToFile(ASMModel model, String file) {
initMDR();


        OutputStream out = null;

        Map parameters = Collections.EMPTY_MAP;

        XMLExtractor xmle = new XMLExtractor();

        try {
            out = new FileOutputStream(file);

            xmle.extract(model, out, parameters); // Do extraction !

out.flush(); out.close(); // close stream
} catch(FileNotFoundException f) {
System.out.println("Error: File is not found-3");
} catch(IOException io) {
System.out.println("Error: in extraction of XML model to XML file");
}
} // -- end of extractXMLModelToFile


/**
* Extract input XML model (instance of XML metamodel - MOF 1.4) to String
* @param model input XML model which will be extracted to XML file
* @return input model returned as String
*/
public String extractXMLModelToString(ASMModel model) {
initMDR();


        OutputStream out = null; String ret = null;

        Map parameters = Collections.EMPTY_MAP;

        XMLExtractor xmle = new XMLExtractor();

        try {
            out = new ByteArrayOutputStream();

            xmle.extract(model, out, parameters); // Do extraction !

            ret = out.toString();

out.flush(); out.close(); // close stream
} catch(FileNotFoundException f) {
System.out.println("Error: File is not found-4");
} catch(IOException io) {
System.out.println("Error: in extraction of XML model to XML file");
}
return ret;
} // -- end of extractXMLModelToFile


/////////////////////////////////////////////////////////////////////////////////////////////////////////////

// An example EBNF inject/extract methods for some MM metamodel (this should be changed for every metamodel)
// Note: you should have generated MM-ebnfinjector.jar and putted
// in into classpath with other libs
/////////////////////////////////////////////////////////////////////////////////////////////////////////////



/**
* Extract input MM model (instance of some MM metamodel - MOF 1.4) to File
* @param MMModel input MM model which will be extracted to File
* @param file path to the file in which will be extracted input MM model
*/
public void saveMMModelToFile(ASMModel MMModel, String file) {
initMDR();


        OutputStream out = null;

        Extractor ext = new EBNFExtractor();
        Map params = new HashMap();
        params.put("format", MDRMetaModels.get("MM-TCS"));
        params.put("indentString", "\t");

        try {
            out = new FileOutputStream(file);
            ext.extract(MMModel, out, params); // do it!

        } catch(Exception e) {
            e.printStackTrace();
        }
    } // -- end of saveMMModelToFile

/**
* Deserializes a MM model from a File. (works with MDR, but if it is needed, just change to EMF)
* @param file is the MM file.
* @return the MM model that is injected from input MM code.
*/
public ASMModel getMMFromFile(String file) {
initMDR(); // if MDR (and EMF) is not initialized, do it now !


ASMModel ret = mdramh.newModel("IN", oneMM_MDR); // create new output model with OneMM (or some your MM) metamodel

        EBNFInjector2 ebnfi = new EBNFInjector2();
        InputStream in = null;

        try {
            in = new FileInputStream(file);

//Class lexer = MMLexer.class; // This are your generated classes
//Class parser = MMParser.class;


//ebnfi.performImportation(oneMM_MDR, ret, in, "MM", lexer, parser);

            in.close();

            } catch(FileNotFoundException f) {
                System.out.println("Error: File is not found-5");
            } catch(IOException io) {
                System.out.println("Error: in injection of MM file");
            } catch(Exception e) {
                e.printStackTrace();
            }

// TODO: Check for problems with: int nbPbs = markerMaker.applyMarkers(file, pbs); ...

            return ret;
    } // -- end of getMMFromFile

/**
* Launch ATL transformation
* @param modelHandler model handler which is used for creating output model
* @param transformation URL to compiled ATL transformation
* @param inputModel input model for transformation
* @param inputMetamodel input metamodel for transformation
* @param outputMetamodel output metamodel for transformation
* @param inParams additional parameters for transformation
* @param inLibs additional libraries for transformation
* @throws IOException */
public ASMModel runATLTransformation(AtlModelHandler modelHandler, URL transformation, ASMModel inputModel,
ASMModel inputMetamodel, ASMModel outputMetamodel, Map inParams, Map inLibs) throws IOException {
initMDR(); // Initialize MDR model handler


        ASMModel ret = null; // return model

// Set launch configuration
Map models = new HashMap();
models.put(inputMetamodel.getName(), inputMetamodel); // input metamodel
models.put(outputMetamodel.getName(), outputMetamodel); // output metamodel
models.put("IN", inputModel); // input model
ret = modelHandler.newModel("OUT", outputMetamodel); // output model
models.put("OUT", ret);


        Map params = inParams; // Parameters
        Map libs = inLibs;        // Libraries

// Launch ATL transformation
AtlLauncher.getDefault().launch(transformation, libs, models, params);


        return ret;
    } // -- end of runATLTransformation

/**
* Load model from file (XMI) as MOF-1.4
* @param file name of file which containts input model
* @param inputMetamodel input metamodel (as String)
* @return model which is constructed from input file
*/
public ASMModel loadMDRModelFromFile(String file, String inputMetamodel) {
// Initialize MDR
initMDR();


        // Get metamodel from map
        ASMModel metamodel = (ASMModel)MDRMetaModels.get(inputMetamodel);

        InputStream in = null;

        try {
            // Create input stream from file
            in = new FileInputStream(file);

        } catch(FileNotFoundException e) {
            System.out.println("Error: Input file is not found!");
            return null;
        }

        return mdramh.loadModel(file, metamodel, in);
    } // -- end of loadMDRModelFromFile

/**
* Save model to file (XMI) as MOF-1.4
* @param inputModel input model for saving to file
* @param file name of file in which model will be saved
*/
public void saveMDRModelToFile(ASMModel inputModel, String file) {
// Bridge actual problem of saving model outside of Eclipse environment
ASMMDRModel model = (ASMMDRModel)inputModel;


        OutputStream out = null;
        try {
            // Create output stream
            out = new FileOutputStream(file);

            // Save model
            model.save(out);

            out.flush(); out.close();

        } catch(FileNotFoundException f) {
            System.out.println("Error: output file can't be created");
        } catch(IOException io) {
            System.out.println("Error: model can't be saved to file");
        }
    } // -- end of saveMDRModelToFile

  /**
    * Converts MDR ASMModel to String
    * @param MOFmodel input model for converting to string
    * @return String which containts input model
    */
    public String MOFModelToString(ASMModel MOFmodel) {
        // Create output stream
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        String ret = null;

        try {
            // Save model
            ((ASMMDRModel)MOFmodel).save(out);

            out.flush();

            ret = out.toString();

            out.close();

        } catch(IOException io) {
            System.out.println("Error: model to string");
        }
        return ret;
    } // -- end of MOFModelToString

//////////////////////////////////////////////////////////////////////////////////

//// Specific transformations
//////////////////////////////////////////////////////////////////////////////////



/**
* Run OneMM to OtherMM (example) ATL transformation (OneMM2OtherMM).
* Note: MDR is used as model handler, if you want to use EMF, just change 'mdramh' to 'emfamh'
* @param oneModel input ONE model
* @return output (cleaned) OtherMM model
* @throws IOException */
public ASMModel getOtherMMFromOneMM(ASMModel oneModel) throws IOException {


// If you need library, you can add it in following way:
// e.g., Map libs = new HashMap();
// libs.put("XMLHelpers", XMLHelpersurl);
// And you just have to add this 'libs' object instead of the last Collections.EMPTY_MAP below


// Run transformation and return output model
return runATLTransformation(mdramh, OneMM2OtherMMurl, oneModel, oneMM_MDR, otherMM_MDR, Collections.EMPTY_MAP, Collections.EMPTY_MAP);
} // -- end of getCleanedXMLFromXML


/**
* Transform input One (XML-based) file to output Other (XML-based) file - an example with injection/extraction
* @param InputOneFile name of input One XML file
* @param OutputOtherFile name of output Other XML file
* @return Result of running this transformation
* @throws IOException */
public String transformOnetoOther(String InputOneFile, String OutputOtherFile) throws IOException {
// Check is input String well-formed (XML)
if (!checkForWellFormedness(InputOneFile, true)) return new String("Document is not well-formed.");


ASMModel xmlModel = injectXMLModelFromFile(InputOneFile); // One XML -> XML model
ASMModel otherModel = getOtherMMFromOneMM(xmlModel); // One XML -> Other
extractXMLModelToFile(otherModel, OutputOtherFile); // Other -> Other XML
return new String("OK");
} // -- end of transformOnetoOther


//////////////////////////////////////////////////////////////////////////////////

//// Main method - used only for testing this class
//////////////////////////////////////////////////////////////////////////////////


    public static void main(String [] arguments) throws IOException {

// Create new instance of this class
ATLTransformations transformation = ATLTransformations.getATLTransformations();


// Transform input file to output file
String message = transformation.transformOnetoOther("src/atl/PetriNet.xmi", "src/atl/PetriNet-private.xmi"); // Message is OK if all goes well
// or document is not well-formed
}


}


begin:vcard
fn:William Piers
n:Piers;William
org:Obeo
adr:2 rue Robert Schumann;;lot 24;NANTES;;44408;France
email;internet:william.piers@xxxxxxx
title:MDA Consultant
tel;work:+33 (0)2 51 13 51 82
tel;cell:+33 (0)6 20 31 75 98
url:http://www.obeo.fr
version:2.1
end:vcard