/* * Copyright (c) 2020 MarkLogic Corporation */ package com.marklogic.xcc.examples; import java.io.IOException; import java.io.OutputStream; import java.net.URI; import com.marklogic.xcc.ContentCreateOptions; import com.marklogic.xcc.ContentSource; import com.marklogic.xcc.ContentSourceFactory; import com.marklogic.xcc.Session; /** *
* This class illustrates a sample usage of the {@link OutputStreamContent} class. *
** Click here for the source code for this * class *
** A simple inner class is defined here which generates some content programmatically and writes it * to an {@link OutputStream}. It makes use of {@link OutputStreamContent} to obtain an * {@link OutputStream} instance tied to a {@link com.marklogic.xcc.Content} object. *
** The way this works is that {@link OutputStreamContent} creates a pipe (double-ended stream). A * thread is spawned which writes data to the sink end of the pipe. The {@link OutputStreamContent} * object is passed to {@link Session#insertContent(com.marklogic.xcc.Content)} which will * ultimately read data from the source end of the pipe. It's therefore important that the writer * thread be started before doing the insert. *
** To make use of {@link OutputStreamContent}, you simply need to implement the standard * {@link Runnable} interface and put your data transfer logic in the {@link Runnable#run()} method. *
** See the source code for the main() method. *
* * @see OutputStreamContent */ public class OutputStreamInserter { private OutputStreamInserter() { } /** * Looks for a server URI and a document URI on the command line, then spawns a thread to * generate and insert some content there. * * @param args * Server URI: xcc://user:password@host:port/contentbase, Doc URI: any valid URI * string to assign to the new content. * @throws Exception * If anything bad happens. */ public static void main(String[] args) throws Exception { if (args.length < 2) { usage(); return; } URI serverUri = new URI(args[0]); String docUri = args[1]; ContentSource cs = ContentSourceFactory.newContentSource(serverUri); Session session = cs.newSession(); ContentCreateOptions options = ContentCreateOptions.newXmlInstance(); OutputStreamContent content = new OutputStreamContent(docUri, options); OutputStream out = content.getOutputStream(); Runnable producer = new DocBuilder(out, 50); Thread thread = spawnThread(producer); session.insertContent(content); session.close(); thread.join(); // not strictly necessary, waits for thread to finish } /** * A simple dummy content generator which writes to an {@link OutputStream}. This is a * brain-dead example that simply generates dummy content. A real implementation might be * fetching rows from an SQL database or some other transient source. You should only use this * approach if you don't have a better option. If the data can be written to a temp file or * provided as a standard {@link java.io.InputStream} then one of the provided implementations * in {@link com.marklogic.xcc.ContentFactory} should be used. Note also that inserting content * this way is not eligible for automatic error recovery and you can get in trouble if you don't * manage threads properly. */ public static class DocBuilder implements Runnable { private final OutputStream out; private final int lines; /** * Initialize this instance. * * @param out * An {@link OutputStream} to which content should be written. * @param lines * How many lines to generate. */ public DocBuilder(OutputStream out, int lines) { this.out = out; this.lines = lines; } /** * Entry point when the new {@link Thread} starts. This is where your real business logic * would go, ulitmately writing data to the {@link OutputStream}. */ public void run() { StringBuffer sb = new StringBuffer(); try { out.write("