package org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.servlet.http.HttpServletRequest; import org.gcube.common.portal.PortalContext; import org.gcube.common.storagehubwrapper.server.StorageHubWrapper; import org.gcube.common.storagehubwrapper.server.tohl.Workspace; import org.gcube.common.storagehubwrapper.shared.tohl.WorkspaceItem; import org.gcube.common.storagehubwrapper.shared.tohl.impl.URLFile; import org.gcube.common.storagehubwrapper.shared.tohl.items.FileItem; import org.gcube.common.storagehubwrapper.shared.tohl.items.GCubeItem; import org.gcube.common.storagehubwrapper.shared.tohl.items.PropertyMap; import org.gcube.datacatalogue.utillibrary.shared.ResourceBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceElementBean; import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.liferay.portal.service.UserLocalServiceUtil; /** * The Class WorkspaceUtils. * * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) * * Feb 18, 2021 */ public class WorkspaceUtils { //private static final org.slf4j.Logger logger = LoggerFactory.getLogger(WorkspaceUtils.class); private static final Logger logger = LoggerFactory.getLogger(WorkspaceUtils.class); private static final String RESOURCES_NAME_SEPARATOR = "_"; private static final String STRIP_NOT_ALPHANUMERIC = "[^A-Za-z0-9.-_]"; /** * Checks if is within portal. * * @return true if you're running into the portal, false if in development */ public static boolean isWithinPortal() { try { UserLocalServiceUtil.getService(); return true; } catch (Exception ex) { logger.trace("Development Mode ON"); return false; } } /** * Gets the storage hub wrapper. * * @param request * the request * @param scopeGroupId * the scope group id. If scopeGroupId is null the scope is read * by using the request else by using the scopeGroupId * @param user * the user * @return the storage hub wrapper * @throws Exception * the exception */ public static StorageHubWrapper getStorageHubWrapper(final HttpServletRequest request, String scopeGroupId, GCubeUser user) throws Exception { if (user == null || user.getUsername().isEmpty()) throw new Exception("Session expired"); try { String scope; PortalContext pContext = PortalContext.getConfiguration(); if (isWithinPortal() && scopeGroupId != null) { scope = pContext.getCurrentScope(scopeGroupId); logger.debug(scope + " has retrieved by using the scopeGroupId=" + scopeGroupId); } else scope = pContext.getCurrentScope(request); logger.debug("Getting " + StorageHubWrapper.class.getSimpleName() + " for user: " + user.getUsername() + " by using the scope: " + scope); String token = pContext.getCurrentUserToken(scope, user.getUsername()); return new StorageHubWrapper(scope, token, false, false, true); } catch (Exception e) { logger.error("Error during getting storageHub wrapper", e); throw new Exception("Error on gettig the StorageHub wrapper for userId: " + user); } } /** * This method receives an item-id within the user's workspace and setit in the dataset bean to be returned. * revisited by Francesco * * @param wsItemId the ws item id * @param userName the user name * @param bean the bean * @param workspace the workspace * @throws Exception the exception */ public static void toWorkspaceResource(String wsItemId, String userName, DatasetBean bean, Workspace workspace) throws Exception { WorkspaceItem originalFolderOrFile = workspace.getItem(wsItemId); logger.debug("Item retrieved is " + originalFolderOrFile); String title = originalFolderOrFile.getTitle() != null && !originalFolderOrFile.getTitle().isEmpty() ? originalFolderOrFile.getTitle() : originalFolderOrFile.getName(); title = title.replaceAll(STRIP_NOT_ALPHANUMERIC, " "); bean.setTitle(title); ResourceElementBean resourceEB = new ResourceElementBean(); resourceEB.setOriginalIdInWorkspace(wsItemId); resourceEB.setName(originalFolderOrFile.getName()); resourceEB.setDescription(originalFolderOrFile.getDescription()); resourceEB.setFolder(originalFolderOrFile.isFolder()); resourceEB.setEditableName(originalFolderOrFile.getName()); resourceEB.setRootIdInWorkspace(workspace.getRoot().getId()); //in case of folder if(originalFolderOrFile.isFolder()) { // loading gcube properties Map folderItems = getGcubeItemProperties(originalFolderOrFile); if(folderItems != null && folderItems.size()>0){ // transform this properties Map> tempItems = new HashMap>(folderItems.size()); Iterator> iterator = folderItems.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = (Map.Entry) iterator.next(); tempItems.put(entry.getKey(), Arrays.asList(entry.getValue())); } //setting properties as custom fields bean.setCustomFields(tempItems); } resourceEB.setChildrenSize(workspace.getChildren(originalFolderOrFile.getId()).size()); }else { //it is a file, removing extension int indexOfDot = title.lastIndexOf("."); if(indexOfDot>0) { String suffix = title.substring(indexOfDot, title.length()); if(suffix.length()>=1 && suffix.length()<=4) { //I'm considering last .suffix as an file extension so removing it. title = title.substring(0,indexOfDot); bean.setTitle(title); } } } //Replacing /Home/user.name with "" String fullPathBase = originalFolderOrFile.getPath(); logger.debug("Path is: "+fullPathBase); String prefixNodeWorkspace = String.format("/%s/%s", "Home",userName); logger.debug("Searching: "+prefixNodeWorkspace); if(fullPathBase.startsWith(prefixNodeWorkspace)){ logger.info("Removing from path the prefix: "+prefixNodeWorkspace); fullPathBase = fullPathBase.replaceFirst(prefixNodeWorkspace, ""); } resourceEB.setFullPath(fullPathBase); //setting parent id ResourceElementBean theParent = new ResourceElementBean(); if(originalFolderOrFile.getParentId()!=null) { try { WorkspaceItem parentItem = workspace.getItem(originalFolderOrFile.getParentId()); theParent.setOriginalIdInWorkspace(parentItem.getId()); theParent.setName(parentItem.getName()); }catch (Exception e) { logger.warn("Error on loading the parent item with id: "+originalFolderOrFile.getParentId()+" skipping it"); } } resourceEB.setParent(theParent); bean.setResourceRoot(resourceEB); } /** Gets the gcube item properties. * * @param item the item * @return the gcube item properties */ public static Map getGcubeItemProperties(WorkspaceItem item) { if(item instanceof GCubeItem){ GCubeItem gItem = (GCubeItem) item; try { Map properties = null; if(gItem.getPropertyMap()!=null){ Map map = toSimpleMap(gItem.getPropertyMap()); if(map!=null) { properties = new HashMap(map.size()); //TO PREVENT GWT SERIALIZATION ERROR for (String key : map.keySet()) properties.put(key, map.get(key)); } return properties; } } catch (Exception e) { logger.error("Error in server getItemProperties: ", e); } } return null; } /** * To simple map. * * @param propertyMap the property map * @return the map */ public static Map toSimpleMap(PropertyMap propertyMap) { if (propertyMap == null) return null; try { Map properties = null; Map map = propertyMap.getValues(); if (map != null) { properties = new HashMap(map.size()); for (String key : map.keySet()) { Object theValue = map.get(key); properties.put(key, (String) theValue); } } if(properties!=null) logger.error("Converted: "+properties.size()+" property/properties"); return properties; } catch (Exception e) { logger.error("Error on converting a PropertyMap to simple Map: ", e); return null; } } /** * Copy into the .catalogue area folder the checked resources. * There is no difference among a single-file-publish and a folder-publish. * * @param bean the bean * @param workspace the workspace * @param username the username * @return the list * @throws Exception the exception */ public static List toResources(DatasetBean bean, Workspace workspace, String username) throws Exception{ logger.debug("Called to Resources...: "); List resources = new ArrayList(); ResourceElementBean rootResource = bean.getResourceRoot(); if(rootResource==null) { logger.info("No resource root, returning empty list of resources"); return resources; } // retrieve the children List resourcesToAdd = rootResource.getToPublish(); if(resourcesToAdd==null) { logger.info("No resource to add, returning empty list of resources"); return resources; } // copy only the selected ones for(ResourceElementBean resource : resourcesToAdd){ if (resource.isToBeAdded()) { logger.debug("Resource to add is " + resource); // ok it is a file, so copy it into the copiedFolder WorkspaceItem wsItem = workspace.getItem(resource.getOriginalIdInWorkspace()); String mimeType = null; if(wsItem instanceof FileItem) { mimeType = ((FileItem)wsItem).getMimeType(); } // check if it is an URLFile String externalUrl = null; try{ if(wsItem instanceof URLFile) { URLFile urlFile = (URLFile) wsItem; externalUrl = urlFile.getValue()!=null?urlFile.getValue().toString():null; } }catch(Exception e){ logger.warn("Unable to check if it is an external url file ", e); } String resourceURL = externalUrl; //it is not a URLFile if(resourceURL==null) { //getting public link of file URL publicLink = workspace.getPublicLinkForFile(resource.getOriginalIdInWorkspace()); if(publicLink!=null) resourceURL = publicLink.toString(); } resources.add(new ResourceBean(resourceURL, resource.getEditableName(), resource.getDescription(), wsItem.getId(), username, null, // dataset id, to be set mimeType)); } } return resources; } }