package org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import org.gcube.common.homelibrary.home.HomeLibrary; import org.gcube.common.homelibrary.home.exceptions.InternalErrorException; import org.gcube.common.homelibrary.home.workspace.Workspace; import org.gcube.common.homelibrary.home.workspace.WorkspaceFolder; import org.gcube.common.homelibrary.home.workspace.WorkspaceItem; import org.gcube.common.homelibrary.home.workspace.catalogue.WorkspaceCatalogue; import org.gcube.common.homelibrary.home.workspace.folder.FolderItem; import org.gcube.datacatalogue.ckanutillibrary.models.ResourceBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetMetadataBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceElementBean; import org.slf4j.LoggerFactory; public class WorkspaceUtils { private static final org.slf4j.Logger logger = LoggerFactory.getLogger(WorkspaceUtils.class); private static final String RESOURCES_NAME_SEPARATOR = "_"; /** * Copy into the .catalogue area folder the checked resources * @param folderId * @param userName * @param bean * @return */ public static List copyResourcesToUserCatalogueArea(String folderId, String userName, DatasetMetadataBean bean) throws Exception{ logger.debug("Request to copy onto catalogue area...."); List resources = new ArrayList(); WorkspaceItem copiedFolder = null; WorkspaceCatalogue userCatalogue = null; List resourcesToAdd = bean.getResources(); // in to the .catalogue area of the user's workspace Workspace ws = HomeLibrary .getHomeManagerFactory() .getHomeManager() .getHome() .getWorkspace(); // Retrieve the catalogue of the user userCatalogue = ws.getCatalogue(); // Create the folder in the catalogue copiedFolder = userCatalogue.addWorkspaceItem(folderId, userCatalogue.getId()); // add to .catalogue root area // change description for the folder copiedFolder.setDescription(bean.getDescription()); // change name of the copied folder to match the title (append the timestamp to avoid ties) ((WorkspaceFolder)copiedFolder).rename(org.gcube.datacatalogue.ckanutillibrary.utils.UtilMethods.fromProductTitleToName(bean.getTitle()) + "_" + System.currentTimeMillis()); // copy only the selected ones for(ResourceElementBean resource : resourcesToAdd){ if (resource.isToBeAdded()) { // ok it is a file, so copy it into the copiedFolder WorkspaceItem copiedFile = userCatalogue.addWorkspaceItem(resource.getOriginalIdInWorkspace(), copiedFolder.getId()); // name and description could have been edited copiedFile.setDescription(resource.getDescription()); resources.add(new ResourceBean( copiedFile.getPublicLink(true), resource.getName(), copiedFile.getDescription(), copiedFile.getId(), userName, null, // to be set ((FolderItem)copiedFile).getMimeType())); // postpone rename operation copiedFile.rename(resource.getName() + "_" + System.currentTimeMillis()); } } // return return resources; } /** * This method receives a folder id within the user's workspace and set the list of resources in the dataset bean to be returned * @param folderId * @param owner * @param bean * @param userName * @throws Exception */ public static void handleWorkspaceResources(String folderId, String userName, DatasetMetadataBean bean) throws Exception { // get workspace Workspace ws = HomeLibrary .getHomeManagerFactory() .getHomeManager() .getHome().getWorkspace(); WorkspaceItem originalFolder = ws.getItem(folderId); // set some info String onlyAlphanumericTitle = originalFolder.getName().replaceAll("[^A-Za-z0-9.-_]", " "); // that is, remove characters different than the ones inside // since it will (likely) be the name of the product bean.setTitle(onlyAlphanumericTitle); bean.setDescription(originalFolder.getDescription()); // Create the folder in the catalogue Map folderItems = Utils.getGcubeItemProperties(originalFolder); bean.setCustomFields(folderItems); // set them into the bean bean.setResources(Arrays.asList(WorkspaceUtils.getTreeFromFolder(folderId, ws))); } /** * Returns a tree object * @param workspaceFolderId * @param ws * @return ResourceElementBean a tree object * @throws Exception */ public static ResourceElementBean getTreeFromFolder(String workspaceFolderId, Workspace ws) throws Exception{ // start tree construction ResourceElementBean rootElem = new ResourceElementBean(); String pathSeparator = ws.getPathSeparator(); try{ WorkspaceItem initialItemWS = ws.getItem(workspaceFolderId); String fullPathBase = initialItemWS.getPath(); fullPathBase = fullPathBase.endsWith(ws.getPathSeparator()) ? fullPathBase : fullPathBase + ws.getPathSeparator(); rootElem.setFolder(initialItemWS.isFolder()); rootElem.setFullPath(initialItemWS.getPath().replace(fullPathBase, "")); rootElem.setParent(null); rootElem.setName(initialItemWS.getName()); rootElem.setOriginalIdInWorkspace(initialItemWS.getId()); replaceFullPath(rootElem, pathSeparator); // start visiting visit(rootElem, initialItemWS, fullPathBase, pathSeparator); }catch(Exception e){ logger.error("Failed to build the resource tree", e); return null; } return rootElem; } /** * Replaces the "/" char with a custom one * @param rootElem * @param pathSeparatorInWs */ private static void replaceFullPath(ResourceElementBean rootElem, String pathSeparatorInWs) { if(rootElem == null) return; String elemName = rootElem.getName(); int lastIndex = rootElem.getFullPath().lastIndexOf(elemName); String fullPath = rootElem.getFullPath().substring(0, lastIndex); fullPath = fullPath.replaceAll(pathSeparatorInWs, RESOURCES_NAME_SEPARATOR) + elemName; rootElem.setFullPath(fullPath); } /** * Recursive visit of a workspace item * @param rootElem * @param initialItemWS * @throws InternalErrorException */ private static void visit(ResourceElementBean rootElem, WorkspaceItem initialItemWS, String fullPathBase, String pathSeparator) throws InternalErrorException { List children = initialItemWS.getChildren(); ArrayList childrenInTree = new ArrayList(children.size()); for (WorkspaceItem workspaceItem : children) { ResourceElementBean elem = new ResourceElementBean(); elem.setFolder(workspaceItem.isFolder()); elem.setOriginalIdInWorkspace(workspaceItem.getId()); elem.setFullPath(workspaceItem.getPath().replace(fullPathBase, "")); elem.setParent(rootElem); elem.setName(workspaceItem.getName()); replaceFullPath(elem, pathSeparator); childrenInTree.add(elem); visit(elem, workspaceItem, fullPathBase, pathSeparator); } rootElem.setChildren(childrenInTree); } }