FileContainerService.java

package de.dlr.shepard.neo4Core.services;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.List;

import de.dlr.shepard.mongoDB.FileService;
import de.dlr.shepard.mongoDB.NamedInputStream;
import de.dlr.shepard.mongoDB.ShepardFile;
import de.dlr.shepard.neo4Core.dao.FileContainerDAO;
import de.dlr.shepard.neo4Core.dao.PermissionsDAO;
import de.dlr.shepard.neo4Core.dao.UserDAO;
import de.dlr.shepard.neo4Core.entities.FileContainer;
import de.dlr.shepard.neo4Core.entities.Permissions;
import de.dlr.shepard.neo4Core.io.FileContainerIO;
import de.dlr.shepard.util.DateHelper;
import de.dlr.shepard.util.PermissionType;
import de.dlr.shepard.util.QueryParamHelper;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class FileContainerService implements IContainerService<FileContainer, FileContainerIO> {

	private FileContainerDAO fileContainerDAO = new FileContainerDAO();
	private PermissionsDAO permissionsDAO = new PermissionsDAO();
	private UserDAO userDAO = new UserDAO();
	private DateHelper dateHelper = new DateHelper();
	private FileService fileService = new FileService();

	/**
	 * Creates a FileContainer and stores it in Neo4J
	 *
	 * @param fileContainerIO to be stored
	 * @param username        of the related user
	 * @return the created FileContainer
	 */
	@Override
	public FileContainer createContainer(FileContainerIO fileContainerIO, String username) {
		var user = userDAO.find(username);
		var toCreate = new FileContainer();
		toCreate.setCreatedAt(dateHelper.getDate());
		toCreate.setCreatedBy(user);
		toCreate.setMongoId(fileService.createFileContainer());
		toCreate.setName(fileContainerIO.getName());

		var created = fileContainerDAO.createOrUpdate(toCreate);
		permissionsDAO.createOrUpdate(new Permissions(created, user, PermissionType.Private));
		return created;
	}

	/**
	 * Searches the FileContainer in Neo4j
	 *
	 * @param id identifies the searched FileContainer
	 * @return the FileContainer with matching id or null
	 */
	@Override
	public FileContainer getContainer(long id) {
		FileContainer fileContainer = fileContainerDAO.findByNeo4jId(id);
		if (fileContainer == null || fileContainer.isDeleted()) {
			log.error("File Container with id {} is null or deleted", id);
			return null;
		}
		return fileContainer;
	}

	/**
	 * Searches the database for all FileContainers
	 *
	 * @param params   QueryParamsHelper
	 * @param username the name of the user
	 * @return a list of FileContainers
	 */
	@Override
	public List<FileContainer> getAllContainers(QueryParamHelper params, String username) {
		var containers = fileContainerDAO.findAllFileContainers(params, username);
		return containers;
	}

	/**
	 * Deletes a FileContainer in Neo4j
	 *
	 * @param fileContainerId identifies the FileContainer
	 * @param username        the deleting user
	 * @return a boolean to determine if FileContainer was successfully deleted
	 */
	@Override
	public boolean deleteContainer(long fileContainerId, String username) {
		var user = userDAO.find(username);
		FileContainer fileContainer = fileContainerDAO.findByNeo4jId(fileContainerId);
		if (fileContainer == null) {
			return false;
		}
		String mongoid = fileContainer.getMongoId();
		fileContainer.setDeleted(true);
		fileContainer.setUpdatedAt(dateHelper.getDate());
		fileContainer.setUpdatedBy(user);
		fileContainerDAO.createOrUpdate(fileContainer);
		return fileService.deleteFileContainer(mongoid);
	}

	/**
	 * Get file payload
	 *
	 * @param fileContainerId The container to get the payload from
	 * @param oid             The specific file
	 * @return a NamedInputStream
	 */
	public NamedInputStream getFile(long fileContainerId, String oid) {
		var container = fileContainerDAO.findLightByNeo4jId(fileContainerId);
		if (container == null || container.isDeleted()) {
			log.error("File Container with id {} is null or deleted", fileContainerId);
			return null;
		}
		var result = fileService.getPayload(container.getMongoId(), oid);
		return result;
	}

	/**
	 * Create a new file
	 *
	 * @param fileContainerId identifies the file container
	 * @param fileName        the name of the new file
	 * @param inputStream     the file itself
	 * @return The newly created file
	 */
	public ShepardFile createFile(long fileContainerId, String fileName, InputStream inputStream) {
		var fileContainer = fileContainerDAO.findByNeo4jId(fileContainerId);
		if (fileContainer == null || fileContainer.isDeleted()) {
			log.error("File Container with id {} is null or deleted", fileContainerId);
			return null;
		}
		if (fileName == null || fileName.isBlank()) {
			var sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
			var dateStr = sdf.format(dateHelper.getDate());
			fileName = "shepard-file-" + dateStr;
		}
		var result = fileService.createFile(fileContainer.getMongoId(), fileName, inputStream);
		if (result == null) {
			log.error("Failed to create shepard file");
			return null;
		}
		fileContainer.addFile(result);
		fileContainerDAO.createOrUpdate(fileContainer);
		return result;
	}

	/**
	 * Delete one file
	 *
	 * @param fileContainerId The container to get the payload from
	 * @param oid             The specific file
	 * @return Whether the deletion was successful or not
	 */
	public boolean deleteFile(long fileContainerId, String oid) {
		var container = fileContainerDAO.findByNeo4jId(fileContainerId);
		if (container == null || container.isDeleted())
			return false;
		var result = fileService.deleteFile(container.getMongoId(), oid);
		if (result) {
			var newFiles = container.getFiles().stream().filter(f -> !f.getOid().equals(oid)).toList();
			container.setFiles(newFiles);
			fileContainerDAO.createOrUpdate(container);
		}
		return result;
	}

}