/** * <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.List; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.diffmerge.api.scopes.IEditableModelScope; import org.eclipse.emf.diffmerge.util.ModelImplUtil; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.ecore.util.FeatureMapUtil; /** * A partial implementation of IEditableModelScope based on unbounded EMF containment. * @author Olivier Constant */ public abstract class AbstractEditableModelScope extends AbstractModelScope implements IEditableModelScope { /** * @see org.eclipse.emf.diffmerge.api.scopes.IEditableModelScope#add(EObject, EAttribute, Object) */ public boolean add(EObject source_p, EAttribute attribute_p, Object value_p) { boolean result; if (FeatureMapUtil.isMany(source_p, attribute_p)) { @SuppressWarnings("unchecked") List<Object> values = (List<Object>)source_p.eGet(attribute_p, resolveProxies()); result = values.add(value_p); } else { source_p.eSet(attribute_p, value_p); result = true; } return result; } /** * @see org.eclipse.emf.diffmerge.api.scopes.IEditableModelScope#add(EObject, EReference, EObject) */ public boolean add(EObject source_p, EReference reference_p, EObject value_p) { boolean result; if (FeatureMapUtil.isMany(source_p, reference_p)) { @SuppressWarnings("unchecked") List<EObject> values = (List<EObject>)source_p.eGet(reference_p, resolveProxies()); result = values.add(value_p); // Guarantees uniqueness } else { source_p.eSet(reference_p, value_p); result = true; } return result; } /** * @see org.eclipse.emf.diffmerge.api.scopes.IEditableModelScope#isReadOnly() */ public boolean isReadOnly() { return false; } /** * @see org.eclipse.emf.diffmerge.api.scopes.IEditableModelScope#move(org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EStructuralFeature, int, int) */ public Object move(EObject source_p, EStructuralFeature feature_p, int newPosition_p, int oldPosition_p) { Object result = null; if (FeatureMapUtil.isMany(source_p, feature_p) && source_p.eIsSet(feature_p) && newPosition_p >= 0) { @SuppressWarnings("unchecked") EList<Object> values = (EList<Object>)source_p.eGet(feature_p, false); int size = values.size(); int oldPosition = oldPosition_p >= 0? oldPosition_p: size-1; int newPosition = oldPosition >= newPosition_p? newPosition_p: newPosition_p-1; if (newPosition < size && oldPosition < size) { try { result = values.move(newPosition, oldPosition); } catch (RuntimeException e) { // Move is not supported on this setting: return null } } } return result; } /** * @see org.eclipse.emf.diffmerge.api.scopes.IEditableModelScope#remove(EObject) */ public boolean remove(EObject element_p) { // Warning: this implementation ignores cross-references from outside the scope. // Override if complete deletion of the element is needed. EcoreUtil.remove(element_p); return true; } /** * @see org.eclipse.emf.diffmerge.api.scopes.IEditableModelScope#remove(EObject, EAttribute, Object) */ public boolean remove(EObject source_p, EAttribute attribute_p, Object value_p) { return removeValue(source_p, attribute_p, value_p); } /** * @see org.eclipse.emf.diffmerge.api.scopes.IEditableModelScope#remove(EObject, EReference, EObject) */ public boolean remove(EObject source_p, EReference reference_p, EObject value_p) { return removeValue(source_p, reference_p, value_p); } /** * Remove the given value on the given feature from the given element. * @param source_p a non-null element * @param feature_p a non-null feature * @param value_p a non-null value * @return whether the operation succeeded */ protected boolean removeValue(EObject source_p, EStructuralFeature feature_p, Object value_p) { boolean result = false; // Differs from EcoreUtil.remove in the non-many case if (FeatureMapUtil.isMany(source_p, feature_p)) { result = ((List<?>)source_p.eGet(feature_p)).remove(value_p); } else if (source_p.eGet(feature_p) == value_p) { source_p.eUnset(feature_p); result = true; } return result; } /** * @see org.eclipse.emf.diffmerge.api.scopes.IPersistentModelScope.Editable#setExtrinsicID(EObject, Object) */ protected boolean setExtrinsicID(EObject element_p, Object id_p) { // Default implementation only covers XML/XMI Resources boolean result = false; if (id_p instanceof String) result = ModelImplUtil.setXMLID(element_p, (String)id_p); return result; } }