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

net.derquinse.common.io.MemoryByteSink Maven / Gradle / Ivy

Go to download

Module containing support classes depending on Java SE 6, Guava 11 and Joda-Time 2.0

There is a newer version: 1.0.37
Show newest version
/*
 * Copyright (C) the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.derquinse.common.io;

import static com.google.common.base.Preconditions.checkNotNull;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import com.google.common.annotations.Beta;
import com.google.common.collect.Queues;
import com.google.common.io.ByteSink;
import com.google.common.util.concurrent.ForwardingBlockingQueue;

/**
 * Memory byte sink. Every time an atomic write operation is performed on the sink or an stream
 * opened through the sink is closed, a MemoryByteSource is added to the queue.
 * @author Andres Rodriguez
 */
@Beta
public final class MemoryByteSink extends ByteSink {
	/** Loader to use. */
	private final MemoryByteSourceLoader loader;
	/** Queue. */
	private final LinkedBlockingQueue queue = Queues.newLinkedBlockingQueue();
	/** Queue view. */
	private final BlockingQueue view = new Queue();

	/** Constructor. */
	MemoryByteSink(MemoryByteSourceLoader loader) {
		this.loader = checkNotNull(loader);
	}

	/**
	 * Adds a loaded byte source to the sink queue. The source is merged if specified by the loader.
	 */
	MemoryByteSource add(MemoryByteSource source) {
		checkNotNull(source);
		if (loader.isMerge()) {
			source = source.merge();
		}
		queue.add(source);
		return source;
	}

	/**
	 * Returns a view of the sink queue. All operations that add elements to the queue throw
	 * {@link UnsupportedOperationException}.
	 */
	public BlockingQueue queue() {
		return view;
	}

	@Override
	public OutputStream openStream() throws IOException {
		final MemoryOutputStream mos = loader.openStream();
		return new SinkOutputStream(mos);
	}

	private final class Queue extends ForwardingBlockingQueue {
		/** Constructor. */
		Queue() {
		}

		@Override
		protected BlockingQueue delegate() {
			return queue;
		}

		@Override
		public boolean add(MemoryByteSource e) {
			throw new UnsupportedOperationException("Can't add elements to the sink queue");
		}

		@Override
		public boolean addAll(Collection c) {
			throw new UnsupportedOperationException("Can't add elements to the sink queue");
		}

		@Override
		public boolean offer(MemoryByteSource e) {
			throw new UnsupportedOperationException("Can't add elements to the sink queue");
		}

		@Override
		public boolean offer(MemoryByteSource e, long timeout, TimeUnit unit) throws InterruptedException {
			throw new UnsupportedOperationException("Can't add elements to the sink queue");
		}

		@Override
		public void put(MemoryByteSource e) throws InterruptedException {
			throw new UnsupportedOperationException("Can't add elements to the sink queue");
		}

	}

	final class SinkOutputStream extends OutputStream {
		/** Whether the stream is closed. */
		private boolean closed = false;
		/** Memory stream. */
		private final MemoryOutputStream os;

		/** Constructor. */
		SinkOutputStream(MemoryOutputStream os) {
			this.os = os;
		}

		@Override
		public void write(int b) throws IOException {
			os.write(b);
		}

		@Override
		public void write(byte[] b, int off, int len) throws IOException {
			os.write(b, off, len);
		}

		@Override
		public synchronized final void close() {
			if (!closed) {
				queue.add(os.toByteSource());
				closed = true;
			}
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy