【问题标题】:How can I load a papyrus uml model by using Java?如何使用 Java 加载纸莎草 uml 模型?
【发布时间】:2016-03-07 11:21:21
【问题描述】:

我使用纸莎草创建了一个类图,并获得了一个 *.uml 模型。现在我想通过编写一些 Java 代码来遍历 *.uml 元素。

我试过这段代码:

URI uri = URI.createURI("*.uml");

ResourceSet set = new ResourceSetImpl();

set.getPackageRegistry().put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
set.getResourceFactoryRegistry().getExtensionToFactoryMap()
       .put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);
EPackage.Registry.INSTANCE.put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap()
       .put("uml", UMLResource.Factory.INSTANCE);

set.getResourceFactoryRegistry().getExtensionToFactoryMap()
       .put("xmi", new XMIResourceFactoryImpl());
//set.createResource(uri);
Resource res = set.getResource(URI.createURI(new URL("*.uml").toString(),true),true);

但我遇到了异常:

线程“主”java.lang.NoSuchMethodError 中的异常: org.eclipse.emf.ecore.resource.URIConverter.createInputStream( Lorg/eclipse/emf/common/util/URI;Ljava/util/Map;)Ljava/io/InputStream;

如何使用 Java 加载纸莎草 uml 模型?

【问题讨论】:

    标签: java uml emf papyrus


    【解决方案1】:

    你几乎得到了所有东西,它只遗漏了一些细节,并且有一些线条需要删除。

    但首先,.uml 文件与 Papyrus 没有直接关系。 Papyrus 能够生成 .uml 文件,但它们不仅仅是 Papyrus 文件。此文件扩展名由 UML 插件管理,该插件提供 UML 元模型(在 Ecore 中定义)、它的实现和处理这些文件的不同工具。

    如果我们获取您的代码:

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

    这部分应该足以将 UML 元模型及其工厂注册到您的ResourceSet

    这一行:

    EPackage.Registry.INSTANCE.put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
    

    只要您使用set 加载模型,就不需要。 ResourceSetImpl 中包含的包Registry 是分层的:如果它找不到链接到元模型URI 的元模型包实例,它会尝试在全局EPackage.Registry 中找到它。因此,要么在全局注册表中注册绑定 (URI string, EPackage instance),要么在 ResourceSet 实例中注册绑定。两者都不是必需的。

    另外,您的情况也不需要xmi 工厂注册。

    最后,使用 ResourcetSet 中的 getResource 加载资源差不多好了,这里是修改后的版本:

    Resource res = set.getResource(URI.createFileURI("/path/to/my_model.uml"), true);
    

    此片段创建一个URI,它指向您磁盘上的一个文件并加载它。然后,您可以从您的资源中使用 getContents() 方法访问您的元素。

    res.getContents().get(0); // For example to get the root of your model.
    

    另外,尽量使用UMLUtilUML2UtilEcoreUtil静态类,它提供了很多查找/复制/过滤...元素的便利

    这是我使用的最后一个片段:

    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("/path/to/my_model.uml"), true);
    

    编辑 > 大部分问题是使用的 EMF 版本。从 EMF 2.3 到 >2.4 修复了异常抛出。为了清理不必要的代码,其余答案仍然有效。

    【讨论】:

    • 感谢您的回答,我尝试了您的代码,但出现异常:线程“main”中的异常 java.lang.NoSuchMethodError: org.eclipse.emf.ecore.resource.URIConverter.createInputStream( Lorg/eclipse/emf/common/util/URI;Ljava/util/Map;)Ljava/io/InputStream;在 org.eclipse.emf.ecore.xmi.impl.XMLHandler.getPackageForURI(XMLHandler.java:2534) 在 org.eclipse.emf.ecore.xmi.impl.XMLHandler.getFactoryForPrefix(XMLHandler.java:2422) 在 org.eclipse .emf.ecore.xmi.impl.XMLHandler.createObjectByType(XMLHandler.java:1299)
    • 您的依赖项似乎有问题,您使用的是哪个版本的 EMF?
    • 我在我的项目中使用这些 emf jar 包:eclipse-emf-ecore-2.3.1.jar org.eclipse.emf.common-2.8.0.v20130125-0546.jar org.eclipse .emf.ecore.xmi.jar org.eclipse.emf.ecore-2.8.1.v20120911-0500.jar org.eclipse.uml2.common_1.7.0.v20120913-1441.jar org.eclipse.uml2.types_1.0.0。 v20120913-1441.jar org.eclipse.uml2.uml.resources-3.1.0.v201005031530.jar org.eclipse.uml2.uml_4.0.1.v20120913-1441.jar 感谢您的帮助..
    • 您的 EMF 版本似乎有点过时(3 年了)。我不知道问题是否来自于此,但有疑问:您可以尝试下载最新的“Eclipse Modeling”版本,创建一个新项目,链接新 jar 并构建一个小的最小 main 吗?
    • 谢谢它现在可以使用,我现在使用的是 emf 2.11 版,现在也不例外,但是当我使用这行代码时 Model root = (Model)EcoreUtil.getRootContainer(UMLPackage.eINSTANCE.获取模型());我得到错误: org.eclipse.uml2.uml.internal.impl.UMLPackageImpl 不能转换为 org.eclipse.uml2.uml.Model 所以我使用了这个代码 EList lst = res.getContents(); ModelImpl 模型 = (ModelImpl)lst.get(0);模型根 = model.getModel();是一样的吗?!以及如何遍历模型元素?
    猜你喜欢
    • 2014-01-13
    • 2012-05-20
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-21
    • 2013-07-17
    相关资源
    最近更新 更多