Skip to content

Commit

Permalink
[28] Add support for changing attributes type
Browse files Browse the repository at this point in the history
Bug: #28
  • Loading branch information
vrichard12 authored and sbegaudeau committed Jan 11, 2024
1 parent 25da059 commit cdbf855
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -911,22 +911,41 @@ private void deserializeEAttribute(EAttribute eAttribute, JsonElement jsonElemen
EDataType dataType = eAttribute.getEAttributeType();
if (!eAttribute.isMany()) {
String newValue = this.getAsFlexibleString(jsonElement);
Object value = EcoreUtil.createFromString(dataType, newValue);
Object value = this.tryCreateDataTypeFromString(dataType, newValue);
this.helper.setValue(eObject, eAttribute, value);
} else {
JsonArray asJsonArray = this.getAsFlexibleArray(jsonElement);
Object eGet = this.helper.getValue(eObject, eAttribute);
if (eGet instanceof Collection<?>) {
for (JsonElement jElement : asJsonArray) {
Object value = EcoreUtil.createFromString(dataType, jElement.getAsString());
@SuppressWarnings("unchecked")
Collection<Object> collection = (Collection<Object>) eGet;
collection.add(value);
Object value = this.tryCreateDataTypeFromString(dataType, jElement.getAsString());
this.helper.setValue(eObject, eAttribute, value);
}
}
}
}

/**
* Try to create a {@link EDataType} instance from a serialized form of the value. If the serialization is not
* compatible with the given EDataType, returns the serialized form of the value unchanged.
*
* @param dataType
* The {@link EDataType} to instantiate
* @param serializedValue
* The serialized form of the value
* @return A new EDataType instance or the given serializedValue if the EDataType could not be instantiated from the
* serializedValue.
*/
private Object tryCreateDataTypeFromString(EDataType dataType, String serializedValue) {
Object value;
try {
value = EcoreUtil.createFromString(dataType, serializedValue);
} catch (IllegalArgumentException e) {
value = serializedValue;
}
return value;
}

