Home > Blockchain >  Parse .uml file with eclipse uml2
Parse .uml file with eclipse uml2

Time:04-05

I am working on a task where I need to convert UML diagram to a prototype in any language that I choose. I have created a diagram through eclypse papyrus and saved it as .uml file. It contains Use-case, state machine diagram and class diagram. Combining those should be enough to create a prototype - states represent screens and their follow-up. Class diagram provides info what each screen contains and use-case diagram provides info how is it to be used. I then wish to load the uml file to a java code. After a short research, eclipse uml2 package seem to be what I need - a tool for manipulating UML elements. Thus I managed to load the UML file and somehow print it part by part:

import org.eclipse.emf.common.util.TreeIterator;
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.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.resource.UMLResource;

import java.util.Collection;
import java.util.Iterator;

public class Loader {

    public Loader(){
        //default behaviour
        ResourceSet set = new ResourceSetImpl();
        set.getPackageRegistry().put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
        set.getResourceFactoryRegistry().getExtensionToFactoryMap()
                .put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);
        Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap()
                .put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);

        Resource res = set.getResource(URI.createFileURI("C:/Users/gopco/workspace-papyrus/Test/Test.uml"), true);
        Resource model = set.createResource(URI.createFileURI("C:/Users/gopco/workspace-papyrus/Test/Test.uml"));

        for (TreeIterator<EObject> stuffInModel = res.getAllContents();
             stuffInModel.hasNext();) {
            EObject eObject = stuffInModel.next();
            System.out.println("--------------------------------------------");
            System.out.println(eObject.eContents());

        }
    }
}

However, this produces the following output (part of it):

first result ommited for size
--------------------------------------------
[org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@dd3b207 (eProxyURI: pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0 eClass: org.eclipse.emf.ecore.impl.EClassImpl@641147d0 (name: Model) (instanceClassName: null) (abstract: false, interface: false))]
--------------------------------------------
[]
--------------------------------------------
[org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@731f8236 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@255b53dc (name: Region) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [ecore.xml.type:text=
      , transition=org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@6b53e23f (eClass: org.eclipse.emf.ecore.impl.EClassImpl@64d2d351 (name: Transition) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [source=__KptIH08EeyJJLSm_hhhpA, target=_7Rd1EH08EeyJJLSm_hhhpA]), ecore.xml.type:text=
      , transition=org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@3b2c72c2 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@64d2d351 (name: Transition) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [name=InsertCardNo, source=_7Rd1EH08EeyJJLSm_hhhpA, target=_89NlMH08EeyJJLSm_hhhpA]), ecore.xml.type:text=
      , transition=org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@491666ad (eClass: org.eclipse.emf.ecore.impl.EClassImpl@64d2d351 (name: Transition) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [name=InsertPassword, source=_89NlMH08EeyJJLSm_hhhpA, target=_BNzQoH09EeyJJLSm_hhhpA]), ecore.xml.type:text=
      , transition=org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@176d53b2 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@64d2d351 (name: Transition) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [name=[invalid_InputData], source=_BNzQoH09EeyJJLSm_hhhpA, target=_7Rd1EH08EeyJJLSm_hhhpA]), ecore.xml.type:text=
      , transition=org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@971d0d8 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@64d2d351 (name: Transition) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [source=_BNzQoH09EeyJJLSm_hhhpA, target=_GwWTMH09EeyJJLSm_hhhpA]), ecore.xml.type:text=
      , subvertex=org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@2b4a2ec7 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@564718df (name: State) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [name=S1]), ecore.xml.type:text=
      , subvertex=org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@51b7e5df (eClass: org.eclipse.emf.ecore.impl.EClassImpl@564718df (name: State) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [name=S2]), ecore.xml.type:text=
      , subvertex=org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@18a70f16 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@62e136d3 (name: Pseudostate) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [name=Init]), ecore.xml.type:text=
      , subvertex=org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@c8e4bb0 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@564718df (name: State) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [name=S3]), ecore.xml.type:text=
      , subvertex=org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@6279cee3 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@4206a205 (name: FinalState) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [name=Final State]), ecore.xml.type:text=
    ], anyAttribute: [name=Region1])]
