[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Newsgroup Home]
[news.eclipse.tools.emf] Re: Model Migration

Mike,

Comments below.

Mike Gering wrote:
I've figured out how to use the ecore2xml method for migrating a
serialized model from a prior version. I hacked the code into the
generated Editor.createModel() method to get the basic method working.
You deserve a prize!
Now I want to refactor that code so the migration occurs no matter how
the model is loaded.

I think the right approach is to create and register a ResourceFactory.
Yes.
I created a subclass of XMIResourceFactoryImpl and overrode
createResource(URI uri):

    public Resource createResource(URI uri) {
        EPackage.Registry ePackageRegistry = new EPackageRegistryImpl(EPackage.Registry.INSTANCE);
        ePackageRegistry.put("http://www.ibm.com/vce/1.0.0/rules", RulesPackage.eINSTANCE);
        ePackageRegistry.put("platform:/plugin/com.ibm.adt.vce.rules.model/model/Rules.ecore", RulesPackage.eINSTANCE);
        ResourceSet resourceSet = new ResourceSetImpl();
You could have just used the resourceSet's package registry without creating one because it's implemented like this:
  public EPackage.Registry getPackageRegistry()
  {
    if (packageRegistry == null)
    {
      packageRegistry = new EPackageRegistryImpl(EPackage.Registry.INSTANCE);
    }
    return packageRegistry;
  }
        resourceSet.setPackageRegistry(ePackageRegistry);
        Ecore2XMLRegistry ecore2xmlRegistry = new Ecore2XMLRegistryImpl(Ecore2XMLRegistry.INSTANCE);
        ecore2xmlRegistry.put("http://www.ibm.com/vce/1.0.0/rules",
                EcoreUtil.getObjectByType(
                        resourceSet.getResource(URI.createURI("platform:/plugin/com.ibm.adt.vce.rules.model/model/Rules100_2_Rules.ecore2xml"),
                                true).getContents(),
                                Ecore2XMLPackage.Literals.XML_MAP));
I see.  You're loading that resource for the mapping and ensuring that you've mapped the development time model to the real generated model.  It strikes me though that you should only have to do this once ever, not once each time a resource is created.  So it's better to do this once and cache the result for reuse with each resource created.
        ExtendedMetaData extendedMetaData = new Ecore2XMLExtendedMetaData(EPackage.Registry.INSTANCE, ecore2xmlRegistry);
        Map defaultLoadOptions = resourceSet.getLoadOptions();
        defaultLoadOptions.put(XMLResource.OPTION_EXTENDED_META_DATA,
                extendedMetaData);
        defaultLoadOptions.put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE,
                Boolean.TRUE);
        defaultLoadOptions.put(XMLResource.OPTION_RESOURCE_HANDLER,
                new RulesResourceHandler());
So these are the options you want to set on the resource you create, but you've set them on the resource set that's not used again beyond this point in the code.  What you'll want to do is create the resource and put these options into the resource's load options.
        Resource resource = super.createResource(uri);
       
        return resource;
    }

It isn't working -- my resource handler never gets invoked and none of substitutions are made.
Nope I don't imagine they would.

So, what is the best way to package this so the migration occurs whenever the resource is loaded?
It can be improved a little.  :-P

Note that in EMF 2.4 it's possible to register against a content type so that you could register this resource factory to apply only for resources that use the old namespace.  Unfortunately the docs are non-existent.  The XMI plugin shows how the content type for Ecore itself is registered so at least there's one working example and obviously I'll be happy to answer questions about it...

Thanks,
Mike Gering