package com.lucidworks.storm.solr; import org.apache.solr.common.util.ContentStream; import org.apache.solr.common.util.ContentStreamBase; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.io.InputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; public class DefaultJsonContentStreamMapper implements JsonContentStreamMapper { class PipedInputContentStream extends ContentStreamBase implements Runnable { private final ObjectMapper mapper; private final Object docObj; private final PipedOutputStream out; private final PipedInputStream in; PipedInputContentStream(ObjectMapper mapper, Object docObj) throws IOException { this.mapper = mapper; this.docObj = docObj; this.out = new PipedOutputStream(); this.in = new PipedInputStream(this.out, 4096); } public InputStream getStream() throws IOException { return in; } public void run() { try { mapper.writeValue(out, docObj); out.flush(); } catch (IOException e) { throw new RuntimeException(e); } finally { try { out.close(); } catch (Exception ignore){ ignore.printStackTrace(); } } } } public static final String JSON_CONTENT_TYPE = "application/json"; protected ObjectMapper mapper = new ObjectMapper(); public ContentStream toContentStream(String docId, Object docObj) throws Exception { if (docObj instanceof String) { // already a string, so just stream it out directly ContentStreamBase.StringStream ss = new ContentStreamBase.StringStream((String)docObj); ss.setContentType(JSON_CONTENT_TYPE); return ss; } // pipe the bytes written by the ObjectMapper during JSON serialization to the InputStream PipedInputContentStream contentStream = new PipedInputContentStream(mapper, docObj); contentStream.setContentType(JSON_CONTENT_TYPE); Thread serThread = new Thread(contentStream); serThread.start(); // start pumping bytes from the JSON serializer into the input stream using a separate thread return contentStream; } }