Skip to main content

Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » ATL » Model injection of a registered XML/XSD model
Model injection of a registered XML/XSD model [message #1271242] Fri, 14 March 2014 16:08 Go to next message
Mathias K is currently offline Mathias KFriend
Messages: 16
Registered: March 2014
Junior Member

I am trying to programatically run an ATL transformation where one of the injected models is defined by XML/XSD, but it seems the model is not correctly injected by ATL.

If I define and load an EMF plugin that has the corresponding XSD2Ecore mapping, the transformation goes fine. However I want to run the transformation without the plugin available, i.e programatically mimic what the EMF plugin is doing.

From what I understand so far, these are my steps :
- Build the EPackage from the XSD using XSDEcoreBuilder
- Register the package in the model factory registry
- Use that model factory to create ReferenceModel, Model and injections

Although registrations/injections seem to go fine, the ATL transformation launcher raises an exception about missing class in the reference model.

Remarks before I enter into the code:
- the XSDEcoreBuilder changes class names by adding Type to each of them (e.g. MyClass->MyClassType) so I use those modified names in the transformation (though I'd prefer not to). I have tried old names and it doesn't change the behaviour.

- After registrations, I can programatically load the XML resource and navigate into it using EMF without problems. I find the expected classes. I looked at how ATL implements the injections (IInjector) and tried to mimic it in my "manual" EMF loading to see if I could reproduce the ATL error but it works fine.

- I tried to use the global registry instead of the factory local one without success.

- I know there is a potential workaround: directly passing the EMF loaded resource to ATL, but I would like to avoid that if possible.

Attached is a set of sample files for checking/testing: a sample ATL A2B, sample XML/XSD (A: inputs), sample XMI/Ecore (B: outputs), java code for testing.

Below is the java code for the tests, then the debug output and the ATL launch error:

public class TestATLXML {

	public static void main(String[] args) {

		try {
			IPath inputMMPath = new Path("files/A.xsd");
			IPath inputMPath = new Path("files/A-XSD.xml");
			String inputMMName = "A";
			IPath outputMMPath = new Path("files/B.ecore");
			IPath outputMPath = new Path("files/B-XSD.xmi");
			String outputMMName = "B";
			IPath asmPath = new Path("files/A2B.asm");
			ILauncher transformationLauncher = new EMFVMLauncher();
			EMFModelFactory modelFactory = new EMFModelFactory();
			IInjector injector = new EMFInjector();
			IExtractor extractor = new EMFExtractor();

			transformationLauncher.initialize(new HashMap<String,Object>());
			// input
			testEMFLoad(modelFactory, inputMPath);
			IReferenceModel inputMM = modelFactory.newReferenceModel();	
			injector.inject(inputMM, URI.createFileURI(inputMMPath.toString()).toString());
			IModel inputM = modelFactory.newModel(inputMM);
			injector.inject(inputM, URI.createFileURI(inputMPath.toString()).toString());

			transformationLauncher.addInModel(inputM, "IN", inputMMName);

			// output
			IReferenceModel outputMM = modelFactory.newReferenceModel();
			injector.inject(outputMM, URI.createFileURI(outputMMPath.toString()).toString());
			IModel outputM = modelFactory.newModel(outputMM);

			transformationLauncher.addOutModel(outputM, "OUT", outputMMName);
			// transformation
			transformationLauncher.launch(ILauncher.RUN_MODE, new NullProgressMonitor(), new HashMap<String,Object>(),
					new FileInputStream(asmPath.toOSString()));
			// extract results
			extractor.extract(outputM, URI.createFileURI(outputMPath.toString()).toString());
		catch (ATLCoreException e) {
		catch (FileNotFoundException e) {
		catch (IOException e) {

		catch (ATLExecutionException e) {
	private static void registerXSD(EMFModelFactory modelFactory, IPath XSD) throws IOException {
		//local registry
		ResourceSet resourceSet = modelFactory.getResourceSet();
		resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put( "xsd",
				new XSDResourceFactoryImpl());
		resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put( "xml",
				new XMLResourceFactoryImpl());
		// global registry
		//ResourceSet resourceSet = new ResourceSetImpl();
				//new XMLResourceFactoryImpl());
				//new XMLResourceFactoryImpl());

		XSDEcoreBuilder xsdEcoreBuilder = new XSDEcoreBuilder();
	    Collection<EObject> loaded = xsdEcoreBuilder.generate(URI.createFileURI(XSD.toOSString()));
	    for (Object loadedObject : loaded) {
			if (loadedObject instanceof EPackage) {

				resourceSet.getPackageRegistry().put(((EPackage) loadedObject).getNsURI(), (EPackage) loadedObject);
				// for xml with missing namespace and schema location
				resourceSet.getPackageRegistry().put(null, (EPackage) loadedObject);
				System.out.println("registerXSD: an EPackage in the input: " + ((EPackage) loadedObject).getNsURI());
			} else {
				final String typeInfo = (loadedObject == null)?
						"N/A" : loadedObject.getClass().getName();
				System.out.println("registerXSD: A non-EPackage in the input: " + typeInfo);
	private static void testEMFLoad(EMFModelFactory modelFactory, IPath XML) {
		// get factory resource set
		ResourceSet resourceSet = modelFactory.getResourceSet();
		// Not sure how these loading options should be set
	    Map options = resourceSet.getLoadOptions();
	    final ExtendedMetaData extendedMetaData = new BasicExtendedMetaData(resourceSet.getPackageRegistry());
	    options.put(XMLResource.OPTION_EXTENDED_META_DATA, extendedMetaData);
		options.put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE);
		// get resource
	    Resource resource = resourceSet.getResource(URI.createFileURI(XML.toOSString()), true);

	    // get & output root element name
	    EObject object = (EObject) resource.getContents().get(0);
	    // get & output root's first contained element

registerXSD: an EPackage in the input: files/A.xsd
org.eclipse.emf.ecore.impl.EClassImpl@aa8837c (name: DocumentRoot) (instanceClassName: null) (abstract: false, interface: false)
org.eclipse.emf.ecore.impl.DynamicEObjectImpl@5606b5d8 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@69d2bdc3 (name: AType) (instanceClassName: null) (abstract: false, interface: false))
org.eclipse.m2m.atl.engine.emfvm.VMException: Cannot find class AType in reference model A
	at __matchA2B#2(A2B.atl)
		local variables: self=A2B : ASMModule
	at __matcher__#1(A2B.atl)
		local variables: self=A2B : ASMModule
	at main#22(A2B.atl)
		local variables: self=A2B : ASMModule

That'(s about it. I know I'm missing something but I can't find it. Any help appreciated.

Re: Model injection of a registered XML/XSD model [message #1274421 is a reply to message #1271242] Fri, 21 March 2014 12:49 Go to previous message
Mathias K is currently offline Mathias KFriend
Messages: 16
Registered: March 2014
Junior Member

As a follow-up, I have tried the following workaround but the result is the same :

1) loading the resource "manually" using EMF
2) passing this resource URI to the ATL injector

As of now, my only option (considering the XSD2Ecore plugin is not available) is to first generate & serialize the corresponding XMI/ECORE with EMF and using these as transformation source.

Any ideas on what is wrong with my preferred approach ?


Previous Topic:Enumeration #"Rule" doesn't work
Next Topic:[EMFTVM] Profiling now available
Goto Forum:

Current Time: Sat May 26 08:30:08 GMT 2018

Powered by FUDForum. Page generated in 0.02167 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top