教程–EMFStore–模型存储库

Eclipse建模框架(EMF)允许从一种非常集中和紧凑的模型语言Ecore生成Java实体。我们喜欢将生成的实体视为“类固醇上的javabean”,它们提供了额外的功能,例如更改通知和反射访问,而且生成的实体遵循相同的模板,非常类似于javabean(这里有更多关于EMF的信息)。这允许为不同的用例提供框架,这些用例适用于所有EMF实体。

这种框架的一个例子是EMFStore,EMF实体的服务器解决方案或“模型存储库”。EMFStore允许对实体进行并行和分布式编辑,支持连续的脱机工作。这意味着客户机可以修改可用的实体,直到它决定一组更改是一致的并且应该与其他客户机共享。通过EMFStore对EMF模型实体的交互式合并的支持,解决了两个客户机之间潜在的冲突更改。

试试看!

EMFStore模型库是一个无头框架。它通常与定制应用程序集成,为EMF实体提供协作和版本控制。但是,由于方法调用在视觉上对理解框架的使用没有帮助,EMFStore还提供了一个现成的示例应用程序。这个应用程序基于EMF客户机平台,EMF的一个通用UI框架。示例客户机提供了创建模型实体、修改它们以及与EMFStore服务器同步所有更改的功能。对于这个示例客户机,您只需要自己的EMF模型和生成的实体就可以试用EMFStore了。

要安装和运行EMFStore、EMF客户机平台并找到示例模型,这里和这里都有文档。本文使用的示例模型包含保龄球游戏中的实体,例如球员或联盟。但是,实体可以来自任何类型的域。

在EMFStore中尝试的第一件事是为您的模型创建一些实体。一种简单的方法是使用提供的示例客户机。EMFStore将实体组织到项目中。示例客户机提供了一个navigator视图,其中显示了所有项目以及包含的实体。编辑器视图允许您修改所创建实体的所有属性和引用。使用示例客户机,您可以在EMFStore服务器上共享项目之前在本地创建项目(请参见下面的图1)。

图1:示例客户端允许您创建和修改实体

一旦在本地创建了项目,就可以在EMFStore服务器上共享它。其他客户端可以签出共享项目。甚至可以在同一个客户机上多次签出同一个项目,例如,为了访问它的不同版本(参见下面的图2)。

图2:EMFStore允许您创建同一项目的多个签出

与EMFStore共享项目后,将跟踪应用于模型实体的所有更改。要了解其工作原理,可以添加新的模型实体或更改属性值。这些更改可以通过示例客户机、自定义客户机或实体的API(使用setter方法)进行。默认情况下,更改仅在本地项目中可见。一旦一组一致的更改完成,就可以将它们提交到EMFStore服务器。示例客户机将使用一个默认对话框,提示用户输入提交消息,描述应用的更改。此外,提交对话框允许在将更改传输到EMFStore服务器之前对其进行详细检查。提交也可以在没有任何UI交互的情况下触发(见下文)。

图3:默认提交对话框允许查看应用的更改并添加描述它们的注释

提交完成后,其他客户机可以触发更新以从EMFStore服务器接收最新更改。同样,示例客户机将显示一个对话框,详细描述应用的更改。此工作流将自动生成所有实体的非常详细的历史记录。示例客户机提供了一个查看项目所有早期版本的视图(参见下面的图4)。在此视图中,还可以签出项目的特定版本。

图4:历史视图允许查看和重新创建项目的所有版本

使用此工作流(提交/更新),任意数量的客户端可以在实体(应用程序的数据)上协作。所有更改都可以在本地完成,即使没有服务器连接。如前所述,客户机之间可能存在冲突的更改。例如,两个客户端可以同时为一个实体设置不同的名称。为了解决这个冲突,EMFStore服务器支持模型实体的交互式合并。示例客户机包括一个用于冲突解决和交互式合并的默认UI(参见图5)。

图5:如果客户机之间发生冲突,合并对话框允许选择要应用的更改

示例客户机提供了其他功能,例如用于管理对不同服务器的访问的存储库浏览器。示例客户机的所有UI组件都可以在自定义应用程序中重用。这样,就可以高效地创建一个支持所有特性的初始运行版本。使用EMFStore服务器的API,这里描述的所有特性也可以在没有默认UI组件的情况下使用。我们将在“API”一节中更详细地描述这个API。

幕后

EMFStore的用例与SVN、CVS或Git等源代码管理系统(SCM)非常相似。但是,从技术角度来看,EMFStore的工作原理是不同的。如果对EMF模型实体应用了Git等版本控制系统,则需要将它们序列化为文件,例如XMI。在提交或更新期间,将比较这些文件以计算应用的更改(差异化)。在SCMs中,这个过程是基于行的。虽然它对于原始用例、管理代码非常有效,但是这种技术对于模型和模型实体有着明显的缺点(参见基于操作的模型演化,Maximilian Kögel,Dr.Hut Verlag,ISBN:978-3843900812)。

