2016-10-07 10:44:31 +02:00
|
|
|
package org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
2016-11-11 19:31:05 +01:00
|
|
|
import java.util.Arrays;
|
2016-12-07 10:58:11 +01:00
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.Iterator;
|
2016-10-07 10:44:31 +02:00
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
2016-12-07 10:58:11 +01:00
|
|
|
import java.util.Map.Entry;
|
2016-10-07 10:44:31 +02:00
|
|
|
|
2017-06-27 17:57:07 +02:00
|
|
|
import org.gcube.common.homelibary.model.items.type.FolderItemType;
|
2016-10-07 10:44:31 +02:00
|
|
|
import org.gcube.common.homelibrary.home.HomeLibrary;
|
2016-11-09 19:13:39 +01:00
|
|
|
import org.gcube.common.homelibrary.home.exceptions.InternalErrorException;
|
2016-10-07 10:44:31 +02:00
|
|
|
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;
|
2017-06-27 17:57:07 +02:00
|
|
|
import org.gcube.common.homelibrary.home.workspace.folder.items.ExternalUrl;
|
2017-02-28 12:36:29 +01:00
|
|
|
import org.gcube.common.homelibrary.home.workspace.folder.items.GCubeItem;
|
2018-02-23 15:23:33 +01:00
|
|
|
import org.gcube.datacatalogue.ckanutillibrary.server.utils.CatalogueUtilMethods;
|
2017-03-08 16:36:06 +01:00
|
|
|
import org.gcube.datacatalogue.ckanutillibrary.shared.ResourceBean;
|
2017-04-25 15:41:27 +02:00
|
|
|
import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetBean;
|
2016-11-09 19:13:39 +01:00
|
|
|
import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceElementBean;
|
2016-12-26 23:15:29 +01:00
|
|
|
|
|
|
|
import com.liferay.portal.kernel.log.Log;
|
|
|
|
import com.liferay.portal.kernel.log.LogFactoryUtil;
|
2016-10-07 10:44:31 +02:00
|
|
|
|
|
|
|
public class WorkspaceUtils {
|
|
|
|
|
2016-12-26 23:15:29 +01:00
|
|
|
//private static final org.slf4j.Logger logger = LoggerFactory.getLogger(WorkspaceUtils.class);
|
|
|
|
private static final Log logger = LogFactoryUtil.getLog(WorkspaceUtils.class);
|
2016-11-11 19:31:05 +01:00
|
|
|
private static final String RESOURCES_NAME_SEPARATOR = "_";
|
2017-05-15 12:59:17 +02:00
|
|
|
private static final String STRIP_NOT_ALPHANUMERIC = "[^A-Za-z0-9.-_]";
|
2016-10-07 12:49:37 +02:00
|
|
|
|
2016-10-07 10:44:31 +02:00
|
|
|
/**
|
|
|
|
* 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,
|
2017-04-25 15:41:27 +02:00
|
|
|
DatasetBean bean) throws Exception {
|
2016-10-07 10:44:31 +02:00
|
|
|
|
|
|
|
// get workspace
|
|
|
|
Workspace ws = HomeLibrary
|
|
|
|
.getHomeManagerFactory()
|
|
|
|
.getHomeManager()
|
2016-11-08 15:17:41 +01:00
|
|
|
.getHome().getWorkspace();
|
2016-10-07 10:44:31 +02:00
|
|
|
|
2017-02-22 17:40:16 +01:00
|
|
|
WorkspaceItem originalFolderOrFile = ws.getItem(folderId);
|
2017-05-15 12:59:17 +02:00
|
|
|
|
2017-02-23 16:25:12 +01:00
|
|
|
logger.debug("Item retrieved is " + originalFolderOrFile);
|
2016-10-07 10:44:31 +02:00
|
|
|
|
2017-02-22 17:40:16 +01:00
|
|
|
if(!originalFolderOrFile.isFolder()){
|
2016-10-07 10:44:31 +02:00
|
|
|
|
2017-02-22 17:40:16 +01:00
|
|
|
ResourceElementBean resource = new ResourceElementBean();
|
|
|
|
resource.setDescription(originalFolderOrFile.getDescription());
|
|
|
|
resource.setFolder(false);
|
|
|
|
resource.setEditableName(originalFolderOrFile.getName());
|
|
|
|
resource.setName(originalFolderOrFile.getName());
|
|
|
|
resource.setOriginalIdInWorkspace(folderId);
|
|
|
|
bean.setResourceRoot(resource);
|
2017-05-15 12:59:17 +02:00
|
|
|
bean.setTitle(originalFolderOrFile.getName().replaceAll(STRIP_NOT_ALPHANUMERIC, " "));
|
2017-02-22 17:40:16 +01:00
|
|
|
bean.setDescription(originalFolderOrFile.getDescription());
|
2016-12-07 10:58:11 +01:00
|
|
|
|
2017-02-22 17:40:16 +01:00
|
|
|
}else{
|
2016-12-07 10:58:11 +01:00
|
|
|
|
2017-05-15 12:59:17 +02:00
|
|
|
String onlyAlphanumericTitle = originalFolderOrFile.getName().replaceAll(STRIP_NOT_ALPHANUMERIC, " ");
|
2017-02-22 17:40:16 +01:00
|
|
|
bean.setTitle(onlyAlphanumericTitle);
|
|
|
|
bean.setDescription(originalFolderOrFile.getDescription());
|
|
|
|
|
|
|
|
// Create the folder in the catalogue
|
2017-02-28 12:36:29 +01:00
|
|
|
Map<String, String> folderItems = getGcubeItemProperties(originalFolderOrFile);
|
2017-02-22 17:40:16 +01:00
|
|
|
|
|
|
|
if(folderItems != null){
|
|
|
|
// 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()));
|
|
|
|
}
|
|
|
|
bean.setCustomFields(tempItems);
|
2016-12-07 10:58:11 +01:00
|
|
|
}
|
2016-10-07 10:44:31 +02:00
|
|
|
|
2017-02-22 17:40:16 +01:00
|
|
|
// set them into the bean
|
|
|
|
bean.setResourceRoot(WorkspaceUtils.getTreeFromFolder(folderId, ws));
|
|
|
|
}
|
2016-10-07 10:44:31 +02:00
|
|
|
|
|
|
|
}
|
2017-05-15 12:59:17 +02:00
|
|
|
|
2017-02-28 12:36:29 +01:00
|
|
|
/** 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 {
|
|
|
|
if(gItem.getProperties()!=null){
|
|
|
|
Map<String, String> map = gItem.getProperties().getProperties();
|
|
|
|
HashMap<String, String> 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 (InternalErrorException e) {
|
|
|
|
logger.error("Error in server getItemProperties: ", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
2016-10-07 12:49:37 +02:00
|
|
|
|
2016-10-07 12:21:04 +02:00
|
|
|
/**
|
2016-11-09 19:13:39 +01:00
|
|
|
* Returns a tree object
|
|
|
|
* @param workspaceFolderId
|
2016-10-07 12:21:04 +02:00
|
|
|
* @param ws
|
2016-11-09 19:13:39 +01:00
|
|
|
* @return ResourceElementBean a tree object
|
|
|
|
* @throws Exception
|
2016-10-07 12:21:04 +02:00
|
|
|
*/
|
2016-11-09 19:13:39 +01:00
|
|
|
public static ResourceElementBean getTreeFromFolder(String workspaceFolderId, Workspace ws) throws Exception{
|
2017-05-15 12:59:17 +02:00
|
|
|
|
2016-11-09 19:13:39 +01:00
|
|
|
ResourceElementBean rootElem = new ResourceElementBean();
|
2016-11-11 19:31:05 +01:00
|
|
|
String pathSeparator = ws.getPathSeparator();
|
2017-05-15 12:59:17 +02:00
|
|
|
WorkspaceItem initialItem = ws.getItem(workspaceFolderId);
|
|
|
|
String fullPathBase = initialItem.getPath();
|
|
|
|
fullPathBase = fullPathBase.endsWith(ws.getPathSeparator()) ? fullPathBase : fullPathBase + ws.getPathSeparator();
|
|
|
|
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, fullPathBase, pathSeparator);
|
|
|
|
|
2017-02-23 16:25:12 +01:00
|
|
|
logger.debug("Tree that is going to be returned is " + rootElem);
|
2016-11-11 19:31:05 +01:00
|
|
|
return rootElem;
|
|
|
|
}
|
|
|
|
|
2016-11-09 19:13:39 +01:00
|
|
|
/**
|
|
|
|
* Recursive visit of a workspace item
|
|
|
|
* @param rootElem
|
|
|
|
* @param initialItemWS
|
|
|
|
* @throws InternalErrorException
|
|
|
|
*/
|
2016-11-13 22:38:27 +01:00
|
|
|
private static void visit(ResourceElementBean parent, WorkspaceItem initialItemWS, String fullPathBase, String pathSeparator) throws InternalErrorException {
|
2016-11-09 19:13:39 +01:00
|
|
|
List<? extends WorkspaceItem> children = initialItemWS.getChildren();
|
|
|
|
ArrayList<ResourceElementBean> childrenInTree = new ArrayList<ResourceElementBean>(children.size());
|
2016-11-13 22:38:27 +01:00
|
|
|
for (WorkspaceItem item : children) {
|
2017-05-15 12:59:17 +02:00
|
|
|
// 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());
|
2016-11-09 19:13:39 +01:00
|
|
|
ResourceElementBean elem = new ResourceElementBean();
|
2016-11-13 22:38:27 +01:00
|
|
|
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);
|
2016-11-09 19:13:39 +01:00
|
|
|
childrenInTree.add(elem);
|
2017-02-23 16:25:12 +01:00
|
|
|
logger.trace("Elem is " + elem);
|
2016-11-13 22:38:27 +01:00
|
|
|
if(item.isFolder())
|
|
|
|
visit(elem, item, fullPathBase, pathSeparator);
|
2016-11-09 19:13:39 +01:00
|
|
|
}
|
2016-11-13 22:38:27 +01:00
|
|
|
// add these list as child of the rootElem
|
|
|
|
parent.setChildren(childrenInTree);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2016-11-17 14:08:22 +01:00
|
|
|
* Replaces the "/" char with a custom one and return an editable name for the user
|
2016-11-13 22:38:27 +01:00
|
|
|
* @param rootElem
|
|
|
|
* @param pathSeparatorInWs
|
|
|
|
*/
|
|
|
|
private static void extractEditableNameFromPath(ResourceElementBean rootElem, String pathSeparatorInWs) {
|
|
|
|
|
|
|
|
if(rootElem == null)
|
|
|
|
return;
|
|
|
|
|
|
|
|
String elemName = rootElem.getName();
|
2017-05-15 12:59:17 +02:00
|
|
|
String fullPath = rootElem.getFullPath();
|
|
|
|
logger.info("Element original is " + rootElem);
|
|
|
|
|
2016-11-13 22:38:27 +01:00
|
|
|
int lastIndex = rootElem.getFullPath().lastIndexOf(elemName);
|
2017-05-15 12:59:17 +02:00
|
|
|
fullPath = rootElem.getFullPath().substring(0, lastIndex);
|
2016-11-13 22:38:27 +01:00
|
|
|
fullPath = fullPath.replaceAll(pathSeparatorInWs, RESOURCES_NAME_SEPARATOR) + elemName;
|
|
|
|
rootElem.setEditableName(fullPath);
|
2016-11-09 19:13:39 +01:00
|
|
|
}
|
2016-10-07 10:44:31 +02:00
|
|
|
|
2017-05-15 12:59:17 +02:00
|
|
|
/**
|
|
|
|
* 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());
|
2018-02-23 15:23:33 +01:00
|
|
|
((WorkspaceFolder)copiedFolder).rename(CatalogueUtilMethods.fromProductTitleToName(bean.getTitle()) + "_" + referenceTime);
|
2017-05-15 12:59:17 +02:00
|
|
|
}
|
|
|
|
else{
|
2018-02-23 15:23:33 +01:00
|
|
|
copiedFolder = userCatalogue.createFolder(CatalogueUtilMethods.fromProductTitleToName(bean.getTitle()) + "_" + referenceTime, bean.getDescription());
|
2017-05-15 12:59:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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());
|
|
|
|
|
2017-06-27 17:57:07 +02:00
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
|
2017-05-15 12:59:17 +02:00
|
|
|
resources.add(new ResourceBean(
|
2017-06-27 17:57:07 +02:00
|
|
|
externalUrl != null ? externalUrl : copiedFile.getPublicLink(true),
|
|
|
|
resource.getEditableName(),
|
|
|
|
copiedFile.getDescription(),
|
|
|
|
copiedFile.getId(),
|
|
|
|
userName,
|
|
|
|
null, // dataset id, to be set
|
|
|
|
((FolderItem)copiedFile).getMimeType()));
|
2017-05-15 12:59:17 +02:00
|
|
|
|
|
|
|
// postpone rename operation
|
2017-05-24 16:23:32 +02:00
|
|
|
copiedFile.rename(resource.getEditableName());
|
2017-05-15 12:59:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
return resources;
|
|
|
|
}
|
|
|
|
|
2017-02-22 17:40:16 +01:00
|
|
|
}
|