/**
* <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.util.Collections;
import java.util.List;
import org.eclipse.emf.diffmerge.util.structures.FArrayList;
import org.eclipse.emf.diffmerge.util.structures.IEqualityTester;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.util.EcoreUtil;
/**
* A model scope covering the full EMF containment tree of a modifiable set of root elements.
* EMF undo/redo is not supported due to the local non-EMF state.
* Removal of elements which are cross-referenced outside the scope is not supported.
* @author Olivier Constant
*/
public class RootedModelScope extends AbstractEditableModelScope {
/** The roots of this scope */
protected final List<EObject> _roots;
/**
* Constructor
* @param roots_p a non-null list of elements whose containment trees are disjoint,
* that is, no element is the ancestor of another one
*/
public RootedModelScope(List<? extends EObject> roots_p) {
_roots = new FArrayList<EObject>(roots_p, IEqualityTester.BY_REFERENCE);
}
/**
* Constructor
* @param roots_p a non-null list of elements whose containment trees are disjoint,
* that is, no element is the ancestor of another one
* @param operateOnList_p whether the list must be used directly as the root container,
* where true implies that roots_p is modifiable
*/
public RootedModelScope(List<EObject> roots_p, boolean operateOnList_p) {
_roots = operateOnList_p? roots_p:
new FArrayList<EObject>(roots_p, IEqualityTester.BY_REFERENCE);
}
/**
* @see org.eclipse.emf.diffmerge.api.scopes.IEditableModelScope#add(org.eclipse.emf.ecore.EObject)
*/
public boolean add(EObject element_p) {
// Must be called by redefinitions in subclasses
return _roots.add(element_p);
}
/**
* @see org.eclipse.emf.diffmerge.impl.scopes.AbstractEditableModelScope#add(org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EReference, org.eclipse.emf.ecore.EObject)
*/
@Override
public boolean add(EObject source_p, EReference reference_p, EObject value_p) {
boolean result = super.add(source_p, reference_p, value_p);
if (result && reference_p.isContainment())
_roots.remove(value_p);
return result;
}
/**
* @see org.eclipse.emf.diffmerge.api.scopes.IModelScope#covers(EObject)
*/
@Override
public boolean covers(EObject element_p) {
return EcoreUtil.isAncestor(_roots, element_p);
}
/**
* @see org.eclipse.emf.diffmerge.api.scopes.IModelScope#getContainer(EObject)
*/
@Override
public EObject getContainer(EObject element_p) {
return getContents().contains(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 getContents().contains(element_p)? null: super.getContainment(element_p);
}
/**
* @see org.eclipse.emf.diffmerge.api.scopes.IModelScope#getContents()
*/
public List<EObject> getContents() {
return Collections.unmodifiableList(_roots);
}
/**
* @see org.eclipse.emf.diffmerge.impl.scopes.AbstractEditableModelScope#remove(org.eclipse.emf.ecore.EObject)
*/
@Override
public boolean remove(EObject element_p) {
// Must be called by redefinitions in subclasses
boolean result = super.remove(element_p);
if (result)
_roots.remove(element_p);
return result;
}
}