Skip to content

Commit

Permalink
[32] Add the ability to retrieve information during the serialization
Browse files Browse the repository at this point in the history
Bug: #32
Signed-off-by: Stéphane Bégaudeau <[email protected]>
  • Loading branch information
sbegaudeau committed Mar 7, 2024
1 parent 72ac65d commit 80dbda5
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;

Expand Down Expand Up @@ -425,6 +426,75 @@ interface IEObjectHandler {
*/
Object OPTION_SAVE_FEATURES_ORDER_COMPARATOR = "OPTION_SAVE_FEATURES_ORDER_COMPARATOR"; //$NON-NLS-1$

/**
* An option to provide an ISerializationListener.
*/
String OPTION_SERIALIZATION_LISTENER = "OPTION_SERIALIZATION_LISTENER"; //$NON-NLS-1$

/**
* Used to listen to various events during the serialization.
*
* @author <a href="mailto:[email protected]">Stephane Begaudeau</a>
*/
interface ISerializationListener {

/**
* Called when an entry is added to the namespace header.
*
* @param nsPrefix
* The prefix of the ePackage added
* @param nsURI
* The URI of the ePackage added
*/
void onNsHeaderEntryAdded(String nsPrefix, String nsURI);

/**
* Called when an object is serialized.
*
* @param eObject
* The EObject serialized
* @param jsonElement
* The serialization of the EObject
*/
void onObjectSerialized(EObject eObject, JsonElement jsonElement);

/**
* Called when a proxy to an object located in another resource has been created.
*
* @param eObject
* The object for which the URI is created
* @param eReference
* The reference containing the object
* @param uri
* The uri created
*/
void onCrossReferenceURICreated(EObject eObject, EReference eReference, String uri);

/**
* Implementation of the listener which does nothing.
*
* @author <a href="mailto:[email protected]">Stephane Begaudeau</a>
*/
class NoOp implements ISerializationListener {

@Override
public void onNsHeaderEntryAdded(String nsPrefix, String nsURI) {
// Do nothing
}

@Override
public void onObjectSerialized(EObject eObject, JsonElement jsonElement) {
// Do nothing
}

@Override
public void onCrossReferenceURICreated(EObject eObject, EReference eReference, String uri) {
// Do nothing
}

}
}

/**
* Associate an ID to the {@link EObject}.
*
Expand All @@ -434,4 +504,5 @@ interface IEObjectHandler {
* the id
*/
void setID(EObject eObject, String id);

}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import org.eclipse.sirius.emfjson.resource.JsonResource;
import org.eclipse.sirius.emfjson.resource.JsonResource.EStructuralFeaturesFilter;
import org.eclipse.sirius.emfjson.resource.JsonResource.IEObjectHandler;
import org.eclipse.sirius.emfjson.resource.JsonResource.ISerializationListener;
import org.eclipse.sirius.emfjson.resource.JsonResource.ResourceEntityHandler;
import org.eclipse.sirius.emfjson.resource.exception.DanglingHREFException;