--------------------------------------------
[org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@6b53e23f (eClass: org.eclipse.emf.ecore.impl.EClassImpl@64d2d351 (name: Transition) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [source=__KptIH08EeyJJLSm_hhhpA, target=_7Rd1EH08EeyJJLSm_hhhpA]), org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@3b2c72c2 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@64d2d351 (name: Transition) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [name=InsertCardNo, source=_7Rd1EH08EeyJJLSm_hhhpA, target=_89NlMH08EeyJJLSm_hhhpA]), org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@491666ad (eClass: org.eclipse.emf.ecore.impl.EClassImpl@64d2d351 (name: Transition) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [name=InsertPassword, source=_89NlMH08EeyJJLSm_hhhpA, target=_BNzQoH09EeyJJLSm_hhhpA]), org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@176d53b2 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@64d2d351 (name: Transition) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [name=[invalid_InputData], source=_BNzQoH09EeyJJLSm_hhhpA, target=_7Rd1EH08EeyJJLSm_hhhpA]), org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@971d0d8 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@64d2d351 (name: Transition) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [source=_BNzQoH09EeyJJLSm_hhhpA, target=_GwWTMH09EeyJJLSm_hhhpA]), org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@2b4a2ec7 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@564718df (name: State) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [name=S1]), org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@51b7e5df (eClass: org.eclipse.emf.ecore.impl.EClassImpl@564718df (name: State) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [name=S2]), org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@18a70f16 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@62e136d3 (name: Pseudostate) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [name=Init]), org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@c8e4bb0 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@564718df (name: State) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [name=S3]), org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@6279cee3 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@4206a205 (name: FinalState) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [name=Final State])]
--------------------------------------------
[]
--------------------------------------------
[]
--------------------------------------------
[]
--------------------------------------------
[]
--------------------------------------------
[]
--------------------------------------------
[]
--------------------------------------------
[]
--------------------------------------------
[]
--------------------------------------------
[]
--------------------------------------------
[]
--------------------------------------------
[]
--------------------------------------------
[]
--------------------------------------------
[org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@61009542 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@77e9807f (name: Include) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [addition=_7NZC0H07EeyJJLSm_hhhpA])]
--------------------------------------------
[]
--------------------------------------------
[org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@44a664f2 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@7f9fcf7f (name: ExtensionPoint) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [name=ExtensionPoint1])]
--------------------------------------------
[]
--------------------------------------------
[org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@145eaa29 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@15bb6bea (name: Extend) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [extendedCase=_7NZC0H07EeyJJLSm_hhhpA, extensionLocation=_A3uvcH08EeyJJLSm_hhhpA])]
--------------------------------------------
[]
--------------------------------------------
[org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@41ee392b (eClass: org.eclipse.emf.ecore.impl.EClassImpl@1e67a849 (name: Generalization) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [general=_2gOwIH07EeyJJLSm_hhhpA])]
--------------------------------------------
[]
--------------------------------------------
[org.eclipse.emf.ecore.xml.type.impl.AnyTypeImpl@36f0f1be (eClass: org.eclipse.emf.ecore.impl.EClassImpl@1e67a849 (name: Generalization) (instanceClassName: null) (abstract: false, interface: false)) (mixed: [], anyAttribute: [general=_2gOwIH07EeyJJLSm_hhhpA])]
--------------------------------------------

I cannot find clear description for this, how can I manipulate these objects? I need to determine which one is of what type (Eg. class, graph edge, actor, etc.) and according to that, create a UI representation - for example for a single state create a single screen. All I can find is commercial software converting UML to code, no opensource projects I could take inspiration from. Can somebody provide an example how to parse UML elements from .uml file and possibly process it (for examples, println is totally OK). Maybe it is described somewhere but I haven't found?

CodePudding user response:

Studying the docs, looking here and there on forums I was able to write some basic parser for the UML file. Right now it is parsing only a single element of state machine diagram, has unfinished list of possible attr names and just prints out the names and values, but I am adding it here if soomebody ever was looking for such code as it is hard to find some examples. It is possible that the way I am parsing it is not 100% correct, but it seems to be working.

import org.eclipse.emf.common.util.TreeIterator;
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.eclipse.emf.ecore.util.BasicFeatureMap;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.resource.UMLResource;

import java.util.Arrays;
import java.util.List;

public class Loader {

