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

com.crabshue.commons.archive.filesystem.FileSystemArchiveService Maven / Gradle / Ivy

package com.crabshue.commons.archive.filesystem;

import java.io.File;
import java.io.InputStream;
import java.util.Collection;
import java.util.stream.Collectors;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOCase;
import org.apache.commons.io.filefilter.FileFilterUtils;

import com.crabshue.commons.archive.Archivable;
import com.crabshue.commons.archive.ArchiveService;
import com.crabshue.commons.archive.exceptions.ArchiveErrorContext;
import com.crabshue.commons.archive.exceptions.ArchiveErrorType;
import com.crabshue.commons.exceptions.ApplicationException;
import com.crabshue.commons.file.FileIOUtils;
import com.crabshue.commons.file.FileSystemUtils;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;

/**
 * Abstract class for filesystem-based archive service.
 *
 * @param  the type of archivable.
 */
@Slf4j
public abstract class FileSystemArchiveService implements ArchiveService {

    @Override
    public abstract String getArchiveRootPath();

    @Override
    public String getArchiveFolderPath(@NonNull final T archivable) {

        if (archivable.getArchiveId() == null) {
            throw new IllegalArgumentException("Cannot provide archive folder for an archivable without id " + archivable);
        }

        final String folderName = archivable.getArchiveId();

        final File archiveFolder = new File(getArchiveRootPath(), folderName);
        final String ret = archiveFolder.getAbsolutePath();
        logger.debug("Archive folder for [{}] is [{}]", archivable, ret);
        return ret;
    }

    @Override
    public Collection listFilesInArchive(@NonNull final T archivable) {

        final File archiveFolder = this.provideArchiveFolder(archivable);

        final Collection candidates = FileUtils.listFiles(archiveFolder,
            FileFilterUtils.trueFileFilter(), FileFilterUtils.trueFileFilter());

        final Collection ret = candidates.stream()
            .map(File::getAbsolutePath)
            .collect(Collectors.toList());
        logger.info("Files in archive of [{}] : [{}]", archivable, ret);
        return ret;
    }


    @Override
    public File retrieveUniqueFileInArchive(@NonNull final T archivable,
                                            @NonNull final String filename) {

        final File archiveFolder = this.provideArchiveFolder(archivable);
        final Collection candidates = FileUtils.listFiles(archiveFolder,
            FileFilterUtils.nameFileFilter(filename, IOCase.SENSITIVE), FileFilterUtils.trueFileFilter());

        if (candidates.isEmpty()) {
            throw new ApplicationException(ArchiveErrorType.ARCHIVE_FILE_NOT_FOUND, "Unexpected number of files in archive. Excepted one and only one.")
                .addContextValue(ArchiveErrorContext.FILENAME, filename);
        }

        final File ret = candidates.iterator().next();
        logger.info("Found file [{}] for archivable [{}] and filename [{}]", ret, archivable, filename);
        return ret;
    }

    @Override
    public void deleteArchiveFolder(@NonNull final T archivable) {

        final File archiveFolder = new File(this.getArchiveFolderPath(archivable));

        if (!archiveFolder.exists()) {
            return;
        }
        FileUtils.deleteQuietly(archiveFolder);
        logger.info("Deleted archive folder [{}] for archivable [{}]", archiveFolder, archivable);
    }

    @Override
    public void cleanArchiveFolder(@NonNull final T archivable) {

        final File archiveFolder = this.provideArchiveFolder(archivable);

        FileSystemUtils.cleanDirectory(archiveFolder);

        logger.info("Cleaned archive folder [{}] for archivable [{}]", archiveFolder, archivable);
    }

    @Override
    public void cleanArchiveRoot() {

        final File archiveRoot = new File(this.getArchiveRootPath());

        FileSystemUtils.cleanDirectory(archiveRoot);

        logger.info("Cleaned archive root folder [{}]", archiveRoot);
    }

    @Override
    public void storeInArchive(@NonNull final T archivable,
                               @NonNull final File file) {

        final File folder = this.provideArchiveFolder(archivable);
        final File ret = new File(folder, file.getName());

        FileSystemUtils.copyFile(file, ret);

        logger.info("Stored file [{}] for [{}]", ret, archivable);
    }

    @Override
    public void storeInArchive(@NonNull final T archivable,
                               @NonNull final String filename,
                               @NonNull final InputStream inputStream) {

        final File archiveFile = new File(this.getArchiveFolderPath(archivable), filename);
        FileIOUtils.writeFile(inputStream, archiveFile);

        logger.info("Stored input stream into [{}] for [{}]", archiveFile, archivable);

    }

    @Override
    public void storeFolderContentInArchive(@NonNull final T archivable,
                                            @NonNull final File folder) {

        FileSystemUtils.copyFolder(folder, this.provideArchiveFolder(archivable));
    }

    protected File provideArchiveFolder(@NonNull final T archivable) {

        if (archivable.getArchiveId() == null) {
            throw new IllegalArgumentException("Cannot provide archive folder for an archivable without id " + archivable);
        }

        final File ret = new File(this.getArchiveFolderPath(archivable));

        if (!ret.exists()) {
            FileSystemUtils.provideFolder(ret);
        }

        logger.debug("Provided archive folder [{}] for [{}]", ret, archivable);
        return ret;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy