org.emfjson.jackson.databind.deser.ResourceDeserializer.java Source code

Java tutorial

Introduction

Here is the source code for org.emfjson.jackson.databind.deser.ResourceDeserializer.java

Source

/*
 * 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.deser;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.emfjson.jackson.databind.EMFContext;
import org.emfjson.jackson.databind.type.EcoreTypeFactory;
import org.emfjson.jackson.handlers.URIHandler;
import org.emfjson.jackson.utils.Cache;

import java.io.IOException;

import static org.emfjson.jackson.databind.EMFContext.Attributes.*;

public class ResourceDeserializer extends JsonDeserializer<Resource> {

    private final URIHandler uriHandler;

    public ResourceDeserializer(URIHandler uriHandler) {
        this.uriHandler = uriHandler;
    }

    @Override
    public boolean isCachable() {
        return true;
    }

    @Override
    public Resource deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
        return deserialize(jp, ctxt, null);
    }

    @Override
    public Resource deserialize(JsonParser jp, DeserializationContext ctxt, Resource intoValue) throws IOException {
        final Resource resource = getResource(ctxt, intoValue);
        if (resource == null) {
            throw new IllegalArgumentException("Invalid resource");
        }

        final ReferenceEntries entries = new ReferenceEntries();
        final EcoreTypeFactory ecoreType = new EcoreTypeFactory();
        final ResourceSet resourceSet = resource.getResourceSet();

        ctxt.setAttribute(RESOURCE, resource);
        ctxt.setAttribute(REFERENCE_ENTRIES, entries);
        ctxt.setAttribute(CACHE, new Cache());
        ctxt.setAttribute(TYPE_FACTORY, ecoreType);
        ctxt.setAttribute(RESOURCE_SET, resourceSet);

        if (!jp.hasCurrentToken()) {
            jp.nextToken();
        }

        final TypeFactory factory = TypeFactory.defaultInstance();
        final JsonDeserializer<Object> deserializer = ctxt
                .findRootValueDeserializer(factory.constructType(EObject.class));

        if (jp.getCurrentToken() == JsonToken.START_ARRAY) {

            while (jp.nextToken() != JsonToken.END_ARRAY) {

                EObject value = (EObject) deserializer.deserialize(jp, ctxt);
                if (value != null) {
                    resource.getContents().add(value);
                }
            }

        } else if (jp.getCurrentToken() == JsonToken.START_OBJECT) {
            EObject value = (EObject) deserializer.deserialize(jp, ctxt);
            if (value != null) {
                resource.getContents().add(value);
            }
        }

        entries.resolve(resourceSet, uriHandler);

        return resource;
    }

    private Resource getResource(DeserializationContext context, Resource resource) {
        if (resource == null) {
            resource = EMFContext.getResource(context);

            if (resource == null) {
                ResourceSet resourceSet = getResourceSet(context);
                URI uri = getURI(context);
                resource = resourceSet.createResource(uri);
                // no factory found for uri
                if (resource == null) {
                    throw new RuntimeException("Cannot create resource for uri " + uri);
                }
            }
        } else {
            ResourceSet resourceSet = resource.getResourceSet();
            if (resourceSet == null) {
                resourceSet = getResourceSet(context);
                resourceSet.getResources().add(resource);
            }

            return resource;
        }

        return resource;
    }

    protected ResourceSet getResourceSet(DeserializationContext context) {
        ResourceSet resourceSet = EMFContext.getResourceSet(context);
        if (resourceSet == null) {
            context.setAttribute(RESOURCE_SET, resourceSet = new ResourceSetImpl());
        }

        return resourceSet;
    }

    private URI getURI(DeserializationContext ctxt) {
        URI uri = EMFContext.getURI(ctxt);
        if (uri == null) {
            uri = URI.createURI("default");
        }

        return uri;
    }

    @Override
    public Class<Resource> handledType() {
        return Resource.class;
    }

}