# XMI über EMF / UML2 einlesen



## HTWTeam (2. Nov 2009)

Hallo,

wir sind gerade dabei, eine XMI Datei über das Eclipse Modelling Framework Projekt und dem UML2 Projekt einzulesen.

Folgenden Thread haben wir gefunden und auch den Code ausprobiert:
http://www.java-forum.org/xml-co/82142-xmi-parsen-ueber-emf.html#post511745

Beim Einlesen mit

```
org.eclipse.uml2.uml.Package package1 = load(model);
```
wird auch keine Exception geworfen, allerdings ist die Variable "package1" nach dem Ladevorgang immernoch "null".

Hat jemand eine Idee woran dies liegen könnte?

Als Alternative zu EMF / UML2 käme für uns auch jeder andere frei verfügbare XMI 2.1 Parser in Frage.


----------



## Wildcard (2. Nov 2009)

Wie sieht dein Code zZ aus?


----------



## HTWTeam (2. Nov 2009)

Folgenden Code nutzen wir derzeit:


```
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Type;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		org.eclipse.uml2.uml.Package package1 = null;
		
		URI uri = URI.createURI("file:///C:/testcase.xmi"); 
		UMLModel.init();
		package1 =UMLModel.load(uri);
		
		for (Type e : package1 .getOwnedTypes()) 
		   System.out.println(e.getName());
		
		System.out.println("ok");
	}
}
```


Diese Datei stammt aus dem Beispiel der Seite eUML und steht unter der Eclipse Public License

```
/**
 * This class uses functionality from
 * com.ibm.uml2.articles plugin found
 * here: [url=http://www.eclipse.org/modeling/mdt/uml2/docs/articles/Getting_Started_with_UML2/article.html]Getting Started with UML2[/url] 
 */


import java.io.File;
import java.io.IOException;
import java.util.Iterator;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
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.URIConverter;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.uml2.uml.AggregationKind;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.UMLFactory;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.resource.UMLResource;
import org.eclipse.uml2.uml.util.UMLUtil;

public class UMLModel {

	private static org.eclipse.uml2.uml.Package model;

	private static final ResourceSet RESOURCE_SET = new ResourceSetImpl();

	private static void registerResourceFactories() {
		Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(
				UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);
		Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(
				"xmi", UMLResource.Factory.INSTANCE);
	}

	private static void registerPathmaps(URI uri) {
		URIConverter.URI_MAP.put(URI.createURI(UMLResource.LIBRARIES_PATHMAP),
				uri.appendSegment("libraries").appendSegment(""));
		URIConverter.URI_MAP.put(URI.createURI(UMLResource.METAMODELS_PATHMAP),
				uri.appendSegment("metamodels").appendSegment(""));
		URIConverter.URI_MAP.put(URI.createURI(UMLResource.PROFILES_PATHMAP),
				uri.appendSegment("profiles").appendSegment(""));
	}

	private static void save(org.eclipse.uml2.uml.Package package_, URI uri) {
		Resource resource = RESOURCE_SET.createResource(uri);
		EList contents = resource.getContents();
		contents.add(package_);

		for (Iterator allContents = UMLUtil.getAllContents(package_, true,
				false); allContents.hasNext();) {

			EObject eObject = (EObject) allContents.next();

			if (eObject instanceof Element) {
				contents
						.addAll(((Element) eObject).getStereotypeApplications());
			}
		}

		try {
			resource.save(null);
		} catch (IOException ioe) {
			System.err.println(ioe.getMessage());
		}
	}

	public static org.eclipse.uml2.uml.Package load(URI uri) {
		registerPathmaps(uri);
		org.eclipse.uml2.uml.Package package_ = null;

		try {
			Resource resource = RESOURCE_SET.getResource(uri, true);

			package_ = (org.eclipse.uml2.uml.Package) EcoreUtil
					.getObjectByType(resource.getContents(),
							UMLPackage.Literals.PACKAGE);
		} catch (WrappedException we) {
			System.err.println(we.getMessage());
			System.exit(1);
		}

		return package_;
	}

	protected static void save(File file) {
		String s = file.toURI().toString();
		if (!s.toLowerCase().endsWith(".xmi"))
			s += ".xmi";
		save(model, URI.createURI(s));
	}

	protected static void load(File file) {
		model = load(URI.createURI(file.toURI().toString()));
	}

	protected static org.eclipse.uml2.uml.Package getModel() {
		return model;
	}

	protected static void createClass(String name) {
		model.createOwnedClass(name, true);
	}

	protected static void createAssociation(String s1, String s2) {
		model.getOwnedType(s1).createAssociation(true,
				AggregationKind.NONE_LITERAL, "[" + s1 + "]", 1, 1,
				model.getOwnedType(s2), true, AggregationKind.NONE_LITERAL,
				"[" + s2 + "]", 1, 1);
	}

	public static void init() {
		registerResourceFactories();
		model = UMLFactory.eINSTANCE.createModel();
		model.setName("uml2_simple_model");
	}

//	protected static void new_() {
//		while (!model.getOwnedElements().isEmpty()) {
//			model.getOwnedElements().get(0).destroy();
//		}
//	}

}
```

