使用 eclipse uml2 解析 .uml 文件

Parse .uml file with eclipse uml2

我正在执行一项任务,我需要将 UML 图转换为我选择的任何语言的原型。我通过 eclypse papyrus 创建了一个图表并将其保存为 .uml 文件。它包含用例、状态机图和 class 图。将这些结合起来应该足以创建一个原型——状态代表屏幕及其后续操作。 Class 图提供了每个屏幕包含的信息,用例图提供了如何使用它的信息。然后我希望将 uml 文件加载到 java 代码。经过短暂的研究,eclipse uml2 包似乎是我所需要的——一个用于操作 UML 元素的工具。因此我设法加载了 UML 文件并以某种方式逐部分打印它:

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());

        }
    }
}

但是,这会产生以下输出(部分):

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])]
--------------------------------------------

我找不到对此的明确描述,我该如何操作这些对象?我需要确定哪一个是什么类型(例如 class、图边、演员等),并据此创建一个 UI 表示 - 例如,对于单个状态创建一个屏幕。我所能找到的只是将 UML 转换为代码的商业软件,没有我可以从中获得灵感的开源项目。有人可以提供一个示例,说明如何从 .uml 文件解析 UML 元素并可能对其进行处理(例如,println 完全可以)。也许在某处有描述,但我没找到?

通过研究文档,在论坛上到处查看,我能够为 UML 文件编写一些基本的解析器。现在它只解析状态机图的一个元素,有未完成的可能 attr 名称列表,只是打印出名称和值,但如果有人正在寻找这样的代码,我会在这里添加它,因为它很难找到一些例子。可能我解析它的方式不是 100% 正确,但它似乎有效。

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);}
        }
    }

}

输出如下:

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
...