package org.emfjson.mongo.streams; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.mongodb.client.MongoCollection; import org.bson.Document; import org.bson.codecs.DocumentCodec; import org.bson.codecs.EncoderContext; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.URIConverter.Loadable; import org.emfjson.jackson.JacksonOptions; import org.emfjson.jackson.module.EMFModule; import org.emfjson.mongo.MongoHandler; import org.emfjson.mongo.bson.codecs.JsonWriter; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.util.Map; public class MongoInputStream extends InputStream implements Loadable { private final Map<?, ?> options; private final URI uri; private MongoHandler handler; public MongoInputStream(MongoHandler handler, URI uri, Map<?, ?> options) { this.uri = uri; this.options = options; this.handler = handler; } @Override public void loadResource(Resource resource) throws IOException { final MongoCollection<Document> collection = handler.getCollection(uri); if (!resource.getContents().isEmpty()) { resource.getContents().clear(); } final String id = uri.segment(2); final Document filter = new Document(MongoHandler.ID_FIELD, id); final Document document = collection .find(filter) .limit(1) .first(); if (document == null) { throw new IOException("Cannot find document with " + MongoHandler.ID_FIELD + " " + id); } JsonWriter writer = new JsonWriter(new StringWriter()); new DocumentCodec().encode(writer, document, EncoderContext .builder() .isEncodingCollectibleDocument(true) .build()); readJson(resource, writer.getWriter().toString()); } private void readJson(Resource resource, String data) throws IOException { final ObjectMapper mapper = new ObjectMapper(); final JacksonOptions jacksonOptions = JacksonOptions.from(options); final EMFModule module = new EMFModule(resource.getResourceSet(), jacksonOptions); mapper.registerModule(module); final JsonNode rootNode = mapper.readTree(data); final JsonNode contents = rootNode.has(MongoHandler.CONTENTS_FIELD) ? rootNode.get(MongoHandler.CONTENTS_FIELD): null; if (contents != null) { mapper.reader() .withAttribute("resource", resource) .treeToValue(contents, Resource.class); } } @Override public int read() throws IOException { return 0; } }