Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xplugins/infra/nattable/org.eclipse.papyrus.infra.emf.nattable/src/org/eclipse/papyrus/infra/emf/nattable/manager/axis/AbstractSynchronizedOnEStructuralFeatureAxisManager.java64
-rw-r--r--plugins/uml/nattable/org.eclipse.papyrus.uml.nattable/src/org/eclipse/papyrus/uml/nattable/manager/axis/AbstractStereotypedElementUMLSynchronizedOnFeatureAxisManager.java1011
2 files changed, 575 insertions, 500 deletions
diff --git a/plugins/infra/nattable/org.eclipse.papyrus.infra.emf.nattable/src/org/eclipse/papyrus/infra/emf/nattable/manager/axis/AbstractSynchronizedOnEStructuralFeatureAxisManager.java b/plugins/infra/nattable/org.eclipse.papyrus.infra.emf.nattable/src/org/eclipse/papyrus/infra/emf/nattable/manager/axis/AbstractSynchronizedOnEStructuralFeatureAxisManager.java
index 84df1a01729..d5499a2f963 100755
--- a/plugins/infra/nattable/org.eclipse.papyrus.infra.emf.nattable/src/org/eclipse/papyrus/infra/emf/nattable/manager/axis/AbstractSynchronizedOnEStructuralFeatureAxisManager.java
+++ b/plugins/infra/nattable/org.eclipse.papyrus.infra.emf.nattable/src/org/eclipse/papyrus/infra/emf/nattable/manager/axis/AbstractSynchronizedOnEStructuralFeatureAxisManager.java
@@ -16,6 +16,7 @@ package org.eclipse.papyrus.infra.emf.nattable.manager.axis;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.Assert;
@@ -348,7 +349,7 @@ public abstract class AbstractSynchronizedOnEStructuralFeatureAxisManager extend
if (notification.isTouch()) {
return;
}
-
+
int eventType = notification.getEventType();
List<Object> toAdd = new ArrayList<Object>();
List<Object> toRemove = new ArrayList<Object>();
@@ -372,7 +373,11 @@ public abstract class AbstractSynchronizedOnEStructuralFeatureAxisManager extend
case Notification.EVENT_TYPE_COUNT:
break;
case Notification.MOVE:
- // we ignore it
+ final Collection<EObject> collection = (Collection<EObject>) ((EObject)notification.getNotifier()).eGet((EStructuralFeature) notification.getFeature());
+ final Collection<EObject> subList = getSubFromFirstNotEquals(collection, (Integer)notification.getOldValue(), getIndex(collection, (EObject) notification.getNewValue()));
+
+ toRemove.addAll(subList);
+ toAdd.addAll(subList);
break;
case Notification.REMOVE:
final Object oldValue = notification.getOldValue();
@@ -401,6 +406,61 @@ public abstract class AbstractSynchronizedOnEStructuralFeatureAxisManager extend
updateManagedList(toAdd, toRemove);
}
}
+
+ /**
+ * Get the sublist of modified objects from the minimum index between the initial and the modified index.
+ *
+ * @param modifiedObjects The list of modified objects.
+ * @param initialIndex The initial index of the moved element.
+ * @param modifiedIndex The modified index of the moved element.
+ * @return The sublist of modified objects from the minimum index.
+ */
+ protected Collection<EObject> getSubFromFirstNotEquals(final Collection<EObject> modifiedObjects, final int initialIndex, final int modifiedIndex){
+ final Collection<EObject> subList = new ArrayList<EObject>(modifiedObjects.size());
+
+ if(initialIndex != modifiedIndex && -1 != modifiedIndex){
+
+ int minimalindex = initialIndex < modifiedIndex ? initialIndex : modifiedIndex;
+
+ final Iterator<EObject> modifiedObjectsIterator = modifiedObjects.iterator();
+ int currentIndex = 0;
+
+ while(modifiedObjectsIterator.hasNext()){
+ final EObject modifiedObject = modifiedObjectsIterator.next();
+
+ // If the current index is superior of the minimal, add the object to the sublist
+ if(currentIndex >= minimalindex){
+ subList.add(modifiedObject);
+ }
+ currentIndex++;
+ }
+ }
+
+ return subList;
+ }
+
+ /**
+ * Get the index of the searched object in the list, otherwise return -1.
+ *
+ * @param modifiedObjects The list of objects.
+ * @param searchedObject The searched object.
+ * @return he index of the searched object in the list, otherwise -1.
+ */
+ protected int getIndex(final Collection<EObject> modifiedObjects, final EObject searchedObject){
+ int index = 0;
+ boolean found = false;
+
+ final Iterator<EObject> iterator = modifiedObjects.iterator();
+ while(iterator.hasNext() && !found){
+ if(iterator.next().equals(searchedObject)){
+ found = true;
+ }else{
+ index++;
+ }
+ }
+
+ return !found ? -1 : index;
+ }
@Override
public List<Object> getAllManagedAxis() {
diff --git a/plugins/uml/nattable/org.eclipse.papyrus.uml.nattable/src/org/eclipse/papyrus/uml/nattable/manager/axis/AbstractStereotypedElementUMLSynchronizedOnFeatureAxisManager.java b/plugins/uml/nattable/org.eclipse.papyrus.uml.nattable/src/org/eclipse/papyrus/uml/nattable/manager/axis/AbstractStereotypedElementUMLSynchronizedOnFeatureAxisManager.java
index eea90f38510..98e92c34f1c 100644
--- a/plugins/uml/nattable/org.eclipse.papyrus.uml.nattable/src/org/eclipse/papyrus/uml/nattable/manager/axis/AbstractStereotypedElementUMLSynchronizedOnFeatureAxisManager.java
+++ b/plugins/uml/nattable/org.eclipse.papyrus.uml.nattable/src/org/eclipse/papyrus/uml/nattable/manager/axis/AbstractStereotypedElementUMLSynchronizedOnFeatureAxisManager.java
@@ -1,498 +1,513 @@
-/*****************************************************************************
- * Copyright (c) 2013 CEA LIST.
- *
- *
- * 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:
- * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.uml.nattable.manager.axis;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.emf.common.notify.Adapter;
-import org.eclipse.emf.common.notify.Notification;
-import org.eclipse.emf.common.notify.impl.AdapterImpl;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.papyrus.infra.nattable.manager.table.INattableModelManager;
-import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisconfiguration.AxisManagerRepresentation;
-import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisprovider.AbstractAxisProvider;
-import org.eclipse.uml2.uml.Element;
-import org.eclipse.uml2.uml.Stereotype;
-import org.eclipse.uml2.uml.util.UMLUtil;
-
-
-/**
- * Axis Manager used when the contents of the table is synchronized on a feature AND that these elements must be stereotyped
- *
- * @author vl222926
- *
- */
-public abstract class AbstractStereotypedElementUMLSynchronizedOnFeatureAxisManager<T_StereotypeApplication extends EObject> extends AbstractUMLSynchronizedOnFeatureAxisManager {
-
- /** the resource listener */
- protected Adapter resourceListener;
-
- /**
- * the map of the listen listening stereotypes applications
- */
- protected Map<EObject, Adapter> listenerMap;
-
- /**
- * the map between the stereotypes applications and the base_element
- */
- protected Map<EObject, Element> stereotypedElementsMap;
-
-
- /**
- *
- * @see org.eclipse.papyrus.infra.emf.nattable.manager.axis.AbstractSynchronizedOnEStructuralFeatureAxisManager#init(org.eclipse.papyrus.infra.nattable.manager.table.INattableModelManager,
- * org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisconfiguration.AxisManagerRepresentation, org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisprovider.AbstractAxisProvider)
- *
- * @param manager
- * @param rep
- * @param provider
- */
- @Override
- public void init(INattableModelManager manager, AxisManagerRepresentation rep, AbstractAxisProvider provider) {
- this.listenerMap = new HashMap<EObject, Adapter>();
- this.stereotypedElementsMap = new HashMap<EObject, Element>();
- super.init(manager, rep, provider);
- }
-
- /**
- *
- * @see org.eclipse.papyrus.infra.emf.nattable.manager.axis.AbstractSynchronizedOnEStructuralFeatureAxisManager#addListeners()
- *
- */
- @Override
- protected void addListeners() {
- super.addListeners();
- addResourceListeners();
- }
-
-
- /**
- * this method a the listener on the resource
- */
- private void addResourceListeners() {
- this.resourceListener = new AdapterImpl() {
-
- @Override
- public void notifyChanged(final Notification notification) {
- resourceHasChanged(notification);
-
- }
- };
-
- for (final Resource current : getResourceToListen()) {
- current.eAdapters().add(this.resourceListener);
- }
- }
-
- /**
- *
- * @return
- */
- protected Collection<Resource> getResourceToListen() {
- return Collections.singleton(getTableContext().eResource());
- }
-
- /**
- *
- * @param notification
- * the notification
- */
- @Override
- protected void featureValueHasChanged(final Notification notification) {
- if (notification.isTouch()) {
- return;
- }
-
- int eventType = notification.getEventType();
- List<Object> toAdd = new ArrayList<Object>();
- List<Object> toRemove = new ArrayList<Object>();
- switch (eventType) {
- case Notification.REMOVING_ADAPTER:
- break;// nothing to do
- case Notification.ADD:
- Object newValue = notification.getNewValue();
- if (isAllowedContents(newValue)) {
- final T_StereotypeApplication stereotypeApplication = getStereotypeApplication((Element) newValue);
- if (stereotypeApplication != null) {
- toAdd.add(newValue);
- addStereotypeApplicationListener(stereotypeApplication);
- this.stereotypedElementsMap.put(stereotypeApplication, (Element) newValue);
- }
- }
- break;
- case Notification.ADD_MANY:
- Collection<?> newValues = (Collection<?>) notification.getNewValue();
- for (final Object current : newValues) {
- if (isAllowedContents(current)) {
- final T_StereotypeApplication stereotypeApplication = getStereotypeApplication((Element) current);
- if (stereotypeApplication != null) {
- toAdd.add(current);
- addStereotypeApplicationListener(stereotypeApplication);
- this.stereotypedElementsMap.put(stereotypeApplication, (Element) current);
- }
- }
- }
- break;
- case Notification.EVENT_TYPE_COUNT:
- break;
- case Notification.MOVE:
- // we ignore it
- break;
- case Notification.REMOVE:
- final Object oldValue = notification.getOldValue();
- if (this.managedObject.contains(oldValue)) {
- toRemove.add(oldValue);// no need to test the stereotype application
- final T_StereotypeApplication stereotypeApplication = getStereotypeApplication((Element) oldValue);
- if (stereotypeApplication != null) {
- removeStereotypeApplicationListener(stereotypeApplication);
- this.stereotypedElementsMap.remove(stereotypeApplication);
- }
- }
- break;
- case Notification.REMOVE_MANY:
- Collection<?> oldValues = (Collection<?>) notification.getOldValue();
- for (final Object current : oldValues) {
- if (this.managedObject.contains(current)) {
- toRemove.add(current);
- final T_StereotypeApplication stereotypeApplication = getStereotypeApplication((Element) current);
- if (stereotypeApplication != null) {
- removeStereotypeApplicationListener(stereotypeApplication);
- this.stereotypedElementsMap.remove(stereotypeApplication);
- }
-
- }
- }
- break;
- case Notification.RESOLVE:
- case Notification.SET:
- case Notification.UNSET:
- // case Notification.NO_FEATURE_ID:
- // case Notification.NO_INDEX:
-
- default:
- break;
- }
- if (toAdd.size() > 0 || toRemove.size() > 0) {
- updateManagedList(toAdd, toRemove);
- }
- }
-
- /**
- *
- * @see org.eclipse.papyrus.infra.nattable.manager.axis.AbstractAxisManager#initializeManagedObjectList()
- *
- */
- @Override
- protected void initializeManagedObjectList() {
- final List<Object> featureValue = getFeaturesValue();
-
- // we filter them now
- for (final EObject current : getTableContext().eResource().getContents()) {
- if (!(current instanceof Element) && isInstanceOfRequiredStereotypeApplication(current)) {
- final Element baseElement = UMLUtil.getBaseElement(current);
- if (baseElement != null) {
- if (isAllowedContents(baseElement) && featureValue.contains(baseElement)) {
- this.managedObject.add(baseElement);
- this.stereotypedElementsMap.put(current, (baseElement));
- addStereotypeApplicationListener(current);
- }
- }
- }
- }
- }
-
-
- /**
- * Do the update of the managed objects list according to the notification
- *
- * @param notification
- * the notification
- */
- @SuppressWarnings("unchecked")
- protected void resourceHasChanged(final Notification notification) {
- if (notification.isTouch()) {
- return;
- }
- int eventType = notification.getEventType();
- final List<Object> toAdd = new ArrayList<Object>();
- final List<Object> toRemove = new ArrayList<Object>();
- switch (eventType) {
- case Notification.ADD:
-
- Object addedValue = notification.getNewValue();
- if (isInstanceOfRequiredStereotypeApplication(addedValue)) {
- List<Object> featureValue = getFeaturesValue();
- final T_StereotypeApplication stereotypeApplication = (T_StereotypeApplication) addedValue;
- final Element stereotypedElement = getStereotypeBaseElement(stereotypeApplication);
- if (stereotypedElement != null && isAllowedAsBaseElement(stereotypedElement) && featureValue.contains(stereotypedElement)) {
- toAdd.add(stereotypedElement);
- this.stereotypedElementsMap.put(stereotypeApplication, stereotypedElement);
- }
- // we add the listener on it in all case
- addStereotypeApplicationListener(stereotypeApplication);
- }
- break;
- case Notification.ADD_MANY:
- final Collection<?> addedValues = (Collection<?>) notification.getNewValue();
- final List<Object> featureValue = getFeaturesValue();
- for (final Object current : addedValues) {
- if (current instanceof EObject && isInstanceOfRequiredStereotypeApplication(current)) {
- final T_StereotypeApplication stereotypeApplication = (T_StereotypeApplication) current;
- final Element stereotypedElement = getStereotypeBaseElement(stereotypeApplication);
- if (stereotypedElement != null && isAllowedAsBaseElement(stereotypedElement) && featureValue.contains(stereotypedElement)) {
- toAdd.add(stereotypedElement);
- this.stereotypedElementsMap.put(stereotypeApplication, stereotypedElement);
- }
- // we add the listener on it in all case
- addStereotypeApplicationListener(stereotypeApplication);
- }
- }
- break;
- case Notification.EVENT_TYPE_COUNT:
- break;
- case Notification.MOVE:
- break;
-
- case Notification.REMOVE:
- final Object removedValue = notification.getOldValue();
- if (isInstanceOfRequiredStereotypeApplication(removedValue)) {
- final Element stereotypedElement = this.stereotypedElementsMap.get(removedValue);
- if (stereotypedElement != null && this.managedObject.contains(stereotypedElement)) {
- toRemove.add(stereotypedElement);
- this.stereotypedElementsMap.remove(removedValue);
- removeStereotypeApplicationListener((EObject) removedValue);
- }
- }
- break;
- case Notification.REMOVE_MANY:
- final Collection<?> removedValues = (Collection<?>) notification.getOldValue();
- for (final Object current : removedValues) {
- if (isInstanceOfRequiredStereotypeApplication(current)) {
- final Element stereotypedElement = this.stereotypedElementsMap.get(current);
- if (stereotypedElement != null && this.managedObject.contains(stereotypedElement)) {
- toRemove.add(stereotypedElement);
- this.stereotypedElementsMap.remove(current);
- removeStereotypeApplicationListener((EObject) current);
- }
- }
- }
- break;
- case Notification.REMOVING_ADAPTER:
- break;
- case Notification.RESOLVE:
- break;
- case Notification.SET:
- break;
- case Notification.UNSET:
- break;
-
- default:
- break;
- }
- if (toAdd.size() > 0 || toRemove.size() > 0) {
- updateManagedList(toAdd, toRemove);
- }
- }
-
- /**
- * Add a listener on the stereotype application update the field {@link #listenerMap}
- *
- * @param stereotypeApplication
- * the stereotype application
- */
- protected final void addStereotypeApplicationListener(final EObject stereotypeApplication) {
- if (this.listenerMap.containsKey(stereotypeApplication)) {
- return;
- }
- final Adapter stereotypeApplicationListener = new AdapterImpl() {
-
- @Override
- public void notifyChanged(Notification notification) {
- stereotypeApplicationHasChanged(notification);
- }
- };
- stereotypeApplication.eAdapters().add(stereotypeApplicationListener);
- this.listenerMap.put(stereotypeApplication, stereotypeApplicationListener);
- }
-
- /**
- * remove the listener on the stereotype application and update the field {@link #listenerMap}
- *
- * @param stereotypeApplication
- * the stereotype application
- */
- protected final void removeStereotypeApplicationListener(final EObject stereotypeApplication) {
- final Adapter listener = this.listenerMap.remove(stereotypeApplication);
- stereotypeApplication.eAdapters().remove(listener);
- }
-
- /**
- *
- * @see org.eclipse.papyrus.infra.emf.nattable.manager.axis.AbstractSynchronizedOnEStructuralFeatureAxisManager#removeListeners()
- *
- */
- @Override
- protected void removeListeners() {
- super.removeListeners();
- for (final EObject current : this.listenerMap.keySet()) {
- current.eAdapters().remove(this.listenerMap.get(current));
- }
- if (this.resourceListener != null) {
- for (final Resource current : getResourceToListen()) {
- current.eAdapters().remove(this.resourceListener);
- }
- }
- }
-
- /**
- *
- * @see org.eclipse.papyrus.infra.nattable.manager.axis.AbstractAxisManager#dispose()
- *
- */
- @Override
- public void dispose() {
- super.dispose();
- this.listenerMap.clear();
- this.stereotypedElementsMap.clear();
- }
-
-
- /**
- *
- * @param object
- * the object
- * @return
- * true if the element is an instance of T
- */
- protected abstract boolean isInstanceOfRequiredStereotypeApplication(final Object object);
-
- /**
- * The subclasses could override this method to be faster in case of static profile
- *
- * @param stereotypeApplication
- * the stereotype application
- * @return
- * the base element for this stereotype application
- */
- protected Element getStereotypeBaseElement(final T_StereotypeApplication stereotypeApplication) {
- return UMLUtil.getBaseElement(stereotypeApplication);
- }
-
- /**
- *
- * @param notification
- * the notification
- */
- protected void stereotypeApplicationHasChanged(final Notification notification) {
- if (notification.isTouch()) {
- return;
- }
- final Object notifier = notification.getNotifier();
- if (!isInstanceOfRequiredStereotypeApplication(notifier)) {
- return;
- }
- Object feature = notification.getFeature();
- int eventType = notification.getEventType();
- if (feature instanceof EReference && ((EReference) feature).getName().startsWith(getStereotypeApplicationBasePropertyName())) {
- final List<Object> featureValues = getFeaturesValue();
- switch (eventType) {
- case Notification.SET:
- final Object newValue = notification.getNewValue();
- final Object oldValue = notification.getOldValue();
- if (newValue instanceof Element && isAllowedAsBaseElement((Element) newValue) && featureValues.contains(newValue)) {
- updateManagedList(Collections.singletonList(newValue), Collections.emptyList());
- this.stereotypedElementsMap.put((EObject) notifier, (Element) newValue);
- } else if (newValue == null && this.managedObject.contains(oldValue)) {
- updateManagedList(Collections.emptyList(), Collections.singletonList(oldValue));
- this.stereotypedElementsMap.remove(notifier);
- removeStereotypeApplicationListener((EObject) notifier);
- }
- break;
-
- case Notification.UNSET:// never used?
- final Object oldValue2 = notification.getOldValue();
- if (oldValue2 instanceof Element && this.managedObject.contains(oldValue2)) {
- updateManagedList(Collections.emptyList(), Collections.singletonList(oldValue2));
- this.stereotypedElementsMap.remove(notifier);
- removeStereotypeApplicationListener((EObject) notifier);
- }
- break;
- default:
- break;
- }
- }
- }
-
- /**
- *
- * @see org.eclipse.papyrus.infra.nattable.manager.axis.AbstractAxisManager#isAllowedContents(java.lang.Object)
- *
- * @param object
- * @return
- * <code>true</code> if the object is an instance of Element + is allowed as base Element + has required stereotype applied on it
- */
- @Override
- public boolean isAllowedContents(final Object object) {
- return object instanceof Element && isAllowedAsBaseElement((Element) object) && hasRequiredStereotypes((Element) object);
- }
-
- /**
- *
- * @param element
- * @return
- * <code>true</code> if the elements has all required stererotypes applied on it
- */
- protected final boolean hasRequiredStereotypes(final Element element) {
- for (final EObject current : element.getStereotypeApplications()) {
- if (isInstanceOfRequiredStereotypeApplication(current)) {
- return true;
- }
- }
- return false;
- }
-
-
- /**
- *
- * @param element
- * an element
- * @return
- * <code>true</code> if the element can be used as base element for the wanted stereotyped elements
- */
- protected abstract boolean isAllowedAsBaseElement(final Element element);
-
- /**
- *
- * @param element
- * an element
- * @return
- * the {@link Stereotype} application for this element
- */
- protected abstract T_StereotypeApplication getStereotypeApplication(final Element element);
-
- /**
- *
- * @return
- * the base property name
- */
- protected abstract String getStereotypeApplicationBasePropertyName();
-
-}
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ * Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net - Bug 439501
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.nattable.manager.axis;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.papyrus.infra.nattable.manager.table.INattableModelManager;
+import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisconfiguration.AxisManagerRepresentation;
+import org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisprovider.AbstractAxisProvider;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Stereotype;
+import org.eclipse.uml2.uml.util.UMLUtil;
+
+
+/**
+ * Axis Manager used when the contents of the table is synchronized on a feature AND that these elements must be stereotyped
+ *
+ * @author vl222926
+ *
+ */
+public abstract class AbstractStereotypedElementUMLSynchronizedOnFeatureAxisManager<T_StereotypeApplication extends EObject> extends AbstractUMLSynchronizedOnFeatureAxisManager {
+
+ /** the resource listener */
+ protected Adapter resourceListener;
+
+ /**
+ * the map of the listen listening stereotypes applications
+ */
+ protected Map<EObject, Adapter> listenerMap;
+
+ /**
+ * the map between the stereotypes applications and the base_element
+ */
+ protected Map<EObject, Element> stereotypedElementsMap;
+
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.emf.nattable.manager.axis.AbstractSynchronizedOnEStructuralFeatureAxisManager#init(org.eclipse.papyrus.infra.nattable.manager.table.INattableModelManager,
+ * org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisconfiguration.AxisManagerRepresentation, org.eclipse.papyrus.infra.nattable.model.nattable.nattableaxisprovider.AbstractAxisProvider)
+ *
+ * @param manager
+ * @param rep
+ * @param provider
+ */
+ @Override
+ public void init(INattableModelManager manager, AxisManagerRepresentation rep, AbstractAxisProvider provider) {
+ this.listenerMap = new HashMap<EObject, Adapter>();
+ this.stereotypedElementsMap = new HashMap<EObject, Element>();
+ super.init(manager, rep, provider);
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.emf.nattable.manager.axis.AbstractSynchronizedOnEStructuralFeatureAxisManager#addListeners()
+ *
+ */
+ @Override
+ protected void addListeners() {
+ super.addListeners();
+ addResourceListeners();
+ }
+
+
+ /**
+ * this method a the listener on the resource
+ */
+ private void addResourceListeners() {
+ this.resourceListener = new AdapterImpl() {
+
+ @Override
+ public void notifyChanged(final Notification notification) {
+ resourceHasChanged(notification);
+
+ }
+ };
+
+ for (final Resource current : getResourceToListen()) {
+ current.eAdapters().add(this.resourceListener);
+ }
+ }
+
+ /**
+ *
+ * @return
+ */
+ protected Collection<Resource> getResourceToListen() {
+ return Collections.singleton(getTableContext().eResource());
+ }
+
+ /**
+ *
+ * @param notification
+ * the notification
+ */
+ @Override
+ protected void featureValueHasChanged(final Notification notification) {
+ if (notification.isTouch()) {
+ return;
+ }
+
+ int eventType = notification.getEventType();
+ List<Object> toAdd = new ArrayList<Object>();
+ List<Object> toRemove = new ArrayList<Object>();
+ switch (eventType) {
+ case Notification.REMOVING_ADAPTER:
+ break;// nothing to do
+ case Notification.ADD:
+ Object newValue = notification.getNewValue();
+ if (isAllowedContents(newValue)) {
+ final T_StereotypeApplication stereotypeApplication = getStereotypeApplication((Element) newValue);
+ if (stereotypeApplication != null) {
+ toAdd.add(newValue);
+ addStereotypeApplicationListener(stereotypeApplication);
+ this.stereotypedElementsMap.put(stereotypeApplication, (Element) newValue);
+ }
+ }
+ break;
+ case Notification.ADD_MANY:
+ Collection<?> newValues = (Collection<?>) notification.getNewValue();
+ for (final Object current : newValues) {
+ if (isAllowedContents(current)) {
+ final T_StereotypeApplication stereotypeApplication = getStereotypeApplication((Element) current);
+ if (stereotypeApplication != null) {
+ toAdd.add(current);
+ addStereotypeApplicationListener(stereotypeApplication);
+ this.stereotypedElementsMap.put(stereotypeApplication, (Element) current);
+ }
+ }
+ }
+ break;
+ case Notification.EVENT_TYPE_COUNT:
+ break;
+ case Notification.MOVE:
+ final Collection<EObject> collection = (Collection<EObject>) ((EObject)notification.getNotifier()).eGet((EStructuralFeature) notification.getFeature());
+ final Collection<EObject> subList = getSubFromFirstNotEquals(collection, (Integer)notification.getOldValue(), getIndex(collection, (EObject) notification.getNewValue()));
+
+ toRemove.addAll(subList);
+ toAdd.addAll(subList);
+ break;
+ case Notification.REMOVE:
+ final Object oldValue = notification.getOldValue();
+ if (this.managedObject.contains(oldValue)) {
+ toRemove.add(oldValue);// no need to test the stereotype application
+ final T_StereotypeApplication stereotypeApplication = getStereotypeApplication((Element) oldValue);
+ if (stereotypeApplication != null) {
+ removeStereotypeApplicationListener(stereotypeApplication);
+ this.stereotypedElementsMap.remove(stereotypeApplication);
+ }
+ }
+ break;
+ case Notification.REMOVE_MANY:
+ Collection<?> oldValues = (Collection<?>) notification.getOldValue();
+ for (final Object current : oldValues) {
+ if (this.managedObject.contains(current)) {
+ toRemove.add(current);
+ final T_StereotypeApplication stereotypeApplication = getStereotypeApplication((Element) current);
+ if (stereotypeApplication != null) {
+ removeStereotypeApplicationListener(stereotypeApplication);
+ this.stereotypedElementsMap.remove(stereotypeApplication);
+ }
+
+ }
+ }
+ break;
+ case Notification.RESOLVE:
+ case Notification.SET:
+ case Notification.UNSET:
+ // case Notification.NO_FEATURE_ID:
+ // case Notification.NO_INDEX:
+
+ default:
+ break;
+ }
+ if (toAdd.size() > 0 || toRemove.size() > 0) {
+ updateManagedList(toAdd, toRemove);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.nattable.manager.axis.AbstractAxisManager#initializeManagedObjectList()
+ */
+ @Override
+ protected void initializeManagedObjectList() {
+ final List<Object> featuresValue = getFeaturesValue();
+
+ // Bug 439501: The feature values must be the initial values order
+ // we filter them now
+ for(final Object featureValue : featuresValue){
+ for (final EObject current : getTableContext().eResource().getContents()) {
+ if (!(current instanceof Element) && isInstanceOfRequiredStereotypeApplication(current)) {
+ final Element baseElement = UMLUtil.getBaseElement(current);
+ if (baseElement != null) {
+ if (featureValue.equals(baseElement) && isAllowedContents(baseElement)) {
+ this.managedObject.add(baseElement);
+ this.stereotypedElementsMap.put(current, (baseElement));
+ addStereotypeApplicationListener(current);
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Do the update of the managed objects list according to the notification
+ *
+ * @param notification
+ * the notification
+ */
+ @SuppressWarnings("unchecked")
+ protected void resourceHasChanged(final Notification notification) {
+ if (notification.isTouch()) {
+ return;
+ }
+
+ int eventType = notification.getEventType();
+ final List<Object> toAdd = new ArrayList<Object>();
+ final List<Object> toRemove = new ArrayList<Object>();
+ switch (eventType) {
+ case Notification.ADD:
+
+ Object addedValue = notification.getNewValue();
+ if (isInstanceOfRequiredStereotypeApplication(addedValue)) {
+ List<Object> featureValue = getFeaturesValue();
+ final T_StereotypeApplication stereotypeApplication = (T_StereotypeApplication) addedValue;
+ final Element stereotypedElement = getStereotypeBaseElement(stereotypeApplication);
+ if (stereotypedElement != null && isAllowedAsBaseElement(stereotypedElement) && featureValue.contains(stereotypedElement)) {
+ toAdd.add(stereotypedElement);
+ this.stereotypedElementsMap.put(stereotypeApplication, stereotypedElement);
+ }
+ // we add the listener on it in all case
+ addStereotypeApplicationListener(stereotypeApplication);
+ }
+ break;
+ case Notification.ADD_MANY:
+ final Collection<?> addedValues = (Collection<?>) notification.getNewValue();
+ final List<Object> featureValue = getFeaturesValue();
+ for (final Object current : addedValues) {
+ if (current instanceof EObject && isInstanceOfRequiredStereotypeApplication(current)) {
+ final T_StereotypeApplication stereotypeApplication = (T_StereotypeApplication) current;
+ final Element stereotypedElement = getStereotypeBaseElement(stereotypeApplication);
+ if (stereotypedElement != null && isAllowedAsBaseElement(stereotypedElement) && featureValue.contains(stereotypedElement)) {
+ toAdd.add(stereotypedElement);
+ this.stereotypedElementsMap.put(stereotypeApplication, stereotypedElement);
+ }
+ // we add the listener on it in all case
+ addStereotypeApplicationListener(stereotypeApplication);
+ }
+ }
+ break;
+ case Notification.EVENT_TYPE_COUNT:
+ break;
+ case Notification.MOVE:
+ final Collection<EObject> collection = (Collection<EObject>) ((EObject)notification.getNotifier()).eGet((EStructuralFeature) notification.getFeature());
+ final Collection<EObject> subList = getSubFromFirstNotEquals(collection, (Integer)notification.getOldValue(), getIndex(collection, (EObject) notification.getNewValue()));
+
+ toRemove.addAll(subList);
+ toAdd.addAll(subList);
+ break;
+
+ case Notification.REMOVE:
+ final Object removedValue = notification.getOldValue();
+ if (isInstanceOfRequiredStereotypeApplication(removedValue)) {
+ final Element stereotypedElement = this.stereotypedElementsMap.get(removedValue);
+ if (stereotypedElement != null && this.managedObject.contains(stereotypedElement)) {
+ toRemove.add(stereotypedElement);
+ this.stereotypedElementsMap.remove(removedValue);
+ removeStereotypeApplicationListener((EObject) removedValue);
+ }
+ }
+ break;
+ case Notification.REMOVE_MANY:
+ final Collection<?> removedValues = (Collection<?>) notification.getOldValue();
+ for (final Object current : removedValues) {
+ if (isInstanceOfRequiredStereotypeApplication(current)) {
+ final Element stereotypedElement = this.stereotypedElementsMap.get(current);
+ if (stereotypedElement != null && this.managedObject.contains(stereotypedElement)) {
+ toRemove.add(stereotypedElement);
+ this.stereotypedElementsMap.remove(current);
+ removeStereotypeApplicationListener((EObject) current);
+ }
+ }
+ }
+ break;
+ case Notification.REMOVING_ADAPTER:
+ break;
+ case Notification.RESOLVE:
+ break;
+ case Notification.SET:
+ break;
+ case Notification.UNSET:
+ break;
+
+ default:
+ break;
+ }
+ if (toAdd.size() > 0 || toRemove.size() > 0) {
+ updateManagedList(toAdd, toRemove);
+ }
+ }
+
+ /**
+ * Add a listener on the stereotype application update the field {@link #listenerMap}
+ *
+ * @param stereotypeApplication
+ * the stereotype application
+ */
+ protected final void addStereotypeApplicationListener(final EObject stereotypeApplication) {
+ if (this.listenerMap.containsKey(stereotypeApplication)) {
+ return;
+ }
+ final Adapter stereotypeApplicationListener = new AdapterImpl() {
+
+ @Override
+ public void notifyChanged(Notification notification) {
+ stereotypeApplicationHasChanged(notification);
+ }
+ };
+ stereotypeApplication.eAdapters().add(stereotypeApplicationListener);
+ this.listenerMap.put(stereotypeApplication, stereotypeApplicationListener);
+ }
+
+ /**
+ * remove the listener on the stereotype application and update the field {@link #listenerMap}
+ *
+ * @param stereotypeApplication
+ * the stereotype application
+ */
+ protected final void removeStereotypeApplicationListener(final EObject stereotypeApplication) {
+ final Adapter listener = this.listenerMap.remove(stereotypeApplication);
+ stereotypeApplication.eAdapters().remove(listener);
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.emf.nattable.manager.axis.AbstractSynchronizedOnEStructuralFeatureAxisManager#removeListeners()
+ *
+ */
+ @Override
+ protected void removeListeners() {
+ super.removeListeners();
+ for (final EObject current : this.listenerMap.keySet()) {
+ current.eAdapters().remove(this.listenerMap.get(current));
+ }
+ if (this.resourceListener != null) {
+ for (final Resource current : getResourceToListen()) {
+ current.eAdapters().remove(this.resourceListener);
+ }
+ }
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.nattable.manager.axis.AbstractAxisManager#dispose()
+ *
+ */
+ @Override
+ public void dispose() {
+ super.dispose();
+ this.listenerMap.clear();
+ this.stereotypedElementsMap.clear();
+ }
+
+
+ /**
+ *
+ * @param object
+ * the object
+ * @return
+ * true if the element is an instance of T
+ */
+ protected abstract boolean isInstanceOfRequiredStereotypeApplication(final Object object);
+
+ /**
+ * The subclasses could override this method to be faster in case of static profile
+ *
+ * @param stereotypeApplication
+ * the stereotype application
+ * @return
+ * the base element for this stereotype application
+ */
+ protected Element getStereotypeBaseElement(final T_StereotypeApplication stereotypeApplication) {
+ return UMLUtil.getBaseElement(stereotypeApplication);
+ }
+
+ /**
+ *
+ * @param notification
+ * the notification
+ */
+ protected void stereotypeApplicationHasChanged(final Notification notification) {
+ if (notification.isTouch()) {
+ return;
+ }
+ final Object notifier = notification.getNotifier();
+ if (!isInstanceOfRequiredStereotypeApplication(notifier)) {
+ return;
+ }
+ Object feature = notification.getFeature();
+ int eventType = notification.getEventType();
+ if (feature instanceof EReference && ((EReference) feature).getName().startsWith(getStereotypeApplicationBasePropertyName())) {
+ final List<Object> featureValues = getFeaturesValue();
+ switch (eventType) {
+ case Notification.SET:
+ final Object newValue = notification.getNewValue();
+ final Object oldValue = notification.getOldValue();
+ if (newValue instanceof Element && isAllowedAsBaseElement((Element) newValue) && featureValues.contains(newValue)) {
+ updateManagedList(Collections.singletonList(newValue), Collections.emptyList());
+ this.stereotypedElementsMap.put((EObject) notifier, (Element) newValue);
+ } else if (newValue == null && this.managedObject.contains(oldValue)) {
+ updateManagedList(Collections.emptyList(), Collections.singletonList(oldValue));
+ this.stereotypedElementsMap.remove(notifier);
+ removeStereotypeApplicationListener((EObject) notifier);
+ }
+ break;
+
+ case Notification.UNSET:// never used?
+ final Object oldValue2 = notification.getOldValue();
+ if (oldValue2 instanceof Element && this.managedObject.contains(oldValue2)) {
+ updateManagedList(Collections.emptyList(), Collections.singletonList(oldValue2));
+ this.stereotypedElementsMap.remove(notifier);
+ removeStereotypeApplicationListener((EObject) notifier);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.nattable.manager.axis.AbstractAxisManager#isAllowedContents(java.lang.Object)
+ *
+ * @param object
+ * @return
+ * <code>true</code> if the object is an instance of Element + is allowed as base Element + has required stereotype applied on it
+ */
+ @Override
+ public boolean isAllowedContents(final Object object) {
+ return object instanceof Element && isAllowedAsBaseElement((Element) object) && hasRequiredStereotypes((Element) object);
+ }
+
+ /**
+ *
+ * @param element
+ * @return
+ * <code>true</code> if the elements has all required stererotypes applied on it
+ */
+ protected final boolean hasRequiredStereotypes(final Element element) {
+ for (final EObject current : element.getStereotypeApplications()) {
+ if (isInstanceOfRequiredStereotypeApplication(current)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ *
+ * @param element
+ * an element
+ * @return
+ * <code>true</code> if the element can be used as base element for the wanted stereotyped elements
+ */
+ protected abstract boolean isAllowedAsBaseElement(final Element element);
+
+ /**
+ *
+ * @param element
+ * an element
+ * @return
+ * the {@link Stereotype} application for this element
+ */
+ protected abstract T_StereotypeApplication getStereotypeApplication(final Element element);
+
+ /**
+ *
+ * @return
+ * the base property name
+ */
+ protected abstract String getStereotypeApplicationBasePropertyName();
+
+}

Back to the top