public void cdoInternalPostDetach(boolean remote) {
    if (remote) {
      setInstanceContainer(null, eContainerFeatureID());
      setInstanceResource(null);
      return;
    }

    // This loop adjusts the opposite wrapper objects to support dangling references. See
    // Bugzilla_251263_Test
    InternalCDORevision revision = cdoRevision();
    for (EReference reference : classInfo.getAllPersistentReferences()) {
      if (!reference.isContainer() && classInfo.hasPersistentOpposite(reference)) {
        if (reference.isMany()) {
          EReference oppositeReference = reference.getEOpposite();

          int size = revision.size(reference);
          for (int i = 0; i < size; i++) {
            EObject object = (EObject) getValueFromRevision(reference, i);
            adjustPersistentOppositeReference(this, object, oppositeReference);
          }
        } else {
          EObject oppositeObject = (EObject) instance.eGet(reference);
          if (oppositeObject != null) {
            EReference oppositeReference = reference.getEOpposite();
            adjustPersistentOppositeReference(this, oppositeObject, oppositeReference);
          }
        }
      }
    }
  }
示例#2
0
  private void addLink(
      EObject sourceEObject, EObject targetEObject, EReference eReference, int targetPosition) {
    Object_ sourceObject = map.getObject(sourceEObject);
    Object_ targetObject = map.getObject(targetEObject);
    Association association = getFUMLAssociation(eReference);

    if (hasOppositeReference(eReference)
        && haveProcessedAsOpposite(eReference, sourceObject, targetObject, association)) {
      return;
    }

    // Setup target property end
    LinkCreationData linkData = new LinkCreationData(sourceObject, targetObject, association);
    LinkEndCreationData targetEndData = linkData.createLinkEndCreationData();
    targetEndData.setEnd(getTargetPropertyEnd(eReference, association));
    linkData.setTargetEndData(targetEndData);
    linkData.setTargetPosition(targetPosition);

    // Setup source property end
    LinkEndCreationData sourceEndData = linkData.createLinkEndCreationData();
    if (hasOppositeReference(eReference)) {
      EReference oppositeReference = eReference.getEOpposite();
      sourceEndData.setEnd(getTargetPropertyEnd(oppositeReference, association));
      int sourcePosition = getPosition(targetEObject, oppositeReference, sourceEObject);
      linkData.setSourcePosition(sourcePosition);
      addProcessedOpposite(sourceEndData);
    } else {
      sourceEndData.setEnd(getSourcePropertyEnd(eReference, association));
    }
    linkData.setSourceEndData(sourceEndData);
    Link link = linkData.createNewLink();
    map.addExtensionalValue(link);
    // link.addTo(locus);
    locus.add(link);
  }
示例#3
0
    public static int kind(EStructuralFeature eStructuralFeature) {
      int result = 0;

      EClassifier eClassifier = eStructuralFeature.getEType();

      if (eClassifier.getInstanceClass() != null) {
        result |= HAS_INSTANCE_CLASS;
      }

      if (eStructuralFeature.isUnsettable()) {
        result |= IS_UNSETTABLE;
      }

      if (eStructuralFeature instanceof EReference) {
        EReference eReference = (EReference) eStructuralFeature;
        EReference inverseEReference = eReference.getEOpposite();
        if (eReference.isContainment()) {
          result |= IS_CONTAINMENT;
        }

        if (inverseEReference != null) {
          // This forces the feature ids to be assigned.
          //
          inverseEReference.getEContainingClass().getFeatureCount();
          result |= HAS_NAVIGABLE_INVERSE;
          if (inverseEReference.isMany()) {
            result |= HAS_MANY_INVERSE;
          }
          if (inverseEReference.isContainment()) {
            result |= IS_CONTAINER;
          }
        }

        if (eReference.isResolveProxies()) {
          result |= HAS_PROXIES;
        }

        result |= IS_EOBJECT;
      } else // if (eStructuralFeature instanceof EAttribute
      {
        if (eClassifier instanceof EEnum) {
          result |= IS_ENUM;
        } else {
          Class<?> instanceClass = eClassifier.getInstanceClass();
          if (instanceClass != null && instanceClass.isPrimitive()) {
            result |= IS_PRIMITIVE;
          }
        }
      }

      if (eStructuralFeature.isUnique()) {
        result |= IS_UNIQUE;
      }

      return result;
    }
 void resolve(EObject object, EReference reference, EObject proxy) {
   EReference opposite = reference.getEOpposite();
   if (opposite != null) {
     if (opposite.isMany()) {
       InternalEList<?> list = (InternalEList<?>) object.eGet(opposite, false);
       int index = list.basicIndexOf(proxy);
       if (index >= 0) {
         list.get(index); // resolve just this index
       }
     } else {
       object.eGet(opposite, true); // resolve the scalar reference
     }
   }
 }
