All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.emfjson.jackson.databind.ser.EObjectSerializer Maven / Gradle / Ivy

There is a newer version: 1.3.0
Show newest version
/*
 * Copyright (c) 2015 Guillaume Hillairet.
 * 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:
 *     Guillaume Hillairet - initial API and implementation
 *
 */
package org.emfjson.jackson.databind.ser;

import org.eclipse.emf.ecore.*;

import org.eclipse.emf.ecore.util.EcoreUtil;
import org.emfjson.jackson.common.Cache;
import org.emfjson.common.EObjects;
import org.emfjson.jackson.JacksonOptions;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;
import java.util.List;
import java.util.Set;

import static org.emfjson.common.EObjects.featureMaps;

public class EObjectSerializer extends JsonSerializer {

	private final JacksonOptions options;

	public EObjectSerializer(JacksonOptions options) {
		this.options = options;
	}

	@Override
	public Class handledType() {
		return EObject.class;
	}

	@Override
	public void serialize(EObject object, JsonGenerator jg, SerializerProvider provider) throws IOException {
		if (object == null) {
			jg.writeNull();
			return;
		}

		provider.setAttribute("options", options);

		Cache cache = (Cache) provider.getAttribute("cache");
		if (cache == null) {
			provider.setAttribute("cache", cache = new Cache());
		}

		if (object.eContainer() != null && EObjects.isContainmentProxy(object.eContainer(), object)) {
			options.referenceSerializer.serialize(object.eContainer(), object, jg, provider);
			return;
		}

		final EClass eClass = object.eClass();
		final List attributes = cache.getAttributes(eClass);
		final List references = cache.getReferences(eClass);
		final List containments = cache.getContainments(eClass);

		jg.writeStartObject();

		writeType(eClass, jg, provider);
		writeId(object, jg, provider);

		for (EAttribute attribute : attributes) {
			if (EObjects.isCandidate(object, attribute, options)) {
				final String field = cache.getKey(attribute);
				final Object value = object.eGet(attribute);

				if (EObjects.isFeatureMap(attribute)) {
					writeFeatureMap(object, attribute, jg, provider);
				} else {
					writeAttribute(jg, (EDataType) object.eClass().getFeatureType(attribute).getEClassifier(), field, value);
				}
			}
		}

		for (EReference reference : references) {
			if (EObjects.isCandidate(object, reference)) {
				final String field = cache.getKey(reference);
				final Object value = object.eGet(reference);

				writeRef(object, field, value, jg, provider);
			}
		}

		for (EReference containment : containments) {
			if (EObjects.isCandidate(object, containment)) {
				final String field = cache.getKey(containment);
				final Object value = object.eGet(containment);

				jg.writeObjectField(field, value);
			}
		}
		jg.writeEndObject();
	}

	private void writeAttribute(JsonGenerator jg, EDataType type, String key, Object value) throws IOException {
		if (EcorePackage.Literals.EJAVA_OBJECT.equals(type) || EcorePackage.Literals.EJAVA_CLASS.equals(type)) {
			jg.writeStringField(key, EcoreUtil.convertToString(type, value));
		} else {
			jg.writeObjectField(key, value);
		}
	}

	protected void writeId(EObject object, JsonGenerator jg, SerializerProvider provider) throws IOException {
		options.idSerializer.serialize(object, jg, provider);
	}

	protected void writeType(EClass eClass, JsonGenerator jg, SerializerProvider provider) throws IOException {
		options.typeSerializer.serialize(eClass, jg, provider);
	}

	private void writeRef(EObject source, String field, Object value, JsonGenerator jg, SerializerProvider provider) throws IOException {
		jg.writeFieldName(field);

		if (value instanceof Iterable) {
			Iterable values = (Iterable) value;

			jg.writeStartArray();
			for (Object current : values) {
				options.referenceSerializer.serialize(source, (EObject) current, jg, provider);
			}
			jg.writeEndArray();

		} else {
			options.referenceSerializer.serialize(source, (EObject) value, jg, provider);
		}
	}

	private void writeFeatureMap(EObject owner, EAttribute attribute, JsonGenerator jg, SerializerProvider provider) throws IOException {
		final Set features = featureMaps(owner, attribute);
		final Cache cache = (Cache) provider.getAttribute("cache");

		for (EStructuralFeature feature : features) {
			final Object value = owner.eGet(feature);
			final String key = cache.getKey(feature);

			if (feature instanceof EAttribute) {

				writeAttribute(jg, ((EAttribute) feature).getEAttributeType(), key, value);

			} else {
				final EReference reference = (EReference) feature;

				if (reference.isContainment()) {
					jg.writeObjectField(key, value);
				} else {
					writeRef(owner, key, value, jg, provider);
				}
			}
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy