All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mitchellbosecke.pebble.utils.FutureWriter Maven / Gradle / Ivy

/*******************************************************************************
 * This file is part of Pebble.
 * 
 * Copyright (c) 2014 by Mitchell Bösecke
 * 
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 ******************************************************************************/
package com.mitchellbosecke.pebble.utils;

import java.io.IOException;
import java.io.Writer;
import java.util.LinkedList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * A Writer that will wrap around the user-provided writer if the user also
 * provided an ExecutorService to the main PebbleEngine. A FutureWriter is
 * capable of handling Futures that will return a string.
 * 
 * It is not thread safe but that is okay. Each thread will have it's own
 * writer, provided by the "parallel" node; i.e. they will never share writers.
 * 
 * @author Mitchell
 * 
 */
public class FutureWriter extends Writer {

    private final LinkedList> orderedFutures = new LinkedList<>();

    private final Writer internalWriter;

    private boolean closed = false;

    public FutureWriter(Writer writer) {
        this.internalWriter = writer;
    }

    public void enqueue(Future future) throws IOException {
        if (closed) {
            throw new IOException("Writer is closed");
        }
        orderedFutures.add(future);
    }

    @Override
    public void write(final char[] cbuf, final int off, final int len) throws IOException {

        if (closed) {
            throw new IOException("Writer is closed");
        }

        final String result = new String(cbuf, off, len);

        if (orderedFutures.isEmpty()) {
            internalWriter.write(result);
        } else {
            Future future = new Future() {

                @Override
                public boolean cancel(boolean mayInterruptIfRunning) {
                    return false;
                }

                @Override
                public boolean isCancelled() {
                    return false;
                }

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

                @Override
                public String get() throws InterruptedException, ExecutionException {
                    return result;
                }

                @Override
                public String get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException,
                        TimeoutException {
                    return null;
                }

            };

            orderedFutures.add(future);
        }
    }

    @Override
    public void flush() throws IOException {
        for (Future future : orderedFutures) {
            try {
                String result = future.get();
                internalWriter.write(result);
                internalWriter.flush();
            } catch (InterruptedException | ExecutionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        orderedFutures.clear();
    }

    @Override
    public void close() throws IOException {
        flush();
        internalWriter.close();
        closed = true;

    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy