513 lines
18 KiB
Java
513 lines
18 KiB
Java
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<String, String> folderItems = getGcubeItemProperties(originalFolderOrFile);
|
|
|
|
if(folderItems != null && folderItems.size()>0){
|
|
// transform this properties
|
|
Map<String, List<String>> tempItems = new HashMap<String, List<String>>(folderItems.size());
|
|
|
|
Iterator<Entry<String, String>> iterator = folderItems.entrySet().iterator();
|
|
while (iterator.hasNext()) {
|
|
Map.Entry<java.lang.String, java.lang.String> entry = (Map.Entry<java.lang.String, java.lang.String>) 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<String, String> getGcubeItemProperties(WorkspaceItem item) {
|
|
|
|
if(item instanceof GCubeItem){
|
|
GCubeItem gItem = (GCubeItem) item;
|
|
try {
|
|
Map<String, String> properties = null;
|
|
if(gItem.getPropertyMap()!=null){
|
|
Map<String, String> map = toSimpleMap(gItem.getPropertyMap());
|
|
if(map!=null) {
|
|
properties = new HashMap<String, String>(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<String, String> toSimpleMap(PropertyMap propertyMap) {
|
|
|
|
if (propertyMap == null)
|
|
return null;
|
|
|
|
try {
|
|
Map<String, String> properties = null;
|
|
Map<String, Object> map = propertyMap.getValues();
|
|
|
|
if (map != null) {
|
|
properties = new HashMap<String, String>(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<String,String>: ", e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
// /**
|
|
// * Returns ResourceElementBean corresponding to workspaceFolderId
|
|
// *
|
|
// * @param workspaceFolderId the workspace folder id
|
|
// * @param workspace the workspace
|
|
// * @return ResourceElementBean a tree object
|
|
// * @throws Exception the exception
|
|
// */
|
|
// public static ResourceElementBean toResourceEBFromFolder(String workspaceFolderId, Workspace workspace) throws Exception{
|
|
//
|
|
// ResourceElementBean rootElem = new ResourceElementBean();
|
|
// String pathSeparator = "/";
|
|
//
|
|
// //String pathSeparator = ws.getPathSeparator();
|
|
//
|
|
// WorkspaceItem initialItem = workspace.getItem(workspaceFolderId);
|
|
// String fullPathBase = initialItem.getPath();
|
|
// fullPathBase = fullPathBase.endsWith(pathSeparator) ? fullPathBase : fullPathBase + pathSeparator;
|
|
// rootElem.setFolder(initialItem.isFolder());
|
|
// rootElem.setFullPath(initialItem.getPath().replace(fullPathBase, ""));
|
|
// rootElem.setName(initialItem.getName());
|
|
// rootElem.setOriginalIdInWorkspace(initialItem.getId());
|
|
// rootElem.setDescription(initialItem.getDescription());
|
|
// extractEditableNameFromPath(rootElem, pathSeparator);
|
|
//
|
|
// // recursive visiting
|
|
//// if(initialItem.isFolder())
|
|
//// visit(rootElem, initialItem, workspace, fullPathBase, pathSeparator);
|
|
//
|
|
// logger.debug("Tree that is going to be returned is " + rootElem);
|
|
// return rootElem;
|
|
// }
|
|
|
|
// /**
|
|
// * Recursive visit of a workspace item.
|
|
// *
|
|
// * @param parent the parent
|
|
// * @param initialItemWS the initial item WS
|
|
// * @param workspace the ws
|
|
// * @param fullPathBase the full path base
|
|
// * @param pathSeparator the path separator
|
|
// * @throws Exception the exception
|
|
// */
|
|
// private static void visit(ResourceElementBean parent, WorkspaceItem initialItemWS, Workspace workspace, String fullPathBase, String pathSeparator) throws Exception {
|
|
// //List<? extends WorkspaceItem> children = initialItemWS.getChildren();
|
|
//
|
|
// List<? extends WorkspaceItem> children = workspace.getChildren(initialItemWS.getId());
|
|
//
|
|
// ArrayList<ResourceElementBean> childrenInTree = new ArrayList<ResourceElementBean>(children.size());
|
|
// for (WorkspaceItem item : children) {
|
|
// // logger.debug("Path BEFORE REPLACE is " + item.getPath());
|
|
// // logger.debug("Path AFTER REPLACE is " + item.getPath().replace(fullPathBase, ""));
|
|
// // logger.debug("Name is " + item.getName());
|
|
// // logger.debug("id is " + item.getId());
|
|
// ResourceElementBean elem = new ResourceElementBean();
|
|
// elem.setFolder(item.isFolder());
|
|
// elem.setOriginalIdInWorkspace(item.getId());
|
|
// elem.setFullPath(item.getPath().replace(fullPathBase, ""));
|
|
// elem.setParent(parent);
|
|
// elem.setName(item.getName());
|
|
// elem.setDescription(item.getDescription());
|
|
// extractEditableNameFromPath(elem, pathSeparator);
|
|
// childrenInTree.add(elem);
|
|
// logger.trace("Elem is " + elem);
|
|
// if(item.isFolder())
|
|
// visit(elem, item, workspace, fullPathBase, pathSeparator);
|
|
// }
|
|
// // add these list as child of the rootElem
|
|
// parent.setChildren(childrenInTree);
|
|
// }
|
|
|
|
// /**
|
|
// * Replaces the "/" char with a custom one and return an editable name for the user.
|
|
// *
|
|
// * @param rootElem the root elem
|
|
// * @param pathSeparatorInWs the path separator in ws
|
|
// */
|
|
// public static void extractEditableNameFromPath(ResourceElementBean rootElem, String pathSeparatorInWs) {
|
|
//
|
|
// if(rootElem == null)
|
|
// return;
|
|
//
|
|
// String elemName = rootElem.getName();
|
|
// String fullPath = rootElem.getFullPath();
|
|
// logger.info("Element original is " + rootElem);
|
|
//
|
|
// int lastIndex = rootElem.getFullPath().lastIndexOf(elemName);
|
|
// fullPath = rootElem.getFullPath().substring(0, lastIndex);
|
|
// fullPath = fullPath.replaceAll(pathSeparatorInWs, RESOURCES_NAME_SEPARATOR) + elemName;
|
|
// rootElem.setEditableName(fullPath);
|
|
// logger.info("Editable name for resource name: "+rootElem.getName()+", is: " + rootElem.getEditableName());
|
|
// }
|
|
|
|
|
|
/**
|
|
* 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<ResourceBean> toResources(DatasetBean bean, Workspace workspace, String username) throws Exception{
|
|
logger.debug("Called to Resources...: ");
|
|
|
|
List<ResourceBean> resources = new ArrayList<ResourceBean>();
|
|
ResourceElementBean rootResource = bean.getResourceRoot();
|
|
|
|
if(rootResource==null) {
|
|
logger.info("No resource root, returning empty list of resources");
|
|
return resources;
|
|
}
|
|
|
|
// retrieve the children
|
|
List<ResourceElementBean> 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;
|
|
}
|
|
|
|
// //MOVED TO GCAT
|
|
// /**
|
|
// * Copy into the .catalogue area folder the checked resources.
|
|
// * There is no difference among a single-file-publish and a folder-publish.
|
|
// * @param folderId
|
|
// * @param userName
|
|
// * @param bean
|
|
// * @return
|
|
// */
|
|
// public static List<ResourceBean> copyResourcesToUserCatalogueArea(String folderOrFileId, String userName, DatasetBean bean) throws Exception{
|
|
//
|
|
// logger.debug("Request to copy onto catalogue area....");
|
|
// List<ResourceBean> resources = new ArrayList<ResourceBean>();
|
|
// WorkspaceItem copiedFolder = null;
|
|
// WorkspaceCatalogue userCatalogue = null;
|
|
// ResourceElementBean rootResource = bean.getResourceRoot();
|
|
//
|
|
// // into the .catalogue area of the user's workspace
|
|
// Workspace ws = HomeLibrary
|
|
// .getHomeManagerFactory()
|
|
// .getHomeManager()
|
|
// .getHome()
|
|
// .getWorkspace();
|
|
//
|
|
// // Retrieve the catalogue of the user
|
|
// userCatalogue = ws.getCatalogue();
|
|
//
|
|
// // get workspace item (it could be a file or a folder)
|
|
// WorkspaceItem originalItem = ws.getItem(folderOrFileId);
|
|
//
|
|
// // copy the folder in the catalogue if it is a folder, or create a new folder
|
|
// long referenceTime = System.currentTimeMillis();
|
|
// if(originalItem.isFolder()){
|
|
// copiedFolder = userCatalogue.addWorkspaceItem(folderOrFileId, userCatalogue.getId()); // add to .catalogue root area
|
|
// copiedFolder.setDescription(bean.getDescription());
|
|
// ((WorkspaceFolder)copiedFolder).rename(CatalogueUtilMethods.fromProductTitleToName(bean.getTitle()) + "_" + referenceTime);
|
|
// }
|
|
// else{
|
|
// copiedFolder = userCatalogue.createFolder(CatalogueUtilMethods.fromProductTitleToName(bean.getTitle()) + "_" + referenceTime, bean.getDescription());
|
|
// }
|
|
//
|
|
// // retrieve the children
|
|
// List<ResourceElementBean> resourcesToAdd = rootResource.getChildren();
|
|
//
|
|
// // 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 copiedFile = userCatalogue.addWorkspaceItem(resource.getOriginalIdInWorkspace(), copiedFolder.getId());
|
|
//
|
|
// // name and description could have been edited
|
|
// copiedFile.setDescription(resource.getDescription());
|
|
//
|
|
// // check if it is an external url
|
|
// String externalUrl = null;
|
|
// try{
|
|
// boolean isExternalUrl = ((FolderItem)copiedFile).getFolderItemType().equals(FolderItemType.EXTERNAL_URL);
|
|
// externalUrl = isExternalUrl ? ((ExternalUrl)copiedFile).getUrl() : null;
|
|
// }catch(Exception e){
|
|
// logger.warn("Unable to check if it is an external url file ", e);
|
|
// }
|
|
//
|
|
// resources.add(new ResourceBean(
|
|
// externalUrl != null ? externalUrl : copiedFile.getPublicLink(true),
|
|
// resource.getEditableName(),
|
|
// copiedFile.getDescription(),
|
|
// copiedFile.getId(),
|
|
// userName,
|
|
// null, // dataset id, to be set
|
|
// ((FolderItem)copiedFile).getMimeType()));
|
|
//
|
|
// // postpone rename operation
|
|
// copiedFile.rename(resource.getEditableName());
|
|
// }
|
|
//
|
|
// }
|
|
// return resources;
|
|
// }
|
|
|
|
|
|
} |