2018-12-04 12:06:22 +01:00
package org.gcube.gcat.persistence.ckan ;
2020-06-22 19:39:29 +02:00
import java.io.StringWriter ;
2018-12-04 12:06:22 +01:00
import java.util.ArrayList ;
import java.util.HashMap ;
2020-06-22 15:39:37 +02:00
import java.util.HashSet ;
2018-12-04 12:06:22 +01:00
import java.util.List ;
import java.util.Map ;
2020-06-22 15:39:37 +02:00
import java.util.Set ;
2019-10-01 18:00:40 +02:00
import java.util.regex.Matcher ;
import java.util.regex.Pattern ;
2018-12-04 12:06:22 +01:00
import javax.ws.rs.BadRequestException ;
2020-06-22 15:39:37 +02:00
import javax.ws.rs.ForbiddenException ;
2018-12-04 12:06:22 +01:00
import javax.ws.rs.InternalServerErrorException ;
import javax.ws.rs.WebApplicationException ;
2019-05-20 17:23:49 +02:00
import javax.ws.rs.core.MultivaluedMap ;
2018-12-04 12:06:22 +01:00
import javax.ws.rs.core.Response.Status ;
2021-05-14 15:34:11 +02:00
import org.apache.http.MethodNotSupportedException ;
2021-05-10 17:05:05 +02:00
import org.gcube.com.fasterxml.jackson.databind.JsonNode ;
import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode ;
import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode ;
2018-12-04 12:06:22 +01:00
import org.gcube.common.scope.impl.ScopeBean ;
import org.gcube.common.scope.impl.ScopeBean.Type ;
2021-05-11 16:05:39 +02:00
import org.gcube.gcat.api.CMItemStatus ;
import org.gcube.gcat.api.CMItemVisibility ;
2019-05-20 17:23:49 +02:00
import org.gcube.gcat.api.GCatConstants ;
2021-05-11 16:05:39 +02:00
import org.gcube.gcat.api.Role ;
2018-12-04 12:06:22 +01:00
import org.gcube.gcat.oldutils.Validator ;
2019-01-10 12:29:47 +01:00
import org.gcube.gcat.profile.MetadataUtility ;
2021-05-11 16:05:39 +02:00
import org.gcube.gcat.social.PortalUser ;
2019-09-12 14:26:24 +02:00
import org.gcube.gcat.social.SocialPost ;
2018-12-04 12:06:22 +01:00
import org.gcube.gcat.utils.URIResolver ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
/ * *
* @author Luca Frosini ( ISTI - CNR )
* /
public class CKANPackage extends CKAN {
private static final Logger logger = LoggerFactory . getLogger ( CKANPackage . class ) ;
2019-02-08 12:25:19 +01:00
/ *
2018-12-04 12:06:22 +01:00
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.get.package_list
public static final String ITEM_LIST = CKAN . CKAN_API_PATH + " package_list " ;
2019-02-08 12:25:19 +01:00
* /
// see https://docs.ckan.org/en/latest/api/index.html#ckan.logic.action.get.package_search
public static final String ITEM_LIST = CKAN . CKAN_API_PATH + " package_search " ;
2021-02-22 09:29:52 +01:00
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.create.package_create
2018-12-04 12:06:22 +01:00
public static final String ITEM_CREATE = CKAN . CKAN_API_PATH + " package_create " ;
2021-02-22 09:29:52 +01:00
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.get.package_show
2018-12-04 12:06:22 +01:00
public static final String ITEM_SHOW = CKAN . CKAN_API_PATH + " package_show " ;
2021-02-22 09:29:52 +01:00
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.update.package_update
2018-12-04 12:06:22 +01:00
public static final String ITEM_UPDATE = CKAN . CKAN_API_PATH + " package_update " ;
2021-02-22 09:29:52 +01:00
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.patch.package_patch
2018-12-04 12:06:22 +01:00
public static final String ITEM_PATCH = CKAN . CKAN_API_PATH + " package_patch " ;
2021-02-22 09:29:52 +01:00
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.delete.package_delete
2018-12-04 12:06:22 +01:00
public static final String ITEM_DELETE = CKAN . CKAN_API_PATH + " package_delete " ;
2021-02-22 09:29:52 +01:00
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.delete.dataset_purge
2018-12-04 12:06:22 +01:00
public static final String ITEM_PURGE = CKAN . CKAN_API_PATH + " dataset_purge " ;
2021-05-11 16:05:39 +02:00
2019-02-08 12:25:19 +01:00
// limit in https://docs.ckan.org/en/latest/api/index.html#ckan.logic.action.get.package_search
2019-09-16 14:48:18 +02:00
protected static final String ROWS_KEY = " rows " ;
2019-02-08 12:25:19 +01:00
// offset in https://docs.ckan.org/en/latest/api/index.html#ckan.logic.action.get.package_search
protected static final String START_KEY = " start " ;
2019-10-01 18:00:40 +02:00
protected static final String ORGANIZATION_FILTER_TEMPLATE = GCatConstants . ORGANIZATION_PARAMETER + " :%s " ;
2020-06-22 19:39:29 +02:00
protected static final String ORGANIZATION_REGEX = GCatConstants . ORGANIZATION_PARAMETER + " :[a-zA-Z0-9_ \" ]* " ;
2019-10-01 18:00:40 +02:00
protected static final Pattern ORGANIZATION_REGEX_PATTERN ;
static {
ORGANIZATION_REGEX_PATTERN = Pattern . compile ( ORGANIZATION_REGEX ) ;
}
2019-02-08 12:25:19 +01:00
2018-12-04 12:06:22 +01:00
protected static final String LICENSE_KEY = " license_id " ;
2019-02-26 14:58:06 +01:00
protected static final String EXTRAS_ITEM_URL_KEY = " Item URL " ;
2018-12-04 12:06:22 +01:00
protected static final String AUTHOR_KEY = " author " ;
protected static final String AUTHOR_EMAIL_KEY = " author_email " ;
2021-04-16 16:14:13 +02:00
protected static final String MAINTAINER_KEY = " maintainer " ;
protected static final String MAINTAINER_EMAIL_KEY = " maintainer_email " ;
2018-12-04 12:06:22 +01:00
protected static final String OWNER_ORG_KEY = " owner_org " ;
protected static final String RESOURCES_KEY = " resources " ;
protected static final String TITLE_KEY = " title " ;
2019-02-08 12:04:20 +01:00
public static final String EXTRAS_KEY = " extras " ;
public static final String EXTRAS_KEY_KEY = " key " ;
public static final String EXTRAS_KEY_VALUE_SYSTEM_TYPE = " system:type " ;
public static final String EXTRAS_VALUE_KEY = " value " ;
2019-02-08 14:40:57 +01:00
// The 'results' array is included in the 'result' object for package_search
private static final String RESULTS_KEY = " results " ;
2019-02-08 16:49:30 +01:00
protected static final String PRIVATE_KEY = " private " ;
2019-02-08 14:40:57 +01:00
protected static final String SEARCHABLE_KEY = " searchable " ;
2019-05-20 17:23:49 +02:00
protected static final String CAPACITY_KEY = " capacity " ;
2019-02-08 16:49:30 +01:00
2021-05-11 16:05:39 +02:00
protected static final String CM_STATUS_QUERY_FILTER_KEY = " extras_systemcm_item_status " ;
protected static final String INCLUDE_PRIVATE_KEY = " include_private " ;
2019-02-08 14:40:57 +01:00
// protected static final String INCLUDE_DRAFTS_KEY = "include_drafts";
2018-12-04 12:06:22 +01:00
public static final String GROUPS_KEY = " groups " ;
public static final String TAGS_KEY = " tags " ;
2019-09-16 14:48:18 +02:00
2018-12-04 12:06:22 +01:00
protected final List < CKANResource > managedResources ;
protected String itemID ;
2021-05-10 16:16:18 +02:00
protected final CKANUser ckanUser ;
2020-06-22 15:39:37 +02:00
2021-05-10 17:05:05 +02:00
protected final CKANInstance ckanInstance ;
protected final Set < String > supportedOrganizations ;
2020-06-22 15:39:37 +02:00
2018-12-04 12:06:22 +01:00
public CKANPackage ( ) {
super ( ) ;
2021-05-10 17:05:05 +02:00
2018-12-04 12:06:22 +01:00
LIST = ITEM_LIST ;
CREATE = ITEM_CREATE ;
READ = ITEM_SHOW ;
UPDATE = ITEM_UPDATE ;
PATCH = ITEM_PATCH ;
DELETE = ITEM_DELETE ;
PURGE = ITEM_PURGE ;
managedResources = new ArrayList < CKANResource > ( ) ;
2021-05-10 17:05:05 +02:00
2021-05-10 16:16:18 +02:00
ckanUser = CKANUserCache . getCurrrentCKANUser ( ) ;
2021-05-10 17:05:05 +02:00
ckanInstance = CKANInstance . getInstance ( ) ;
supportedOrganizations = ckanInstance . getSupportedOrganizations ( ) ;
2020-06-22 15:39:37 +02:00
2020-06-23 13:17:58 +02:00
for ( String supportedOrganization : supportedOrganizations ) {
ckanUser . addUserToOrganization ( supportedOrganization ) ;
}
2018-12-04 12:06:22 +01:00
}
2019-02-08 12:25:19 +01:00
/ *
* Return the CKAN organization name using the current context name
* /
2020-06-22 15:39:37 +02:00
protected static String getOrganizationName ( ScopeBean scopeBean ) {
2019-02-08 12:25:19 +01:00
String contextName = scopeBean . name ( ) ;
return contextName . toLowerCase ( ) . replace ( " " , " _ " ) ;
}
2020-06-22 15:39:37 +02:00
protected CKANOrganization checkGotOrganization ( String gotOrganization ) throws ForbiddenException {
if ( ! supportedOrganizations . contains ( gotOrganization ) ) {
String error = String . format (
" IS Configuration does not allow to publish in %s organizations. Allowed organization are: %s " ,
gotOrganization , supportedOrganizations ) ;
throw new ForbiddenException ( error ) ;
}
2020-06-19 17:32:21 +02:00
CKANOrganization ckanOrganization = new CKANOrganization ( ) ;
ckanOrganization . setName ( gotOrganization ) ;
ckanOrganization . read ( ) ;
return ckanOrganization ;
}
2020-06-22 15:39:37 +02:00
protected CKANOrganization getPublishingOrganization ( ObjectNode objectNode ) throws ForbiddenException {
CKANOrganization ckanOrganization = null ;
2020-06-19 17:32:21 +02:00
if ( objectNode . has ( OWNER_ORG_KEY ) ) {
2020-06-22 15:39:37 +02:00
String gotOrganizationName = objectNode . get ( OWNER_ORG_KEY ) . asText ( ) ;
ckanOrganization = checkGotOrganization ( gotOrganizationName ) ;
2020-06-19 17:32:21 +02:00
}
2020-06-22 15:39:37 +02:00
if ( ckanOrganization = = null ) {
// owner organization must be specified if the token belongs to a VRE
2021-05-10 17:05:05 +02:00
String organizationFromContext = ckanInstance . getCurrentOrganizationName ( ) ;
2020-06-22 15:39:37 +02:00
ckanOrganization = checkGotOrganization ( organizationFromContext ) ;
2020-06-22 15:51:11 +02:00
objectNode . put ( OWNER_ORG_KEY , organizationFromContext ) ;
2020-06-19 17:32:21 +02:00
}
2020-06-22 15:39:37 +02:00
return ckanOrganization ;
2020-06-19 17:32:21 +02:00
}
2018-12-04 12:06:22 +01:00
public ObjectNode checkBaseInformation ( String json ) throws Exception {
2020-11-30 19:44:15 +01:00
return checkBaseInformation ( json , false ) ;
}
2021-02-10 14:18:38 +01:00
public JsonNode cleanResult ( JsonNode jsonNode ) {
if ( jsonNode . has ( OWNER_ORG_KEY ) ) {
( ( ObjectNode ) jsonNode ) . remove ( OWNER_ORG_KEY ) ;
}
return jsonNode ;
}
2020-11-30 19:44:15 +01:00
/ * *
* @param json The json to check
* @param allowPartialInfo used for patch method which provide only partial information ( i . e . the info to patch )
* @return ObjectNode from json
* @throws Exception
* /
public ObjectNode checkBaseInformation ( String json , boolean allowPartialInfo ) throws Exception {
2018-12-04 12:06:22 +01:00
ObjectNode objectNode = ( ObjectNode ) mapper . readTree ( json ) ;
2020-11-30 19:44:15 +01:00
try {
objectNode = ( ObjectNode ) checkName ( objectNode ) ;
} catch ( Exception e ) {
if ( ! allowPartialInfo ) {
throw e ;
}
}
2018-12-04 12:06:22 +01:00
// We need to enforce the itemID to properly manage resource persistence
if ( objectNode . has ( ID_KEY ) ) {
itemID = objectNode . get ( ID_KEY ) . asText ( ) ;
}
2019-02-08 16:49:30 +01:00
// To include private item in search result (e.g. listing) a private package must be searchable
2020-12-01 09:57:48 +01:00
// The package it is just included in the search and listing results but remain private and cannot be accessed
2019-02-08 16:49:30 +01:00
// if not authorized
if ( objectNode . has ( PRIVATE_KEY ) ) {
boolean privatePackage = objectNode . get ( PRIVATE_KEY ) . asBoolean ( ) ;
if ( privatePackage ) {
objectNode . put ( SEARCHABLE_KEY , true ) ;
}
}
2018-12-04 12:06:22 +01:00
// check license
String licenseId = null ;
if ( objectNode . has ( LICENSE_KEY ) ) {
licenseId = objectNode . get ( LICENSE_KEY ) . asText ( ) ;
}
2020-12-01 09:55:16 +01:00
if ( licenseId ! = null & & ! licenseId . isEmpty ( ) ) {
try {
CKANLicense . checkLicenseId ( licenseId ) ;
} catch ( Exception e ) {
throw new BadRequestException (
" You must specify an existing license identifier for the item. License list can be retrieved using licence collection " ) ;
}
} else if ( ! allowPartialInfo ) {
2018-12-04 12:06:22 +01:00
throw new BadRequestException (
" You must specify a license identifier for the item. License list can be retrieved using licence collection " ) ;
}
2019-05-20 17:23:49 +02:00
if ( objectNode . has ( CAPACITY_KEY ) ) {
/ *
* When a client provides the ' capacity ' field as ' private ' , the item is not counted in the
* total number of items in the GUI . We want to avoid such a behavior
* See https : //support.d4science.org/issues/16410
* /
objectNode . remove ( CAPACITY_KEY ) ;
}
2021-04-16 16:14:13 +02:00
String authorName = ckanUser . getPortalUser ( ) . getFullName ( ) ;
if ( authorName = = null | | authorName . compareTo ( " " ) = = 0 ) {
authorName = ckanUser . getName ( ) ;
}
objectNode . put ( AUTHOR_KEY , authorName ) ;
String authorEmail = ckanUser . getPortalUser ( ) . getEMail ( ) ;
objectNode . put ( AUTHOR_EMAIL_KEY , authorEmail ) ;
if ( ! objectNode . has ( MAINTAINER_KEY ) ) {
if ( ! objectNode . has ( MAINTAINER_EMAIL_KEY ) ) {
objectNode . put ( MAINTAINER_KEY , authorName ) ;
objectNode . put ( MAINTAINER_EMAIL_KEY , authorEmail ) ;
} else {
objectNode . put ( MAINTAINER_KEY , objectNode . get ( MAINTAINER_EMAIL_KEY ) . toString ( ) ) ;
}
}
2018-12-04 12:06:22 +01:00
2020-06-23 13:17:58 +02:00
getPublishingOrganization ( objectNode ) ;
2019-05-20 17:23:49 +02:00
2018-12-04 12:06:22 +01:00
return objectNode ;
}
protected JsonNode validateJson ( String json ) {
try {
// check base information (and set them if needed)
ObjectNode objectNode = checkBaseInformation ( json ) ;
// Validating against profiles if any
2019-05-20 17:23:49 +02:00
MetadataUtility metadataUtility = new MetadataUtility ( ) ;
2019-01-10 12:29:47 +01:00
if ( ! metadataUtility . getMetadataProfiles ( ) . isEmpty ( ) ) {
2019-02-27 17:36:09 +01:00
Validator validator = new Validator ( mapper ) ;
2019-05-20 17:23:49 +02:00
objectNode = validator . validateAgainstProfile ( objectNode , metadataUtility ) ;
2018-12-04 12:06:22 +01:00
}
return objectNode ;
} catch ( BadRequestException e ) {
throw e ;
} catch ( Exception e ) {
throw new BadRequestException ( e ) ;
}
}
2021-02-03 16:28:17 +01:00
public int count ( ) {
Map < String , String > parameters = new HashMap < > ( ) ;
if ( uriInfo ! = null ) {
MultivaluedMap < String , String > queryParameters = uriInfo . getQueryParameters ( ) ;
parameters = checkListParameters ( queryParameters , parameters ) ;
}
int limit = 1 ;
parameters . put ( ROWS_KEY , String . valueOf ( limit ) ) ;
int offset = 0 ;
parameters . put ( START_KEY , String . valueOf ( offset * limit ) ) ;
if ( ! parameters . containsKey ( GCatConstants . Q_KEY ) ) {
String filter = getFilterForOrganizations ( ) ;
parameters . put ( GCatConstants . Q_KEY , filter ) ;
}
sendGetRequest ( LIST , parameters ) ;
2021-02-03 16:50:23 +01:00
int count = result . get ( GCatConstants . COUNT_KEY ) . asInt ( ) ;
2021-02-03 16:28:17 +01:00
return count ;
}
2021-05-14 15:34:11 +02:00
protected CMItemStatus getRequestedCMItemStatus ( ) {
CMItemStatus cmItemStatus = null ;
try {
MultivaluedMap < String , String > queryParameters = uriInfo . getQueryParameters ( ) ;
if ( queryParameters . containsKey ( GCatConstants . CM_ITEM_STATUS_QUERY_PARAMETER ) ) {
String cmItemStatusString = queryParameters . getFirst ( GCatConstants . CM_ITEM_STATUS_QUERY_PARAMETER ) ;
cmItemStatus = CMItemStatus . getCMItemStatusFromValue ( cmItemStatusString ) ;
}
} catch ( Exception e ) {
cmItemStatus = null ;
}
return cmItemStatus ;
}
2018-12-04 12:06:22 +01:00
@Override
2019-01-10 12:29:47 +01:00
public String list ( int limit , int offset ) {
2019-02-08 12:25:19 +01:00
Map < String , String > parameters = new HashMap < > ( ) ;
if ( limit < = 0 ) {
// According to CKAN documentation
// the number of matching rows to return. There is a hard limit of 1000 datasets per query.
// see https://docs.ckan.org/en/2.6/api/index.html#ckan.logic.action.get.package_search
limit = 1000 ;
}
parameters . put ( ROWS_KEY , String . valueOf ( limit ) ) ;
2019-09-16 14:48:18 +02:00
2019-02-08 12:25:19 +01:00
if ( offset < 0 ) {
offset = 0 ;
}
2019-09-16 14:48:18 +02:00
parameters . put ( START_KEY , String . valueOf ( offset * limit ) ) ;
2019-02-08 12:25:19 +01:00
2019-10-04 14:16:34 +02:00
if ( uriInfo ! = null ) {
2019-10-01 18:00:40 +02:00
MultivaluedMap < String , String > queryParameters = uriInfo . getQueryParameters ( ) ;
parameters = checkListParameters ( queryParameters , parameters ) ;
}
2021-02-03 16:28:17 +01:00
if ( ! parameters . containsKey ( GCatConstants . Q_KEY ) ) {
String filter = getFilterForOrganizations ( ) ;
parameters . put ( GCatConstants . Q_KEY , filter ) ;
}
2021-05-11 11:43:24 +02:00
if ( ckanInstance . isModerationEnabled ( ) ) {
2021-05-11 16:05:39 +02:00
String q = parameters . get ( GCatConstants . Q_KEY ) ;
StringBuffer stringBuffer = new StringBuffer ( ) ;
2021-05-14 15:34:11 +02:00
stringBuffer . append ( " ( " ) ;
2021-05-11 16:05:39 +02:00
stringBuffer . append ( CM_STATUS_QUERY_FILTER_KEY ) ;
stringBuffer . append ( " : " ) ;
2021-05-14 15:34:11 +02:00
CMItemStatus cmItemStatus = getRequestedCMItemStatus ( ) ;
2021-05-11 16:05:39 +02:00
2021-05-14 15:34:11 +02:00
if ( ! ckanUser . getPortalUser ( ) . isCatalogueModerator ( ) ) {
switch ( ckanUser . getRole ( ) ) {
case ADMIN :
break ;
case EDITOR :
if ( cmItemStatus ! = null & & cmItemStatus ! = CMItemStatus . APPROVED ) {
q = String . format ( " %s AND %s:%s " , q , AUTHOR_EMAIL_KEY , ckanUser . getPortalUser ( ) . getEMail ( ) ) ;
} else {
cmItemStatus = CMItemStatus . APPROVED ;
}
break ;
case MEMBER :
if ( cmItemStatus ! = null & & cmItemStatus ! = CMItemStatus . APPROVED ) {
throw new ForbiddenException ( " You are only authorized to list " + CMItemStatus . APPROVED . getValue ( ) + " items " ) ;
}
cmItemStatus = CMItemStatus . APPROVED ;
break ;
default :
break ;
}
}
if ( cmItemStatus ! = null ) {
stringBuffer . append ( cmItemStatus . getValue ( ) ) ;
if ( cmItemStatus = = CMItemStatus . APPROVED ) {
stringBuffer . append ( " OR (*:* - " ) ;
stringBuffer . append ( CM_STATUS_QUERY_FILTER_KEY ) ;
stringBuffer . append ( " :[* TO *]) " ) ;
}
stringBuffer . append ( " ) " ) ;
q = String . format ( " %s AND %s " , q , stringBuffer . toString ( ) ) ;
parameters . put ( GCatConstants . Q_KEY , q ) ;
}
2021-05-11 16:05:39 +02:00
parameters . put ( INCLUDE_PRIVATE_KEY , String . valueOf ( true ) ) ;
2021-05-11 11:43:24 +02:00
}
2019-10-01 18:00:40 +02:00
return list ( parameters ) ;
}
2020-06-22 19:39:29 +02:00
protected Set < String > checkOrganizationFilter ( String q ) {
2019-10-01 18:00:40 +02:00
Matcher m = ORGANIZATION_REGEX_PATTERN . matcher ( q ) ;
2019-10-04 14:16:34 +02:00
2020-06-22 19:39:29 +02:00
Set < String > matches = new HashSet < > ( ) ;
2019-10-01 18:00:40 +02:00
while ( m . find ( ) ) {
2020-06-22 19:39:29 +02:00
matches . add ( q . substring ( m . start ( ) , m . end ( ) ) . replace ( GCatConstants . ORGANIZATION_PARAMETER + " : " , " " ) ) ;
2019-10-01 18:00:40 +02:00
}
2020-06-22 19:39:29 +02:00
return matches ;
2019-10-01 18:00:40 +02:00
}
2020-02-04 09:45:26 +01:00
protected static String [ ] allowedListQueryParameters = new String [ ] { " q " , " fq " , " fq_list " , " sort " ,
/* "facet", "facet.mincount", "facet.limit", "facet.field", */
2019-10-04 14:42:44 +02:00
" include_drafts " , " include_private " , " ext_bbox " } ;
2019-10-04 14:16:34 +02:00
2020-06-22 19:39:29 +02:00
protected String getFilterForOrganizations ( ) {
StringWriter stringWriter = new StringWriter ( ) ;
int i = 1 ;
for ( String organizationName : supportedOrganizations ) {
stringWriter . append ( String . format ( GCatConstants . ORGANIZATION_FILTER_TEMPLATE , organizationName ) ) ;
if ( i ! = supportedOrganizations . size ( ) ) {
// Please note that an item can only belong to a single organization.
// Hence the query must put supported organizations in OR.
stringWriter . append ( " OR " ) ;
}
i + + ;
}
return stringWriter . toString ( ) ;
}
2019-10-01 18:00:40 +02:00
protected Map < String , String > checkListParameters ( MultivaluedMap < String , String > queryParameters ,
Map < String , String > parameters ) {
String q = null ;
if ( queryParameters . containsKey ( GCatConstants . Q_KEY ) ) {
q = queryParameters . getFirst ( GCatConstants . Q_KEY ) ;
}
2020-06-22 19:39:29 +02:00
if ( q ! = null ) {
Set < String > organizations = checkOrganizationFilter ( q ) ;
if ( organizations . size ( ) = = 0 ) {
2019-10-01 18:00:40 +02:00
// Adding organization filter to q
2020-06-22 19:39:29 +02:00
String filter = getFilterForOrganizations ( ) ;
parameters . put ( GCatConstants . Q_KEY , String . format ( " %s AND %s " , q , filter ) ) ;
} else {
organizations . removeAll ( this . supportedOrganizations ) ;
if ( organizations . size ( ) > 0 ) {
String error = String . format ( " It is not possible to query the following organizations %s. Supported organization in this context are %s " , organizations . toString ( ) , supportedOrganizations . toString ( ) ) ;
throw new ForbiddenException ( error ) ;
}
2019-09-27 17:33:10 +02:00
}
2019-10-01 18:00:40 +02:00
} else {
2020-06-22 19:39:29 +02:00
String filter = getFilterForOrganizations ( ) ;
parameters . put ( GCatConstants . Q_KEY , filter ) ;
2019-09-27 17:33:10 +02:00
}
2020-06-22 19:39:29 +02:00
2019-09-27 17:33:10 +02:00
2019-10-04 14:42:44 +02:00
for ( String key : allowedListQueryParameters ) {
2019-10-04 14:16:34 +02:00
if ( queryParameters . containsKey ( key ) ) {
parameters . put ( key , queryParameters . getFirst ( key ) ) ;
2019-10-01 18:00:40 +02:00
}
2019-09-27 17:33:10 +02:00
}
2019-02-08 12:25:19 +01:00
2019-02-08 15:17:09 +01:00
// parameters.put(INCLUDE_PRIVATE_KEY, String.valueOf(true));
2019-02-08 14:40:57 +01:00
// By default not including draft
// parameters.put(INCLUDE_DRAFTS_KEY, String.valueOf(false));
2019-10-01 18:00:40 +02:00
return parameters ;
}
public String list ( Map < String , String > parameters ) {
2019-02-08 14:40:57 +01:00
sendGetRequest ( LIST , parameters ) ;
ArrayNode results = ( ArrayNode ) result . get ( RESULTS_KEY ) ;
ArrayNode arrayNode = mapper . createArrayNode ( ) ;
for ( JsonNode node : results ) {
try {
2019-02-08 16:49:30 +01:00
String name = node . get ( NAME_KEY ) . asText ( ) ;
arrayNode . add ( name ) ;
2019-09-16 14:48:18 +02:00
} catch ( Exception e ) {
2019-02-08 14:40:57 +01:00
try {
2019-09-16 14:48:18 +02:00
logger . error ( " Unable to get the ID of {}. the result will not be included in the result " ,
mapper . writeValueAsString ( node ) ) ;
} catch ( Exception ex ) {
2019-02-08 14:40:57 +01:00
logger . error ( " " , ex ) ;
}
}
}
return getAsString ( arrayNode ) ;
2018-12-04 12:06:22 +01:00
}
protected void rollbackManagedResources ( ) {
for ( CKANResource ckanResource : managedResources ) {
try {
ckanResource . rollback ( ) ;
2019-09-16 14:48:18 +02:00
} catch ( Exception e ) {
2018-12-04 12:06:22 +01:00
logger . error ( " Unable to rollback resource {} to the original value " , ckanResource . getResourceID ( ) ) ;
}
}
}
protected ArrayNode createResources ( ArrayNode resourcesToBeCreated ) {
ArrayNode created = mapper . createArrayNode ( ) ;
for ( JsonNode resourceNode : resourcesToBeCreated ) {
CKANResource ckanResource = new CKANResource ( itemID ) ;
String json = ckanResource . create ( getAsString ( resourceNode ) ) ;
created . add ( getAsJsonNode ( json ) ) ;
managedResources . add ( ckanResource ) ;
}
return created ;
}
2019-02-26 14:58:06 +01:00
protected JsonNode addExtraField ( JsonNode jsonNode , String key , String value ) {
ArrayNode extras = null ;
boolean found = false ;
if ( jsonNode . has ( EXTRAS_KEY ) ) {
extras = ( ArrayNode ) jsonNode . get ( EXTRAS_KEY ) ;
for ( JsonNode extra : extras ) {
2019-09-16 14:48:18 +02:00
if ( extra . has ( EXTRAS_KEY_KEY ) & & extra . get ( EXTRAS_KEY_KEY ) . asText ( ) . compareTo ( key ) = = 0 ) {
2019-02-26 14:58:06 +01:00
( ( ObjectNode ) extra ) . put ( EXTRAS_VALUE_KEY , value ) ;
found = true ;
break ;
}
}
2019-09-16 14:48:18 +02:00
} else {
2021-05-11 16:05:39 +02:00
extras = ( ( ObjectNode ) jsonNode ) . putArray ( EXTRAS_KEY ) ;
2019-02-26 14:58:06 +01:00
}
if ( ! found ) {
ObjectNode extra = mapper . createObjectNode ( ) ;
extra . put ( EXTRAS_KEY_KEY , key ) ;
extra . put ( EXTRAS_VALUE_KEY , value ) ;
extras . add ( extra ) ;
}
return jsonNode ;
}
protected String addItemURLViaResolver ( JsonNode jsonNode ) {
// Adding Item URL via Resolver
URIResolver uriResolver = new URIResolver ( ) ;
String catalogueItemURL = uriResolver . getCatalogueItemURL ( name ) ;
addExtraField ( jsonNode , EXTRAS_ITEM_URL_KEY , catalogueItemURL ) ;
return catalogueItemURL ;
}
2019-05-20 17:23:49 +02:00
protected void sendSocialPost ( String title , String catalogueItemURL ) {
try {
2021-05-14 15:34:11 +02:00
boolean makePost = false ;
2019-05-20 17:23:49 +02:00
try {
2019-09-16 14:48:18 +02:00
MultivaluedMap < String , String > queryParameters = uriInfo . getQueryParameters ( ) ;
2021-05-14 15:34:11 +02:00
if ( queryParameters . containsKey ( GCatConstants . SOCIAL_POST_QUERY_PARAMETER ) ) {
makePost = Boolean . parseBoolean ( queryParameters . getFirst ( GCatConstants . SOCIAL_POST_QUERY_PARAMETER ) ) ;
2019-05-20 17:23:49 +02:00
}
2019-09-16 14:48:18 +02:00
} catch ( Exception e ) {
2021-05-14 15:34:11 +02:00
makePost = false ;
2019-05-20 17:23:49 +02:00
}
2021-05-14 15:34:11 +02:00
if ( makePost ) {
2019-05-20 17:23:49 +02:00
ArrayNode arrayNode = ( ArrayNode ) result . get ( TAGS_KEY ) ;
2021-05-14 15:34:11 +02:00
SocialPost socialPost = new SocialPost ( ) ;
socialPost . setItemID ( itemID ) ;
socialPost . setItemURL ( catalogueItemURL ) ;
socialPost . setTags ( arrayNode ) ;
socialPost . setItemTitle ( title ) ;
socialPost . start ( ) ;
2019-09-16 14:48:18 +02:00
} else {
2019-05-20 17:23:49 +02:00
logger . info ( " The request explicitly disabled the Social Post. " ) ;
}
2019-09-16 14:48:18 +02:00
} catch ( Exception e ) {
logger . warn (
" error dealing with Social Post. The service will not raise the exception belove. Please contact the administrator to let him know about this message. " ,
e ) ;
2019-05-20 17:23:49 +02:00
}
}
2021-05-11 16:05:39 +02:00
protected CMItemStatus getCMItemStatus ( ) {
String cmItemStatusString = CMItemStatus . APPROVED . getValue ( ) ;
boolean found = false ;
if ( result . has ( EXTRAS_KEY ) ) {
ArrayNode extras = ( ArrayNode ) result . get ( EXTRAS_KEY ) ;
for ( JsonNode extra : extras ) {
2021-05-14 15:34:11 +02:00
if ( extra . has ( EXTRAS_KEY_KEY ) & & extra . get ( EXTRAS_KEY_KEY ) . asText ( ) . compareTo ( GCatConstants . SYSTEM_CM_ITEM_STATUS ) = = 0 ) {
2021-05-11 16:05:39 +02:00
cmItemStatusString = extra . get ( EXTRAS_VALUE_KEY ) . asText ( ) ;
found = true ;
break ;
}
}
}
CMItemStatus cmItemStatus = CMItemStatus . getCMItemStatusFromValue ( cmItemStatusString ) ;
if ( ! found ) {
// TODO can be used to fix an item published before activating the moderation.
2021-05-14 15:34:11 +02:00
// The item is considered ad approved and the item representation must be updated
2021-05-11 16:05:39 +02:00
return cmItemStatus ;
}
return cmItemStatus ;
}
2021-05-14 15:34:11 +02:00
protected boolean isModerationEnabled ( ) {
return ckanInstance . isModerationEnabled ( ) ;
}
2021-03-09 12:16:42 +01:00
@Override
public String read ( ) {
try {
String ret = super . read ( ) ;
result = mapper . readTree ( ret ) ;
result = cleanResult ( result ) ;
2021-05-11 16:05:39 +02:00
2021-05-14 15:34:11 +02:00
if ( isModerationEnabled ( ) ) {
2021-05-11 16:05:39 +02:00
CMItemStatus cmItemStatus = getCMItemStatus ( ) ;
if ( cmItemStatus = = CMItemStatus . APPROVED ) {
return getAsString ( result ) ;
}
PortalUser portalUser = ckanUser . getPortalUser ( ) ;
if ( result . get ( AUTHOR_EMAIL_KEY ) . asText ( ) . compareTo ( portalUser . getEMail ( ) ) = = 0 ) {
// The author is entitled to read its own items independently from the status
return getAsString ( result ) ;
}
if ( ckanUser . getRole ( ) = = Role . ADMIN | | portalUser . isCatalogueModerator ( ) ) {
// Catalogue-Admin and Catalogue-Moderator are entitled to read items with any statues
return getAsString ( result ) ;
}
throw new ForbiddenException ( " You are not entitled to read a " + cmItemStatus . getValue ( ) + " item " ) ;
}
2021-03-09 12:16:42 +01:00
return getAsString ( result ) ;
2021-05-11 16:05:39 +02:00
2021-03-09 12:16:42 +01:00
} catch ( WebApplicationException e ) {
throw e ;
} catch ( Exception e ) {
throw new InternalServerErrorException ( e ) ;
}
}
2021-05-14 15:34:11 +02:00
protected void setToPending ( JsonNode jsonNode ) {
addExtraField ( jsonNode , GCatConstants . SYSTEM_CM_ITEM_STATUS , CMItemStatus . PENDING . getValue ( ) ) ;
CMItemVisibility cmItemVisibility = CMItemVisibility . PUBLIC ;
if ( jsonNode . has ( PRIVATE_KEY ) ) {
boolean privatePackage = jsonNode . get ( PRIVATE_KEY ) . asBoolean ( ) ;
if ( privatePackage ) {
cmItemVisibility = CMItemVisibility . RESTRICTED ;
}
}
addExtraField ( jsonNode , GCatConstants . SYSTEM_CM_ITEM_VISIBILITY , cmItemVisibility . getValue ( ) ) ;
( ( ObjectNode ) jsonNode ) . put ( PRIVATE_KEY , true ) ;
( ( ObjectNode ) jsonNode ) . put ( SEARCHABLE_KEY , false ) ;
}
protected void setToApproved ( JsonNode jsonNode ) {
ArrayNode extras = ( ArrayNode ) jsonNode . get ( EXTRAS_KEY ) ;
boolean approvedSet = false ;
CMItemVisibility cmItemVisibility = null ;
for ( JsonNode extra : extras ) {
if ( extra . has ( EXTRAS_KEY_KEY ) & & extra . get ( EXTRAS_KEY_KEY ) . asText ( ) . compareTo ( GCatConstants . SYSTEM_CM_ITEM_STATUS ) = = 0 ) {
( ( ObjectNode ) extra ) . put ( EXTRAS_VALUE_KEY , CMItemStatus . APPROVED . getValue ( ) ) ;
approvedSet = true ;
}
if ( extra . has ( EXTRAS_KEY_KEY ) & & extra . get ( EXTRAS_KEY_KEY ) . asText ( ) . compareTo ( GCatConstants . SYSTEM_CM_ITEM_VISIBILITY ) = = 0 ) {
cmItemVisibility = CMItemVisibility . getCMItemStatusFromValue ( extra . get ( EXTRAS_VALUE_KEY ) . asText ( ) ) ;
}
}
if ( ! approvedSet ) {
addExtraField ( jsonNode , GCatConstants . SYSTEM_CM_ITEM_STATUS , CMItemStatus . APPROVED . getValue ( ) ) ;
}
if ( cmItemVisibility = = null ) {
cmItemVisibility = CMItemVisibility . PUBLIC ;
addExtraField ( jsonNode , GCatConstants . SYSTEM_CM_ITEM_VISIBILITY , cmItemVisibility . getValue ( ) ) ;
}
( ( ObjectNode ) jsonNode ) . put ( PRIVATE_KEY , cmItemVisibility = = CMItemVisibility . RESTRICTED ? true : false ) ;
( ( ObjectNode ) jsonNode ) . put ( SEARCHABLE_KEY , true ) ;
}
2021-02-22 09:29:52 +01:00
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.create.package_create
2018-12-04 12:06:22 +01:00
@Override
public String create ( String json ) {
try {
logger . debug ( " Going to create Item {} " , json ) ;
2021-05-14 15:34:11 +02:00
if ( ckanUser . getRole ( ) . ordinal ( ) < Role . EDITOR . ordinal ( ) ) {
StringBuffer stringBuffer = new StringBuffer ( ) ;
stringBuffer . append ( " Only " ) ;
stringBuffer . append ( Role . EDITOR . getPortalRole ( ) ) ;
stringBuffer . append ( " and " ) ;
stringBuffer . append ( Role . ADMIN . getPortalRole ( ) ) ;
stringBuffer . append ( " are entitled to create items. " ) ;
stringBuffer . append ( " Please contact the VRE Manager to request your grant. " ) ;
throw new ForbiddenException ( stringBuffer . toString ( ) ) ;
2021-05-11 11:43:24 +02:00
}
2018-12-04 12:06:22 +01:00
JsonNode jsonNode = validateJson ( json ) ;
2021-05-14 15:34:11 +02:00
if ( isModerationEnabled ( ) ) {
setToPending ( jsonNode ) ;
2021-05-11 16:05:39 +02:00
}
2018-12-04 12:06:22 +01:00
ArrayNode resourcesToBeCreated = mapper . createArrayNode ( ) ;
if ( jsonNode . has ( RESOURCES_KEY ) ) {
resourcesToBeCreated = ( ArrayNode ) jsonNode . get ( RESOURCES_KEY ) ;
( ( ObjectNode ) jsonNode ) . remove ( RESOURCES_KEY ) ;
}
2019-05-20 17:23:49 +02:00
String catalogueItemURL = " " ;
2021-05-10 17:05:05 +02:00
if ( ckanInstance . getCurrentScopeBean ( ) . is ( Type . VRE ) ) {
2019-05-20 17:23:49 +02:00
catalogueItemURL = addItemURLViaResolver ( jsonNode ) ;
}
2019-02-26 14:58:06 +01:00
2018-12-04 12:06:22 +01:00
super . create ( getAsString ( jsonNode ) ) ;
this . itemID = result . get ( ID_KEY ) . asText ( ) ;
ArrayNode created = createResources ( resourcesToBeCreated ) ;
( ( ObjectNode ) result ) . replace ( RESOURCES_KEY , created ) ;
2019-02-26 14:58:06 +01:00
// Adding Item URL via Resolver as
// ((ObjectNode) result).put(ITEM_URL_KEY, catalogueItemURL);
2018-12-04 12:06:22 +01:00
// Actions performed after a package has been correctly created on ckan.
String title = result . get ( TITLE_KEY ) . asText ( ) ;
2021-05-10 17:05:05 +02:00
if ( ckanInstance . getCurrentScopeBean ( ) . is ( Type . VRE ) ) {
2019-05-20 17:23:49 +02:00
sendSocialPost ( title , catalogueItemURL ) ;
}
2018-12-04 12:06:22 +01:00
2021-02-10 14:18:38 +01:00
result = cleanResult ( result ) ;
2018-12-04 12:06:22 +01:00
return getAsString ( result ) ;
} catch ( WebApplicationException e ) {
rollbackManagedResources ( ) ;
throw e ;
} catch ( Exception e ) {
rollbackManagedResources ( ) ;
throw new InternalServerErrorException ( e ) ;
}
}
2021-05-14 15:34:11 +02:00
protected JsonNode checkModerationUpdate ( JsonNode jsonNode ) {
PortalUser portalUser = ckanUser . getPortalUser ( ) ;
if ( isModerationEnabled ( ) ) {
CMItemStatus cmItemStatus = getCMItemStatus ( ) ;
boolean setToPending = true ;
switch ( cmItemStatus ) {
case APPROVED :
if ( ckanUser . getRole ( ) ! = Role . ADMIN ) {
throw new ForbiddenException ( " Only " + Role . ADMIN . getPortalRole ( ) + " s are entitled to update an " + cmItemStatus . getValue ( ) + " item " ) ;
}
setToPending = false ;
break ;
case PENDING :
if ( result . get ( AUTHOR_EMAIL_KEY ) . asText ( ) . compareTo ( portalUser . getEMail ( ) ) = = 0 ) {
break ;
}
if ( portalUser . isCatalogueModerator ( ) ) {
break ;
}
throw new ForbiddenException ( " You are not entitled to update a " + cmItemStatus . getValue ( ) + " item " ) ;
case REJECTED :
if ( result . get ( AUTHOR_EMAIL_KEY ) . asText ( ) . compareTo ( portalUser . getEMail ( ) ) = = 0 ) {
break ;
}
if ( ckanUser . getRole ( ) = = Role . ADMIN | | portalUser . isCatalogueModerator ( ) ) {
break ;
}
throw new ForbiddenException ( " You are not entitled to update a " + cmItemStatus . getValue ( ) + " item " ) ;
default :
break ;
}
if ( setToPending ) {
setToPending ( jsonNode ) ;
}
}
return jsonNode ;
}
2021-02-22 09:29:52 +01:00
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.update.package_update
2018-12-04 12:06:22 +01:00
@Override
public String update ( String json ) {
try {
JsonNode jsonNode = validateJson ( json ) ;
read ( ) ;
2019-07-22 11:54:05 +02:00
this . itemID = result . get ( ID_KEY ) . asText ( ) ;
2018-12-04 12:06:22 +01:00
2021-05-14 15:34:11 +02:00
jsonNode = checkModerationUpdate ( jsonNode ) ;
2019-09-16 14:48:18 +02:00
Map < String , CKANResource > originalResources = new HashMap < > ( ) ;
ArrayNode originalResourcesarrayNode = ( ArrayNode ) result . get ( RESOURCES_KEY ) ;
if ( originalResources ! = null ) {
2018-12-04 12:06:22 +01:00
for ( JsonNode resourceNode : originalResourcesarrayNode ) {
CKANResource ckanResource = new CKANResource ( itemID ) ;
ckanResource . setPreviousRepresentation ( resourceNode ) ;
String resourceID = ckanResource . getResourceID ( ) ;
originalResources . put ( resourceID , ckanResource ) ;
}
}
if ( jsonNode . has ( RESOURCES_KEY ) ) {
ArrayNode resourcesToBeSend = mapper . createArrayNode ( ) ;
ArrayNode receivedResources = ( ArrayNode ) jsonNode . get ( RESOURCES_KEY ) ;
for ( JsonNode resourceNode : receivedResources ) {
CKANResource ckanResource = new CKANResource ( itemID ) ;
String resourceId = CKANResource . extractResourceID ( resourceNode ) ;
2019-09-16 14:48:18 +02:00
if ( resourceId ! = null ) {
2018-12-04 12:06:22 +01:00
if ( originalResources . containsKey ( resourceId ) ) {
ckanResource = originalResources . get ( resourceId ) ;
originalResources . remove ( resourceId ) ;
2019-09-16 14:48:18 +02:00
} else {
throw new BadRequestException (
2020-02-04 09:45:26 +01:00
" The content contains a resource with id " + resourceId + " which does not exists " ) ;
2018-12-04 12:06:22 +01:00
}
}
2020-06-22 15:39:37 +02:00
if ( originalResources . get ( resourceId ) ! = null
& & ( ! originalResources . get ( resourceId ) . getPreviousRepresentation ( ) . equals ( resourceNode ) ) ) {
2020-02-04 09:45:26 +01:00
resourceNode = ckanResource . createOrUpdate ( resourceNode ) ;
}
2018-12-04 12:06:22 +01:00
resourcesToBeSend . add ( resourceNode ) ;
managedResources . add ( ckanResource ) ;
}
( ( ObjectNode ) jsonNode ) . replace ( RESOURCES_KEY , resourcesToBeSend ) ;
}
2019-02-26 14:58:06 +01:00
addItemURLViaResolver ( jsonNode ) ;
2018-12-04 12:06:22 +01:00
sendPostRequest ( ITEM_UPDATE , getAsString ( jsonNode ) ) ;
for ( String resourceId : originalResources . keySet ( ) ) {
CKANResource ckanResource = originalResources . get ( resourceId ) ;
ckanResource . deleteFile ( ) ;
}
2019-02-26 14:58:06 +01:00
/ *
2018-12-04 12:06:22 +01:00
// Adding Item URL via Resolver
URIResolver uriResolver = new URIResolver ( ) ;
String catalogueItemURL = uriResolver . getCatalogueItemURL ( name ) ;
( ( ObjectNode ) result ) . put ( ITEM_URL_KEY , catalogueItemURL ) ;
2019-02-26 14:58:06 +01:00
* /
2021-02-10 14:18:38 +01:00
result = cleanResult ( result ) ;
2018-12-04 12:06:22 +01:00
return getAsString ( result ) ;
} catch ( WebApplicationException e ) {
rollbackManagedResources ( ) ;
throw e ;
} catch ( Exception e ) {
rollbackManagedResources ( ) ;
throw new InternalServerErrorException ( e ) ;
}
}
2021-05-14 15:34:11 +02:00
public String approve ( ) {
try {
read ( ) ;
if ( isModerationEnabled ( ) ) {
setToApproved ( result ) ;
} else {
throw new MethodNotSupportedException ( " The approve operation is available only in moderation mode " ) ;
}
result = cleanResult ( result ) ;
return getAsString ( result ) ;
} catch ( WebApplicationException e ) {
throw e ;
} catch ( Exception e ) {
throw new InternalServerErrorException ( e ) ;
}
}
2021-02-22 09:29:52 +01:00
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.patch.package_patch
2018-12-04 12:06:22 +01:00
@Override
public String patch ( String json ) {
2020-11-30 19:44:15 +01:00
try {
2021-05-14 15:34:11 +02:00
read ( ) ;
2021-05-11 11:43:24 +02:00
2020-12-02 16:57:39 +01:00
JsonNode jsonNode = checkBaseInformation ( json , true ) ;
2020-11-30 19:44:15 +01:00
this . itemID = result . get ( ID_KEY ) . asText ( ) ;
2020-12-02 16:57:39 +01:00
( ( ObjectNode ) jsonNode ) . put ( ID_KEY , this . itemID ) ;
2020-11-30 19:44:15 +01:00
2021-05-14 15:34:11 +02:00
jsonNode = checkModerationUpdate ( jsonNode ) ;
2020-11-30 19:44:15 +01:00
Map < String , CKANResource > originalResources = new HashMap < > ( ) ;
ArrayNode originalResourcesarrayNode = ( ArrayNode ) result . get ( RESOURCES_KEY ) ;
if ( originalResources ! = null ) {
for ( JsonNode resourceNode : originalResourcesarrayNode ) {
CKANResource ckanResource = new CKANResource ( itemID ) ;
ckanResource . setPreviousRepresentation ( resourceNode ) ;
String resourceID = ckanResource . getResourceID ( ) ;
originalResources . put ( resourceID , ckanResource ) ;
}
}
if ( jsonNode . has ( RESOURCES_KEY ) ) {
ArrayNode resourcesToBeSend = mapper . createArrayNode ( ) ;
ArrayNode receivedResources = ( ArrayNode ) jsonNode . get ( RESOURCES_KEY ) ;
for ( JsonNode resourceNode : receivedResources ) {
CKANResource ckanResource = new CKANResource ( itemID ) ;
String resourceId = CKANResource . extractResourceID ( resourceNode ) ;
if ( resourceId ! = null ) {
if ( originalResources . containsKey ( resourceId ) ) {
ckanResource = originalResources . get ( resourceId ) ;
originalResources . remove ( resourceId ) ;
} else {
throw new BadRequestException (
" The content contains a resource with id " + resourceId + " which does not exists " ) ;
}
}
if ( originalResources . get ( resourceId ) ! = null
& & ( ! originalResources . get ( resourceId ) . getPreviousRepresentation ( ) . equals ( resourceNode ) ) ) {
resourceNode = ckanResource . createOrUpdate ( resourceNode ) ;
}
resourcesToBeSend . add ( resourceNode ) ;
managedResources . add ( ckanResource ) ;
}
( ( ObjectNode ) jsonNode ) . replace ( RESOURCES_KEY , resourcesToBeSend ) ;
}
addItemURLViaResolver ( jsonNode ) ;
sendPostRequest ( ITEM_PATCH , getAsString ( jsonNode ) ) ;
for ( String resourceId : originalResources . keySet ( ) ) {
CKANResource ckanResource = originalResources . get ( resourceId ) ;
ckanResource . deleteFile ( ) ;
}
/ *
// Adding Item URL via Resolver
URIResolver uriResolver = new URIResolver ( ) ;
String catalogueItemURL = uriResolver . getCatalogueItemURL ( name ) ;
( ( ObjectNode ) result ) . put ( ITEM_URL_KEY , catalogueItemURL ) ;
* /
2021-02-10 14:18:38 +01:00
result = cleanResult ( result ) ;
2020-11-30 19:44:15 +01:00
return getAsString ( result ) ;
} catch ( WebApplicationException e ) {
rollbackManagedResources ( ) ;
throw e ;
} catch ( Exception e ) {
rollbackManagedResources ( ) ;
throw new InternalServerErrorException ( e ) ;
}
2018-12-04 12:06:22 +01:00
}
@Override
protected void delete ( ) {
2021-05-14 15:34:11 +02:00
if ( isModerationEnabled ( ) ) {
2021-05-11 11:43:24 +02:00
// TODO
}
2018-12-04 12:06:22 +01:00
super . delete ( ) ;
}
@Override
public void purge ( ) {
try {
delete ( ) ;
} catch ( WebApplicationException e ) {
// If the item was deleted but not purged we obtain Not Found. This is accepted. The item has to be purged
// with SysAdmin right.
Status status = Status . fromStatusCode ( e . getResponse ( ) . getStatusInfo ( ) . getStatusCode ( ) ) ;
if ( status ! = Status . NOT_FOUND ) {
throw e ;
}
}
setApiKey ( CKANUtility . getSysAdminAPI ( ) ) ;
read ( ) ;
if ( result . has ( RESOURCES_KEY ) ) {
itemID = result . get ( ID_KEY ) . asText ( ) ;
ArrayNode arrayNode = ( ArrayNode ) result . get ( RESOURCES_KEY ) ;
for ( JsonNode jsonNode : arrayNode ) {
CKANResource ckanResource = new CKANResource ( itemID ) ;
ckanResource . setPreviousRepresentation ( jsonNode ) ;
2019-01-10 12:29:47 +01:00
ckanResource . deleteFile ( ) ; // Only delete file is required because the item has been deleted
2018-12-04 12:06:22 +01:00
}
}
super . purge ( ) ;
}
}