Commit eee4fcef authored by Erwan Bousse's avatar Erwan Bousse

Fixing bug in cloning algo in which cloned objects dont have a container yet,...

Fixing bug in cloning algo in which cloned objects dont have a container yet, and adding new feature with the possibility to create readonly clones in which the containment semantics is not ok when shared objects are moved from a container to another (thus should not be moved, thus readonly)
parent b0c2f490
......@@ -32,8 +32,12 @@ public interface Cloner {
* folder
* @return The cloned model.
*/
public ResourceSet clone(ResourceSet model, String folderName);//,boolean light);
public ResourceSet clone(ResourceSet model, String folderName);
public ResourceSet clone(ResourceSet cloned, File outputFolder);//,boolean light);
public ResourceSet clone(ResourceSet cloned, File outputFolder);
public ResourceSet clone(ResourceSet cloned, File outputFolder, boolean readOnly);
public ResourceSet clone(ResourceSet cloned, String folderName, boolean readOnly);
}
......@@ -42,7 +42,7 @@ public class ClonerImpl implements Cloner {
cloningMaterial = cm;
}
private ResourceSet clone(ResourceSet cloned, File outputFolder, String folderName) {//, boolean light) {
private ResourceSet clone(ResourceSet cloned, File outputFolder, String folderName, boolean readOnly) {
// Creating empty clone resource set
ResourceSet clone = new ResourceSetImpl();
......@@ -76,7 +76,7 @@ public class ClonerImpl implements Cloner {
Resource resourceClone = null;
// LooseResource if there are readonly objects that might be shared among models
if (tags.mayTagClassesShareable()) {
resourceClone = new LooseResource(tags);
resourceClone = new LooseResource(tags,readOnly);
resourceClone.setURI(uri);
clone.getResources().add(resourceClone);
}
......@@ -94,7 +94,7 @@ public class ClonerImpl implements Cloner {
ClassTag tag = tags.getTagOf(o.eClass());
// We only put the copied object in the resource if not contained already
if (o.eContainer() == null) {
//if (o.eContainer() == null) {
switch (tag) {
case NOT_SHAREABLE: // here the copier should always produce a regular copy
resourceClone.getContents().add(copier.copy(o));
......@@ -103,10 +103,11 @@ public class ClonerImpl implements Cloner {
resourceClone.getContents().add(copier.copy(o));
break;
case COMPLETELY_SHAREABLE: // no copy, shared object
resourceClone.getContents().add(o);
if (o.eContainer() == null)
resourceClone.getContents().add(o);
break;
}
} else {
/*} else {
switch (tag) {
case NOT_SHAREABLE: // here the copier should always produce a regular copy
copier.copy(o);
......@@ -115,9 +116,10 @@ public class ClonerImpl implements Cloner {
copier.copy(o);
break;
case COMPLETELY_SHAREABLE: // no copy, shared object
break;
}
}
}*/
}
}
......@@ -131,12 +133,23 @@ public class ClonerImpl implements Cloner {
@Override
public ResourceSet clone(ResourceSet cloned, File outputFolder) {//, boolean light) {
return clone(cloned, outputFolder, "NOTHING");//, light);
return clone(cloned, outputFolder, "NOTHING", false);//, light);
}
@Override
public ResourceSet clone(ResourceSet cloned, String folderName) {//, boolean light) {
return clone(cloned, null, folderName);//, light);
return clone(cloned, null, folderName, false);//, light);
}
@Override
public ResourceSet clone(ResourceSet cloned, File outputFolder,boolean readOnly) {
return clone(cloned, outputFolder, "NOTHING", readOnly);
}
@Override
public ResourceSet clone(ResourceSet cloned, String folderName,boolean readOnly) {
return clone(cloned,null, folderName,readOnly);
}
}
......@@ -32,11 +32,12 @@ import fr.inria.diverse.cloning.runtime.util.EcoreHelper;
* container, at all time (eContainer).
*
* @author ebousse
*
*
*/
public abstract class AbstractShareableEObject extends MinimalEObjectImpl.Container {// implements
// ShareableEObject
// {
public abstract class AbstractShareableEObject extends
MinimalEObjectImpl.Container {// implements
// ShareableEObject
// {
/**
* Internal class to store the context temporarily
......@@ -119,7 +120,8 @@ public abstract class AbstractShareableEObject extends MinimalEObjectImpl.Contai
// LooseResource
boolean toChange = (otherResource != null)
&& (otherResource instanceof LooseResource)
&& (((LooseResource) (otherResource)).getTags().getTagOf(this.eClass()) == ClassTag.COMPLETELY_SHAREABLE)
&& (((LooseResource) (otherResource)).getTags().getTagOf(
this.eClass()) == ClassTag.COMPLETELY_SHAREABLE)
&& (otherRS != null) && (otherRS != currentRS);
// If we do change the context
......@@ -129,37 +131,26 @@ public abstract class AbstractShareableEObject extends MinimalEObjectImpl.Contai
ReadonlyContext context = new ReadonlyContext(this);
// We get the resource set in which "things happen"
ResourceSet otherResourceSet = otherEnd.eResource().getResourceSet();
// We initialize the maps at the first usage
// if (this.additionnalContainersOrResources == null) {
// additionnalContainersOrResources = new HashMap<ResourceSet,
// Object>(1);
// }
// If we don't have entries for the otherResourceSet,
// we create ones with 'null' (ie not contained in this resource
// yet)
// if
// (!this.additionnalContainersOrResources.containsKey(otherResourceSet))
// {
// this.additionnalContainersOrResources.put(otherResourceSet,
// null);
// }
// ResourceSet otherResourceSet =
// otherEnd.eResource().getResourceSet();
// We remove ourselves from a resource
if (this.eResource() != null)
this.eResource().getContents().remove(this);
// We only load/store another container if we are not manipulated in
// a read-only context
Object container = null;
if (!((LooseResource) (otherResource)).isReadOnly()) {
if (this.additionnalContainersOrResources == null)
container = null;
else
container = this.additionnalContainersOrResources
.get(otherRS);
}
// We temporarily change the container (which might of course erase
// the resource)
Object container;
if (this.additionnalContainersOrResources == null)
container = null;
else
container = this.additionnalContainersOrResources.get(otherResourceSet);
if (container != null) {
if (container instanceof InternalEObject) {
this.eBasicSetContainer((InternalEObject) container);
......@@ -172,18 +163,6 @@ public abstract class AbstractShareableEObject extends MinimalEObjectImpl.Contai
this.setResourceNonInverse(null);
}
/*
* InternalEObject otherCont = (InternalEObject)
* this.additionnalContainersAndResources.get(otherResourceSet)[0];
*
*
* // We temporarily change the resource, if the container was null
* if (otherCont == null) { Resource otherResource = (Resource)
* this.additionnalContainersAndResources.get(otherResourceSet)[1];
* if (otherResource != null) otherResource.getContents().add(this);
* }
*/
// And we return the context for further restore
return context;
......@@ -200,7 +179,8 @@ public abstract class AbstractShareableEObject extends MinimalEObjectImpl.Contai
*
* @param context
*/
protected void restoreContext(ReadonlyContext context, InternalEObject otherEnd) {
protected void restoreContext(ReadonlyContext context,
InternalEObject otherEnd) {
// If null, nothing to restore
if (context != null) {
......@@ -214,23 +194,32 @@ public abstract class AbstractShareableEObject extends MinimalEObjectImpl.Contai
MetamodelTags tags = null;
if (otherResource != null && otherResource instanceof LooseResource)
tags = ((LooseResource) (otherResource)).getTags();
// if (tags != null &&
// tags.isPropertyShareable(this.eContainmentFeature())) {
if (tags != null && !EcoreHelper.isPropertyDesignedMutable(this.eContainmentFeature())) {
if (tags != null
&& !EcoreHelper.isPropertyDesignedMutable(this
.eContainmentFeature())) {
storeContainer = false;
}
if (storeContainer) {
// We initialize the maps at the first usage
if (this.additionnalContainersOrResources == null) {
additionnalContainersOrResources = new HashMap<ResourceSet, Object>(1);
}
// We only store other resources if we are not manipulated in a read
// only context
if (!((LooseResource) (otherResource)).isReadOnly()) {
if (storeContainer) {
// We initialize the maps at the first usage
if (this.additionnalContainersOrResources == null) {
additionnalContainersOrResources = new HashMap<ResourceSet, Object>(
1);
}
// We store the current context in our map
if (this.eContainer != null)
this.additionnalContainersOrResources.put(
currentResourceSet, this.eContainer);
else
this.additionnalContainersOrResources.put(
currentResourceSet, this.eResource());
// We store the current context in our map
if (this.eContainer != null)
this.additionnalContainersOrResources.put(currentResourceSet, this.eContainer);
else
this.additionnalContainersOrResources.put(currentResourceSet, this.eResource());
}
}
......@@ -253,14 +242,15 @@ public abstract class AbstractShareableEObject extends MinimalEObjectImpl.Contai
* .ecore.InternalEObject, int, java.lang.Class,
* org.eclipse.emf.common.notify.NotificationChain)
*/
public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID,
Class<?> baseClass, NotificationChain msgs) {
public NotificationChain eInverseAdd(InternalEObject otherEnd,
int featureID, Class<?> baseClass, NotificationChain msgs) {
// Changing the context
ReadonlyContext context = changeContext(otherEnd);
// Actual call
NotificationChain result = super.eInverseAdd(otherEnd, featureID, baseClass, msgs);
NotificationChain result = super.eInverseAdd(otherEnd, featureID,
baseClass, msgs);
// Restoring the context
restoreContext(context, otherEnd);
......@@ -278,24 +268,20 @@ public abstract class AbstractShareableEObject extends MinimalEObjectImpl.Contai
* .emf.ecore.InternalEObject, int, java.lang.Class,
* org.eclipse.emf.common.notify.NotificationChain)
*/
public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID,
Class<?> baseClass, NotificationChain msgs) {
public NotificationChain eInverseRemove(InternalEObject otherEnd,
int featureID, Class<?> baseClass, NotificationChain msgs) {
// Changing the context
ReadonlyContext context = changeContext(otherEnd);
// Actual call
NotificationChain result = super.eInverseRemove(otherEnd, featureID, baseClass, msgs);
NotificationChain result = super.eInverseRemove(otherEnd, featureID,
baseClass, msgs);
// handling the removal from the hashmap, if required
Resource otherResource = findResource(otherEnd);
ResourceSet otherRS = findResourceSet(otherEnd);
//MetamodelTags tags = null;
if (otherResource != null && otherResource instanceof LooseResource) {
// tags = ((LooseResource) (otherResource)).getTags();
// if (tags != null &&
// !EcoreHelper.isPropertyDesignedMutable(this.eContainmentFeature()))
// {
this.additionnalContainersOrResources.remove(otherRS);
if (this.additionnalContainersOrResources.size() == 0)
this.additionnalContainersOrResources = null;
......@@ -322,14 +308,4 @@ public abstract class AbstractShareableEObject extends MinimalEObjectImpl.Contai
eSetDirectResource(resource);
}
// @Override
// public Object getContainerOrResourceInContext(ResourceSet context) {
// if (findResourceSet(this) == context)
// return this.eContainer();
// else if (this.additionnalContainersOrResources.containsKey(context))
// return this.additionnalContainersOrResources.get(context);
// else
// return null;
// }
}
......@@ -45,9 +45,10 @@ public class LooseResource extends XMIResourceImpl {
* @param c
* The cloning technique tagger.
*/
public LooseResource(MetamodelTags t) {
public LooseResource(MetamodelTags tags, boolean readOnly) {
this();
this.tags = t;
this.tags = tags;
this.readOnly = readOnly;
}
/**
......@@ -74,13 +75,18 @@ public class LooseResource extends XMIResourceImpl {
private static final long serialVersionUID = 1410188721350066354L;
private boolean changeResourceOfObject(InternalEObject eObject) {
return (!(LooseResource.this.tags.getTagOf(eObject.eClass()) == ClassTag.COMPLETELY_SHAREABLE));
}
@Override
public NotificationChain inverseAdd(E object,
NotificationChain notifications) {
InternalEObject eObject = (InternalEObject) object;
// We only allow Readonly (from the cloning technique pov) objects
// to be in multiple resources at once
if (!(LooseResource.this.tags.getTagOf(eObject.eClass()) == ClassTag.COMPLETELY_SHAREABLE))
if (changeResourceOfObject(eObject))
notifications = eObject.eSetResource(LooseResource.this,notifications);
LooseResource.this.attached(eObject);
return notifications;
......@@ -95,7 +101,7 @@ public class LooseResource extends XMIResourceImpl {
}
// We only allow Readonly (from the cloning technique pov) objects
// to be in multiple resources at once
if (!(LooseResource.this.tags.getTagOf(eObject.eClass()) == ClassTag.COMPLETELY_SHAREABLE))
if (changeResourceOfObject(eObject))
return eObject.eSetResource(null, notifications);
else
return notifications;
......@@ -104,6 +110,7 @@ public class LooseResource extends XMIResourceImpl {
}
protected EList<EObject> realContents;
private boolean readOnly;
@Override
/**
......@@ -178,5 +185,9 @@ public class LooseResource extends XMIResourceImpl {
// Restore the context of all contents
restoreContext(context);
}
public boolean isReadOnly() {
return readOnly;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment