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
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-01-25 18:29:47 +01:00
import org.gcube.datacatalogue.ckanutillibrary.server.models.ResourceBean ;
import org.gcube.datacatalogue.ckanutillibrary.server.utils.UtilMethods ;
2016-10-07 10:44:31 +02:00
import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetMetadataBean ;
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-11-11 19:31:05 +01:00
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 = " _ " ;
2016-10-07 10:44:31 +02:00
/ * *
2017-02-22 17:40:16 +01:00
* Copy into the . catalogue area folder the checked resources .
* There is no difference among a single - file - publish and a folder - publish .
2016-10-07 10:44:31 +02:00
* @param folderId
* @param userName
* @param bean
* @return
* /
2017-02-22 17:40:16 +01:00
public static List < ResourceBean > copyResourcesToUserCatalogueArea ( String folderOrFileId , String userName , DatasetMetadataBean bean ) throws Exception {
2016-10-07 10:44:31 +02:00
logger . debug ( " Request to copy onto catalogue area.... " ) ;
List < ResourceBean > resources = new ArrayList < ResourceBean > ( ) ;
WorkspaceItem copiedFolder = null ;
WorkspaceCatalogue userCatalogue = null ;
2017-02-22 17:40:16 +01:00
ResourceElementBean rootResource = bean . getResourceRoot ( ) ;
2016-10-07 10:44:31 +02:00
2017-02-22 17:40:16 +01:00
// into the .catalogue area of the user's workspace
2016-10-07 10:44:31 +02:00
Workspace ws = HomeLibrary
. getHomeManagerFactory ( )
. getHomeManager ( )
2016-11-09 19:13:39 +01:00
. getHome ( )
2016-10-07 10:44:31 +02:00
. getWorkspace ( ) ;
// Retrieve the catalogue of the user
userCatalogue = ws . getCatalogue ( ) ;
2017-02-22 17:40:16 +01:00
// get workspace item (it could be a file or a folder)
WorkspaceItem originalItem = ws . getItem ( folderOrFileId ) ;
2016-10-07 10:44:31 +02:00
2017-02-22 17:40:16 +01:00
// 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 ( ) ) ;
}
else {
copiedFolder = userCatalogue . createFolder ( UtilMethods . fromProductTitleToName ( bean . getTitle ( ) ) + " _ " + referenceTime , bean . getDescription ( ) ) ;
}
2016-10-07 10:44:31 +02:00
// change name of the copied folder to match the title (append the timestamp to avoid ties)
2017-01-25 18:29:47 +01:00
( ( WorkspaceFolder ) copiedFolder ) . rename ( UtilMethods . fromProductTitleToName ( bean . getTitle ( ) ) + " _ " + referenceTime ) ;
2016-10-07 10:44:31 +02:00
2017-02-22 17:40:16 +01:00
// retrieve the children
List < ResourceElementBean > resourcesToAdd = rootResource . getChildren ( ) ;
2016-10-07 10:44:31 +02:00
// copy only the selected ones
2016-11-11 19:31:05 +01:00
for ( ResourceElementBean resource : resourcesToAdd ) {
2016-10-07 10:44:31 +02:00
2016-11-11 19:31:05 +01:00
if ( resource . isToBeAdded ( ) ) {
2016-10-07 10:44:31 +02:00
2016-11-13 22:38:27 +01:00
logger . debug ( " Resource to add is " + resource ) ;
2016-10-07 10:44:31 +02:00
// ok it is a file, so copy it into the copiedFolder
2016-11-11 19:31:05 +01:00
WorkspaceItem copiedFile = userCatalogue . addWorkspaceItem ( resource . getOriginalIdInWorkspace ( ) , copiedFolder . getId ( ) ) ;
2016-10-07 10:44:31 +02:00
// name and description could have been edited
2016-11-11 19:31:05 +01:00
copiedFile . setDescription ( resource . getDescription ( ) ) ;
2016-10-07 10:44:31 +02:00
resources . add ( new ResourceBean (
copiedFile . getPublicLink ( true ) ,
2016-11-11 19:31:05 +01:00
resource . getName ( ) ,
2016-10-07 10:44:31 +02:00
copiedFile . getDescription ( ) ,
copiedFile . getId ( ) ,
userName ,
2016-11-13 22:38:27 +01:00
null , // dataset id, to be set
2016-10-07 10:44:31 +02:00
( ( FolderItem ) copiedFile ) . getMimeType ( ) ) ) ;
// postpone rename operation
2016-11-13 22:38:27 +01:00
copiedFile . rename ( resource . getName ( ) + " _ " + referenceTime ) ;
2016-10-07 10:44:31 +02:00
}
2017-02-22 17:40:16 +01:00
2016-10-07 10:44:31 +02:00
}
return resources ;
}
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 ,
DatasetMetadataBean bean ) throws Exception {
// 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 ) ;
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 ) ;
bean . setTitle ( originalFolderOrFile . getName ( ) . replaceAll ( " [^A-Za-z0-9.-_] " , " " ) ) ;
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-02-22 17:40:16 +01:00
String onlyAlphanumericTitle = originalFolderOrFile . getName ( ) . replaceAll ( " [^A-Za-z0-9.-_] " , " " ) ; // that is, remove characters different than the ones inside
bean . setTitle ( onlyAlphanumericTitle ) ;
bean . setDescription ( originalFolderOrFile . getDescription ( ) ) ;
// Create the folder in the catalogue
Map < String , String > folderItems = Utils . getGcubeItemProperties ( originalFolderOrFile ) ;
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
}
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 {
ResourceElementBean rootElem = new ResourceElementBean ( ) ;
2016-11-11 19:31:05 +01:00
String pathSeparator = ws . getPathSeparator ( ) ;
2016-11-09 19:13:39 +01:00
try {
2016-11-13 22:38:27 +01:00
WorkspaceItem initialItem = ws . getItem ( workspaceFolderId ) ;
String fullPathBase = initialItem . getPath ( ) ;
2016-11-11 19:31:05 +01:00
fullPathBase = fullPathBase . endsWith ( ws . getPathSeparator ( ) ) ? fullPathBase : fullPathBase + ws . getPathSeparator ( ) ;
2016-11-13 22:38:27 +01:00
rootElem . setFolder ( initialItem . isFolder ( ) ) ;
rootElem . setFullPath ( initialItem . getPath ( ) . replace ( fullPathBase , " " ) ) ;
2016-11-11 19:31:05 +01:00
rootElem . setParent ( null ) ;
2016-11-13 22:38:27 +01:00
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 ) ;
2016-11-09 19:13:39 +01:00
} catch ( Exception e ) {
logger . error ( " Failed to build the resource tree " , e ) ;
return null ;
2016-10-07 12:49:37 +02:00
}
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 ) {
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 ) ;
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 ( ) ;
int lastIndex = rootElem . getFullPath ( ) . lastIndexOf ( elemName ) ;
String fullPath = rootElem . getFullPath ( ) . substring ( 0 , lastIndex ) ;
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-02-22 17:40:16 +01:00
}