/**
* <copyright>
*
* Copyright (c) 2010-2016 Thales Global Services S.A.S.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Thales Global Services S.A.S. - initial API and implementation
*
* </copyright>
*/
package org.eclipse.emf.diffmerge.impl.scopes;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.diffmerge.api.scopes.IPersistentModelScope;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
/**
* A single-resource model scope covering the full EMF containment subtree of a given
* element.
* The root cannot be removed from the scope and the load/unload life-cycle is not handled.
* EMF undo/redo is supported because the local state never changes.
* Complete deletion of elements which are cross-referenced outside the scope is not supported.
* @author Olivier Constant
*/
public class SubtreeModelScope extends AbstractEditableModelScope
implements IPersistentModelScope.Editable {
/** The root of this scope */
private final EObject _root;
/**
* Constructor
* @param root_p the root element
*/
public SubtreeModelScope(EObject root_p) {
_root = root_p;
}
/**
* @see org.eclipse.emf.diffmerge.api.scopes.IEditableModelScope#add(org.eclipse.emf.ecore.EObject)
*/
public boolean add(EObject element_p) {
if (element_p != getRoot() && getHoldingResource() != null)
getHoldingResource().getContents().add(element_p);
// The element does not belong to the scope after execution
return false;
}
/**
* @see org.eclipse.emf.diffmerge.api.scopes.IModelScope#getContainer(EObject)
*/
@Override
public EObject getContainer(EObject element_p) {
return getRoot() == element_p? null: super.getContainer(element_p);
}
/**
* @see org.eclipse.emf.diffmerge.impl.scopes.AbstractModelScope#getContainment(org.eclipse.emf.ecore.EObject)
*/
@Override
public EReference getContainment(EObject element_p) {
return getRoot() == element_p? null: super.getContainment(element_p);
}
/**
* @see org.eclipse.emf.diffmerge.api.scopes.IModelScope#getContents()
*/
public List<EObject> getContents() {
return Collections.singletonList(getRoot());
}
/**
* @see org.eclipse.emf.diffmerge.impl.scopes.AbstractModelScope#getDefaultOriginator()
*/
@Override
protected Object getDefaultOriginator() {
return _root;
}
/**
* @see IPersistentModelScope#getExtrinsicID(EObject)
*/
@Override
public Object getExtrinsicID(EObject element_p) {
// Increases visibility
return super.getExtrinsicID(element_p);
}
/**
* @see org.eclipse.emf.diffmerge.api.scopes.IPersistentModelScope#getHoldingResource()
*/
public Resource getHoldingResource() {
return getRoot().eResource();
}
/**
* Return the root of this scope
* @return a non-null element
*/
public EObject getRoot() {
return _root;
}
/**
* @see org.eclipse.emf.diffmerge.api.scopes.IPersistentModelScope#isLoaded()
*/
public boolean isLoaded() {
return !_root.eIsProxy();
}
/**
* @see org.eclipse.emf.diffmerge.api.scopes.IPersistentModelScope#load()
*/
public boolean load() throws Exception {
return isLoaded(); // Load/unload life-cycle not handled
}
/**
* @see org.eclipse.emf.diffmerge.impl.scopes.AbstractEditableModelScope#remove(org.eclipse.emf.ecore.EObject)
*/
@Override
public boolean remove(EObject element_p) {
boolean result = false;
if (element_p != getRoot())
result = super.remove(element_p);
return result;
}
/**
* @see org.eclipse.emf.diffmerge.api.scopes.IPersistentModelScope.Editable#save()
*/
public boolean save() throws IOException {
boolean result = false;
Resource resource = getHoldingResource();
if (resource != null) {
Map<Object, Object> options = new HashMap<Object, Object>();
options.put(Resource.OPTION_SAVE_ONLY_IF_CHANGED,
Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER);
resource.save(options);
result = true;
}
return result;
}
/**
* @see org.eclipse.emf.diffmerge.impl.scopes.AbstractEditableModelScope#setExtrinsicID(org.eclipse.emf.ecore.EObject, java.lang.Object)
*/
@Override
public boolean setExtrinsicID(EObject element_p, Object id_p) {
// Increases visibility
return super.setExtrinsicID(element_p, id_p);
}
/**
* @see org.eclipse.emf.diffmerge.api.scopes.IPersistentModelScope.Editable#setStream(java.io.InputStream)
*/
public void setStream(InputStream stream_p) {
// Ignore since scope is always loaded
}
/**
* @see org.eclipse.emf.diffmerge.api.scopes.IPersistentModelScope#unload()
*/
public List<Resource> unload() {
return Collections.emptyList(); // Load/unload life-cycle not handled
}
}