/*
* Copyright 2015 MovingBlocks
*
* 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.terasology.rendering.nui.layers.mainMenu;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.concurrent.Callable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Downloads a file.
*/
public class FileDownloader implements Callable<Path> {
private static final Logger logger = LoggerFactory.getLogger(FileDownloader.class);
private final URL url;
private final Path target;
private final ProgressListener listener;
public FileDownloader(URL url, Path target) {
this(url, target, p -> { });
}
/**
* @param url
* @param listener a progress listener. Will be called with 0 repeatedly if size cannot be determined.
*/
public FileDownloader(URL url, Path target, ProgressListener listener) {
this.url = url;
this.target = target;
this.listener = listener;
}
@Override
public Path call() throws IOException {
Path folder = target.getParent();
String prefix = target.getFileName().toString();
Path tempModuleLocation = Files.createTempFile(folder, prefix + "_", ".tmp");
tempModuleLocation.toFile().deleteOnExit();
logger.debug("Downloading {} from {}", target, url);
long length = -1;
URLConnection conn = url.openConnection();
if (conn instanceof HttpURLConnection) {
length = ((HttpURLConnection) conn).getContentLengthLong();
}
try (InputStream is = url.openStream();
OutputStream os = Files.newOutputStream(tempModuleLocation)) {
copy(is, os, length, listener);
Files.move(tempModuleLocation, target, StandardCopyOption.REPLACE_EXISTING);
}
return target;
}
/**
* Reads all bytes from an input stream and writes them to an output stream.
* Copied and adapted from Files.copy().
*/
private static long copy(InputStream source, OutputStream sink, long max, ProgressListener listener) throws IOException {
long nread = 0L;
int bufferSize = 0x10000; // 64 kB
byte[] buf = new byte[bufferSize];
int n;
while ((n = source.read(buf)) > 0) {
sink.write(buf, 0, n);
nread += n;
if (max <= 0) {
listener.onProgress(0);
} else {
listener.onProgress((float) nread / max);
}
}
return nread;
}
}