blob: 5a00ee6ad81c078b3e4d9f5e69a73111b0c8b41d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2020 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.mdm.api.atfxadapter.filetransfer;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.time.LocalTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
import org.eclipse.mdm.api.base.file.FileService;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.FileLink;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author akn
*
*/
public class ATFXFileService implements FileService {
private static final Logger LOGGER = LoggerFactory.getLogger(ATFXFileService.class);
private final Path parentDirectory;
public ATFXFileService(File parentDirectory) {
this.parentDirectory = parentDirectory.toPath();
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.mdm.api.base.file.FileService#downloadSequential(org.eclipse.mdm.
* api.base.model.Entity, java.nio.file.Path, java.util.Collection,
* org.eclipse.mdm.api.base.file.FileService.ProgressListener)
*/
@Override
public void downloadSequential(Entity entity, Path target, Collection<FileLink> fileLinks,
ProgressListener progressListener) throws IOException {
Map<String, List<FileLink>> groups = fileLinks.stream().filter(FileLink::isRemote)
.collect(Collectors.groupingBy(FileLink::getRemotePath));
long totalSize = calculateDownloadSize(groups);
final AtomicLong transferred = new AtomicLong();
LocalTime start = LocalTime.now();
UUID id = UUID.randomUUID();
LOGGER.debug("Sequential download of {} file(s) with id '{}' started.", groups.size(), id);
for (List<FileLink> group : groups.values()) {
FileLink fileLink = group.get(0);
download(entity, target, fileLink, (b, p) -> {
double tranferredBytes = transferred.addAndGet(b);
if (progressListener != null) {
progressListener.progress(b, (float) (tranferredBytes / totalSize));
}
});
for (FileLink other : group.subList(1, group.size())) {
other.setLocalStream(fileLink.getLocalStream());
}
}
LOGGER.debug("Sequential download with id '{}' finished in {}.", id, Duration.between(start, LocalTime.now()));
}
private long calculateDownloadSize(Map<String, List<FileLink>> groups) {
List<FileLink> links = groups.values().stream().map(l -> l.get(0)).collect(Collectors.toList());
long totalSize = 0;
for (FileLink fileLink : links) {
File f = new File(fileLink.getRemotePath());
// overflow may occur in case of total size exceeds 9223 PB!
totalSize = Math.addExact(totalSize, f.length());
}
return totalSize;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.mdm.api.base.file.FileService#downloadParallel(org.eclipse.mdm.
* api.base.model.Entity, java.nio.file.Path, java.util.Collection,
* org.eclipse.mdm.api.base.file.FileService.ProgressListener)
*/
@Override
public void downloadParallel(Entity entity, Path target, Collection<FileLink> fileLinks,
ProgressListener progressListener) throws IOException {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.mdm.api.base.file.FileService#download(org.eclipse.mdm.api.base.
* model.Entity, java.nio.file.Path, org.eclipse.mdm.api.base.model.FileLink,
* org.eclipse.mdm.api.base.file.FileService.ProgressListener)
*/
@Override
public void download(Entity entity, Path target, FileLink fileLink, ProgressListener progressListener)
throws IOException {
if (Files.exists(target)) {
if (!Files.isDirectory(target)) {
throw new IllegalArgumentException("Target path is not a directory.");
}
} else {
Files.createDirectory(target);
}
try (InputStream inputStream = openStream(entity, fileLink)) {
Path absolutePath = target.resolve(fileLink.getFileName()).toAbsolutePath();
String remotePath = fileLink.getRemotePath();
LOGGER.debug("Starting download of file '{}' to '{}'.", remotePath, absolutePath);
LocalTime start = LocalTime.now();
Files.copy(inputStream, absolutePath);
LOGGER.debug("File '{}' successfully downloaded in {} to '{}'.", remotePath,
Duration.between(start, LocalTime.now()), absolutePath);
}
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.mdm.api.base.file.FileService#openStream(org.eclipse.mdm.api.base
* .model.Entity, org.eclipse.mdm.api.base.model.FileLink,
* org.eclipse.mdm.api.base.file.FileService.ProgressListener)
*/
@Override
public InputStream openStream(Entity entity, FileLink fileLink, ProgressListener progressListener)
throws IOException {
return new FileInputStream(parentDirectory.resolve(fileLink.getRemotePath()).toFile());
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.mdm.api.base.file.FileService#loadSize(org.eclipse.mdm.api.base.
* model.Entity, org.eclipse.mdm.api.base.model.FileLink)
*/
@Override
public void loadSize(Entity entity, FileLink fileLink) throws IOException {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.mdm.api.base.file.FileService#uploadSequential(org.eclipse.mdm.
* api.base.model.Entity, java.util.Collection,
* org.eclipse.mdm.api.base.file.FileService.ProgressListener)
*/
@Override
public void uploadSequential(Entity entity, Collection<FileLink> fileLinks, ProgressListener progressListener)
throws IOException {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.mdm.api.base.file.FileService#uploadParallel(org.eclipse.mdm.api.
* base.model.Entity, java.util.Collection,
* org.eclipse.mdm.api.base.file.FileService.ProgressListener)
*/
@Override
public void uploadParallel(Entity entity, Collection<FileLink> fileLinks, ProgressListener progressListener)
throws IOException {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.mdm.api.base.file.FileService#delete(org.eclipse.mdm.api.base.
* model.Entity, java.util.Collection)
*/
@Override
public void delete(Entity entity, Collection<FileLink> fileLinks) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.mdm.api.base.file.FileService#delete(org.eclipse.mdm.api.base.
* model.Entity, org.eclipse.mdm.api.base.model.FileLink)
*/
@Override
public void delete(Entity entity, FileLink fileLink) {
// TODO Auto-generated method stub
}
}