Jetzt kommt der Teil, der etwas verwirrend ist. Wenn die Klasse "Test" ausgeführt wird und als Build-Libraries die bei dem eUML Projekt mitgelieferten (EMF 2.3 und UML2 2.1) verwendet werden funktioniert das Einlesen der XMI Datei und die Ausgabe der enthaltenen Klassen. Sobald als Build-Libraries die aktuellen Pakete (d.h. die aktuellen EMF 2.5.0 und UML2 3.0.1 Pakete) angegeben werden, gibt es zwar wie schon geschildert bei der load-Methode keine Fehler, allerdings bleibt die Variable "package1" leer und somit löst der dann folgende Code der die Klassennamen ausgeben soll eine NullPointerException aus.

Leider unterstüzt die ältere Version von UML2 kaum aktuelle Programme und deshalb sollten wir die aktuelle Version verwenden und dort funktioniert wie geschildert der Ladevorgang nicht.

Vielen Dank im Voraus für die Hilfe


----------



## Wildcard (3. Nov 2009)

Vielleicht hat sich ja am UML3 Modell etwas inkompatibel geändert.
Versuch mal folgendes:

```
registerPathmaps(uri);
        Resource resource = RESOURCE_SET.getResource(uri, true);
        EObject o = resource.getContents().get(0);
```


----------



## HTWTeam (4. Nov 2009)

Danke, wir wissen jetzt auch woran es lag, dass der andere Code nicht funktioniert.

Wenn der xmlns:uml Tag der XMI-Datei eine Versionsnummer unter 3.0.0 hat, wird die Datei nicht eingelesen, sobald diese hochgesetzt wird, funktioniert es:
xmlns:uml="http://www.eclipse.org/uml2/3.0.0/UML

Wenn die Datei allerdings über die normale GUI des Eclipse UML2 Projekts geöffnet wird, wird dies automatisch angepasst. Leider wissen wir noch nicht über welche Methode(n) dies funktioniert.

Es ist auch keine dauerhafte Lösung die Versionsnummer einfach hochzusetzen, da zwischen den Versionen immer einige Notationen geändert wurden und diese ggf. angepasst werden müssen. Beim Laden der Datei über die GUI wird dies automatisch erledigt.

Wer hat eine Idee über welche Methode wir die XMI Dateien so laden können wie es über die GUI gemacht wird?


----------



## Wildcard (4. Nov 2009)

UML2 2.2 Migration Guide


----------



## HTWTeam (4. Nov 2009)

Wildcard hat gesagt.:


> UML2 2.2 Migration Guide


Danke, den haben wir bereits gelesen. Wir konnten dort aber keine Informationen darüber finden über welche Methoden die automatische Migration beim Öffnen über die GUI stattfindet.


----------



## Wildcard (4. Nov 2009)

Vielleicht findet sich in einem der Bugreports die genau Änderung. MDT/UML2/New and Noteworthy/Galileo - Eclipsepedia
Ansonsten, einfach selbst im Quellcode nachschauen, oder bei den UML2 Leuten nachfragen.


----------

