开发元数据
Java包org.eclipse.emf.ecore中包含了Ecore中每一个被建模类对应的接口。任何EMF对象的元数据是使用Ecore的实现(implementation)来表示的。这些信息在运行期间(runtime)总是可获取的,所以我们可以使用Ecore API来查询模型的结构,还可以使用反射式EObject API来访问和操纵实例中的数据。此外,仅通过实例化 Ecore,我们就可以在运行期间动态定义一个模型。
本章我们仔细研究EMF对象暴露的元数据,并且看看元数据是如何被反射和动态EMF机制所利用的。
包(Packages)
在第10章中,EMF生成了一个包接口,它为定义在包中的类型提供了对元数据的简单访问。
这个生成的接口仅仅是个便利:它提供的所有访问也可以在基本接口中使用泛型方法(generic methods)。例如,接口EPO2Package,它从ExtendedPO2模型中生成,它提供了有个便捷的方法来访问PurchaseOrder类。我们可以像这样使用它:
EClass poClass = epo2Package.getPurchaseOrder();
不使用这个生成类,我们可以使用EPackage接口中的getEClassifier方法来简单检索类,如下:
EClass poClass = (EClass)epo2Package.getEClassifier("PurchaseOrder");
我们可以类似地访问生成的包提供的属性,引用以及其他所有内容。
加载模型的序列化形式是个在运行期间获取元数据的有效方法。事实上,这也是在内存中创建模型的最初方法。但是,从磁盘中读取,解析XML,构建整个模型是非常昂贵的操作,所以对于给定的模型,我们应该只做一次。
我们希望可以检查两个EMF对象是否是同一个类的实例。
包注册表( package registry)提供对含有元数据的包的访问,不管这些包是如何被初始化的。
使用java.util.Map填充包注册表。键(key)是String类型命名空间URI,EPackage是值(value)。一些值也可能是EPackage的实例。
使用注册表键入的getEPackage()方法来注册生成的包。
当EMF独立运行时,生成的包通常是在构建的时候注册的,如下:
EPO2Package epo2Package = EPO2Package.eINSTANCE;
注册包还有其他两种通常的机制:URIConverters和xsi:schemaLocation,它们与没有生成代码的模型一起使用。包从它们的序列化形式中加载并自动注册。
一旦包被注册,就可以在任何需要它的时候轻松访问:在合适的* EPackage.Registry*上调用getEPackage()方法。例如,基于名称和包的命名空间URI,使用全局包注册表来获取特定EClassifier,如下: