package org.gcube.gcat.workspace; import java.io.StringWriter; import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.ws.rs.InternalServerErrorException; import org.gcube.common.homelibrary.home.Home; import org.gcube.common.homelibrary.home.HomeLibrary; import org.gcube.common.homelibrary.home.HomeManager; import org.gcube.common.homelibrary.home.HomeManagerFactory; import org.gcube.common.homelibrary.home.User; import org.gcube.common.homelibrary.home.workspace.Workspace; import org.gcube.common.storagehub.client.StreamDescriptor; import org.gcube.common.storagehub.client.dsl.ContainerType; import org.gcube.common.storagehub.client.dsl.FileContainer; import org.gcube.common.storagehub.client.dsl.FolderContainer; import org.gcube.common.storagehub.client.dsl.ItemContainer; import org.gcube.common.storagehub.client.dsl.ListResolver; import org.gcube.common.storagehub.client.dsl.ListResolverTyped; import org.gcube.common.storagehub.client.dsl.OpenResolver; import org.gcube.common.storagehub.client.dsl.StorageHubClient; import org.gcube.common.storagehub.model.Metadata; import org.gcube.common.storagehub.model.items.AbstractFileItem; import org.gcube.common.storagehub.model.items.Item; import org.gcube.gcat.utils.Constants; import org.gcube.gcat.utils.ContextUtility; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class StorageHubManagement { private static final Logger logger = LoggerFactory.getLogger(StorageHubManagement.class); public static final String ORIGINAL_URL = "OriginalURL"; public static final String ORIGINAL_NAME = "OriginalName"; public static final String CATALOGUE_ITEM_ID = "CatalogueItemID"; public static final String CATALOGUE_RESOURCE_ID = "CatalogueResourceID"; public static final String CATALOGUE_RESOURCE_REVISION_ID = "CatalogueResourceRevisionID"; public static final String CATALOGUE_FOLDER_DESCRIPTION = "Catalogue Folder used to persist Resources"; protected final StorageHubClient storageHubClient; protected FileContainer createdFile; protected String mimeType; public String getMimeType() { return mimeType; } public StorageHubManagement() { storageHubClient = new StorageHubClient(); } protected void recursiveList(FolderContainer folder, int level) { ListResolverTyped listResolverTyped = folder.list(); List> containers = listResolverTyped.getContainers(); for(ItemContainer itemContainer : containers) { Item item = itemContainer.get(); String name = item.getName(); ContainerType containerType = itemContainer.getType(); StringWriter indent = new StringWriter(level + 1); for(int i = 0; i < level + 1; i++) { indent.append('-'); } logger.debug("{} {} {} (ID:{})", indent.toString(), containerType, name, itemContainer.getId()); switch(containerType) { case FOLDER: FolderContainer folderContainer = (FolderContainer) itemContainer; //if(item.getName().compareTo("553095a0-a14a-4e41-b014-2e6f3a1aeac7")!=0) recursiveList(folderContainer, level + 1); break; case FILE: break; case GENERIC_ITEM: break; default: break; } } } protected FolderContainer getWorkspaceRoot() { try { return storageHubClient.getWSRoot(); }catch (Exception e) { String username = ContextUtility.getUsername(); logger.info("Unable to obtain the Workspace Root for {}. Going to create it.", username); try { HomeManagerFactory factory = HomeLibrary.getHomeManagerFactory(); HomeManager manager = factory.getHomeManager(); User user = manager.createUser(username); @SuppressWarnings("deprecation") Home home = manager.getHome(user); Workspace ws = home.getWorkspace(); ws.getRoot(); return storageHubClient.getWSRoot(); }catch (Exception ex) { logger.info("Unable to create the Workspace Root for {}.", username); throw new InternalServerErrorException(e); } } } protected FolderContainer getOrCreateFolder(FolderContainer parent, String name, String description) { try { FolderContainer destinationFolder = null; ListResolverTyped listResolverTyped = parent.list(); List> containers = listResolverTyped.getContainers(); for(ItemContainer itemContainer : containers) { if(itemContainer instanceof FolderContainer) { if(itemContainer.get().getName().compareTo(name) == 0) { destinationFolder = (FolderContainer) itemContainer; } } } if(destinationFolder == null) { destinationFolder = parent.newFolder(name, description); } return destinationFolder; } catch(Exception e) { throw new InternalServerErrorException(e); } } public static String getFolderName() { String currentContext = ContextUtility.getCurrentContext(); String folderName = currentContext.replaceFirst("/", "").replace("/", "_"); return folderName; } protected FolderContainer getCatalogueFolder() { FolderContainer destinationFolder = getWorkspaceRoot(); String folderName = getFolderName(); destinationFolder = getOrCreateFolder(destinationFolder, folderName, ContextUtility.getCurrentContext() + " folder"); destinationFolder = getOrCreateFolder(destinationFolder, Constants.CATALOGUE_NAME, CATALOGUE_FOLDER_DESCRIPTION); return destinationFolder; } protected FolderContainer getDestinationFolder(AbstractFileItem item) { FolderContainer destinationFolder = getCatalogueFolder(); mimeType = item.getContent().getMimeType(); String[] splittedMimeType = mimeType.split("/"); for(String name : splittedMimeType) { try { destinationFolder = getOrCreateFolder(destinationFolder, name, "Automatic Folder Created using mimetype"); } catch(Exception e) { throw new InternalServerErrorException(e); } } return destinationFolder; } protected FileContainer copyFile(FileContainer sourceFileContainer, FolderContainer destinationFolder, String copiedFilename) { StreamDescriptor streamDescriptor = sourceFileContainer.download(""); FileContainer createdFile = destinationFolder.uploadFile(streamDescriptor.getStream(), copiedFilename, sourceFileContainer.get().getDescription()); /* FileContainer copiedFile = sourceFileContainer.copy(destinationFolder, copiedFilename); */ return createdFile; } protected ItemContainer getContainerByStorageURL(URL url) { URL finalURL = url; String path = finalURL.getPath(); String fileID = path.substring(path.lastIndexOf('/') + 1); OpenResolver openResolver = storageHubClient.open(fileID); ItemContainer itemContainer = openResolver.asItem(); Item item = itemContainer.get(); if(item instanceof AbstractFileItem) { logger.debug("The resource with ID {} is a file", fileID); return openResolver.asFile(); } return itemContainer; } protected boolean isItemPersistedFile(FileContainer fileContainer, FolderContainer destinationFolder, String itemID) { // Checking if the file is already a file of the science catalogue folder of the scope related to such an item. ListResolver listResolver = fileContainer.getAnchestors(); List> itemContainers = listResolver.getContainers(); for(ItemContainer itemContainer : itemContainers) { if(itemContainer.getId().compareTo(destinationFolder.getId()) == 0) { Metadata metadata = fileContainer.get().getPropertyMap(); Map map = metadata.getValues(); if(map.get(CATALOGUE_ITEM_ID).toString().compareTo(itemID) == 0) { return true; } } } return false; } public boolean isItemPersistedFile(URL url, String itemID) { ItemContainer itemContainer = getContainerByStorageURL(url); FileContainer fileContainer; if(itemContainer instanceof FileContainer) { fileContainer = (FileContainer) itemContainer; }else { return false; } FolderContainer destinationFolder = getDestinationFolder(fileContainer.get()); return isItemPersistedFile(fileContainer, destinationFolder, itemID); } protected void tree(FolderContainer folderContainer) throws Exception { logger.debug("{} (ID:{})", folderContainer.get().getName(), folderContainer.getId()); recursiveList(folderContainer, 0); } protected FileContainer getFileByID(String id) throws Exception { OpenResolver openResolver = storageHubClient.open(id); FileContainer fileContainer = (FileContainer) openResolver.asFile(); return fileContainer; } protected void deleteFileByID(String id) throws Exception { FileContainer fileContainer = getFileByID(id); fileContainer.delete(); } public URL ensureResourcePersistence(URL url, String itemID, String resourceID, String name) { ItemContainer itemContainer = getContainerByStorageURL(url); FileContainer fileContainer; if(itemContainer instanceof FileContainer) { fileContainer = (FileContainer) itemContainer; }else { return url; } FolderContainer destinationFolder = getDestinationFolder(fileContainer.get()); if(isItemPersistedFile(fileContainer, destinationFolder, itemID)) { return url; } createdFile = copyFile(fileContainer, destinationFolder, resourceID); Map map = new HashMap<>(); map.put(ORIGINAL_URL, url.toString()); map.put(ORIGINAL_NAME, name); map.put(CATALOGUE_ITEM_ID, itemID); map.put(CATALOGUE_RESOURCE_ID, resourceID); Metadata metadata = new Metadata(map); createdFile.setMetadata(metadata); URL finalURL = createdFile.getPublicLink(); logger.debug("Original File URL was {} - Final URL to ensure persistency is {}", url, finalURL); return finalURL; } public void deleteResourcePersistence(URL url, String itemID) { FileContainer fileContainer = (FileContainer) getContainerByStorageURL(url); FolderContainer destinationFolder = getDestinationFolder(fileContainer.get()); if(isItemPersistedFile(fileContainer, destinationFolder, itemID)) { fileContainer.delete(); } } protected void addRevisionID(FileContainer fileContainer, String resourceID, String revisionID) { Metadata metadata = fileContainer.get().getPropertyMap(); Map map = metadata.getValues(); map.put(CATALOGUE_RESOURCE_ID, resourceID); map.put(CATALOGUE_RESOURCE_REVISION_ID, revisionID); metadata.setValues(map); fileContainer.setMetadata(metadata);; } public void addRevisionID(String resourceID, String revisionID) { addRevisionID(createdFile, resourceID, revisionID); } public void renameFile(String resourceID, String revisionID) { renameFile(createdFile, resourceID); addRevisionID(createdFile, resourceID, revisionID); } protected void renameFile(FileContainer fileContainer, String newName) { fileContainer.rename(newName); } }