原因主要是SCM管理文件和文本,但它不考虑模型本身。例如,如果两个客户机创建对同一模型实体的引用,SCM可能会检测到冲突,因为序列化中的相同行已更改。但是,从模型的角度来看,添加引用可能根本不是冲突。SCM的第二个问题是交互式合并支持,它同样是基于文本而不是基于模型的。由于实体上的更改(如添加引用)可能会更改序列化中完全不同的位置,因此基于文本的模型实体合并非常困难且容易出错。对于许多最终用户应用程序,基于文本的合并无论如何都不是一种选择。

为了解决这些问题,EMFStore使用了EMF模型实体的一个特性。EMF提供了通知实体上所有更改的功能,例如,更改属性或添加引用。EMFStore的客户机组件在本地记录所有这些更改。一旦触发了提交,就不需要任何差异。客户机已经知道本地应用了哪些更改。因此,只需将更改传输到服务器。这同样适用于更新。

记录更改创建了另一个主要优势,因为它比区分文件更精确。如果发生冲突,EMFStore可以考虑模型实体级别的信息。应用的更改不是文件中任意行中的更改–它是对实体的操作,例如“在Y和X之间添加了引用Z”。此附加信息允许更精确地检测冲突(请参阅上面的参考书)。在发生冲突的情况下,用户可以通过在模型实体级别上显示更改的UI来获得支持,这比合并文本文件更具信息性。冲突检测和解决策略甚至可以被调整,例如,包括特定于域的规则。最后,EMFStore还提供了一个历史记录,它比标准的SCM更详细(例如,可以跟踪应用更改的顺序)。

API

在“试试看!“,我们基于一个可扩展的示例客户机来描述最重要的用例。但是,EMFStore也可以独立于示例客户机使用,并且可以集成到现有的应用程序中。为了向您展示如何做到这一点,我们将介绍emfstoreapi中的一些示例。查看emfstoreapi的详细文档以了解更多信息。

客户机上的项目在允许您访问和创建项目的工作区中进行管理。项目由ProjectSpace管理,ProjectSpace的实体包含元信息,例如项目名称或跟踪的更改。以下代码示例检索当前工作区并创建新的本地项目:

Workspace workspace = WorkspaceManager.getInstance().getCurrentWorkspace();
ProjectSpace projectSpace = workspace.createLocalProject("ProjectName", "Project Description");

下一步是用模型实体填充本地项目。在EMF中,实体是由包含层次结构构成的(参见前面的教程示例)。以下调用将新实体添加到项目中:

projectSpace.getProject().getModelElements().add(myEntity);

使用getter和setter方法对实体进行常规更改,使EMFStore对客户端透明。如果将新实体添加到其他实体中,它们也会自动添加到项目中。下面的代码示例更改一个实体的属性,并将一个新实体添加到另一个实体中。

myEntity.setName(“xxx”);
myEntity.getChildren().add(newObject);

创建的项目仅在本地可用,但在下面的代码示例中,它与EMFStore服务器共享,因此可用于其他客户端。要管理与EMFStore服务器的连接,将创建一个UserSession,其中包含访问控制的凭据、服务器地址和端口。

Usersession usersession = EMFStoreClientUtil.createUsersession("super", "super",
 "localhost", 8080);
projectSpace.shareProject(usersession);

一旦项目在EMFStore服务器上共享,其他客户端就可以通过签出来检索它。在这种情况下,用户通常从从服务器检索到的可用项目列表中进行选择。下面的代码示例检索可用项目的列表,并选择第一个项目进行签出。

ListprojectList =
workspace.getRemoteProjectList(usersession);
workspace.checkout(usersession, projectList.get(0));

一旦项目在多个客户机上共享,就可以同步更改。第一步是对模型实体应用更改,例如。someElement.setName(“新名称”)。这些更改将自动记录并发送到EMFStore服务器:

projectSpace.commit(logMessage, null, new ConsoleProgressMonitor());

反过来,可以从触发更新的服务器检索更改:

projectSpace.update();

使用share、checkout、commit和update功能,您可以创建一个自定义客户机,通过EMFStore服务器同步其数据(模型实体)。API提供了许多附加功能,例如检索当前更改的列表或将项目状态重置为特定版本。

结论

EMFStore模型存储库是一种运行时技术,允许您协作修改EMF模型实体。使用EMF客户机平台提供的示例客户机,它帮助测试最重要的用例。与现有的源代码管理系统相比,EMFStore模型存储库不直接处理文件,而是在模型级别对实体进行版本化。这使得EMF模型实体的精确冲突检测以及交互式合并成为可能。EMFStore的所有功能也可以通过API触发。这允许将EMFStore集成到定制客户机中,无论是否使用UI。EMFStore是一个开源框架(Eclipse公共许可证)。源代码、版本和文档都可以在线获得。

作者介绍

用微信扫一扫

收藏