2016-05-26 18:12:53 +02:00
package org.gcube.portlets.widgets.ckandatapublisherwidget.server ;
import java.util.ArrayList ;
2016-11-14 18:37:45 +01:00
import java.util.Arrays ;
2016-06-06 17:24:52 +02:00
import java.util.Calendar ;
2017-04-25 15:41:27 +02:00
import java.util.Collections ;
import java.util.Comparator ;
2016-05-26 18:12:53 +02:00
import java.util.List ;
2016-05-27 19:08:03 +02:00
import java.util.Map ;
2017-01-27 11:27:18 +01:00
import java.util.Map.Entry ;
import java.util.Set ;
2016-10-06 14:24:05 +02:00
import java.util.concurrent.ConcurrentHashMap ;
2016-06-08 18:31:54 +02:00
2016-07-04 12:44:20 +02:00
import javax.servlet.http.HttpSession ;
2021-04-09 14:51:55 +02:00
import org.gcube.common.portal.PortalContext ;
import org.gcube.common.storagehubwrapper.server.StorageHubWrapper ;
import org.gcube.common.storagehubwrapper.server.tohl.Workspace ;
import org.gcube.datacatalogue.utillibrary.server.DataCatalogue ;
import org.gcube.datacatalogue.utillibrary.server.DataCatalogueFactory ;
import org.gcube.datacatalogue.utillibrary.server.utils.CatalogueUtilMethods ;
import org.gcube.datacatalogue.utillibrary.server.utils.SessionCatalogueAttributes ;
import org.gcube.datacatalogue.utillibrary.shared.ResourceBean ;
import org.gcube.datacatalogue.utillibrary.shared.RolesCkanGroupOrOrg ;
import org.gcube.datacatalogue.utillibrary.shared.jackan.model.CkanGroup ;
import org.gcube.datacatalogue.utillibrary.shared.jackan.model.CkanLicense ;
2016-05-26 18:12:53 +02:00
import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherService ;
2017-04-25 15:41:27 +02:00
import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.CatalogueRoleManager ;
2017-04-05 18:42:07 +02:00
import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.DiscoverTagsList ;
2017-04-25 15:41:27 +02:00
import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.GenericUtils ;
import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.MetadataDiscovery ;
2016-10-07 10:44:31 +02:00
import org.gcube.portlets.widgets.ckandatapublisherwidget.server.utils.WorkspaceUtils ;
2017-04-25 15:41:27 +02:00
import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetBean ;
2016-07-20 22:41:15 +02:00
import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.OrganizationBean ;
2016-11-09 19:13:39 +01:00
import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceElementBean ;
2017-04-25 15:41:27 +02:00
import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.licenses.LicenseBean ;
import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.metadata.MetaDataProfileBean ;
2017-01-25 18:29:47 +01:00
import org.gcube.vomanagement.usermanagement.GroupManager ;
2016-05-27 19:08:03 +02:00
import org.gcube.vomanagement.usermanagement.UserManager ;
2016-11-25 10:32:50 +01:00
import org.gcube.vomanagement.usermanagement.exception.GroupRetrievalFault ;
import org.gcube.vomanagement.usermanagement.exception.UserManagementSystemException ;
2017-01-25 18:29:47 +01:00
import org.gcube.vomanagement.usermanagement.impl.LiferayGroupManager ;
2016-06-21 14:36:49 +02:00
import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager ;
import org.gcube.vomanagement.usermanagement.model.GCubeUser ;
2017-04-25 15:41:27 +02:00
import org.geojson.GeoJsonObject ;
2021-04-09 14:51:55 +02:00
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
2016-05-26 18:12:53 +02:00
2017-04-25 15:41:27 +02:00
import com.fasterxml.jackson.databind.ObjectMapper ;
2016-05-26 18:12:53 +02:00
import com.google.gwt.user.server.rpc.RemoteServiceServlet ;
import com.liferay.portal.service.UserLocalServiceUtil ;
2021-04-09 14:51:55 +02:00
2016-07-13 16:11:15 +02:00
2016-05-26 18:12:53 +02:00
/ * *
* Server side of the data publisher .
* @author Costantino Perciante at ISTI - CNR ( costantino . perciante @isti.cnr.it )
* /
public class CKANPublisherServicesImpl extends RemoteServiceServlet implements CKanPublisherService {
2016-12-22 23:53:30 +01:00
2016-11-25 10:32:50 +01:00
private static final long serialVersionUID = 7252248774050361697L ;
2016-05-26 18:12:53 +02:00
// Logger
2016-12-26 23:15:29 +01:00
//private static final org.slf4j.Logger logger = LoggerFactory.getLogger(CKANPublisherServicesImpl.class);
2021-04-09 14:51:55 +02:00
private static final Logger logger = LoggerFactory . getLogger ( CKANPublisherServicesImpl . class ) ;
2017-02-15 17:10:22 +01:00
private static final String ITEM_URL_FIELD = " Item URL " ;
2017-04-25 15:41:27 +02:00
private static final String SYS_TYPE = " system:type " ;
2017-04-25 18:11:13 +02:00
private static final String TAGS_VOCABULARY_KEY = " TAGS_VOCABULARY " ;
2016-12-10 11:58:41 +01:00
2016-10-06 14:24:05 +02:00
// map <orgName, scope>
private ConcurrentHashMap < String , String > mapOrganizationScope = new ConcurrentHashMap < String , String > ( ) ;
2021-04-09 14:51:55 +02:00
/ * *
* Dev mode set contexts .
* /
private void devModeSetContexts ( ) {
if ( ! isWithinPortal ( ) ) {
logger . info ( " DETECTED DEV MODE " ) ;
GenericUtils . getCurrentContext ( getThreadLocalRequest ( ) , true ) ;
GenericUtils . getCurrentToken ( getThreadLocalRequest ( ) , true ) ;
}
}
2016-06-27 11:12:15 +02:00
/ * *
2021-04-09 14:51:55 +02:00
* Retrieve an instance of the library for the scope .
*
2016-07-20 19:14:20 +02:00
* @param scope if it is null it is evaluated from the session
2021-04-09 14:51:55 +02:00
* @return the catalogue
2016-06-27 11:12:15 +02:00
* /
2016-09-28 16:41:55 +02:00
public DataCatalogue getCatalogue ( String scope ) {
2016-06-18 10:13:37 +02:00
2016-09-28 16:41:55 +02:00
DataCatalogue instance = null ;
2016-11-08 15:17:41 +01:00
String scopeInWhichDiscover = null ;
2016-07-04 16:24:00 +02:00
try {
2018-09-28 10:26:22 +02:00
scopeInWhichDiscover = scope ! = null & & ! scope . isEmpty ( ) ? scope : GenericUtils . getCurrentContext ( getThreadLocalRequest ( ) , false ) ;
2016-07-20 19:14:20 +02:00
logger . debug ( " Discovering ckan instance into scope " + scopeInWhichDiscover ) ;
2016-09-28 16:41:55 +02:00
instance = DataCatalogueFactory . getFactory ( ) . getUtilsPerScope ( scopeInWhichDiscover ) ;
2016-07-04 16:24:00 +02:00
} catch ( Exception e ) {
2016-11-17 14:08:22 +01:00
logger . warn ( " Unable to retrieve ckan utils in scope " + scopeInWhichDiscover + " . Error is " + e . getLocalizedMessage ( ) ) ;
2016-07-04 16:13:51 +02:00
}
2016-06-27 11:12:15 +02:00
return instance ;
2016-06-16 18:09:54 +02:00
}
2016-05-26 18:12:53 +02:00
2016-06-16 18:09:54 +02:00
/ * *
2021-04-09 14:51:55 +02:00
* Retrieve the list of organizations in which the user can publish ( roles ADMIN / EDITOR ) .
*
* @param username the username
* @param scope the scope
2016-06-16 18:09:54 +02:00
* @return the list of organizations
2021-04-09 14:51:55 +02:00
* @throws UserManagementSystemException the user management system exception
* @throws GroupRetrievalFault the group retrieval fault
2016-06-16 18:09:54 +02:00
* /
2016-11-25 10:32:50 +01:00
private List < OrganizationBean > getUserOrganizationsListAdmin ( String username , String scope ) throws UserManagementSystemException , GroupRetrievalFault {
2016-06-17 22:43:57 +02:00
2016-06-16 18:09:54 +02:00
logger . debug ( " Request for user " + username + " organizations list " ) ;
2016-07-20 22:41:15 +02:00
List < OrganizationBean > orgsName = new ArrayList < OrganizationBean > ( ) ;
2016-07-04 16:13:00 +02:00
2016-07-04 12:44:20 +02:00
HttpSession httpSession = getThreadLocalRequest ( ) . getSession ( ) ;
2018-02-23 15:23:33 +01:00
String keyPerScope = CatalogueUtilMethods . concatenateSessionKeyScope ( SessionCatalogueAttributes . CKAN_ORGANIZATIONS_PUBLISH_KEY , scope ) ;
2016-07-04 16:13:00 +02:00
2016-07-04 12:44:20 +02:00
if ( httpSession . getAttribute ( keyPerScope ) ! = null ) {
2016-07-20 22:41:15 +02:00
orgsName = ( List < OrganizationBean > ) httpSession . getAttribute ( keyPerScope ) ;
2016-07-21 11:26:18 +02:00
logger . info ( " List of organizations was into session " + orgsName ) ;
2016-06-28 11:52:04 +02:00
}
else {
2019-06-12 12:26:30 +02:00
String gatewayURL = GenericUtils . getGatewayClientHostname ( getThreadLocalRequest ( ) ) ;
2019-06-12 12:15:07 +02:00
logger . info ( " The Gateway URL is: " + gatewayURL ) ;
CatalogueRoleManager . getHighestRole ( scope , username , GenericUtils . getGroupFromScope ( scope ) . getGroupName ( ) , this , orgsName , gatewayURL ) ;
2016-07-04 12:44:20 +02:00
httpSession . setAttribute ( keyPerScope , orgsName ) ;
2016-07-20 22:41:15 +02:00
logger . info ( " Organizations name for user " + username + " has been saved into session " + orgsName ) ;
2016-06-17 22:43:57 +02:00
}
2016-06-28 11:52:04 +02:00
2016-06-17 22:43:57 +02:00
return orgsName ;
2016-05-26 18:12:53 +02:00
}
/ * *
2021-04-09 14:51:55 +02:00
* Online or in development mode ? .
*
2016-05-26 18:12:53 +02:00
* @return true if you ' re running into the portal , false if in development
* /
private boolean isWithinPortal ( ) {
try {
UserLocalServiceUtil . getService ( ) ;
return true ;
2018-09-28 10:26:22 +02:00
}
catch ( com . liferay . portal . kernel . bean . BeanLocatorException ex ) {
2016-05-26 18:12:53 +02:00
logger . trace ( " Development Mode ON " ) ;
return false ;
2018-09-28 10:26:22 +02:00
}
2016-05-26 18:12:53 +02:00
}
2021-04-09 14:51:55 +02:00
/ * *
* Gets the workspace from storage hub .
*
* @return the workspace from storage hub
* @throws Exception
* the exception
* /
protected Workspace getWorkspaceFromStorageHub ( ) throws Exception {
GCubeUser user = PortalContext . getConfiguration ( ) . getCurrentUser ( this . getThreadLocalRequest ( ) ) ;
StorageHubWrapper storageHubWrapper = WorkspaceUtils . getStorageHubWrapper ( this . getThreadLocalRequest ( ) , null , user ) ;
return storageHubWrapper . getWorkspace ( ) ;
}
2016-05-26 18:12:53 +02:00
2016-06-06 17:24:52 +02:00
/ * *
* Find a license id given the license text .
2021-04-09 14:51:55 +02:00
*
* @param chosenLicense the chosen license
* @return the string
2016-06-06 17:24:52 +02:00
* /
2018-09-28 10:26:22 +02:00
private String findLicenseIdByLicense ( String chosenLicense ) {
2016-10-06 14:24:05 +02:00
2016-11-25 10:32:50 +01:00
// get scope from client url
2017-04-25 15:41:27 +02:00
String scope = GenericUtils . getScopeFromClientUrl ( getThreadLocalRequest ( ) ) ;
2016-09-28 16:41:55 +02:00
return getCatalogue ( scope ) . findLicenseIdByLicenseTitle ( chosenLicense ) ;
2016-10-06 14:24:05 +02:00
2016-06-08 18:31:54 +02:00
}
2016-06-06 17:24:52 +02:00
2021-04-09 14:51:55 +02:00
/ * *
* Gets the licenses .
*
* @return the licenses
* /
2016-05-26 18:12:53 +02:00
@Override
2017-04-25 15:41:27 +02:00
public List < LicenseBean > getLicenses ( ) {
2016-05-26 18:12:53 +02:00
2016-11-25 10:32:50 +01:00
// get http session
HttpSession httpSession = getThreadLocalRequest ( ) . getSession ( ) ;
2017-04-25 15:41:27 +02:00
String scope = GenericUtils . getScopeFromClientUrl ( getThreadLocalRequest ( ) ) ;
2016-11-25 10:32:50 +01:00
logger . info ( " Request for CKAN licenses for scope " + scope ) ;
2018-02-23 15:23:33 +01:00
String keyPerScope = CatalogueUtilMethods . concatenateSessionKeyScope ( SessionCatalogueAttributes . CKAN_LICENSES_KEY , scope ) ;
2021-04-09 14:51:55 +02:00
// if(!isWithinPortal()){
// logger.info("DEV MODE returning funny licenses...");
// List<LicenseBean> licenses = new ArrayList<LicenseBean>();
// licenses.add(new LicenseBean("AFL-3.0", "https://opensource.org/licenses/AFL-3.0"));
// return licenses;
// }
2016-06-28 11:52:04 +02:00
2017-04-25 15:41:27 +02:00
List < LicenseBean > licensesBean = null ;
2016-11-25 10:32:50 +01:00
if ( httpSession . getAttribute ( keyPerScope ) ! = null ) {
2017-04-25 15:41:27 +02:00
licensesBean = ( List < LicenseBean > ) httpSession . getAttribute ( keyPerScope ) ;
2016-11-25 10:32:50 +01:00
logger . info ( " List of licenses was into session " ) ;
}
else {
2017-04-25 15:41:27 +02:00
List < CkanLicense > licenses = getCatalogue ( scope ) . getLicenses ( ) ;
licensesBean = new ArrayList < LicenseBean > ( ) ;
for ( CkanLicense license : licenses ) {
licensesBean . add ( new LicenseBean ( license . getTitle ( ) , license . getUrl ( ) ) ) ;
2016-07-13 16:11:15 +02:00
}
2017-04-25 15:41:27 +02:00
// sort the list
Collections . sort ( licensesBean , new Comparator < LicenseBean > ( ) {
public int compare ( LicenseBean l1 , LicenseBean l2 ) {
return l1 . getTitle ( ) . compareTo ( l2 . getTitle ( ) ) ;
} } ) ;
2016-11-25 10:32:50 +01:00
httpSession . setAttribute ( keyPerScope , licensesBean ) ;
logger . info ( " List of licenses has been saved into session " ) ;
2016-11-13 22:38:27 +01:00
}
2016-11-25 10:32:50 +01:00
return licensesBean ;
2016-05-26 18:12:53 +02:00
}
2021-04-09 14:51:55 +02:00
2016-05-26 18:12:53 +02:00
2021-04-09 14:51:55 +02:00
/ * *
* Gets the dataset bean .
*
* @param folderId the folder id
* @return the dataset bean
* @throws Exception the exception
* /
2016-05-27 19:08:03 +02:00
@Override
2017-04-27 16:24:21 +02:00
public DatasetBean getDatasetBean ( String folderId ) throws Exception {
2016-05-27 19:08:03 +02:00
2017-04-25 15:41:27 +02:00
DatasetBean bean = null ;
String userName = GenericUtils . getCurrentUser ( getThreadLocalRequest ( ) ) . getUsername ( ) ;
2016-09-12 17:58:50 +02:00
logger . info ( " DatasetBean request for " + folderId + " and " + userName ) ;
2016-05-27 19:08:03 +02:00
if ( isWithinPortal ( ) ) {
try {
2017-04-25 15:41:27 +02:00
String scope = GenericUtils . getScopeFromClientUrl ( getThreadLocalRequest ( ) ) ;
2016-11-13 22:38:27 +01:00
logger . debug ( " Scope recovered from session is " + scope ) ;
2016-05-27 19:08:03 +02:00
logger . debug ( " Request dataset metadata bean for folder with id " + folderId
2016-09-12 17:58:50 +02:00
+ " whose owner is " + userName ) ;
2016-11-13 22:38:27 +01:00
2016-05-27 19:08:03 +02:00
UserManager liferUserManager = new LiferayUserManager ( ) ;
2016-09-12 17:58:50 +02:00
GCubeUser userOwner = liferUserManager . getUserByUsername ( userName ) ;
2016-06-27 11:55:06 +02:00
2016-05-27 19:08:03 +02:00
// build bean
logger . debug ( " Building bean " ) ;
2017-04-25 15:41:27 +02:00
bean = new DatasetBean ( ) ;
2016-05-27 19:08:03 +02:00
bean . setId ( folderId ) ;
2016-09-12 17:58:50 +02:00
bean . setOwnerIdentifier ( userName ) ;
2016-05-27 19:08:03 +02:00
bean . setVersion ( 1 ) ;
2016-07-13 16:11:15 +02:00
bean . setAuthorName ( userOwner . getFirstName ( ) ) ;
bean . setAuthorSurname ( userOwner . getLastName ( ) ) ;
2016-05-27 19:08:03 +02:00
bean . setAuthorEmail ( userOwner . getEmail ( ) ) ;
bean . setMaintainer ( userOwner . getFullname ( ) ) ;
bean . setMaintainerEmail ( userOwner . getEmail ( ) ) ;
2016-09-12 17:58:50 +02:00
bean . setOrganizationList ( getUserOrganizationsListAdmin ( userName , scope ) ) ;
2017-04-05 18:42:07 +02:00
bean . setTagsVocabulary ( discoverTagsVocabulary ( scope ) ) ;
2016-05-27 19:08:03 +02:00
2016-06-08 18:31:54 +02:00
// if the request comes from the workspace
2016-06-06 17:24:52 +02:00
if ( folderId ! = null & & ! folderId . isEmpty ( ) ) {
2021-04-09 14:51:55 +02:00
Workspace workspace = getWorkspaceFromStorageHub ( ) ;
WorkspaceUtils . toWorkspaceResource ( folderId , userName , bean , workspace ) ;
2016-06-06 17:24:52 +02:00
}
2016-06-14 12:35:10 +02:00
2016-05-27 19:08:03 +02:00
} catch ( Exception e ) {
2017-04-27 16:24:21 +02:00
logger . error ( " Error while retrieving bean information " , e ) ;
throw new Exception ( " Error while retrieving basic information " + e . getMessage ( ) ) ;
2016-05-27 19:08:03 +02:00
}
} else {
2016-06-06 17:24:52 +02:00
2017-02-23 16:25:12 +01:00
logger . info ( " DEV MODE DETECTED " ) ;
2017-04-25 15:41:27 +02:00
GenericUtils . getCurrentToken ( getThreadLocalRequest ( ) , true ) ;
2017-02-23 16:25:12 +01:00
2016-06-06 17:24:52 +02:00
try {
2017-04-25 15:41:27 +02:00
bean = new DatasetBean ( ) ;
2016-06-06 17:24:52 +02:00
bean . setId ( folderId ) ;
bean . setDescription ( " This is a fantastic description " ) ;
bean . setVersion ( 1 ) ;
2016-07-06 18:41:43 +02:00
String onlyAlphanumeric = " test-creation-blablabla " . replaceAll ( " [^A-Za-z0-9] " , " " ) ;
bean . setTitle ( onlyAlphanumeric + Calendar . getInstance ( ) . getTimeInMillis ( ) ) ;
2021-04-09 14:51:55 +02:00
bean . setAuthorName ( " Francesco " ) ;
bean . setAuthorSurname ( " Mangiacrapa " ) ;
bean . setAuthorEmail ( " francesco.mangiacrapa@isti.cnr.it " ) ;
bean . setMaintainer ( " Francesco Mangiacrapa " ) ;
bean . setMaintainerEmail ( " francesco.mangiacrapa@isti.cnr.it " ) ;
2019-02-22 15:15:25 +01:00
//UPDATED By Francesco
String scope = GenericUtils . getCurrentContext ( this . getThreadLocalRequest ( ) , false ) ;
String vreName = scope . substring ( scope . lastIndexOf ( " / " ) + 1 , scope . length ( ) ) ;
logger . debug ( " In dev mode using the scope: " + scope + " and VRE name: " + vreName ) ;
bean . setOrganizationList ( Arrays . asList ( new OrganizationBean ( vreName , vreName . toLowerCase ( ) , true ) ) ) ;
2016-09-12 17:58:50 +02:00
bean . setOwnerIdentifier ( userName ) ;
2016-06-06 17:24:52 +02:00
if ( folderId ! = null & & ! folderId . isEmpty ( ) ) {
2021-04-09 14:51:55 +02:00
Workspace workspace = getWorkspaceFromStorageHub ( ) ;
WorkspaceUtils . toWorkspaceResource ( folderId , userName , bean , workspace ) ;
2016-06-06 17:24:52 +02:00
}
} catch ( Exception e ) {
logger . error ( " Error while building bean into dev mode " , e ) ;
2017-04-27 16:24:21 +02:00
throw new Exception ( " Error while retrieving basic information " + e . getMessage ( ) ) ;
2016-06-06 17:24:52 +02:00
}
2016-05-27 19:08:03 +02:00
}
2017-02-23 16:25:12 +01:00
logger . debug ( " Returning bean " + bean ) ;
2016-05-27 19:08:03 +02:00
return bean ;
}
2017-04-05 18:42:07 +02:00
/ * *
2021-04-09 14:51:55 +02:00
* Discover from the IS the vocabulary of tags for this scope , if present .
*
* @param context the context
2017-04-05 18:42:07 +02:00
* @return a list of tags vocabulary
* /
2017-04-27 16:24:21 +02:00
private List < String > discoverTagsVocabulary ( String context ) {
2016-06-14 12:36:50 +02:00
2017-04-06 14:42:00 +02:00
logger . debug ( " Looking for vocabulary of tags in this context " + context ) ;
2018-09-28 10:26:22 +02:00
String keyPerVocabulary = CatalogueUtilMethods . concatenateSessionKeyScope ( TAGS_VOCABULARY_KEY , context ) ;
2016-06-06 17:24:52 +02:00
2017-04-05 18:42:07 +02:00
List < String > vocabulary = ( List < String > ) getThreadLocalRequest ( ) . getSession ( ) . getAttribute ( keyPerVocabulary ) ;
2017-04-06 14:42:00 +02:00
if ( vocabulary = = null ) {
2017-04-25 15:41:27 +02:00
vocabulary = DiscoverTagsList . discoverTagsList ( context ) ;
2017-04-27 16:24:21 +02:00
if ( vocabulary ! = null )
getThreadLocalRequest ( ) . getSession ( ) . setAttribute ( keyPerVocabulary , vocabulary ) ;
2017-04-05 18:42:07 +02:00
}
2017-04-19 14:39:59 +02:00
2017-04-06 14:42:00 +02:00
logger . debug ( " Vocabulary for tags is " + vocabulary ) ;
2016-06-28 20:27:04 +02:00
2017-04-05 18:42:07 +02:00
return vocabulary ;
}
2016-06-28 20:27:04 +02:00
2021-04-09 14:51:55 +02:00
/ * *
* Gets the tags for organization .
*
* @param orgName the org name
* @return the tags for organization
* @throws Exception the exception
* /
2017-04-05 18:42:07 +02:00
@Override
2017-04-27 16:24:21 +02:00
public List < String > getTagsForOrganization ( String orgName ) throws Exception {
2017-04-25 15:41:27 +02:00
return discoverTagsVocabulary ( getScopeFromOrgName ( orgName ) ) ;
}
2016-11-02 23:10:44 +01:00
2021-04-09 14:51:55 +02:00
/ * *
* Creates the C kan dataset .
*
* @param toCreate the to create
* @return the dataset bean
* @throws Exception the exception
* /
2017-04-25 15:41:27 +02:00
@Override
public DatasetBean createCKanDataset ( DatasetBean toCreate ) throws Exception {
2017-04-25 16:14:59 +02:00
try {
2021-04-09 14:51:55 +02:00
devModeSetContexts ( ) ;
2017-04-25 18:11:13 +02:00
logger . info ( " Request for creating a dataset with these information " + toCreate ) ;
2017-04-25 16:14:59 +02:00
String userName = GenericUtils . getCurrentUser ( getThreadLocalRequest ( ) ) . getUsername ( ) ;
String title = toCreate . getTitle ( ) ;
String organizationNameOrId = toCreate . getSelectedOrganization ( ) ;
String author = toCreate . getAuthorFullName ( ) ;
String authorMail = toCreate . getAuthorEmail ( ) ;
String maintainer = toCreate . getMaintainer ( ) ;
String maintainerMail = toCreate . getMaintainerEmail ( ) ;
long version = toCreate . getVersion ( ) ;
String description = toCreate . getDescription ( ) ;
String chosenLicense = toCreate . getLicense ( ) ;
String licenseId = findLicenseIdByLicense ( chosenLicense ) ;
List < String > listOfTags = toCreate . getTags ( ) ;
Map < String , List < String > > customFields = toCreate . getCustomFields ( ) ;
// add Type for custom fields
if ( toCreate . getChosenType ( ) ! = null )
customFields . put ( SYS_TYPE , Arrays . asList ( toCreate . getChosenType ( ) ) ) ;
boolean setPublic = toCreate . getVisibility ( ) ;
// get the list of resources and convert to ResourceBean
List < ResourceBean > resources = null ;
ResourceElementBean resourcesToAdd = toCreate . getResourceRoot ( ) ;
2021-04-09 14:51:55 +02:00
//converting to resources to be added
2017-04-25 16:14:59 +02:00
if ( resourcesToAdd ! = null ) {
2021-04-09 14:51:55 +02:00
Workspace workspace = getWorkspaceFromStorageHub ( ) ;
resources = WorkspaceUtils . toResources ( toCreate , workspace , userName ) ;
2017-04-25 16:14:59 +02:00
}
2017-04-25 15:41:27 +02:00
2017-04-25 16:14:59 +02:00
logger . debug ( " The user wants to publish in organization with name " + organizationNameOrId ) ;
String scope = getScopeFromOrgName ( organizationNameOrId ) ;
DataCatalogue utils = getCatalogue ( scope ) ;
2021-04-09 14:51:55 +02:00
if ( ! isWithinPortal ( ) ) {
logger . debug ( " Should be added: " ) ;
for ( String key : customFields . keySet ( ) ) {
logger . debug ( " Custom field with key: " + key + " , value: " + customFields . get ( key ) ) ;
}
}
String datasetId = utils . createCkanDatasetMultipleCustomFields ( userName ,
title ,
null ,
organizationNameOrId ,
author ,
authorMail ,
maintainer ,
maintainerMail ,
version ,
description ,
licenseId ,
listOfTags ,
customFields ,
resources ,
setPublic ,
true ,
true ) ;
2017-04-25 16:14:59 +02:00
2021-04-09 14:51:55 +02:00
2017-04-25 16:14:59 +02:00
if ( datasetId ! = null ) {
logger . info ( " Dataset created! " ) ;
toCreate . setId ( datasetId ) ;
// retrieve the url
2022-06-14 12:28:03 +02:00
//String datasetUrl = utils.getUnencryptedUrlFromDatasetIdOrName(datasetId);
//toCreate.setSource(datasetUrl);
2021-04-09 14:51:55 +02:00
2022-06-14 12:28:03 +02:00
//#23491 Building the go to the item to "Catalogue Portlet URL" (instead of URI Resolver URL)
String catalogueURL = utils . getPortletUrl ( ) ;
toCreate . setSource ( String . format ( " %s?path=/dataset/%s " , catalogueURL , datasetId ) ) ;
2017-04-25 16:14:59 +02:00
return toCreate ;
} else {
logger . error ( " Failed to create the dataset " ) ;
2016-06-14 12:35:10 +02:00
}
2017-04-05 18:42:07 +02:00
2017-04-25 16:14:59 +02:00
} catch ( Exception e ) {
logger . error ( " Error while creating item " , e ) ;
2021-04-09 14:51:55 +02:00
throw new Exception ( e . getMessage ( ) ) ;
2016-06-06 17:24:52 +02:00
}
2017-04-05 18:42:07 +02:00
2016-06-14 12:36:50 +02:00
return null ;
2017-04-25 16:14:59 +02:00
2016-06-10 18:06:31 +02:00
}
2021-04-09 14:51:55 +02:00
/ * *
* Adds the resource to dataset .
*
* @param resource the resource
* @param datasetId the dataset id
* @return the resource element bean
* @throws Exception the exception
* /
2016-06-07 17:50:33 +02:00
@Override
2017-04-05 18:42:07 +02:00
public ResourceElementBean addResourceToDataset ( ResourceElementBean resource , String datasetId ) throws Exception {
2021-04-09 14:51:55 +02:00
logger . info ( " called addResourceToDataset " ) ;
devModeSetContexts ( ) ;
2017-04-25 15:41:27 +02:00
String username = GenericUtils . getCurrentUser ( getThreadLocalRequest ( ) ) . getUsername ( ) ;
2016-07-20 19:14:20 +02:00
logger . debug ( " Incoming request for creating new resource for dataset with id " + datasetId + " and organization name of the dataset is " + resource . getOrganizationNameDatasetParent ( ) ) ;
2016-09-12 17:58:50 +02:00
logger . debug ( " Owner is " + username + " and resource is " + resource ) ;
2016-06-08 18:31:54 +02:00
2021-04-09 14:51:55 +02:00
ResourceBean resourceBean = new ResourceBean (
resource . getUrl ( ) ,
resource . getName ( ) ,
resource . getDescription ( ) ,
null ,
username ,
datasetId ,
null ) ;
// get the scope in which we should discover the ckan instance given the organization name in which the dataset was created
String scope = getScopeFromOrgName ( resource . getOrganizationNameDatasetParent ( ) ) ;
DataCatalogue catalogue = getCatalogue ( scope ) ;
String resourceId = catalogue . addResourceToDataset ( resourceBean , resource . getOrganizationNameDatasetParent ( ) , username ) ;
if ( resourceId ! = null ) {
logger . info ( " Resource " + resource . getName ( ) + " is now available " ) ;
// set its id and turn it to the client
resource . setOriginalIdInWorkspace ( resourceId ) ;
2016-06-30 12:56:34 +02:00
return resource ;
}
2021-04-09 14:51:55 +02:00
logger . debug ( " No resource created " ) ;
return null ;
2016-06-08 18:31:54 +02:00
}
2021-04-09 14:51:55 +02:00
/ * *
* Delete resource from dataset .
*
* @param resource the resource
* @return true , if successful
* @throws Exception the exception
* /
2016-06-08 18:31:54 +02:00
@Override
2017-04-27 16:24:21 +02:00
public boolean deleteResourceFromDataset ( ResourceElementBean resource ) throws Exception {
2016-06-30 12:56:34 +02:00
logger . debug ( " Request for deleting resource " + resource ) ;
2016-06-14 12:35:10 +02:00
boolean deleted = false ;
2021-04-09 14:51:55 +02:00
devModeSetContexts ( ) ;
try {
// get the scope in which we should discover the ckan instance given the organization name in which the dataset was created
String scope = getScopeFromOrgName ( resource . getOrganizationNameDatasetParent ( ) ) ;
DataCatalogue catalogue = getCatalogue ( scope ) ;
2017-04-25 15:41:27 +02:00
String username = GenericUtils . getCurrentUser ( getThreadLocalRequest ( ) ) . getUsername ( ) ;
2021-04-09 14:51:55 +02:00
deleted = catalogue . deleteResourceFromDataset ( resource . getOriginalIdInWorkspace ( ) , username ) ;
if ( deleted ) {
logger . info ( " Resource described by " + resource + " deleted " ) ;
} else
logger . error ( " Resource described by " + resource + " NOT deleted " ) ;
} catch ( Exception e ) {
logger . error ( " Error while trying to delete resource described by " + resource , e ) ;
throw new Exception ( " Error while trying to delete resource. " + e . getMessage ( ) ) ;
2016-06-07 17:50:33 +02:00
}
2021-04-09 14:51:55 +02:00
return deleted ;
2016-06-07 17:50:33 +02:00
}
2016-07-04 12:44:20 +02:00
2021-04-09 14:51:55 +02:00
/ * *
* Gets the profiles .
*
* @param orgName the org name
* @return the profiles
* @throws Exception the exception
* /
2016-07-20 19:14:20 +02:00
@Override
2017-04-27 16:24:21 +02:00
public List < MetaDataProfileBean > getProfiles ( String orgName ) throws Exception {
2016-09-12 17:58:50 +02:00
2016-07-22 12:51:19 +02:00
logger . debug ( " Requested profiles for products into orgName " + orgName ) ;
2016-07-21 19:31:05 +02:00
List < MetaDataProfileBean > toReturn = new ArrayList < MetaDataProfileBean > ( ) ;
2016-07-06 18:41:43 +02:00
try {
2016-10-06 14:24:05 +02:00
String evaluatedScope = getScopeFromOrgName ( orgName ) ;
2016-07-22 12:51:19 +02:00
logger . debug ( " Evaluated scope is " + evaluatedScope ) ;
2017-04-25 15:41:27 +02:00
toReturn = MetadataDiscovery . getMetadataProfilesList ( evaluatedScope , getThreadLocalRequest ( ) ) ;
2016-07-06 18:41:43 +02:00
} catch ( Exception e ) {
2016-07-20 19:14:20 +02:00
logger . error ( " Failed to retrieve profiles for scope coming from organization name " + orgName , e ) ;
2017-04-27 16:24:21 +02:00
throw e ;
2016-07-06 18:41:43 +02:00
}
return toReturn ;
}
2016-09-23 18:50:16 +02:00
2021-04-09 14:51:55 +02:00
/ * *
* Dataset id already exists .
*
* @param title the title
* @param orgName the org name
* @return true , if successful
* @throws Exception the exception
* /
2016-09-23 18:50:16 +02:00
@Override
2017-04-27 16:24:21 +02:00
public boolean datasetIdAlreadyExists ( String title , String orgName ) throws Exception {
2016-09-23 18:50:16 +02:00
if ( title = = null | | title . isEmpty ( ) )
return true ; // it's an error somehow
try {
2017-04-25 16:14:59 +02:00
String scopeFromOrgName = getScopeFromOrgName ( orgName ) ;
2018-02-23 15:23:33 +01:00
String idFromTitle = CatalogueUtilMethods . fromProductTitleToName ( title ) ;
2017-04-27 16:24:21 +02:00
logger . debug ( " Evaluating if dataset with id " + title + " in context " + scopeFromOrgName + " already exists " ) ;
2017-04-25 16:14:59 +02:00
return getCatalogue ( scopeFromOrgName ) . existProductWithNameOrId ( idFromTitle ) ;
2016-09-23 18:50:16 +02:00
} catch ( Exception e ) {
logger . error ( " Unable to check if such a dataset id already exists " , e ) ;
2017-04-27 16:24:21 +02:00
throw new Exception ( " Unable to check if such a dataset id already exists " + e . getMessage ( ) ) ;
2016-09-23 18:50:16 +02:00
}
}
2016-10-06 14:24:05 +02:00
/ * *
* The method tries to retrieve the scope related to the organization using the map first ,
* if no match is found , it retrieves such information by using liferay
* /
private String getScopeFromOrgName ( String orgName ) {
2016-10-06 21:22:39 +02:00
2021-04-09 14:51:55 +02:00
logger . info ( " Request for scope related to orgName " + orgName + " [map that will be used is " + mapOrganizationScope . toString ( ) + " ] " ) ;
2016-10-06 14:24:05 +02:00
if ( orgName = = null | | orgName . isEmpty ( ) )
throw new IllegalArgumentException ( " orgName cannot be empty or null! " ) ;
String toReturn = null ;
2017-02-23 16:25:12 +01:00
if ( isWithinPortal ( ) ) {
2021-04-09 14:51:55 +02:00
if ( mapOrganizationScope . containsKey ( orgName ) ) {
2017-02-23 16:25:12 +01:00
toReturn = mapOrganizationScope . get ( orgName ) ;
2021-04-09 14:51:55 +02:00
} else {
2017-02-23 16:25:12 +01:00
try {
2017-04-25 15:41:27 +02:00
String evaluatedScope = GenericUtils . retrieveScopeFromOrganizationName ( orgName ) ;
2021-04-09 14:51:55 +02:00
//see #20801
if ( evaluatedScope = = null | | evaluatedScope . isEmpty ( ) ) {
logger . warn ( " Scope detected for OrganizationName: " + orgName + " is null or empty, skipping filling 'mapOrganizationScope' and returning null " ) ;
return toReturn ;
}
2017-02-23 16:25:12 +01:00
mapOrganizationScope . put ( orgName , evaluatedScope ) ;
toReturn = evaluatedScope ;
} catch ( Exception e ) {
logger . error ( " Failed to retrieve scope from OrgName for organization " + orgName , e ) ;
}
2016-10-06 14:24:05 +02:00
}
2017-02-23 16:25:12 +01:00
} else {
2019-02-22 15:15:25 +01:00
//UPDATED By FRANCESCO
toReturn = GenericUtils . getCurrentContext ( this . getThreadLocalRequest ( ) , false ) ;
2017-02-23 16:25:12 +01:00
mapOrganizationScope . put ( orgName , toReturn ) ;
2016-10-06 14:24:05 +02:00
}
2021-04-09 14:51:55 +02:00
logger . info ( " Returning scope " + toReturn ) ;
2016-10-06 14:24:05 +02:00
return toReturn ;
}
2016-11-13 22:38:27 +01:00
2021-04-09 14:51:55 +02:00
/ * *
* Gets the user groups .
*
* @param orgName the org name
* @return the user groups
* /
2016-11-14 18:37:45 +01:00
@Override
2017-04-25 15:41:27 +02:00
public List < OrganizationBean > getUserGroups ( String orgName ) {
2016-11-14 18:37:45 +01:00
2017-04-25 15:41:27 +02:00
List < OrganizationBean > toReturn = new ArrayList < OrganizationBean > ( ) ;
2016-11-14 18:37:45 +01:00
if ( isWithinPortal ( ) ) {
2021-04-09 14:51:55 +02:00
GCubeUser user = GenericUtils . getCurrentUser ( getThreadLocalRequest ( ) ) ;
String username = null ;
if ( user ! = null )
username = user . getUsername ( ) ;
2016-11-14 18:37:45 +01:00
2017-01-25 18:29:47 +01:00
logger . debug ( " Request for user " + username + " groups. Organization name is " + orgName ) ;
2016-11-14 18:37:45 +01:00
// get http session
HttpSession httpSession = getThreadLocalRequest ( ) . getSession ( ) ;
2017-04-25 15:41:27 +02:00
String scope = orgName ! = null ? getScopeFromOrgName ( orgName ) : GenericUtils . getScopeFromClientUrl ( getThreadLocalRequest ( ) ) ;
2016-11-16 10:25:35 +01:00
2016-11-17 14:29:58 +01:00
// check if they are in session
2018-02-23 15:23:33 +01:00
String keyPerScopeGroups = CatalogueUtilMethods . concatenateSessionKeyScope ( SessionCatalogueAttributes . CKAN_GROUPS_MEMBER , scope ) ;
2016-11-17 14:08:22 +01:00
2016-11-17 14:29:58 +01:00
if ( httpSession . getAttribute ( keyPerScopeGroups ) ! = null ) {
2017-04-25 15:41:27 +02:00
toReturn = ( List < OrganizationBean > ) httpSession . getAttribute ( keyPerScopeGroups ) ;
2016-11-17 14:29:58 +01:00
logger . info ( " Found user's groups in session " + toReturn ) ;
} else {
2016-11-17 14:08:22 +01:00
2018-09-28 10:26:22 +02:00
//Fixing Incident #12563
try {
DataCatalogue catalogue = getCatalogue ( scope ) ;
//Fixing Incident #12563
2021-04-09 14:51:55 +02:00
if ( username ! = null & & ! username . isEmpty ( ) ) {
Map < String , Map < CkanGroup , RolesCkanGroupOrOrg > > mapRoleGroup = catalogue . getUserRoleByGroup ( username ) ;
2018-09-28 10:26:22 +02:00
Set < Entry < String , Map < CkanGroup , RolesCkanGroupOrOrg > > > set = mapRoleGroup . entrySet ( ) ;
for ( Entry < String , Map < CkanGroup , RolesCkanGroupOrOrg > > entry : set ) {
Set < Entry < CkanGroup , RolesCkanGroupOrOrg > > subSet = entry . getValue ( ) . entrySet ( ) ;
for ( Entry < CkanGroup , RolesCkanGroupOrOrg > subEntry : subSet ) {
toReturn . add ( new OrganizationBean ( subEntry . getKey ( ) . getTitle ( ) , subEntry . getKey ( ) . getName ( ) , false ) ) ;
}
}
httpSession . setAttribute ( keyPerScopeGroups , toReturn ) ;
} else
logger . warn ( " The API_KEY for " + username + " is null or empty in the catalogue: " + catalogue . getCatalogueUrl ( ) ) ;
} catch ( Exception e ) {
logger . error ( " Error on recovery the user groups for " + username , e ) ;
2016-11-17 14:29:58 +01:00
}
}
2016-11-14 18:37:45 +01:00
} else {
logger . warn ( " Dev mode detected " ) ;
2017-02-23 16:25:12 +01:00
toReturn = Arrays . asList ( ) ;
2016-11-14 18:37:45 +01:00
}
return toReturn ;
}
2017-01-25 18:29:47 +01:00
2021-04-09 14:51:55 +02:00
/ * *
* Checks if is publisher user .
*
* @param isWorkspaceRequest the is workspace request
* @return true , if is publisher user
* @throws Exception the exception
* /
2017-01-25 18:29:47 +01:00
@Override
2017-04-27 16:24:21 +02:00
public boolean isPublisherUser ( boolean isWorkspaceRequest ) throws Exception {
2017-01-25 18:29:47 +01:00
2017-04-25 15:41:27 +02:00
String username = GenericUtils . getCurrentUser ( getThreadLocalRequest ( ) ) . getUsername ( ) ;
2017-01-26 19:00:55 +01:00
logger . info ( " Checking if the user " + username + " can publish or not on the catalogue " ) ;
2017-01-25 18:29:47 +01:00
2017-01-26 19:00:55 +01:00
if ( ! isWithinPortal ( ) ) {
logger . warn ( " OUT FROM PORTAL DETECTED RETURNING TRUE " ) ;
2017-02-23 16:25:12 +01:00
return true ;
2017-01-26 19:00:55 +01:00
}
2017-02-22 17:40:16 +01:00
2017-01-25 18:29:47 +01:00
try {
HttpSession httpSession = this . getThreadLocalRequest ( ) . getSession ( ) ;
// retrieve scope per current portlet url
2017-04-25 15:41:27 +02:00
String scopePerCurrentUrl = GenericUtils . getScopeFromClientUrl ( getThreadLocalRequest ( ) ) ;
2017-01-25 18:29:47 +01:00
// get key per scope
2018-02-23 15:23:33 +01:00
String keyPerScopeRole = CatalogueUtilMethods . concatenateSessionKeyScope ( SessionCatalogueAttributes . CKAN_HIGHEST_ROLE , scopePerCurrentUrl ) ;
String keyPerScopeOrganizations = CatalogueUtilMethods . concatenateSessionKeyScope ( SessionCatalogueAttributes . CKAN_ORGANIZATIONS_PUBLISH_KEY , scopePerCurrentUrl ) ;
String keyPerScopeGroups = CatalogueUtilMethods . concatenateSessionKeyScope ( SessionCatalogueAttributes . CKAN_GROUPS_MEMBER , scopePerCurrentUrl ) ;
2017-01-25 18:29:47 +01:00
// check if this information was already into session(true means the user has at least in one org
// the role editor), false that he is just a member so he cannot publish
RolesCkanGroupOrOrg role = ( RolesCkanGroupOrOrg ) httpSession . getAttribute ( keyPerScopeRole ) ;
// if the attribute was already set..
if ( role ! = null )
return ! role . equals ( RolesCkanGroupOrOrg . MEMBER ) ;
else {
try {
GroupManager gm = new LiferayGroupManager ( ) ;
String groupName = gm . getGroup ( gm . getGroupIdFromInfrastructureScope ( scopePerCurrentUrl ) ) . getGroupName ( ) ;
// we build up also a list that keeps track of the scopes (orgs) in which the user has role ADMIN/EDITOR
List < OrganizationBean > orgsInWhichAtLeastEditorRole = new ArrayList < OrganizationBean > ( ) ;
2019-06-12 12:26:30 +02:00
String gatewayURL = GenericUtils . getGatewayClientHostname ( getThreadLocalRequest ( ) ) ;
2019-06-12 12:15:07 +02:00
logger . info ( " The Gateway URL is: " + gatewayURL ) ;
role = CatalogueRoleManager . getHighestRole ( scopePerCurrentUrl , username , groupName , this , orgsInWhichAtLeastEditorRole , gatewayURL ) ;
2017-01-25 18:29:47 +01:00
// if he is an admin/editor preload:
// 1) organizations in which he can publish (the widget will find these info in session)
if ( ! role . equals ( RolesCkanGroupOrOrg . MEMBER ) ) {
httpSession . setAttribute ( keyPerScopeOrganizations , orgsInWhichAtLeastEditorRole ) ;
String orgName = scopePerCurrentUrl . split ( " / " ) [ scopePerCurrentUrl . split ( " / " ) . length - 1 ] ;
httpSession . setAttribute ( keyPerScopeGroups , getUserGroups ( orgName ) ) ;
}
} catch ( Exception e ) {
logger . error ( " Unable to retrieve the role information for this user. Returning FALSE " , e ) ;
return false ;
}
}
// set role in session for this scope
httpSession . setAttribute ( keyPerScopeRole , role ) ;
logger . info ( " Does the user have the right to publish on the catalogue? " + role ) ;
return ! role . equals ( RolesCkanGroupOrOrg . MEMBER ) ;
2017-02-22 17:40:16 +01:00
2017-01-25 18:29:47 +01:00
} catch ( Exception e ) {
logger . error ( " Failed to check the user's role " , e ) ;
2017-04-27 16:24:21 +02:00
throw new Exception ( " Failed to check if you are an Administrator or Editor " + e . getMessage ( ) ) ;
2017-01-25 18:29:47 +01:00
}
}
2021-04-09 14:51:55 +02:00
/ * *
* Checks if is geo JSON valid .
*
* @param geoJson the geo json
* @return true , if is geo JSON valid
* @throws Exception the exception
* /
2017-04-25 15:41:27 +02:00
@Override
public boolean isGeoJSONValid ( String geoJson ) throws Exception {
try {
new ObjectMapper ( ) . readValue ( geoJson , GeoJsonObject . class ) ;
return true ;
} catch ( Exception e ) {
throw new Exception ( " GeoJSON field with value ' " + geoJson + " ' seems not valid! " ) ;
}
}
2016-06-30 12:56:34 +02:00
}