Bug 489842

Summary: The default saving policy fails to recognize metamodels referenced by plugin uris
Product: [Modeling] Sirius Reporter: Amine Lajmi <amlajmi>
Component: CoreAssignee: Project inbox <sirius.core-inbox>
Status: NEW --- QA Contact:
Severity: normal    
Priority: P3 CC: esteban.dugueperoux, maxime.porhel, pierre-charles.david
Version: 3.1.0Keywords: triaged
Target Milestone: ---   
Hardware: PC   
OS: Windows 7   
Whiteboard:
Bug Depends on:    
Bug Blocks: 481849    

Description Amine Lajmi CLA 2016-03-17 08:49:57 EDT
The default saving policy uses the ResourceSetSync helper which fails to recognize metamodels referenced by plugin uris. In particular, the method isMetamodel:

    private static boolean isMetamodel(Resource resource) {
        boolean isMetamodel = false;
        URI resourceURI = resource.getURI();
        ResourceSet resourceSet = resource.getResourceSet();
        isMetamodel = EPackage.Registry.INSTANCE.containsKey(resourceURI.toString()) || resourceSet != null && resourceSet.getPackageRegistry().containsKey(resourceURI.toString());
        return isMetamodel;
    }

returns true only if the metamodel is referenced by his namespace URI. As a consequence, any metamodel referenced by plugin uri (e.g. target platform) are requested to be saved, leading to an IOException.
Comment 1 Esteban DUGUEPEROUX CLA 2016-03-17 11:46:06 EDT
Hi,

ResourceSetSync.isMetamodel() is called by ResourceSetSync.isReadOnly() which do an additional check on read-only state of resource then if your referenced metamodel is in a plugin ResourceSetSync.isReadOnly() should returns true.

Could you give more details about your exception and provide a use case to reproduce?
Comment 2 Amine Lajmi CLA 2016-03-17 12:51:58 EDT
Providing an example will probably take a while as the code is not open-source, but the problem is clearly identified: isMetamodel(resource) should return whether a resource is a metamodel right?

isReadOnly to return true must enter the following condition:

        if (resourceURI != null && isMetamodel(resource)
                || (resourceSet != null && Boolean.TRUE.equals(resourceSet.getURIConverter().getAttributes(resourceURI, null).get(URIConverter.ATTRIBUTE_READ_ONLY)))) {
            readonly = true;
        }

as isMetamodel(resource) returns false, the second alternative must be true, which means the user should specify it by hand for each resource uri using the URIConverter; not sure if this the expected practice.

Here is the stack trace:

java.io.IOException: cannot delete D:\PBOC001\xxxxxxxx\CapellaStudio\plugins\org.polarsys.capella.common.data.activity.gen_0.8.0.2015-07-30_07-31-43.jar
	at org.eclipse.emf.common.archive.ArchiveURLConnection$2.close(ArchiveURLConnection.java:524)
	at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:1003)
	at org.eclipse.sirius.common.tools.api.resource.ResourceSetSync.doSave(ResourceSetSync.java:548)
	at org.eclipse.sirius.common.tools.api.resource.ResourceSetSync.save(ResourceSetSync.java:500)
	at org.eclipse.sirius.business.api.session.AbstractSavingPolicy.save(AbstractSavingPolicy.java:58)
	at org.eclipse.sirius.business.internal.session.danalysis.DAnalysisSessionImpl$1.run(DAnalysisSessionImpl.java:785)
	at org.eclipse.sirius.business.internal.session.danalysis.DAnalysisSessionImpl.doSave(DAnalysisSessionImpl.java:797)
	at org.eclipse.sirius.business.internal.session.danalysis.Saver.wrappedSave(Saver.java:144)
	at org.eclipse.sirius.business.internal.session.danalysis.Saver.access$0(Saver.java:133)
	at org.eclipse.sirius.business.internal.session.danalysis.Saver$1.run(Saver.java:121)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2241)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2225)
	at org.eclipse.sirius.business.internal.session.danalysis.Saver.saveNow(Saver.java:118)
	at org.eclipse.sirius.business.internal.session.danalysis.Saver.save(Saver.java:94)
	at org.eclipse.sirius.business.internal.session.danalysis.DAnalysisSessionImpl.save(DAnalysisSessionImpl.java:759)
	at org.eclipse.sirius.business.internal.session.danalysis.DAnalysisSessionImpl.save(DAnalysisSessionImpl.java:754)
	at org.eclipse.sirius.diagram.ui.tools.internal.resource.CustomSiriusDocumentProvider.doSaveDocument(CustomSiriusDocumentProvider.java:284)
	at org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.AbstractDocumentProvider$1SaveOperation.execute(AbstractDocumentProvider.java:596)
	at org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.AbstractDocumentProvider$DocumentProviderOperation.run(AbstractDocumentProvider.java:66)
	at org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.AbstractDocumentProvider.executeOperation(AbstractDocumentProvider.java:530)
	at org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.AbstractDocumentProvider.saveDocument(AbstractDocumentProvider.java:579)
	at org.eclipse.gmf.runtime.diagram.ui.resources.editor.parts.DiagramDocumentEditor.performSave(DiagramDocumentEditor.java:864)
	at org.eclipse.gmf.runtime.diagram.ui.resources.editor.parts.DiagramDocumentEditor.doSave(DiagramDocumentEditor.java:684)
	at org.eclipse.sirius.ui.business.internal.session.SaveSessionRunnable.run(SaveSessionRunnable.java:62)
	at org.eclipse.ui.internal.SaveableHelper$6.run(SaveableHelper.java:387)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)

Thanks & Regards
Comment 3 Esteban DUGUEPEROUX CLA 2016-03-18 04:14:44 EDT
Hi,

You are right ResourceSetSync.isMetamodel() should returns true if the resource is about a metamodel, i.e. containing at least one EPackage registered in EPackage.Registry singleton, but we want to allow saving of metamodel in case it is a semantic resource of a Sirius session, as platform resource in workspace for example. 
In addition ResourceSetSync.isMetamodel() is private then we don't provide API contract on it.

I see you get the stacktrace using Capella, perhaps you could reproduce only with Capella and report a bugzilla on this component.
Comment 4 Maxime Porhel CLA 2016-04-26 09:39:11 EDT
One of the tasks of Bug 481849 is to add the capability to reference metamodels from the target platform to a RepresentationDescrion in the VSM editor. 

The corrections of this task in Bug 481849 and the current bugzilla might have a common part.