Expand Down Expand Up @@ -127,6 +128,8 @@ public class GsonEObjectSerializer implements JsonSerializer<List<EObject>> {
*/
private IEObjectHandler eObjectHandler;

private ISerializationListener serializationListener;

/**
* The constructor.
*
Expand Down Expand Up @@ -166,7 +169,11 @@ public GsonEObjectSerializer(Resource resource, Map<?, ?> options) {
this.helper.setExtendedMetaData(this.extendedMetaData);
}

this.eObjectHandler = (JsonResource.IEObjectHandler) serializedOptions.get(JsonResource.OPTION_EOBJECT_HANDLER);
this.eObjectHandler = (IEObjectHandler) serializedOptions.get(JsonResource.OPTION_EOBJECT_HANDLER);
this.serializationListener = (ISerializationListener) serializedOptions.get(JsonResource.OPTION_SERIALIZATION_LISTENER);
if (this.serializationListener == null) {
this.serializationListener = new ISerializationListener.NoOp();
}

this.declareSchemaLocation = Boolean.TRUE.equals(options.get(JsonResource.OPTION_SCHEMA_LOCATION));

Expand Down Expand Up @@ -236,6 +243,8 @@ private JsonElement createData(EObject eObject) {
this.eObjectHandler.processSerializedContent(jsonElement, eObject);
}

this.serializationListener.onObjectSerialized(eObject, jsonElement);

return jsonElement;
}

Expand Down Expand Up @@ -835,6 +844,7 @@ private JsonElement createNsHeader() {
List<String> nsPrefixes = this.helper.getPrefixes(ePackage);
for (String nsPrefix : nsPrefixes) {
jsonObject.add(nsPrefix, new JsonPrimitive(nsURI));
this.serializationListener.onNsHeaderEntryAdded(nsPrefix, nsURI);
}
}
}
Expand Down Expand Up @@ -1381,7 +1391,7 @@ private JsonElement serializeMultipleNonContainmentEReference(EObject eObject, E
break;
case CROSS_DOC:
if (value != null) {
jsonArray.add(new JsonPrimitive(this.saveHref(value, null)));
jsonArray.add(new JsonPrimitive(this.saveHref(value, eReference)));
}
break;
default:
Expand Down Expand Up @@ -1495,6 +1505,7 @@ private String saveHref(EObject object, EReference eReference) {
// TODO: element Handler if statement : look at XMLSaveImpl line 2308
value += href;
}
this.serializationListener.onCrossReferenceURICreated(object, eReference, value);
return value;
}

Expand Down Expand Up @@ -1540,8 +1551,8 @@ private int docKindSingle(EObject eObject, EReference eReference) {
}

/**
* Return the the URI fragment if the pointed resource URI schema is the same of the Resource URI schema. Return the
* all URI otherwise.
* Return the URI fragment if the pointed resource URI schema is the same of the Resource URI schema. Return the all
* URI otherwise.
*
* @param pointedResourceUri
* the pointed resource URI
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
Expand Down Expand Up @@ -67,6 +68,11 @@ public abstract class AbstractEMFJsonTests {
*/
protected Map<Object, Object> options = new HashMap<Object, Object>();

/**
* Data saved by the serialization listener.
*/
protected Map<String, Object> listenerData = new HashMap<String, Object>();

/**
* Returns the path of the folder containing the models used during the tests of this class.
*
Expand All @@ -82,6 +88,8 @@ public abstract class AbstractEMFJsonTests {
* The name of the resource to save
*/
protected void testSave(String resourceName) {
this.listenerData.clear();

Resource modelResource = this.getModelResource(resourceName, true);

ResourceSet resourceSet = new ResourceSetImpl();
Expand All @@ -104,6 +112,20 @@ protected void testSave(String resourceName) {
this.options.put(JsonResource.OPTION_PRETTY_PRINTING_INDENT, JsonResource.INDENT_2_SPACES);
this.options.put(JsonResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);

JsonResource.ISerializationListener serializationListener = new JsonResource.ISerializationListener.NoOp() {
@Override
public void onNsHeaderEntryAdded(String nsPrefix, String nsURI) {
AbstractEMFJsonTests.this.listenerData.put("onNsHeaderEntryAdded", nsPrefix + " - " + nsURI); //$NON-NLS-1$//$NON-NLS-2$
}

@Override
public void onCrossReferenceURICreated(EObject eObject, EReference eReference, String uri) {
AbstractEMFJsonTests.this.listenerData.put("onCrossReferenceURICreated", uri); //$NON-NLS-1$
}
};

this.options.put(JsonResource.OPTION_SERIALIZATION_LISTENER, serializationListener);

resource.save(outputStream, this.options);

String json = new String(outputStream.toByteArray(), Charset.forName("utf-8")); //$NON-NLS-1$
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ protected String getRootPath() {
@Test
public void testSaveSingleValuedEReference() {
this.testSave("NodeSingleValueEReference.xmi"); //$NON-NLS-1$

Assert.assertEquals(this.listenerData.get("onNsHeaderEntryAdded"), "nodes - http://www.obeo.fr/EMFJson"); //$NON-NLS-1$ //$NON-NLS-2$
}

/**
Expand Down Expand Up @@ -105,6 +107,8 @@ public void testSaveLibraryWithBookReferencingItsOwnLibrary() {
@Test
public void testSaveLibraryWithBookReferencingLibraries() {
this.testSave("TestLibraryWithBookReferencingLibraries.xmi"); //$NON-NLS-1$

Assert.assertEquals(this.listenerData.get("onNsHeaderEntryAdded"), "extlib - http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0"); //$NON-NLS-1$//$NON-NLS-2$
}

/**
Expand All @@ -123,6 +127,8 @@ public void testSaveLibraryWithExternalBookReferencingBranchLibrary() {
@Test
public void testSaveLibraryWithExternalBookReferencingLibraries() {
this.testSave("TestLibraryWithExternalBookReferencingLibraries_Book.xmi"); //$NON-NLS-1$

Assert.assertEquals(this.listenerData.get("onCrossReferenceURICreated"), "TestLibraryWithExternalBookReferencingLibraries_Library.xmi#/0/@branches.0"); //$NON-NLS-1$//$NON-NLS-2$
}

/**
Expand All @@ -140,6 +146,8 @@ public void testSaveLibraryWithExternalBookReferencingLibrary() {
@Test
public void testSaveExternalMultiNonContainmentReferences() {
this.testSave("TestExternalMultiNonContainmentReferences.ecore"); //$NON-NLS-1$

Assert.assertEquals(this.listenerData.get("onCrossReferenceURICreated"), "../../../nodes.ecore#//NodeMultipleCustomDataType"); //$NON-NLS-1$//$NON-NLS-2$
}

/**
Expand Down

0 comments on commit 80dbda5

Please sign in to comment.