/** * Converts a primitive type value, this implementation only converts an EEnum to an Enum value. * * @param value the value to convert * @param eDataType its EDataType * @return the converted value */ @SuppressWarnings({"unchecked", "rawtypes"}) protected Object convertEAttributeValue(final Object value, final EDataType eDataType) { if (value instanceof Enum<?>) { final EDataType enumDataType = getDataTypeOrBaseType(eDataType); Check.isInstanceOf(enumDataType, EEnum.class); final ModelPackage modelPackage = ModelResolver.getInstance().getModelPackage(enumDataType.getEPackage().getNsURI()); final Class<? extends Enum> enumClass = (Class<? extends Enum>) modelPackage.getEClassifierClass(enumDataType); return Enum.valueOf(enumClass, ((Enum<?>) value).name().toUpperCase(Locale.ENGLISH)); } else if (value instanceof EEnumLiteral) { final EDataType enumDataType = getDataTypeOrBaseType(eDataType); Check.isInstanceOf(enumDataType, EEnum.class); final EEnumLiteral eeNumLiteral = (EEnumLiteral) value; final ModelPackage modelPackage = ModelResolver.getInstance().getModelPackage(enumDataType.getEPackage().getNsURI()); if (modelPackage == null) { // dynamic model return eeNumLiteral; } final Class<? extends Enum> enumClass = (Class<? extends Enum>) modelPackage.getEClassifierClass(enumDataType); return Enum.valueOf(enumClass, eeNumLiteral.getName().toUpperCase(Locale.ENGLISH)); } // convert these to a Date always if (value instanceof XMLGregorianCalendar) { final XMLGregorianCalendar xmlCalendar = (XMLGregorianCalendar) value; final Date date = xmlCalendar.toGregorianCalendar().getTime(); return date; } return value; }
/** * Converts a primitive type value. For EEnum: this implementation only converts an Enum to an * EEnum value. * * @param value the value to convert * @param eDataType its EDataType * @return the converted value */ protected Object convertEAttributeValue(final Object value, final EDataType eDataType) { if (value instanceof Enum<?>) { final EDataType enumDataType = getDataTypeOrBaseType(eDataType); Check.isInstanceOf(enumDataType, EEnum.class); final EEnum eeNum = (EEnum) enumDataType; for (final EEnumLiteral enumLiteral : eeNum.getELiterals()) { // the code generation template uppercases enum if (enumLiteral.getName().toUpperCase(Locale.ENGLISH).equals(((Enum<?>) value).name())) { return enumLiteral.getInstance(); } } } if (value instanceof Date && eDataType == XMLTypePackage.eINSTANCE.getDate()) { final Date date = (Date) value; final XMLCalendar xmlCalendar = new XMLCalendar(date, XMLCalendar.DATE); final Calendar calendar = Calendar.getInstance(); calendar.setTime(date); xmlCalendar.clear(); xmlCalendar.setYear(calendar.get(Calendar.YEAR)); xmlCalendar.setMonth(1 + calendar.get(Calendar.MONTH)); xmlCalendar.setDay(calendar.get(Calendar.DATE)); // note xmlcalendar expects minutes, calendar gives millis xmlCalendar.setTimezone(calendar.get(Calendar.ZONE_OFFSET) / 60000); return xmlCalendar; } if (value instanceof Date && eDataType == XMLTypePackage.eINSTANCE.getDateTime()) { final Date date = (Date) value; return new XMLCalendar(date, XMLCalendar.DATETIME); } return value; }
/** * Converts a set of model managed objects and all the objects they reference to a collection of * EObjects. * * @param objects the model objects to convert, also the references/children are converted * @return the created EObjects */ public List<EObject> convert(final List<Object> objects) { doBaseActions(objects); // the process creates the new target objects and then converts the content // this multi-step process prevents stack overflow with large object graphs final List<EObject> result = new ArrayList<EObject>(); Check.isNotNullArgument(objects, "objects"); // $NON-NLS-1$ for (final Object object : objects) { result.add(createTarget(object)); } while (!toConvert.isEmpty()) { final ArrayList<Object> beingConverted = new ArrayList<Object>(toConvert); toConvert.clear(); for (Object object : beingConverted) { convertContent(object); converted.add(object); } } // for (ManyToMany mtm : toRepairManyToMany) { // final ModelObject<?> modelObject = mtm.getOwner(); // final EObject eObject = objectMapping.get(modelObject.getTarget()); // for (EReference eReference : eObject.eClass().getEAllReferences()) { // if (eReference.isMany()) { // final Collection<?> coll1 = (Collection<?>) modelObject.eGet(eReference); // final Collection<?> coll2 = (Collection<?>) eObject.eGet(eReference); // if (coll1.size() != coll2.size()) { // throw new IllegalStateException("Unequal sizes of collection for EReference " // //$NON-NLS-1$ // + eReference); // } // } // } // } // now repair the ManyToMany for (ManyToMany mtm : toRepairManyToMany) { mtm.repair(); } return result; }
/** * 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); } }