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-12-10 11:58:41 +01:00
import java.util.HashMap ;
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 ;
2017-01-25 18:29:47 +01:00
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue ;
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueFactory ;
2018-02-23 15:23:33 +01:00
import org.gcube.datacatalogue.ckanutillibrary.server.utils.CatalogueUtilMethods ;
2018-09-28 10:26:22 +02:00
import org.gcube.datacatalogue.ckanutillibrary.server.utils.SessionCatalogueAttributes ;
2017-03-08 16:36:06 +01:00
import org.gcube.datacatalogue.ckanutillibrary.shared.ResourceBean ;
2017-01-25 18:29:47 +01:00
import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg ;
2016-05-26 18:12:53 +02:00
import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherService ;
2016-11-17 14:08:22 +01:00
import org.gcube.portlets.widgets.ckandatapublisherwidget.server.threads.AssociationToGroupAndNotifyThread ;
import org.gcube.portlets.widgets.ckandatapublisherwidget.server.threads.WritePostCatalogueManagerThread ;
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 ;
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 ;
2016-12-26 23:15:29 +01:00
import com.liferay.portal.kernel.log.Log ;
import com.liferay.portal.kernel.log.LogFactoryUtil ;
2016-05-26 18:12:53 +02:00
import com.liferay.portal.service.UserLocalServiceUtil ;
2016-11-14 18:37:45 +01:00
import eu.trentorise.opendata.jackan.model.CkanGroup ;
2016-07-13 16:11:15 +02:00
import eu.trentorise.opendata.jackan.model.CkanLicense ;
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);
private static final Log logger = LogFactoryUtil . getLog ( 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 > ( ) ;
2016-06-27 11:12:15 +02:00
/ * *
2016-07-20 19:14:20 +02:00
* Retrieve an instance of the library for the scope
* @param scope if it is null it is evaluated from the session
2016-06-27 11:12:15 +02:00
* @return
* /
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
/ * *
2017-01-25 18:29:47 +01:00
* Retrieve the list of organizations in which the user can publish ( roles ADMIN / EDITOR )
2016-06-16 18:09:54 +02:00
* @param username
* @return the list of organizations
2018-09-28 10:26:22 +02:00
* @throws GroupRetrievalFault
* @throws UserManagementSystemException
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
}
/ * *
* Online or in development mode ?
* @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
}
2016-06-06 17:24:52 +02:00
/ * *
* Find a license id given the license text .
* @param chosenLicense
* @return
* /
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
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 ) ;
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
}
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 ( ) ) {
2016-10-07 10:44:31 +02:00
WorkspaceUtils . handleWorkspaceResources ( folderId , userName , bean ) ;
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 ( ) ) ;
2016-07-13 16:11:15 +02:00
bean . setAuthorName ( " Costantino " ) ;
bean . setAuthorSurname ( " Perciante " ) ;
2016-06-06 17:24:52 +02:00
bean . setAuthorEmail ( " costantino.perciante@isti.cnr.it " ) ;
bean . setMaintainer ( " Costantino Perciante " ) ;
bean . setMaintainerEmail ( " costantino.perciante@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 ( ) ) {
2016-10-07 10:44:31 +02:00
WorkspaceUtils . handleWorkspaceResources ( folderId , userName , bean ) ;
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
/ * *
* Discover from the IS the vocabulary of tags for this scope , if present
* @return a list of tags vocabulary
2018-09-28 10:26:22 +02:00
* @throws Exception
2017-04-05 18:42:07 +02:00
* /
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
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
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 {
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 ( ) ;
// we need to copy such resource in the .catalogue area of the user's ws
if ( resourcesToAdd ! = null ) {
resources = WorkspaceUtils . copyResourcesToUserCatalogueArea ( toCreate . getId ( ) , userName , toCreate ) ;
}
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 ) ;
String userApiKey = utils . getApiKeyFromUsername ( userName ) ;
String datasetId = utils . createCKanDatasetMultipleCustomFields
2018-09-28 10:26:22 +02:00
( userApiKey , title , null , organizationNameOrId , author , authorMail , maintainer ,
2017-04-25 16:14:59 +02:00
maintainerMail , version , description , licenseId , listOfTags , customFields , resources , setPublic ) ;
if ( datasetId ! = null ) {
logger . info ( " Dataset created! " ) ;
toCreate . setId ( datasetId ) ;
// retrieve the url
String datasetUrl = utils . getUnencryptedUrlFromDatasetIdOrName ( datasetId ) ;
toCreate . setSource ( datasetUrl ) ;
// add also this information as custom field
Map < String , List < String > > addField = new HashMap < String , List < String > > ( ) ;
addField . put ( ITEM_URL_FIELD , Arrays . asList ( datasetUrl ) ) ;
2018-02-09 10:55:44 +01:00
utils . patchProductCustomFields ( datasetId , userApiKey , addField , false ) ;
2017-04-25 16:14:59 +02:00
// start a thread that will associate this dataset with the group
if ( /*toCreate.getChosenType() != null ||*/ toCreate . getGroups ( ) ! = null ) {
2018-09-28 10:26:22 +02:00
AssociationToGroupAndNotifyThread threadAssociationToGroup =
2017-04-25 16:14:59 +02:00
new AssociationToGroupAndNotifyThread (
toCreate . getGroups ( ) ,
2017-04-27 16:24:21 +02:00
toCreate . getGroupsForceCreation ( ) ,
2017-04-25 16:14:59 +02:00
null , //toCreate.getChosenType(), TODO
datasetUrl ,
datasetId ,
toCreate . getTitle ( ) ,
GenericUtils . getCurrentUser ( getThreadLocalRequest ( ) ) . getFullname ( ) ,
2018-09-28 10:26:22 +02:00
userName ,
utils ,
2017-04-25 16:14:59 +02:00
organizationNameOrId ,
getThreadLocalRequest ( )
) ;
threadAssociationToGroup . start ( ) ;
2017-04-25 15:41:27 +02:00
2017-04-25 16:14:59 +02:00
}
2017-04-05 18:42:07 +02:00
2017-04-25 16:14:59 +02:00
// launch notification thread
2018-09-28 10:26:22 +02:00
WritePostCatalogueManagerThread threadWritePost =
2017-04-25 16:14:59 +02:00
new WritePostCatalogueManagerThread (
userName ,
2018-09-28 10:26:22 +02:00
scope ,
toCreate . getTitle ( ) ,
datasetUrl ,
false , // send notification to other people
toCreate . getTags ( ) ,
2018-02-09 15:40:21 +01:00
GenericUtils . getCurrentUser ( getThreadLocalRequest ( ) ) . getFullname ( ) ,
GenericUtils . getCurrentClientUrl ( getThreadLocalRequest ( ) )
2016-10-28 18:47:40 +02:00
) ;
2017-04-25 16:14:59 +02:00
threadWritePost . start ( ) ;
2016-10-06 14:24:05 +02:00
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 ) ;
2017-04-27 16:24:21 +02:00
throw new Exception ( " An error occurred while creating the item " + 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
}
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 {
2017-04-25 15:41:27 +02:00
String username = GenericUtils . getCurrentUser ( getThreadLocalRequest ( ) ) . getUsername ( ) ;
2016-06-08 18:31:54 +02:00
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
2016-06-30 12:56:34 +02:00
if ( ! isWithinPortal ( ) ) {
2016-06-08 18:31:54 +02:00
2016-06-30 12:56:34 +02:00
logger . warn ( " Running outside the portal " ) ;
return resource ;
2016-06-08 18:31:54 +02:00
2016-06-30 12:56:34 +02:00
} else {
2016-06-09 18:58:19 +02:00
2016-11-25 10:32:50 +01:00
2017-04-05 18:42:07 +02:00
ResourceBean resourceBean = new ResourceBean (
2018-09-28 10:26:22 +02:00
resource . getUrl ( ) ,
resource . getName ( ) ,
resource . getDescription ( ) ,
null ,
username ,
2017-04-05 18:42:07 +02:00
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 , catalogue . getApiKeyFromUsername ( username ) ) ;
if ( resourceId ! = null ) {
logger . debug ( " Resource " + resource . getName ( ) + " is now available " ) ;
// set its id and turn it to the client
resource . setOriginalIdInWorkspace ( resourceId ) ;
return resource ;
2016-06-30 12:56:34 +02:00
}
2016-11-25 10:32:50 +01:00
2016-06-30 12:56:34 +02:00
logger . debug ( " No resource created " ) ;
return null ;
}
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-08 18:31:54 +02:00
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 ;
2016-06-08 18:31:54 +02:00
2016-06-30 12:56:34 +02:00
if ( ! isWithinPortal ( ) ) {
logger . warn ( " Running outside the portal " ) ;
return deleted ;
} else {
2016-06-08 18:31:54 +02:00
2017-04-25 15:41:27 +02:00
String username = GenericUtils . getCurrentUser ( getThreadLocalRequest ( ) ) . getUsername ( ) ;
2016-11-25 10:32:50 +01:00
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 ) ;
deleted = catalogue .
deleteResourceFromDataset ( resource . getOriginalIdInWorkspace ( ) , catalogue . getApiKeyFromUsername ( 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 ) ;
2017-04-27 16:24:21 +02:00
throw new Exception ( " Error while trying to delete resource. " + e . getMessage ( ) ) ;
2016-06-30 12:56:34 +02:00
}
2016-11-25 10:32:50 +01:00
return deleted ;
2016-06-07 17:50:33 +02:00
}
}
2016-07-04 12:44:20 +02:00
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
@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
2016-10-06 14:24:05 +02:00
logger . debug ( " Request for scope related to orgName " + orgName + " [ map that will be used is " + mapOrganizationScope . toString ( ) + " ] " ) ;
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 ( ) ) {
if ( mapOrganizationScope . containsKey ( orgName ) )
toReturn = mapOrganizationScope . get ( orgName ) ;
else {
try {
2017-04-25 15:41:27 +02:00
String evaluatedScope = GenericUtils . retrieveScopeFromOrganizationName ( orgName ) ;
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
}
logger . debug ( " Returning scope " + toReturn ) ;
return toReturn ;
}
2016-11-13 22:38:27 +01:00
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 ( ) ) {
2017-04-25 15:41:27 +02:00
String username = GenericUtils . getCurrentUser ( getThreadLocalRequest ( ) ) . 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 ) ;
String apiKey = catalogue . getApiKeyFromUsername ( username ) ;
//Fixing Incident #12563
if ( apiKey ! = null & & ! apiKey . isEmpty ( ) ) {
Map < String , Map < CkanGroup , RolesCkanGroupOrOrg > > mapRoleGroup = catalogue . getUserRoleByGroup ( username , apiKey ) ;
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
@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
}
}
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
}