summaryrefslogtreecommitdiff
path: root/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FDeployManager.java
blob: d23896fd6b19290495d875c625c1cb5e2b09e2a7 (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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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.franca.FModel;
import org.franca.core.utils.ImportsProvider;
import org.franca.deploymodel.dsl.FDeployImportsProvider;
import org.franca.deploymodel.dsl.fDeploy.FDModel;
import org.franca.deploymodel.dsl.fDeploy.Import;

/**
 * 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);
			// Set the isLoaded flag to false in order to force reloading of fdepl or imported fidl files
			resource.unload();
			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();
			if(importURIStr != null) {
				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);
				EObject localModel = loadModel(resolvedURI, root);
				if(localModel == 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;
	}	
	
	/**
	 * Load the model from fdepl that has an fidl file import
	 * @param fdmodel - the deployment model from fdepl 
	 * @param input - the fdepl uri
	 * @return the model defined in the fidl file import
	 */
	public FModel getModelFromFdepl(FDModel fdmodel, URI input) {
		for(Import fdimport : fdmodel.getImports()) {
			String uriString = fdimport.getImportURI();
			if (uriString.endsWith("fidl")) {
				URI newUri = URI.createURI(uriString);
				URI fidlUri = newUri.resolve(input);
				// load model
				Resource resource = null;
				try {
					resource = resourceSet.getResource(fidlUri, true);
					resource.load(Collections.EMPTY_MAP);
				} catch (Exception e) {
					// failed to  load model from fidl
					return null;
				}
				return (FModel) resource.getContents().get(0);
			}
		}
		return null;
	}	
	
	
}