EMF Compare Editor Investigation
This page is for anyone to contribute notes on how to get EMF Compare working with Rodin Files
This is the documented method for using the EMF Compare editor
- An extension to add a file association to EMF Compare for *.bum and *.buc files
(Doing this breaks the Rodin DB getRodinFile(Name) operations because it thinks files with these extensions are no longer Rodin files)
<extension point="org.eclipse.core.runtime.contentTypes"> <file-association content-type="org.eclipse.emf.compare.ui.contenttype.ModelContentType" file-extensions="bum,buc"> </file-association> </extension>
Colin's Notes
- you need to make a file association with *.bum to the EMF compare editor. (you can do this in preferences but it is better to do it by a content type extension)
- doing this does not work because the text compare editor opens in preference (I think this is because Rodin content type is based on XML - not XMI which is the EMF content type)
- the new file association breaks the RodinDB getRodinFile operation because this operation sees the wrong file association and regards it as a non-rodin file (hence the new component wizard reports an invalid name)
- I have tried to alter the priorities in the content type extensions (rodin core, eventb core etc) but this did not seem to work
- I tried to alter the descriptors in the content type extensions to break the link to XML - I added a new descriptor that detects the root element of a machine file - but this just breaks the RodinDB again because it can't get the content type its expecting (hence the editor raises a null pointer exception because the rodin file is returned as null) -> it appears to get the EMF compare one (good!) but the EMF compare editor still didn't open.
24/09/09
I noticed that the org.eclipse.emf.compare.ui plugin binds some explicit content types as well as the documented "ModelContentType" one mentioned above. E.g. there is a binding for an ecore type to link it to the "ModelContentMergeViewer" and ModelStructureMergeViewer". I guess they may have had similar problems to us. Therefore I added similar content bindings for machineFile and contextFile contentTypes:
<extension point="org.eclipse.compare.contentMergeViewers"> <contentTypeBinding contentMergeViewerId="org.eclipse.emf.compare.ui.contentmergeviewer.ModelContentMergeViewer" contentTypeId="org.eventb.core.machineFile"> </contentTypeBinding> <contentTypeBinding contentMergeViewerId="org.eclipse.emf.compare.ui.contentmergeviewer.ModelContentMergeViewer" contentTypeId="org.eventb.core.contextFile"> </contentTypeBinding> </extension> <extension point="org.eclipse.compare.structureMergeViewers"> <contentTypeBinding structureMergeViewerId="org.eclipse.emf.compare.ui.structuremergeviewer.ModelStructureMergeViewer" contentTypeId="org.eventb.core.machineFile"> </contentTypeBinding> <contentTypeBinding structureMergeViewerId="org.eclipse.emf.compare.ui.structuremergeviewer.ModelStructureMergeViewer" contentTypeId="org.eventb.core.contextFile"> </contentTypeBinding> </extension>
The EMF compare editor now opens but doesn't work properly. + The functions of the Rodin database are not affected. Could be a step in the right direction, maybe.
A few hours later....
The reason the EMF compare editor wasn't working correctly is that EMF compare calls the resource's save(outputStream,options) method to produce a byte array of the contents. Since we weren't interested in I/O streams (because we save via the Rodin API) we didn't bother to implement these streaming methods. I extended the default EMF serialisation (XMIResourceImpl) instead of the extensible base one (ResourceImpl) so that it can use the default xmi streaming methods.
/** * * This is the serialisation of Event-B models from EMF into the Rodin database * We overload save and load directly as we are not interested in input or * output streams (because we load/save through the Rodin API) * * We extend XMIResourceImpl (rather than ResourceImpl). This allows clients to * call the I/O stream versions of save and load to obtain the model content in EMF's * default XMI stream. For example, EMF compare uses this. * * @author cfs/ff * */ public class RodinResource extends XMIResourceImpl {
Now it Works!!!