summaryrefslogtreecommitdiff
path: root/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FDeployManager.java
blob: a6c62a9e965e85b7d7b05f7846fa952e934b4ccc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package org.genivi.commonapi.core.generator;

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.franca.core.dsl.FrancaImportsProvider;
import org.franca.core.utils.ImportsProvider;
import org.franca.deploymodel.dsl.FDeployImportsProvider;

/**
 * The FDeployManager loads models from fdepl files and from fidl files that are imported in a fdepl file.
 * It continues to import files even it could not find all of them (e.g an unknown deployment specification).
 * 
 * @author gutknecht
 *
 */
public class FDeployManager {

	private final static String fileExtension = "fdepl";

	private ResourceSet resourceSet;
	
	/**
	 * Map used to handle generically different model files. 
	 */
	private static Map<String, ImportsProvider> fileHandlerRegistry = new HashMap<String, ImportsProvider>();

	public FDeployManager() {
		
		resourceSet = new ResourceSetImpl();
		
		// we expect fdepl files
		fileHandlerRegistry.put(fileExtension, new FDeployImportsProvider());
		// allow for fidl file imports
		fileHandlerRegistry.put("fidl", new FrancaImportsProvider());
	}	
	
	/**
	 * 
	 * Load the model found in the fileName. Its dependencies (imports) can be loaded subsequently.
	 * @param uri       the URI to be loaded
	 * @param root      the root of the model (needed for loading multiple file models)
	 *                  This has to be an absolute, hierarchical URI.
	 * @return the root model or null in case of an error.
	 */
	public EObject loadModel(URI uri, URI root) {
		// resolve the input uri, in case it is a relative path
		URI absURI = uri.resolve(root);
		if (! uri.equals(absURI)) {
			// add this pair to URI converter so that others can get the URI by its relative path
			resourceSet.getURIConverter().getURIMap().put(uri, absURI);
		}
		
		// load root model
		Resource resource = null;
		try {
			resource = resourceSet.getResource(absURI, true);
			resource.load(Collections.EMPTY_MAP);
		} catch (Exception e) {
			// Don't show an error message here, because code may be generated from an included fidl file.
			//System.err.println("Failed to load model from : " + absURI);
			return null;
		}
		EObject model = resource.getContents().get(0);
		
		// load all its imports recursively
		for (Iterator<String> it = fileHandlerRegistry.get(absURI.fileExtension()).importsIterator(model); it.hasNext();) {
			String importURIStr = it.next();
			URI importURI = URI.createURI(importURIStr);
			URI resolvedURI = importURI.resolve(absURI);
			
			// add this pair to URI converter so that others can get the URI by its relative path
			resourceSet.getURIConverter().getURIMap().put(importURI, resolvedURI);
			//System.out.println("trying to load model " + resolvedURI);
			model = loadModel(resolvedURI, root);
			if(model == null) {
				// something went wrong with this import, go on with the next one
				continue;
			}
		}
		return  model;
	}

	/**
	 * @return the file extension this class will deal with (.fdepl)
	 */
	public static String fileExtension() {
		return fileExtension;
	}	
	
	
}