tba*_*ker 5 java eclipse-rcp eclipse-emf emf
情况
我有一个Eclipse RCP应用程序,用于管理EMF模型中的应用程序项目.
通过将它们序列化为XMI格式来保存这些项目.然后可以将这些文件加载回模型中.我使用标准的EMF工具(例如Resource).
由于模型重构,以下内容已更改:
MyClass带有属性的EClass Name(带大写字母).<MyClass Name="My Class Name 1" ... />与
MyClass继承自MyBaseClass,带属性name(没有大写字母).MyClass不再具有Name属性,因为EMF不允许这两者.这是有意义的,因为它会碰到例如getter方法getName().问题
如何将旧的 XMI项目文件加载到我的新模型中?
直到这个问题,我能够:
但是,在这种情况下,我无法首先加载XMI文件:模型name一方面未命中属性,另一方面无法识别(因而忽略)属性Name.
题
实现此向后兼容性支持的正确位置是什么?
我假设我应该处理反序列化过程或XML映射.
解决方案的约束是:
<MyClass name="..." ... />必须正确加载新项目(包含).Ed Merks 在EMF 论坛上解决了这个问题。
ExtendedMetaData通过拦截 XML 映射来支持向后兼容性的最简洁方法是在 EMF 资源上启用 的实现。此类是调整 EMF 资源及其内容的中心入口点。它避免了必须专门化 EMF 框架内的各种其他类。
但是,我的项目已经有一个专门的XMLHelper类,用于处理 XML 序列化/反序列化,因此 Ed Merks 帮助解决了该类中的问题。
请注意,XMI源代码显示了在资源上启用该工具时如何调用该工具!XMLHelperImpl ExtendedMetaData
XMLHelper/**
* Helper class that allows intercepting the XML to model mapping, to support backwards compatibility.
* <p>
* 2 methods must be overridden to handle compatibility mappings:
* <dl>
* <dt>{@link XMLHelperImpl#getFeature(EClass, String, String, boolean)}</dt>
* <dd>Is called to map features of a certain EClass. These include attributes and child elements in the XML file.</dd>
* <dt>{@link XMLHelperImpl#getType(EFactory, String)}</dt>
* <dd>Is called to map types that are used in the model.</dd>
* </dl>
* <p>
* Their difference becomes clear by looking at the model file. Sometimes both need to be handled. For example:
* <ul>
* <li>a {@link Person} has zero or more {@link Person#getPhoneNumber()} configurations ('feature')</li>
* <li>these features are of type {@link PhoneNumber} or possibly a subclass! ('type')</li>
* </ul>
* <p>
* See https://www.eclipse.org/forums/index.php/m/1449615/
*/
public class CustomXmlHelper extends XMLHelperImpl implements XMLHelper {
public CustomXmlHelper() {
super();
deresolve = true;
}
public CustomXmlHelper(XMLResource resource) {
super(resource);
deresolve = true;
}
@Override
public EStructuralFeature getFeature(EClass eClass, String namespaceURI, String name, boolean isElement) {
String compatName = name;
if (eClass == ProjectModelPackage.Literals.MyClass) {
if (!isElement && "Name".equals(name)) {
// 1.x to 2.x compatibility (October 2014)
// 1.x = MyClass attribute 'Name'
// 2.x = MyBaseClass attribute 'name', shared by MyClass
compatName = ProjectModelPackage.Literals.EMY_BASE_CLASS__NAME.getName(); // 'n(!)ame'
}
}
// future feature mappings handled here
return super.getFeature(eClass, namespaceURI, compatName, isElement);
}
@Override
public EClassifier getType(EFactory eFactory, String name) {
String compatName = name;
if (eFactory == ProjectModelPackage.eINSTANCE) {
// placeholder for type compatibility
// if ("OldTypeName".equals(name)) {
// compatName = ProjectModelPackage.Literals.NEW_TYPE_NAME.getName();
// }
}
return super.getType(eFactory, compatName);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
520 次 |
| 最近记录: |