示例#5
0
 /**
  * Converts the value of an EReference with isMany==false, the value is converted to a Object and
  * set in the correct feature in the model managed object.
  *
  * @param eObject the eObject from which the value is read
  * @param modelObject the Object in which the value is to be set
  * @param eReference the eReference which is converted
  */
 protected void convertSingleEReference(
     final EObject eObject, final ModelObject<?> modelObject, final EReference eReference) {
   // bidirectional one-to-many are always set from the many side to preserve the order
   final EObject value = (EObject) eObject.eGet(eReference);
   if (!eReference.isMany()
       && value != null
       && eReference.getEOpposite() != null
       && eReference.getEOpposite().isMany()) {
     return;
   }
   if (value == null) {
     modelObject.eSet(eReference, null);
   } else {
     modelObject.eSet(eReference, createTarget(value));
   }
 }
示例#6
0
  /**
   * Converts the value of an EReference with isMany==true, the values of the collection are
   * converted to Objects and added to the list in the correct feature in the {@link ModelObject}.
   *
   * @param eObject the eObject from which the value is read
   * @param modelObject the Object in which the value is set
   * @param eReference the eReference which is converted
   */
  protected void convertManyEReference(
      final EObject eObject, final ModelObject<?> modelObject, final EReference eReference) {
    @SuppressWarnings("unchecked")
    final Collection<EObject> eValues = (Collection<EObject>) eObject.eGet(eReference);
    if (ModelUtils.isEMap(eReference)) {
      @SuppressWarnings("unchecked")
      final Map<Object, Object> mValues = (Map<Object, Object>) modelObject.eGet(eReference);

      // clear as there can be current values if the target is read from the db
      mValues.clear();

      for (final Object eValue : eValues) {
        @SuppressWarnings("unchecked")
        final Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) eValue;
        // key and value can also be an EObject
        final Object key;
        if (entry.getKey() instanceof EObject) {
          key = createTarget((EObject) entry.getKey());
        } else {
          key = entry.getKey();
        }
        final Object value;
        if (entry.getValue() instanceof EObject) {
          value = createTarget((EObject) entry.getValue());
        } else {
          value = entry.getValue();
        }

        mValues.put(key, value);
      }
    } else {

      // a many to many
      if (eReference.getEOpposite() != null && eReference.getEOpposite().isMany()) {
        final ManyToMany mtm = new ManyToMany();
        mtm.setOwner(eObject);
        mtm.setEReference(eReference);
        toRepairManyToMany.add(mtm);
      }

      final Collection<?> mValues = (Collection<?>) modelObject.eGet(eReference);

      // make a copy
      final List<Object> copiedMValues = new ArrayList<Object>(mValues);

      // clear as there can be current values if the target is read from the db
      // use forloop as the collection can be unmodifiable
      for (Object o : new ArrayList<Object>(mValues)) {
        modelObject.eRemoveFrom(eReference, o);
      }

      // check that the eopposite is indeed cleared, this is not the case if
      // there is no bi-directional code generated
      final EReference eOpposite = eReference.getEOpposite();
      if (eOpposite != null && !eOpposite.isMany()) {
        for (Object mValue : copiedMValues) {
          final ModelObject<?> modelMValue = ModelResolver.getInstance().getModelObject(mValue);
          modelMValue.eSet(eOpposite, null);
        }
      }

      for (final EObject eValue : eValues) {
        final Object target = createTarget(eValue);
        // first add to the many reference
        modelObject.eAddTo(eReference, target);

        // add to the other side, this is needed because the bi-directional
        // api is not always generated
        if (eOpposite != null && !eOpposite.isMany()) {
          final ModelObject<?> modelObjectTarget =
              ModelResolver.getInstance().getModelObject(target);
          modelObjectTarget.eSet(eReference.getEOpposite(), modelObject.getTarget());
        }
      }
    }
  }
示例#7
0
 private boolean hasOppositeReference(EReference eReference) {
   return eReference.getEOpposite() != null;
 }