/**
* Read a JSON element as a string. If the element is a non-empty array, unwrap it and consider the first element
* inside instead of trying to convert the array into a string.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package org.eclipse.sirius.emfjson.utils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -581,7 +582,8 @@ public EClassifier getType(EFactory eFactory, String typeName) {
}

/**
* Sets the value of the feature for the given object.
* Sets the value of the feature for the given object. If the feature is multivalued, add the value to the
* collection of values already set.
*
* @param object
* the given object
Expand All @@ -591,7 +593,13 @@ public EClassifier getType(EFactory eFactory, String typeName) {
* the value to set
*/
public void setValue(EObject object, EStructuralFeature feature, Object value) {
object.eSet(feature, value);
if (feature.isMany()) {
@SuppressWarnings("unchecked")
Collection<Object> collection = (Collection<Object>) object.eGet(feature);
collection.add(value);
} else {
object.eSet(feature, value);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.eclipse.sirius.emfjson.resource.JsonResource;
import org.eclipse.sirius.emfjson.resource.JsonResourceFactoryImpl;
import org.eclipse.sirius.emfjson.resource.JsonResourceImpl;
import org.eclipse.sirius.emfjson.utils.JsonHelper;
import org.junit.Assert;

/**
Expand Down Expand Up @@ -276,6 +277,10 @@ public Resource createResource(URI uriValue) {
resource = resourceSet.createResource(uri);
String extension = resource.getURI().fileExtension();
if (extension.equals(JsonResourceFactoryImpl.EXTENSION)) {
if (this.options.get(JsonResource.OPTION_CUSTOM_HELPER) instanceof JsonHelper) {
JsonHelper jsonHelper = (JsonHelper) this.options.get(JsonResource.OPTION_CUSTOM_HELPER);
jsonHelper.setResource(resource);
}
resource.load(inputStream, this.options);
} else {
resource.load(inputStream, Collections.EMPTY_MAP);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*******************************************************************************
* Copyright (c) 2023 Obeo.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.emfjson.tests.internal.unit.load;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.sirius.emfjson.resource.JsonResource;
import org.eclipse.sirius.emfjson.tests.internal.AbstractEMFJsonTests;
import org.eclipse.sirius.emfjson.utils.JsonHelper;
import org.junit.Test;

/**
* Tests loading with ExtendedMetaData.
*/
public class JsonHelperDataLoadTests extends AbstractEMFJsonTests {

/**
* {@inheritDoc}
*
* @see org.eclipse.sirius.emfjson.tests.internal.AbstractEMFJsonTests#getRootPath()
*/
@Override
protected String getRootPath() {
return "/unit/attributes/extendedmetadata/"; //$NON-NLS-1$
}

/**
* Change the type of a monovalued EAttribute.
*/
@Test
public void testChangeAttributeTypeMono() {
JsonHelper jsonHelper = new JsonHelper() {
@Override
public void setValue(EObject object, EStructuralFeature feature, Object value) {
Object newValue = value;
if ("NodeSingleValueAttribute".equals(feature.getEContainingClass().getName()) && "singleIntAttribute".equals(feature.getName())) { //$NON-NLS-1$ //$NON-NLS-2$
newValue = new Integer(((String) value).length());
}
super.setValue(object, feature, newValue);
}
};

this.options.put(JsonResource.OPTION_CUSTOM_HELPER, jsonHelper);
this.testLoad("TestChangeAttributeTypeMono.xmi"); //$NON-NLS-1$
}

/**
* Change the type of a monovalued EAttribute.
*/
@Test
public void testChangeAttributeTypeMulti() {
JsonHelper jsonHelper = new JsonHelper() {
@Override
public void setValue(EObject object, EStructuralFeature feature, Object value) {
Object newValue = value;
if ("NodeMultiValuedAttribute".equals(feature.getEContainingClass().getName()) && "multiIntAttribute".equals(feature.getName())) { //$NON-NLS-1$ //$NON-NLS-2$
newValue = new Integer(((String) value).length());
}
super.setValue(object, feature, newValue);
}
};

this.options.put(JsonResource.OPTION_CUSTOM_HELPER, jsonHelper);
this.testLoad("TestChangeAttributeTypeMulti.xmi"); //$NON-NLS-1$
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"json": {
"version": "1.0",
"encoding": "utf-8"
},
"ns": {
"emfjson": "http://obeo.fr/emfjson",
"nodes": "http://www.obeo.fr/EMFJson"
},
"schemaLocation": {
"http://www.obeo.fr/EMFJson": "../../../nodes.ecore"
},
"content": [
{
"eClass": "nodes:NodeSingleValueAttribute",
"data": {
"singleIntAttribute": "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="ASCII"?>
<nodes:NodeSingleValueAttribute
xmi:version="2.0"
xmlns:xmi="http://www.omg.org/XMI"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:nodes="http://www.obeo.fr/EMFJson"
xsi:schemaLocation="http://www.obeo.fr/EMFJson ../../../nodes.ecore"
singleIntAttribute="26"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"json": {
"version": "1.0",
"encoding": "utf-8"
},
"ns": {
"emfjson": "http://obeo.fr/emfjson",
"nodes": "http://www.obeo.fr/EMFJson"
},
"schemaLocation": {
"http://www.obeo.fr/EMFJson": "../../../nodes.ecore"
},
"content": [
{
"eClass": "nodes:NodeMultiValuedAttribute",
"data": {
"multiIntAttribute": [
"ABC",
"ABCDEF",
"ABCDEFGHI"
]
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="ASCII"?>
<nodes:NodeMultiValuedAttribute
xmi:version="2.0"
xmlns:xmi="http://www.omg.org/XMI"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:nodes="http://www.obeo.fr/EMFJson"
xsi:schemaLocation="http://www.obeo.fr/EMFJson ../../../nodes.ecore">
<multiIntAttribute>3</multiIntAttribute>
<multiIntAttribute>6</multiIntAttribute>
<multiIntAttribute>9</multiIntAttribute>
</nodes:NodeMultiValuedAttribute>

0 comments on commit cdbf855

Please sign in to comment.