/* * Copyright (C) 2023 Laurent CLOUET * Author Laurent CLOUET * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package com.sheepit.client; import com.sheepit.client.datamodel.Chunk; import lombok.AllArgsConstructor; import java.io.File; import java.io.IOException; import java.nio.file.FileSystemException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; @AllArgsConstructor public class DirectoryManager { private Configuration configuration; private Log log; public String getActualStoragePathFor(Chunk chunk) { return isSharedEnabled() ? getSharedPathFor(chunk) : getCachePathFor(chunk); } public String getCachePathFor(Chunk chunk) { return configuration.getWoolCacheDirectory().getAbsolutePath() + File.separator + chunk.getId() + ".wool"; } public String getSharedPathFor(Chunk chunk) { return configuration.getSharedDownloadsDirectory().getAbsolutePath() + File.separator + chunk.getId() + ".wool"; } public boolean isSharedEnabled() { return configuration.getSharedDownloadsDirectory() != null && configuration.getSharedDownloadsDirectory().exists(); } public boolean copyChunkFromSharedToCache(Chunk chunk) { return copyFileFromSharedToCache(getSharedPathFor(chunk), getCachePathFor(chunk)); } private boolean copyFileFromSharedToCache(String source, String target) { Path existingArchivePath = Paths.get(source); Path targetArchivePath = Paths.get(target); if (existingArchivePath.equals(targetArchivePath)) { // target are the same, do nothing return true; } try { Files.deleteIfExists(targetArchivePath); // createLink only works if the target does not exist try { Files.createLink(targetArchivePath, existingArchivePath); log.debug("Created hardlink from " + targetArchivePath + " to " + existingArchivePath); } catch (UnsupportedOperationException // underlying file system does not support hard-linking | FileSystemException // cache-dir and shared-zip are on separate file systems, even though hard-linking is supported | SecurityException // user is not allowed to create hard-links ignore) { // Creating hardlinks might not be supported on some filesystems log.debug("Failed to create hardlink, falling back to copying file to " + targetArchivePath); Files.copy(existingArchivePath, targetArchivePath, StandardCopyOption.REPLACE_EXISTING); } } catch (IOException e) { log.error("Error while copying " + source + " from shared downloads directory to working dir"); return false; } return true; } }