示例#8
0
  /**
   * Converts the value of an EReference with isMany==true, the values of the collection are
   * converted to EObjects and added to the list in the correct feature in the eObject.
   *
   * @param modelObject the modelObject from which the value is retrieved.
   * @param eObject the eObject in which the value is set (after it has been converted)
   * @param eReference the eReference which is converted
   */
  protected void convertManyEReference(
      final ModelObject<?> modelObject, final EObject eObject, final EReference eReference) {
    // container feature is always set from the other side, the containment
    // side
    if (eReference.isContainer()) {
      return;
    }

    final Object manyValue = modelObject.eGet(eReference);
    final Collection<EObject> newValues = new ArrayList<EObject>();

    boolean isMap = Map.class.isAssignableFrom(manyValue.getClass());
    EStructuralFeature valueFeature = null;
    EStructuralFeature keyFeature = null;
    if (isMap) {
      final EClass mapEClass = eReference.getEReferenceType();
      valueFeature = mapEClass.getEStructuralFeature("value"); // $NON-NLS-1$
      keyFeature = mapEClass.getEStructuralFeature("key"); // $NON-NLS-1$

      Check.isTrue(
          ModelUtils.isEMap(eReference),
          "Expected emap EReference, but th// case for EReference " //$NON-NLS-1$
              + eReference);

      final Map<?, ?> map = (Map<?, ?>) manyValue;

      for (final Object key : map.keySet()) {
        final Object value = map.get(key);
        final EObject mapEntryEObject = EcoreUtil.create(mapEClass);

        // key and value maybe primitive types but can also be
        // references to model objects.
        if (valueFeature instanceof EReference) {
          mapEntryEObject.eSet(valueFeature, createTarget(value));
        } else {
          mapEntryEObject.eSet(valueFeature, value);
        }
        if (keyFeature instanceof EReference) {
          mapEntryEObject.eSet(keyFeature, createTarget(key));
        } else {
          mapEntryEObject.eSet(keyFeature, key);
        }
        newValues.add(mapEntryEObject);
      }
    } else {

      // a many to many
      if (eReference.getEOpposite() != null && eReference.getEOpposite().isMany()) {
        final ManyToMany mtm = new ManyToMany();
        mtm.setOwner(modelObject);
        mtm.setEReference(eReference);
        toRepairManyToMany.add(mtm);
      }

      @SuppressWarnings("unchecked")
      final Collection<Object> values = (Collection<Object>) manyValue;

      for (final Object value : values) {
        if (value == null) {
          newValues.add(null);
        } else {
          final InternalEObject eValue = (InternalEObject) createTarget(value);
          if (!newValues.contains(eValue)) {
            newValues.add(eValue);
          }
        }
      }
    }

    @SuppressWarnings("unchecked")
    final Collection<EObject> eValues = (Collection<EObject>) eObject.eGet(eReference);

    boolean updateList = false;
    if (newValues.size() == eValues.size()) {
      final Iterator<?> it = eValues.iterator();
      for (Object newValue : newValues) {
        final Object oldValue = it.next();

        if (isMap) {
          final EObject oldMapEntry = (EObject) oldValue;
          final EObject newMapEntry = (EObject) newValue;
          final Object oldMapValue = oldMapEntry.eGet(valueFeature);
          final Object oldMapKey = oldMapEntry.eGet(keyFeature);
          final Object newMapValue = newMapEntry.eGet(valueFeature);
          final Object newMapKey = newMapEntry.eGet(keyFeature);
          if (valueFeature instanceof EReference) {
            updateList = oldMapValue == newMapValue;
          } else {
            updateList =
                oldMapValue != null
                    ? !oldMapValue.equals(newMapValue)
                    : newMapValue != null ? !newMapValue.equals(oldMapValue) : false;
          }
          if (keyFeature instanceof EReference) {
            updateList = updateList || oldMapKey == newMapKey;
          } else {
            updateList =
                updateList
                    || (oldMapKey != null
                        ? !oldMapKey.equals(newMapKey)
                        : newMapKey != null ? !newMapKey.equals(oldMapKey) : false);
          }
        } else {
          updateList = oldValue != newValue;
        }

        if (updateList) {
          break;
        }
      }
    } else {
      updateList = true;
    }

    if (updateList) {
      // clear the evalues so that an empty tag is created in the xml
      eValues.clear();
      eValues.addAll(newValues);
    }
  }