/** * Converts the values of an FeatureMap, the values of the collection are converted to and added * to the list in the correct feature in the modelObject. * * @param eObject the eObject from which the value is read * @param modelObject the {@link ModelObject} in which the value is to be set * @param eFeature the eFeature which is converted */ protected void convertFeatureMap( final ModelObject<?> modelObject, final EObject eObject, final EStructuralFeature eFeature) { final Collection<?> mValues = (Collection<?>) modelObject.eGet(eFeature); @SuppressWarnings("unchecked") final Collection<Object> values = (Collection<Object>) eObject.eGet(eFeature); for (final Object mValue : mValues) { final ModelFeatureMapEntry<?> mEntry = ModelResolver.getInstance().getModelFeatureMapEntry(eFeature, mValue); EStructuralFeature entryFeature = mEntry.getEStructuralFeature(); Object entryValue = mEntry.getValue(); // flatten the tree of feature map entries, feature maps maybe nested // EMF uses a flattened api, while Texo builds this actual tree of // featuremaps, the findFeature and findValue find the deepest featureMap entry if (FeatureMapUtil.isFeatureMap(entryFeature)) { final ModelFeatureMapEntry<?> modelFeatureMapEntry = ModelResolver.getInstance().getModelFeatureMapEntry(entryFeature, entryValue); entryFeature = ModelUtils.findFeature(modelFeatureMapEntry); entryValue = ModelUtils.findValue(modelFeatureMapEntry); } final Object convertedValue; if (entryFeature instanceof EAttribute) { convertedValue = convertEAttributeValue(entryValue, ((EAttribute) entryFeature).getEAttributeType()); } else { convertedValue = createTarget(entryValue); } final FeatureMap.Entry eEntry = FeatureMapUtil.createEntry(entryFeature, convertedValue); values.add(eEntry); } }
public void repair() { final Object target = objectMapping.get(owner); final ModelObject<?> modelObject = ModelResolver.getInstance().getModelObject(target); final Object listObject = modelObject.eGet(eReference); if (!(listObject instanceof List<?>)) { // no order maintained anyway return; } final EList<?> eList = (EList<?>) owner.eGet(eReference); @SuppressWarnings("unchecked") final List<Object> list = (List<Object>) listObject; int correctIndex = 0; for (Object objectElement : eList) { final EObject eObjectElement = (EObject) objectElement; final Object element = objectMapping.get(eObjectElement); final int newIndex = list.indexOf(element); if (newIndex != correctIndex) { try { list.remove(element); list.add(correctIndex, element); } catch (UnsupportedOperationException ignore) { // unmodifiable collection, can't handle those, go away return; } } correctIndex++; } }
/** * Converts the values of an FeatureMap, the values of the collection are converted to and added * to the list in the correct feature in the modelObject. * * @param eObject the eObject from which the value is read * @param modelObject the {@link ModelObject} in which the value is to be set * @param eFeature the eFeature which is converted */ protected void convertFeatureMap( final EObject eObject, final ModelObject<?> modelObject, final EStructuralFeature eFeature) { final Collection<?> eValues = (Collection<?>) eObject.eGet(eFeature); @SuppressWarnings("unchecked") final Collection<Object> values = (Collection<Object>) modelObject.eGet(eFeature); // clear as the object may have been read from the db values.clear(); for (final Object eValue : eValues) { final FeatureMap.Entry eEntry = (FeatureMap.Entry) eValue; final Object featureMapEntry = ModelResolver.getInstance().createFeatureMapEntry(eFeature); final ModelFeatureMapEntry<?> mEntry = ModelResolver.getInstance().getModelFeatureMapEntry(eFeature, featureMapEntry); mEntry.setEStructuralFeature(eEntry.getEStructuralFeature()); final Object convertedValue; if (mEntry.getEStructuralFeature() instanceof EAttribute) { convertedValue = convertEAttributeValue( eEntry.getValue(), ((EAttribute) eEntry.getEStructuralFeature()).getEAttributeType()); } else { convertedValue = createTarget((EObject) eEntry.getValue()); } mEntry.setValue(convertedValue); values.add(featureMapEntry); } }
/** * Converts the value of an EAttribute with isMany==false, the value is converted ( {@link * #convertEAttributeValue(Object, EDataType)}) and set 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 eAttribute the EAttribute which is converted * @see #convertEAttributeValue(Object, EDataType) */ protected void convertSingleEAttribute( final ModelObject<?> modelObject, final EObject eObject, final EAttribute eAttribute) { final Object value = modelObject.eGet(eAttribute); // don't set the eObject if the value is null and the attribute is unsettable. // unsettable is modelled with null in Texo. if (value == null && ModelUtils.isUnsettable(eAttribute)) { eObject.eUnset(eAttribute); return; } final Object newValue = convertEAttributeValue(value, eAttribute.getEAttributeType()); ((InternalEObject) eObject).eSet(eAttribute, newValue); }
/** * Converts the value of an EAttribute with isMany==true, the values of the collection are * converted to and added to the list in the correct feature in the eObject. * * @param eObject the eObject from which the value is read * @param modelObject the {@link ModelObject} in which the value is to be set * @param eAttribute the EAttribute which is converted * @see #convertEAttributeValue(Object, EDataType) */ protected void convertManyEAttribute( final EObject eObject, final ModelObject<?> modelObject, final EAttribute eAttribute) { final Collection<?> eValues = (Collection<?>) eObject.eGet(eAttribute); final EDataType eDataType = eAttribute.getEAttributeType(); @SuppressWarnings("unchecked") final Collection<Object> values = (Collection<Object>) modelObject.eGet(eAttribute); // clear as the target may have been read from the db values.clear(); for (final Object eValue : eValues) { values.add(convertEAttributeValue(eValue, eDataType)); } }
public void repair() { final EObject eObjectOwner = objectMapping.get(owner.getTarget()); final ModelObject<?> modelObjectOwner = ModelResolver.getInstance().getModelObject(owner); final Object listObject = modelObjectOwner.eGet(eReference); if (!(listObject instanceof List<?>)) { // no order maintained anyway return; } final EList<?> eList = (EList<?>) eObjectOwner.eGet(eReference); final List<?> list = (List<?>) listObject; int currentIndex = 0; for (Object objectElement : list) { final EObject eObjectElement = objectMapping.get(objectElement); final int newIndex = eList.indexOf(eObjectElement); if (newIndex != currentIndex) { eList.move(currentIndex, newIndex); } currentIndex++; } }
/** * Converts the value of an EReference with isMany==false, the value is converted to an EObject * and set 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 convertSingleEReference( final ModelObject<?> modelObject, final EObject eObject, final EReference eReference) { // containment/container features are always set from the // containment side if (eReference.isContainer()) { return; } if (eObject.eIsSet(eReference)) { return; } final Object value = modelObject.eGet(eReference); if (value == null) { eObject.eSet(eReference, null); } else { final InternalEObject eValue = (InternalEObject) createTarget(value); eObject.eSet(eReference, eValue); } }
/** * Converts the value of an EAttribute with isMany==true, the values of the collection are * converted 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 eAttribute the EAttribute which is converted * @see #convertEAttributeValue(Object, EDataType) */ protected void convertManyEAttribute( final ModelObject<?> modelObject, final EObject eObject, final EAttribute eAttribute) { final Collection<?> values = (Collection<?>) modelObject.eGet(eAttribute); final EDataType eDataType = eAttribute.getEAttributeType(); @SuppressWarnings("unchecked") final List<Object> eValues = (List<Object>) eObject.eGet(eAttribute); final List<Object> newValues = new ArrayList<Object>(); for (final Object value : values) { newValues.add(convertEAttributeValue(value, eDataType)); } boolean updateList = false; if (values.size() == eValues.size()) { final Iterator<?> it = eValues.iterator(); for (Object newValue : newValues) { final Object oldValue = it.next(); if (newValue != null && oldValue == null) { updateList = true; } else if (oldValue == null && newValue != null) { updateList = true; } else if (oldValue != null && newValue != null) { updateList = !oldValue.equals(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); } }
/** * 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()); } } } }
@Test public void testRetrievalAndDelete() { final Library lib = createTestData(); // children final Writer w = lib.getWriters().get(0); final Book bk = lib.getBooks().get(0); // get model information if (!isXmlTest()) { { final String content = doGetRequest("model/epackage?id=library", null, HttpServletResponse.SC_OK); final List<Object> objects = deserialize(content); Assert.assertEquals(1, objects.size()); Assert.assertTrue(objects.get(0) instanceof DynamicModelObject); final DynamicModelObject dmo = (DynamicModelObject) objects.get(0); Assert.assertTrue(dmo.eClass() == EcorePackage.eINSTANCE.getEPackage()); Assert.assertEquals("library", dmo.eGet(EcorePackage.eINSTANCE.getENamedElement_Name())); Assert.assertEquals( LibraryModelPackage.NS_URI, dmo.eGet(EcorePackage.eINSTANCE.getEPackage_NsURI())); } { final String content = doGetRequest( "model/epackage?id=" + LibraryModelPackage.NS_URI, null, HttpServletResponse.SC_OK); final List<Object> objects = deserialize(content); Assert.assertEquals(1, objects.size()); Assert.assertTrue(objects.get(0) instanceof DynamicModelObject); final DynamicModelObject dmo = (DynamicModelObject) objects.get(0); Assert.assertTrue(dmo.eClass() == EcorePackage.eINSTANCE.getEPackage()); Assert.assertEquals("library", dmo.eGet(EcorePackage.eINSTANCE.getENamedElement_Name())); Assert.assertEquals( LibraryModelPackage.NS_URI, dmo.eGet(EcorePackage.eINSTANCE.getEPackage_NsURI())); } { final String content = doGetRequest( "model/eclass?name=Book&epackage=" + LibraryModelPackage.NS_URI, null, HttpServletResponse.SC_OK); final List<Object> objects = deserialize(content); Assert.assertEquals(1, objects.size()); Assert.assertTrue(objects.get(0) instanceof DynamicModelObject); final DynamicModelObject dmo = (DynamicModelObject) objects.get(0); Assert.assertTrue(dmo.eClass() == EcorePackage.eINSTANCE.getEClass()); Assert.assertEquals("Book", dmo.eGet(EcorePackage.eINSTANCE.getENamedElement_Name())); } { final String content = doGetRequest( "model/eclassifier?name=BookCategory&epackage=" + LibraryModelPackage.NS_URI, null, HttpServletResponse.SC_OK); final List<Object> objects = deserialize(content); Assert.assertEquals(1, objects.size()); Assert.assertTrue(objects.get(0) instanceof DynamicModelObject); final DynamicModelObject dmo = (DynamicModelObject) objects.get(0); Assert.assertTrue(dmo.eClass() == EcorePackage.eINSTANCE.getEEnum()); Assert.assertEquals( "BookCategory", dmo.eGet(EcorePackage.eINSTANCE.getENamedElement_Name())); } } // get all libraries { final String content = doGetRequest( LibraryModelPackage.INSTANCE.getLibraryEClass().getName(), null, HttpServletResponse.SC_OK); final List<Object> objects = deserialize(content); Assert.assertEquals(1, objects.size()); final ResponseType responseType = (ResponseType) objects.get(0); final Library libResult = (Library) responseType.getData().get(0); Assert.assertNotSame(lib, libResult); Assert.assertEquals(lib.getDb_Id(), libResult.getDb_Id()); } // get one library, and call its content { String content = getOneObject(lib); getValidateOneObject(lib); System.err.println(content); // and all its content final ModelObject<?> modelObject = ModelResolver.getInstance().getModelObject(lib); for (EReference eReference : modelObject.eClass().getEAllReferences()) { final Object value = modelObject.eGet(eReference); if (value == null) { continue; } if (eReference.isMany()) { for (Object element : (List<?>) value) { if (element instanceof Identifiable) { getValidateOneObject(element); } } } else { if (value instanceof Identifiable) { getValidateOneObject(value); } } } } // now delete the library doDeleteRequest( LibraryModelPackage.INSTANCE.getLibraryEClass().getName() + "/" + lib.getDb_Id(), HttpServletResponse.SC_OK); // $NON-NLS-1$ // this should fail { final String content = doGetRequest( LibraryModelPackage.INSTANCE.getLibraryEClass().getName() + "/" + lib.getDb_Id(), null, HttpServletResponse.SC_NOT_FOUND); // $NON-NLS-1$ final List<Object> objects = deserialize(content); Assert.assertEquals(1, objects.size()); final ErrorType errorType = (ErrorType) objects.get(0); Assert.assertTrue(errorType.getMessage().contains("Resource not found")); // $NON-NLS-1$ } // children are removed checkExists(w, false); checkExists(bk, false); }
/** * 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); } }