emfjson / emfjson-jackson

JSON Binding for Eclipse Modeling Framework
https://emfjson.github.io
Other
80 stars 23 forks source link

Allow option to minimize the use of type information and possible allow to skip that per class during serialization #93

Closed kchobantonov closed 6 years ago

kchobantonov commented 7 years ago

EObjectSerializer.serialized could have potentially the following implementation

       @Override
    public void serialize(EObject object, JsonGenerator jg, SerializerProvider provider) throws IOException {
        EObjectPropertyMap properties = builder.construct(object.eClass());

        final EObject parent = getParent(provider);
        if (parent != null && (object.eIsProxy() || EObjects.isContainmentProxy(parent, object))) {
            // containment proxies are serialized as references
            _refSer.serialize(object, jg, provider);
            return;
        }

        final EStructuralFeature feature = getFeature(provider);

        jg.writeStartObject();
        for (EObjectProperty property : properties.getProperties()) {
            if (property instanceof EObjectTypeProperty) {
                               // potentially this type exclusion could be made configurable
                if (parent != null && feature != null && feature.getEType().equals(object.eClass())) {
                    continue;
                } else if (!JsonAnnotations.shouldIncludeTypeMetadata(object.eClass())) {
                    continue;
                }
            }

            property.serialize(object, jg, provider);
        }
        jg.writeEndObject();
    }

Where the shouldIncludeTypeMetadata in the JsonAnnotations could look like this

       public static boolean shouldIncludeTypeMetadata(EClassifier eClassifier) {
        return eClassifier.getEAnnotation("JsonTypeIgnore") == null;
    }
ghillairet commented 7 years ago

If I understand correctly those are the 2 enhancements you are proposing:

  1. Reduce the number of type information included during serialization
  2. Use a JsonTypeIgnore annotation to mark types that should not be serialized

We can certainly do something for the first one, like it is done for the XMI serialization (see https://github.com/eclipse/emf/blob/db2f900cb6ce9f1e184d60da11d92f650f2840be/plugins/org.eclipse.emf.ecore.xmi/src/org/eclipse/emf/ecore/xmi/impl/XMLSaveImpl.java#L3677)

For the second case, it is something I thought about, and that we could experiment, see the issue #79 where I propose to use annotations like in Jackson. That would be the annotation JsonIgnoreType in that case.

kchobantonov commented 7 years ago

yes that is correct, those are the two enhancements.

ghillairet commented 7 years ago

In my previous comment I made a mistake saying we could use JsonIgnoreType. That annotation is use in Jackson when one does not want to serialize objects of a certain type.

In that case I think we could use the annotation JsonType instead of JsonTypeIgnore. I wanted to include the JsonType annotation so that users could configure type information inside ecore/xcore models.

It would have different options:

It would be use like that

@JsonType(property = "@type",  include = "true", use = "name")
class Foo {
  contains Bar bar
}

@JsonType(include = "false")
class Bar {
  String label
}

Sample result

{
  "@type": "Foo",
  "bar": {
    "label": "b1"
  } 
}
kchobantonov commented 7 years ago

I would say that the default should be the URI for the type since that is the default for the XMI serialization and that is what is actually unique - you could have multiple types provided by different providers for example multiple Address types so in order to not have collisions it is better to be based on the URI I guess.

On Sat, Dec 10, 2016 at 12:39 PM, Guillaume Hillairet < notifications@github.com> wrote:

In my previous comment I made a mistake saying we could use JsonIgnoreType. That annotation is use in Jackson when one does not want to serialize objects of a certain type.

In that case I think we could use the annotation JsonType instead of JsonTypeIgnore. I wanted to include the JsonType annotation so that users could configure type information inside ecore/xcore models.

It would have different options:

  • property: naming of type information property (by default eClass)
  • include: should type information be included during serialization (true by default)
  • use: what's the value that should be used (name of class, uri of class (by default), etc..) (still not sure about this one)

It would be use like that

@JsonType(property = "@type", include = "true", use = "name")class Foo { contains Bar bar } @JsonType(include = "false")class Bar { String label }

Sample result

{ "@type": "Foo", "bar": { "label": "b1" } }

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/emfjson/emfjson-jackson/issues/93#issuecomment-266225158, or mute the thread https://github.com/notifications/unsubscribe-auth/AMLbPyi3sManNPLb5MZmmq0o2Yv4dsdeks5rGuPQgaJpZM4K0f0B .

ghillairet commented 7 years ago

Yes URI would be the default.

kchobantonov commented 7 years ago

Here is how the URI can be compacted in order to not have large json documents

https://www.w3.org/TR/json-ld/#h3_compact-iris

But then the json will be json-ld compatible - e.g. it will have that additional semantic

Krasimir

On Mon, Dec 12, 2016 at 10:41 AM, Guillaume Hillairet < notifications@github.com> wrote:

Yes URI would be the default.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/emfjson/emfjson-jackson/issues/93#issuecomment-266463625, or mute the thread https://github.com/notifications/unsubscribe-auth/AMLbP2IDWrfFGmj3Q8Vv-wYTKaYcHiveks5rHWskgaJpZM4K0f0B .

ghillairet commented 6 years ago

Mark this as close, release 1.1.0 allow use of URI, CLASS or NAME values for JsonType annotations.