/** * 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()); } } } }
/** * 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); } }