java - Eclipse EMF: Customize XML deserialization so old project can be loaded into modified model -
java - Eclipse EMF: Customize XML deserialization so old project can be loaded into modified model -
situation
i have eclipse rcp application manages application projects within emf model.
these projects saved serializing them xmi format. such files can loaded model. utilize standard emf tools (such resource) this.
due model refactoring, next has changed:
old model eclassmyclass
attribute name
(with capital letter). xmi: <myclass name="my class name 1" ... />
vs.
new model eclassmyclass
inherits mybaseclass
, attribute name
(without capital letter). eclass myclass
no longer has name
attribute, since emf not allow both. makes sense collide on e.g. getter method getname()
. problem
how can load old xmi project file new model?
up until problem able either:
avoid modifying model grow model contain both old , new structures , perform modification after loading project file: moving info old new types, updating references,....in case, however, cannot load xmi file in first place: model misses attribute name
on 1 hand , not recognize (and ignores) attribute name
on other.
question
what right place implement backwards compatibility support?
i assume should work on deserialization process or xml mapping.
constraints solution are:
new projects (containing<myclass name="..." ... />
) must loaded correctly well. saving (i.e. serializing) project model should happen in new format!
this question resolved ed merks on emf forums.
backgroundthe cleanest way back upwards backward compatibility intercepting xml mapping, enabling implementation of extendedmetadata
on emf resource. class central entry point tweaking emf resources , content. avoids having specialize various other classes within emf framework.
however, project had specialized xmlhelper
class, handles xml serialization/deserialization, ed merks helped solve issue within class.
note xmi xmlhelperimpl
source code shows how extendedmetadata
tool called when enabled on resource!
xmlhelper
/** * helper class allows intercepting xml model mapping, back upwards backwards compatibility. * <p> * 2 methods must overridden handle compatibility mappings: * <dl> * <dt>{@link xmlhelperimpl#getfeature(eclass, string, string, boolean)}</dt> * <dd>is called map features of eclass. these include attributes , kid elements in xml file.</dd> * <dt>{@link xmlhelperimpl#gettype(efactory, string)}</dt> * <dd>is called map types used in model.</dd> * </dl> * <p> * difference becomes clear looking @ model file. both need handled. example: * <ul> * <li>a {@link person} has 0 or more {@link person#getphonenumber()} configurations ('feature')</li> * <li>these features of type {@link phonenumber} or perchance 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 2.x compatibility (october 2014) // 1.x = myclass attribute 'name' // 2.x = mybaseclass attribute 'name', shared myclass compatname = projectmodelpackage.literals.emy_base_class__name.getname(); // 'n(!)ame' } } // future feature mappings handled here homecoming super.getfeature(eclass, namespaceuri, compatname, iselement); } @override public eclassifier gettype(efactory efactory, string name) { string compatname = name; if (efactory == projectmodelpackage.einstance) { // placeholder type compatibility // if ("oldtypename".equals(name)) { // compatname = projectmodelpackage.literals.new_type_name.getname(); // } } homecoming super.gettype(efactory, compatname); } }
java eclipse-rcp eclipse-emf emf
Comments
Post a Comment