Mar 15, 2008

How does EMF finds the right parser?

ResourceSet resourceSet = new ResourceSetImpl();
Resource resource = resourceSet.createResource(someUri);


The API can't get any simpler. But the implementation details behind this is not simple. Resources are generally loaded by Resource.Factory. Your ECore model would have generated an appropriate Factory. You can find it in the util package with the name {your model name}ResourceFactoryImpl. Lets take a journey from the ResourceSet to this Factory.

ResourceSetImpl class delegates the job of finding the right Factory to the Resource.Factory.Registry. The default implementation of the registry (ResourceFactoryRegistryImpl) tries to find the factory by:

* lookup in the protocol map for the uri
* lookup in the extension map for the uri
* lookup in the content type map for the uri
* lookup in the extension map for the default extension (*)
* lookup in the content type map for the default content type (*)


If the above lookups did not find a factory then the delegatedGetFactory() method is called.

All three maps (protocol, extension & content type) are by default empty in the ResourceFactoryRegistryImpl. Either you can subclass and initialize in your constructor or call the resourceFactory.get{map type}ToFactoryMap().put({key}, {value}) to add your entries.

Since we have not added any entries in the registry, the delegatedGetFactory() method is called. The ResourceSetImpl overrides that method (thru an anonymous subclass of ResourceFactoryRegistryImpl) and calls again the getFactory() method with the maps from Resource.Factory.Registry.INSTANCE. BTW, all three maps in that instance are filled with the details from the extension points:

org.eclipse.emf.ecore.protocol_parser
org.eclipse.emf.ecore.extension_parser
org.eclipse.emf.ecore.content_parser

You should be using these extensions to register the right parser (the generated
ResourceFactoryImpl) for your resource.

Phew! If you think its done, you should look into the EMF code. All the above said stuff are optimized to the core. The ResourceSetImpl creates the ResourceFactoryRegistryImpl instance only when the getResourceFactoryRegistry() is called for the first time; all the above lookups are performed only when the map is not empty; and so on. EMF takes all the pain and finally we end up with:

ResourceSet resourceSet = new ResourceSetImpl();
Resource resource = resourceSet.createResource(someUri);


See, you got to love EMF. Or in general, Eclipse for making our life easier :-)

Related:

EMF Packing changes in 2.4
Using EMF with XML Catalog
Converting EMF Resource to Platform Resource (IFile)

0 comments: