/**
*
*/
package org.eclipse.papyrus.infra.core.resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IPath;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
/**
* Base class for models sharing a common {@link Resource}. To share a common {@link Resource}, one of the model should be Master, while the other are
* slaves. The Master is the one performing the save operation. All the model
* should use the same file extension. So, {@link #getModelFileExtension()} should return the same value for all models.
*
* @author cedric dumoulin
*
* @param T
* Type of the roots of the model.
*/
public abstract class AbstractModelWithSharedResource<T extends EObject> extends AbstractBaseModel {
/**
* Possible type for this model: master or slave
*/
public enum ModelKind {
master, slave
}
/**
* Model kind.
*/
private ModelKind modelKind;;
/**
*
* Constructor.
*
* @param modelKind
*/
public AbstractModelWithSharedResource(ModelKind modelKind) {
this.modelKind = modelKind;
}
/**
* By default, we are a slave. Constructor.
*
* @param modelKind
*/
public AbstractModelWithSharedResource() {
this.modelKind = ModelKind.slave;
}
/**
* Attach the model to its resource if this is not already done.
*
* @see org.eclipse.papyrus.infra.core.resource.AbstractBaseModel#loadModel(org.eclipse.core.runtime.IPath)
*
* @param fullPathWithoutExtension
*/
@Override
public void loadModel(IPath fullPathWithoutExtension) {
// Look for the resource
lookupResource(fullPathWithoutExtension);
// Check if model is loaded.
if(resourceIsSet())
return;
// model is not loaded, do it.
super.loadModel(fullPathWithoutExtension);
}
/**
* Create the model if this is not already done.
*
* @see org.eclipse.papyrus.infra.core.resource.AbstractBaseModel#createModel(org.eclipse.core.runtime.IPath)
*
* @param fullPath
*/
@Override
public void createModel(IPath fullPath) {
// Look for the resource
lookupResource(fullPath);
// Check if model is loaded.
if(resourceIsSet())
return;
// model is not loaded, do it.
super.createModel(fullPath);
}
/**
* Lookup for the resource in the resourceSet. Return the resource or null
* if not found.
*
* @param fullPath
*/
private void lookupResource(IPath fullPath) {
// Compute model URI
resourceURI = getPlatformURI(fullPath.addFileExtension(getModelFileExtension()));
resource = getResourceSet().getResource(resourceURI, false);
}
/**
* Do nothing as we are slave. The Resource is save by the master model.
*
* @see org.eclipse.papyrus.infra.core.resource.AbstractBaseModel#saveModel()
*
* @throws IOException
*/
@Override
public void saveModel() throws IOException {
// Do nothing if we are a slave
if(modelKind == ModelKind.slave)
return;
// Do the save
super.saveModel();
}
/**
* Get the root of this model. Lookup in the associated {@link Resource} for
* the root.
*
* @return The root of the model, or null if no root exist.
*/
@SuppressWarnings("unchecked")
public T getModelRoot() {
for(EObject object : getResource().getContents()) {
if(isModelRoot(object)) {
return (T)object;
}
}
// Not found
return null;
}
/**
* Get the roots of this model. Lookup in the associated {@link Resource} for the roots.
*
* @return A list containing the roots of the model. The list is empty if
* there is no root.
*/
@SuppressWarnings("unchecked")
public List<T> getModelRoots() {
List<T> roots = new ArrayList<T>();
for(EObject object : getResource().getContents()) {
if(isModelRoot(object))
roots.add((T)object);
}
return roots;
}
/**
* Return true if the provided object is a root of the model, false
* otherwise. This method should be implemented by subclasses.
*
* @param object
* @return
*/
protected abstract boolean isModelRoot(EObject object);
/**
* Add a root to this model.
*
* @param root
*/
public void addModelRoot(T root) {
getResource().getContents().add(root);
}
}