Пример #1
0
  private void adjustTransientOppositeReference(
      InternalEObject instance, InternalEObject object, EReference oppositeReference) {
    boolean wasDeliver = object.eDeliver(); // Disable notifications
    if (wasDeliver) {
      object.eSetDeliver(false);
    }

    try {
      if (oppositeReference.isMany()) {
        @SuppressWarnings("unchecked")
        InternalEList<Object> list = (InternalEList<Object>) object.eGet(oppositeReference);
        list.basicAdd(instance, null);
      } else {
        if (object.eGet(oppositeReference) != instance) {
          object.eInverseAdd(
              instance, oppositeReference.getFeatureID(), ((EObject) instance).getClass(), null);
        }
      }
    } finally {
      if (wasDeliver) {
        object.eSetDeliver(true);
      }
    }
  }
 public org.eclipse.emf.common.notify.NotificationChain basicAdd(
     org.eclipse.emf.ecore.EObject object,
     org.eclipse.emf.common.notify.NotificationChain notifications) {
   copy.basicAdd(object, notifications);
   return original.basicAdd(object, notifications);
 }
Пример #3
0
  /** @since 3.0 */
  protected void revisionToInstanceFeature(EStructuralFeature feature) {
    if (feature.isUnsettable() && !viewAndState.view.getStore().isSet(this, feature)) {
      // Clarify if this is sufficient for bidirectional references
      instance.eUnset(feature);
      return;
    }

    if (feature.isMany()) {
      if (TRACER.isEnabled()) {
        TRACER.format(
            "State of Object ("
                + this
                + "/"
                + instance
                + ") is : "
                + viewAndState.state); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      }

      if (viewAndState.state == CDOState.CLEAN
          || viewAndState.state == CDOState.PROXY
          || viewAndState.state == CDOState.NEW
          || viewAndState.state == CDOState.DIRTY) {
        InternalCDORevision revision = cdoRevision();
        int size = revision.size(feature);

        @SuppressWarnings("unchecked")
        InternalEList<Object> list = (InternalEList<Object>) instance.eGet(feature);

        clearEList(list);
        for (int i = 0; i < size; i++) {
          Object object = getValueFromRevision(feature, i);

          if (TRACER.isEnabled()) {
            TRACER.format(
                "Adding "
                    + object
                    + " to feature "
                    + feature
                    + "in instance "
                    + instance); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
          }

          // Disable notifications from value during the
          // invalidation in case of
          // eInverseAdd/eInverseRemove
          boolean eDeliver = false;
          if (object instanceof Notifier) {
            Notifier notifier = (Notifier) object;
            eDeliver = notifier.eDeliver();
            if (eDeliver) {
              notifier.eSetDeliver(false);
            }
          }

          list.basicAdd(object, null);

          if (object instanceof Notifier && eDeliver) {
            Notifier notifier = (Notifier) object;
            notifier.eSetDeliver(eDeliver);
          }
        }
      }
    } else {
      // !feature.isMany()
      Object object = getValueFromRevision(feature, 0);
      if (feature instanceof EAttribute) {
        if (TRACER.isEnabled()) {
          TRACER.format(
              "Setting attribute value "
                  + object
                  + " to feature "
                  + feature
                  + " in instance "
                  + instance); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        }

        // Just fake it for the store :(
        if (feature.isUnsettable() && object.equals(CDORevisionData.NIL)) {
          eSet(feature, null);
        } else {
          if (object != null) {
            eSet(feature, object);
          } else {
            // TODO Unset for features with non-null default values would not lead to null values.
            // Probably CDORevisionData.NIL has to be used, but that impacts all IStores. Deferred
            // ;-(
            eUnset(feature);
          }
        }
      } else {
        // EReferences
        if (TRACER.isEnabled()) {
          TRACER.format(
              "Adding object "
                  + object
                  + " to feature "
                  + feature
                  + " in instance "
                  + instance); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        }

        // Disable notifications from value during the
        // invalidation in case of
        // eInverseAdd/eInverseRemove
        boolean eDeliver = false;
        if (object instanceof Notifier) {
          Notifier notifier = (Notifier) object;
          eDeliver = notifier.eDeliver();
          if (eDeliver) {
            notifier.eSetDeliver(false);
          }
        }
        EObject oldContainerOfValue = null;
        boolean eDeliverForOldContainerOfValue = false;
        if (object instanceof InternalEObject) {
          InternalEObject eObject = (InternalEObject) object;
          oldContainerOfValue = eObject.eInternalContainer();
          if (oldContainerOfValue != null) {
            eDeliverForOldContainerOfValue = oldContainerOfValue.eDeliver();
            if (eDeliverForOldContainerOfValue) {
              oldContainerOfValue.eSetDeliver(false);
            }
          }
        }

        int featureID = instance.eClass().getFeatureID(feature);
        Class<? extends Object> baseClass = object == null ? null : object.getClass();
        EStructuralFeature.Internal internalFeature = (EStructuralFeature.Internal) feature;
        EReference oppositeReference = internalFeature.getEOpposite();

        if (oppositeReference != null) {
          if (object != null && object != instance.eGet(feature)) {
            // If you have a containment reference but the container is not set, but the object is
            // attached to a
            // resource
            // do not set the feature to null. Otherwise the object will be removed from the
            // container which is the
            // resource instead of the original container. As a result the object will be detached.
            // See
            // MapTest.testEObjectToEObjectValueContainedMap for more information
            if (object != instance.eContainer() || !oppositeReference.isContainment()) {
              instance.eInverseAdd((InternalEObject) object, featureID, baseClass, null);
            }

            if (!classInfo.hasPersistentOpposite(internalFeature)) {
              adjustTransientOppositeReference(
                  instance, (InternalEObject) object, oppositeReference);
            }
          }
        } else {
          if (object != CDORevisionData.NIL) {
            EReference reference = (EReference) feature;
            if (reference.isContainment()) {
              if (object != null) {
                // Calling eSet it not the optimal approach, but currently there is no other way to
                // set the value here.
                // To avoid attaching already processed (clean) objects a check was introduced to
                // CDOResourceImpl.attached(EObject).
                // If we find a way to avoid the call of eSet and if we are able to only set the
                // feature value directly
                // this check can be removed from CDOResourceImpl. See also Bug 352204.
                instance.eSet(feature, object);
              } else {
                instance.eSet(feature, null);
              }
            } else {
              instance.eSet(feature, object);
            }
          } else {
            instance.eSet(feature, null);
          }
        }

        if (object instanceof Notifier && eDeliver) {
          Notifier notifier = (Notifier) object;
          notifier.eSetDeliver(eDeliver);
        }
        if (oldContainerOfValue != null && eDeliverForOldContainerOfValue) {
          oldContainerOfValue.eSetDeliver(eDeliverForOldContainerOfValue);
        }

        if (TRACER.isEnabled()) {
          TRACER.format(
              "Added object "
                  + object
                  + " to feature "
                  + feature
                  + " in instance "
                  + instance); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        }
      }
    }
  }