Java tutorial
/* * 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; } }