    public Loader(){
        List<String> statemachine = Arrays.asList("Transition", "State", "Pseudostate", "FinalState");
        List<String> usecase = Arrays.asList("Actor", "UseCase", "Include", "ExtensionPoint", "Extend", "Generalization", "Association", "Property");
        List<String> classdiag = Arrays.asList("Class", "Property", "PrimitiveType", "LiteralInteger", "LiteralUnlimitedNatural","Association", "Generalization", "PrimitiveType");
        //default behaviour
        ResourceSet set = new ResourceSetImpl();
        set.getPackageRegistry().put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
        set.getResourceFactoryRegistry().getExtensionToFactoryMap()
                .put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);
        Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap()
                .put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);

        Resource res = set.getResource(URI.createFileURI("C:/Users/gopco/workspace-papyrus/Test/Test.uml"), true);

        boolean classd = false;
        boolean usecased = false;
        boolean stated = false;
        for (
                TreeIterator<EObject> i = res.getAllContents();
                i.hasNext();
        ) {
            EObject current = i.next();
            try {
                if(!stated & current.eClass().getName().equals("StateMachine")){
                    System.out.println("--------------------------------------------");
                    classd = false;
                    usecased = false;
                    stated = true;
                    System.out.println("State machine diagram found with these elements: ");
                }
                else if(!usecased & current.eClass().getName().equals("Interaction")){
                    System.out.println("--------------------------------------------");
                    classd = false;
                    usecased = true;
                    stated = false;
                    System.out.println("Use-case diagram found with these elements: ");
                }
                else if(!classd & current.eClass().getName().equals("Class")){
                    System.out.println("--------------------------------------------");
                    classd = true;
                    usecased = false;
                    stated = false;
                    System.out.println("Class diagram found with these elements: ");
                }
                else if (statemachine.contains(current.eClass().getName())){
                    System.out.println(current.eClass().getName()   " detected as a state machine element");
                    if (current.eClass().getName().equals("Transition")){
                        BasicFeatureMap m = (BasicFeatureMap)current.eGet(current.eClass().getEStructuralFeature ( "anyAttribute" ));
                        for(int elems=0;elems<m.basicList().size();elems  ){
                            System.out.println("The attr's name: " m.basicList().get(elems).toString().split("=")[0]);
                            System.out.println("The attr's value: " m.basicList().get(elems).getValue());
                        }
                    }
                }
                else if (usecase.contains(current.eClass().getName())){
                    System.out.println(current.eClass().getName()   " detected as a use-case element");
                }
                else if (classd & classdiag.contains(current.eClass().getName())){
                    System.out.println(current.eClass().getName()   " detected as a class diagram element");
                }
                else {
                    //System.out.println(current);
                    System.out.println(current.eClass().getName()   " - detected elements not contained in any diagram keywords");
                }
            }catch(Exception e) {System.out.println(e);}
        }
    }

}

The output follows:

Model - detected elements not contained in any diagram keywords
PackageImport - detected elements not contained in any diagram keywords
Model - detected elements not contained in any diagram keywords
--------------------------------------------
State machine diagram found with these elements: 
Region - detected elements not contained in any diagram keywords
Transition detected as a state machine element
The attr's name: source
The attr's value: __KptIH08EeyJJLSm_hhhpA
The attr's name: target
The attr's value: _7Rd1EH08EeyJJLSm_hhhpA
Transition detected as a state machine element
The attr's name: name
The attr's value: InsertCardNo
The attr's name: source
The attr's value: _7Rd1EH08EeyJJLSm_hhhpA
The attr's name: target
The attr's value: _89NlMH08EeyJJLSm_hhhpA
Transition detected as a state machine element
The attr's name: name
The attr's value: InsertPassword
The attr's name: source
The attr's value: _89NlMH08EeyJJLSm_hhhpA
The attr's name: target
The attr's value: _BNzQoH09EeyJJLSm_hhhpA
Transition detected as a state machine element
The attr's name: name
The attr's value: [invalid_InputData]
The attr's name: source
The attr's value: _BNzQoH09EeyJJLSm_hhhpA
The attr's name: target
The attr's value: _7Rd1EH08EeyJJLSm_hhhpA
Transition detected as a state machine element
The attr's name: source
The attr's value: _BNzQoH09EeyJJLSm_hhhpA
The attr's name: target
The attr's value: _GwWTMH09EeyJJLSm_hhhpA
State detected as a state machine element
State detected as a state machine element
Pseudostate detected as a state machine element
State detected as a state machine element
FinalState detected as a state machine element
--------------------------------------------
Use-case diagram found with these elements: 
Actor detected as a use-case element
UseCase detected as a use-case element
Include detected as a use-case element
UseCase detected as a use-case element
ExtensionPoint detected as a use-case element
UseCase detected as a use-case element
Extend detected as a use-case element
UseCase detected as a use-case element
Generalization detected as a use-case element
...
  • Related