
org.emfjson.jackson.databind.EMFContext Maven / Gradle / Ivy
/*
* 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;
import com.fasterxml.jackson.databind.DatabindContext;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.cfg.ContextAttributes;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.*;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.emfjson.jackson.databind.deser.ReferenceEntries;
import org.emfjson.jackson.databind.type.EcoreTypeFactory;
import org.emfjson.jackson.handlers.URIHandler;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import static java.util.Spliterator.ORDERED;
import static java.util.Spliterators.spliteratorUnknownSize;
import static java.util.stream.StreamSupport.stream;
public class EMFContext {
public enum Attributes {
// public attributes
RESOURCE_SET,
RESOURCE_URI,
RESOURCE,
ROOT_ELEMENT
}
enum Internals {
// internal attributes
INIT,
TYPE_FACTORY,
REFERENCE_ENTRIES,
CURRENT_DATATYPE,
CURRENT_FEATURE,
CURRENT_PARENT,
MAP_OF_OBJECTS,
MAP_OF_URIS,
MAP_OF_RESOURCES,
ALL_TYPES
}
public static void init(Resource resource, DatabindContext context) {
if (context.getAttribute(Internals.INIT) != null) {
return;
}
ReferenceEntries entries = new ReferenceEntries();
EcoreTypeFactory ecoreType = new EcoreTypeFactory();
ResourceSet resourceSet = resource.getResourceSet();
context.setAttribute(Attributes.RESOURCE, resource);
context.setAttribute(Attributes.RESOURCE_SET, resourceSet);
context.setAttribute(Internals.REFERENCE_ENTRIES, entries);
context.setAttribute(Internals.TYPE_FACTORY, ecoreType);
context.setAttribute(Internals.INIT, true);
}
@Deprecated
public static void prepare(DatabindContext ctxt) {
if (ctxt.getAttribute(Internals.INIT) != null) {
return;
}
if (getResourceSet(ctxt) == null) {
ctxt.setAttribute(Attributes.RESOURCE_SET, new ResourceSetImpl());
}
if (getEntries(ctxt) == null) {
ctxt.setAttribute(Internals.REFERENCE_ENTRIES, new ReferenceEntries());
}
}
public static ContextAttributes from(Map, ?> options) {
return ContextAttributes
.getEmpty()
.withSharedAttributes(options == null ? new HashMap<>(): new HashMap<>(options));
}
public static void resolve(DeserializationContext ctxt, URIHandler handler) {
ReferenceEntries entries = getEntries(ctxt);
if (entries != null) {
entries.resolve(ctxt, handler);
}
}
public static URI getURI(DatabindContext ctxt, EObject object) {
if (object == null) {
return null;
}
@SuppressWarnings("unchecked")
Map objects = (Map) ctxt.getAttribute(Internals.MAP_OF_OBJECTS);
if (objects == null) {
ctxt.setAttribute(Internals.MAP_OF_OBJECTS, objects = new HashMap<>());
}
URI uri = objects.get(object);
if (uri == null) {
objects.put(object, uri = EcoreUtil.getURI(object));
}
return uri;
}
public static EClass findEClass(DatabindContext ctxt, String uri) {
if (uri == null || uri.isEmpty()) {
return null;
}
@SuppressWarnings("unchecked")
Map uris = (Map) ctxt.getAttribute(Internals.MAP_OF_URIS);
if (uris == null) {
ctxt.setAttribute(Internals.MAP_OF_URIS, uris = new HashMap<>());
}
EObject object = uris.get(uri);
if (object instanceof EClass) {
return (EClass) object;
}
ResourceSet resourceSet = getResourceSet(ctxt);
if (resourceSet == null) {
return null;
}
object = resourceSet.getEObject(URI.createURI(uri), true);
if (object instanceof EClass) {
uris.put(uri, object);
return (EClass) object;
}
return null;
}
public static EClass findEClassByName(DatabindContext ctxt, String name) {
@SuppressWarnings("unchecked")
Set types = (Set) ctxt.getAttribute(Internals.ALL_TYPES);
if (types == null) {
types = initAllTypes(ctxt);
}
return types.stream().filter(findByName(name)).findFirst().orElse(null);
}
public static EClass findEClassByQualifiedName(DatabindContext ctxt, String name) {
@SuppressWarnings("unchecked")
Set types = (Set) ctxt.getAttribute(Internals.ALL_TYPES);
if (types == null) {
types = initAllTypes(ctxt);
}
return types.stream().filter(findByQualifiedName(name)).findFirst().orElse(null);
}
private static Set initAllTypes(DatabindContext ctxt) {
EPackage.Registry global = EPackage.Registry.INSTANCE;
ResourceSet resourceSet = getResourceSet(ctxt);
EPackage.Registry local = resourceSet.getPackageRegistry();
Map registry = new HashMap<>();
registry.putAll(global);
registry.putAll(local);
Set types = registry.values().stream()
.flatMap(e -> stream(spliteratorUnknownSize(((EPackage) e).eAllContents(), ORDERED), false))
.filter(e -> e instanceof EClass)
.map(e -> (EClass) e)
.collect(Collectors.toSet());
ctxt.setAttribute(Internals.ALL_TYPES, types);
return types;
}
public static EClass findEClassByName(String value, EPackage ePackage) {
return iterateAndFind(Collections.singleton(ePackage), findByName(value));
}
public static EClass findEClassByQualifiedName(String value, EPackage ePackage) {
return iterateAndFind(Collections.singleton(ePackage), findByQualifiedName(value));
}
private static Predicate findByName(String value) {
return e -> value != null && e instanceof EClass && value.equals(((EClass) e).getName());
}
private static Predicate findByQualifiedName(String value) {
return e -> value != null && e instanceof EClass && value.equals(((EClass) e).getInstanceClassName());
}
private static EClass iterateAndFind(Collection
© 2015 - 2025 Weber Informatics LLC | Privacy Policy