/* * Copyright 2007 Alin Dreghiciu. * * 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 org.ops4j.pax.exam.forked.provision; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; import org.ops4j.lang.NullArgumentException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Stream related utilities. TODO add units tests * * @author Alin Dreghiciu * @since August 19, 2007 */ public class StreamUtils { /** * Logger. */ private static final Logger LOGGER = LoggerFactory.getLogger(StreamUtils.class); /** * Utility class. Ment to be used via static methods. */ private StreamUtils() { // utility class } /** * Copy a stream to a destination. It does not close the streams. * * @param in * the stream to copy from * @param out * the stream to copy to * @param progressBar * download progress feedback. Can be null. * * @throws IOException * re-thrown */ public static void streamCopy(final InputStream in, final FileChannel out, final ProgressBar progressBar) throws IOException { NullArgumentException.validateNotNull(in, "Input stream"); NullArgumentException.validateNotNull(out, "Output stream"); final long start = System.currentTimeMillis(); long bytes = 0; ProgressBar feedbackBar = progressBar; if (feedbackBar == null) { feedbackBar = new NullProgressBar(); } try { ReadableByteChannel inChannel = Channels.newChannel(in); bytes = out.transferFrom(inChannel, 0, Integer.MAX_VALUE); inChannel.close(); } finally { feedbackBar.increment(bytes, bytes / Math.max(System.currentTimeMillis() - start, 1)); feedbackBar.stop(); } } /** * Copy a stream from an urlto a destination. * * @param url * the url to copy from * @param out * the stream to copy to * @param progressBar * download progress feedback. Can be null. * * @throws IOException * re-thrown */ public static void streamCopy(final URL url, final FileChannel out, final ProgressBar progressBar) throws IOException { NullArgumentException.validateNotNull(url, "URL"); InputStream is = null; try { is = url.openStream(); streamCopy(is, out, progressBar); } finally { if (is != null) { is.close(); } } } /** * Feddback for downloading process. */ public interface ProgressBar { /** * Callback on download progress. * * @param bytes * download size from when the download started * @param kbps * download speed */ void increment(long bytes, long kbps); /** * Callback when download finished. */ void stop(); } /** * A progress bar that does nothing = does not display anything on console. */ public static class NullProgressBar implements ProgressBar { public void increment(long bytes, long kbps) { // does nothing } public void stop() { // does nothing } } /** * A progress bar that displayed detailed information about downloading of an artifact */ public static class FineGrainedProgressBar implements ProgressBar { int counter; /** * Name of the downloaded artifact. */ private final String downloadTargetName; public FineGrainedProgressBar(final String downloadTargetName) { this.downloadTargetName = downloadTargetName; Info.print(downloadTargetName + " : connecting...\r"); } public void increment(final long bytes, final long kbps) { Info.print(downloadTargetName + " : " + bytes + " bytes @ [ " + kbps + "kBps ]\r"); counter++; } public void stop() { Info.println(); } } /** * A progress bar that displayed corse grained information about downloading of an artifact */ public static class CoarseGrainedProgressBar implements ProgressBar { /** * Name of the downloaded artifact. */ private final String downloadTargetName; private long bytes; private long kbps; public CoarseGrainedProgressBar(final String downloadTargetName) { this.downloadTargetName = downloadTargetName; LOGGER.debug(downloadTargetName + " : downloading..."); } public void increment(final long _bytes, final long _kbps) { this.bytes = _bytes; this.kbps = _kbps; } public void stop() { LOGGER.debug(downloadTargetName + " : " + bytes + " bytes @ [ " + kbps + "kBps ]"); } } }