gcat/src/main/java/org/gcube/gcat/rest/Item.java

676 lines
27 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package org.gcube.gcat.rest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
//import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
import javax.xml.ws.WebServiceException;
//import org.gcube.common.authorization.control.annotations.AuthorizationControl;
import org.gcube.gcat.annotation.PATCH;
import org.gcube.gcat.annotation.PURGE;
import org.gcube.gcat.api.GCatConstants;
//import org.gcube.gcat.api.moderation.Moderated;
//import org.gcube.gcat.api.roles.Role;
import org.gcube.gcat.persistence.ckan.CKANPackage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.ResourceGroup;
import com.webcohesion.enunciate.metadata.rs.ResourceLabel;
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
/**
* Item is a set of metadata to describe a concept.
* An Item can has one or more <a href="./resource_Resource.html">Resource</a> attached.
*
* @author Luca Frosini (ISTI - CNR)
*/
@Path(Item.ITEMS)
@ResourceGroup("Item APIs")
@ResourceLabel("Item APIs")
public class Item extends REST<CKANPackage> implements org.gcube.gcat.api.interfaces.Item<Response,Response> {
private final Logger logger = LoggerFactory.getLogger(Item.class);
public static final String ITEM_ID_PARAMETER = "ITEM_ID";
protected String moderationMessage;
public Item() {
super(ITEMS, ITEM_ID_PARAMETER, CKANPackage.class);
}
/**
* <p>
* The listing API provides paginated results by using the query parameters limit and offset.<br/>
* It returns an array list of string containing the ids (i.e. names) of the items.<br/>
* Each name can be used as <code>{ITEM_ID}</code> path parameter to manage such item.
* </p>
*
* <h3>Filtering options</h3>
* <p>
* The listing method offers options to filter the results, thus enacting to search for items including spatial search (see ext_bbox below).<br/>
* </p>
*
* <h4>Basic Filtering options</h4>
* <dl>
* <dt>include_private (bool)</dt>
* <dd>
* <em>Optional</em>.<em>Default:false</em>.<br/>
* If True, private datasets will be included in the results.<br/>
* Only private datasets from the users organizations will be returned.
* For the sysadmins will be returned all private datasets.<br/>
* E.g. <code>/items?include_private=true</code>
* </dd>
*
* <dt style="margin-top: 5px;">ext_bbox</dt>
* <dd>
* <em>Optional</em>.<em>Default:null</em>.<br/>
* The coordinates of the upper-right and bottom-left angle of a rectangular to query for.
* The form is <code>Lat,Long,Lat,Long</code><br/>
* E.g. <code>/items?limit=10&offset=0&q=Pollution&ext_bbox=-7.535093,49.208494,3.890688,57.372349</code>
* returns the first 10 items with 'Pollution' having a spatial coverage in the specified bounding box.
* </dd>
*
* <dt style="margin-top: 5px;">own_only (bool)</dt>
* <dd>
* <em>Optional</em>.<em>Default:false</em>.<br/>
* If True, only the items of the requester user will be included in the result.<br/>
* E.g. <code>/items?limit=10&offset=0&own_only=true</code>
* </dd>
* </dl>
*
* <h4>Filtering options based on Solr query parameters</h4>
* <p>
* It accepts the following query parameters (a subset of Solr search query parameters, see Solr Query Syntax):
* </p>
* <dl>
* <dt>q (string)</dt>
* <dd>
* <em>Optional</em>.<em>Default:"*:*"</em><br/>
* The solr query.<br/>
* E.g. <code>/items?q=title:foo</code> returns the items with word "foo" in the title.<br/>
* E.g. <code>/items?q=extras_systemtype:MyProfile</code> returns the items having the profile <em>MyProfile</em>
* </dd>
*
* <dt style="margin-top: 5px;">fq (string)</dt>
* <dd>
* <em>Optional</em>.<em>Default:null</em>.<br/>
* Filter query. A query string that limits the query results without influencing their scores.<br/>
* E.g. <code>/items?q=title:foo&fq=notes:bar</code> returns with word "foo" in the 'title' and the word "bar" in the 'notes'.
* </dd>
*
* <dt style="margin-top: 5px;">fq_list (list of strings)</dt>
* <dd>
* <em>Optional</em>.<em>Default:null</em>.<br/>
* Additional filter queries to apply.<br/>
* E.g. <code>/items?q=title:foo&fq_list=...</code> returns the items with word "foo" in the 'title'.
* </dd>
*
* <dt style="margin-top: 5px;">sort (string)</dt>
* <dd>
* <em>Optional</em>.<em>Default:"relevance asc, metadata_modified desc"</em>.<br/>
* Sorting of the search results.<br/>
* As per the solr documentation, this is a comma-separated string of field names and sort-orderings.<br/>
* E.g. <code>/items?q=title:foo&sort=name+asc</code> returns the items with word "foo" in the 'title'
* sorting the results by name ascending.
* </dd>
* <dl>
*
* <h4>Moderated Catalogue filtering options</h4>
* <dl>
* <dt>status (enum)</dt>
* <dd>
* <em>Optional</em>.<em>Default:null</em>.<br/>
*
* <span style="font-weight:bold;">It has sense only for moderated catalogues</span>.<br/>
* When no value is provided, it returns both the items which have been published before the activation of the moderation,
* as weel as the items explicitly <code>approved</code> after the moderation activation.
*
* It can assume the following values:
* <ul>
* <li><code>pending</code>: it returns only the pending items, i.e. the item published by any allowed users and still not <span style="font-weight:bold;">Catalogue-Moderator</span>;</li>
* <li><code>rejected</code>: it returns only the rejected items, i.e. the item published by any allowed users and rejected by a <span style="font-weight:bold;">Catalogue-Moderator</span>;</li>
* <li><code>approved</code>: it returns only the approved items, i.e. the item published by any allowed users and approved by a <span style="font-weight:bold;">Catalogue-Moderator</span>.</li>
* </ul>
*
* <p>
* Please note that only Catalogue-Moderators can filter all items by status.<br />
* Other users using this query parameter will get only its own items with such a status in the results.
* </p>
* </dd>
* </dl>
*
*
* <h3>Query results options</h3>
* <p>
* The result is by default an array list of string containing the ids (i.e. names) of the items.
* Anyway, there are two options to get a different results.
* </p>
* <dl>
* <dt>count (bool)</dt>
* <dd>
* <em>Optional</em>.<em>Default:false</em>.<br/>
* If True, it indicates that the result must contains only the total number of items of the query.<br/>
* E.g. <code>/items?limit=10&offset=0&count=true</code>
* </dd>
*
* <dt style="margin-top: 5px;">all_fields (bool)</dt>
* <dd>
* <em>Optional</em>.<em>Default:false</em>.
* If True, the returned array list contains the whole item representation and not only the id (i.e. the name).</br/>
* E.g. <code>/items?limit=10&offset=0&all_fields=true</code>
* </dd>
* </dl>
* <p>
* Please note that, <code>count</code> query parameter has priority over <code>all_fields</code> query parameter.
* In other words, <code>all_fields</code> query parameter is not considered is <code>count</code> query parameter is true.
* </p>
*
*
* @param limit (<em>Default:10</em>) To get unlimited results the limit query parameters must be set to -1.
* If the results are too much the operation could fail.
* It is recommended to request no more than 1000 results.
* @param offset (<em>Default:0</em>) The offset parameter indicates the starting position of the result.
* @return It returns an array list of string containing the ids (i.e. names) of the items.
* E.g.<pre>["item0","items1",...,"item10"]</pre>
*
* In the case the query parameter <code>count=true</code> it returns the total number of items of the query.
* E.g. <pre>{"count":148}</pre>
*
* In the case the query parameter <code>all_fields=true</code> each element of the resulting array contains the item representation:
* E.g.
* <pre>
* [
* {
* "name"="item0",
* ...,
* "private": false,
* "license_url": "http://www.opensource.org/licenses/AFL-3.0"
* },
* {
* "name"="item1",
* ...,
* "private": true,
* "license_url": "http://www.opensource.org/licenses/AFL-3.0"
* },
* ...,
* {
* "name"="itemN",
* ...,
* "private": false,
* "license_url": "http://www.opensource.org/licenses/AFL-3.0"
* }
*
* ]</pre>
*
* @pathExample /items?limit=10&offset=0
* @responseExample application/json;charset=UTF-8 ["item0","items1",...,"item10"]
*/
@GET
@Produces(GCatConstants.APPLICATION_JSON_CHARSET_UTF_8)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "The request succeeded.")
})
/* Catalogue-Member is not added to VRE members and is assumed as the default role in the catalogue for the VRE members. So we can't enforce
* @AuthorizationControl(allowedRoles={Role.CATALOGUE_MEMBER, Role.CATALOGUE_EDITOR, Role.CATALOGUE_ADMIN, Role.CATALOGUE_MANAGER}, exception=NotAuthorizedException.class)
*/
@Override
public String list(@QueryParam(GCatConstants.LIMIT_QUERY_PARAMETER) @DefaultValue("10") int limit,
@QueryParam(GCatConstants.OFFSET_QUERY_PARAMETER) @DefaultValue("0") int offset) {
Boolean countOnly = false;
MultivaluedMap<String,String> queryParameters = uriInfo.getQueryParameters();
if(queryParameters.containsKey(GCatConstants.COUNT_QUERY_PARAMETER)) {
countOnly = Boolean.parseBoolean(queryParameters.get(GCatConstants.ALL_FIELDS_QUERY_PARAMETER).get(0));
}
if(countOnly) {
CKANPackage ckan = getInstance();
int size = ckan.count();
return createCountJson(size);
}else {
return super.list(limit, offset);
}
}
/**
*
* The create API allows to create an item.
* An Item is mainly described by the following attributes (* indicate mandatory attributes):
*
* <dl>
* <dt>name* (string)</dt>
* <dd>
* the name of the new item, must be between 2 and 100 characters long
* and contain only lowercase alphanumeric characters, '-' and '_';
* </dd>
*
*
* <dt style="margin-top: 5px;">title (string)</dt>
* <dd>
* If not specified it assumes the same value of <em>name</em> attribute.
* The title of the item;
* </dd>
*
* <dt style="margin-top: 5px;">maintainer (string)</dt>
* <dd>the name of the items maintainer;</dd>
*
* <dt style="margin-top: 5px;">maintainer_email (string)</dt>
* <dd>the email address of the items maintainer;</dd>
*
* <dt style="margin-top: 5px;">license_id* (string)</dt>
* <dd>the id of the items license, use <a href="resource_License.html">License listing</a> API to get available values;</dd>
*
* <dt style="margin-top: 5px;">notes (string)</dt>
* <dd>a description of the item;</dd>
*
* <dt style="margin-top: 5px;">url (string)</dt>
* <dd>a URL for the items source;</dd>
*
* <dt style="margin-top: 5px;">version (string)</dt>
* <dd>must be between no longer than 100 characters</dd>
*
* <dt style="margin-top: 5px;">state (string, default='active')</dt>
* <dd>
* the current state of the item, e.g. 'active' or 'deleted', only active items show up in search results and other lists of items,
* this parameter will be ignored if you are not authorized to change the state of the item;
* </dd>
*
* <dt style="margin-top: 5px;">groups (list of dictionaries)</dt>
* <dd>
* the groups to which the item belongs, each group dictionary should have one or more of the
* following keys which identify an existing group:
* 'id' (the id of the group, string), or 'name' (the name of the group, string).
* To see which groups exist use <a href="resource_Group.html#resource_Group_list_limit_offset_countOnly_GET">Group listing</a> API.</dd>
* </dd>
*
* <dt style="margin-top: 5px;">tags (list of tag dictionaries)</dt>
* <dd>
* the items tags. The tag is a dictionary in the format:
* name : the name for the tag, i.e. a string between 2 and 100 characters long containing only alphanumeric characters and '-', '_' and '.'.
* </dd>
*
*
* <dt style="margin-top: 5px;">resources (list of resource dictionaries)</dt>
* <dd>the items resources, see <a href="resource_Resource.html">Resource collection</a> for the format of resource dictionaries;</dd>
*
*
* <dt style="margin-top: 5px;">extras (list of item extra dictionaries)</dt>
* <dd>the items extras, extras are arbitrary (key: value) metadata items that can be added to items, each extra dictionary should have keys 'key' (a string), 'value' (a string);</dd>
*
* <dt style="margin-top: 5px;">owner_org (string)</dt>
* <dd>
* the id of the items owning organization, see <code>supportedOrganizations</code> property in
* <a href="resource_Configuration.html#resource_Configuration_read_context_GET">Read Configuration</a>.
* The <code>defaultOrganization</code> is used if the author does not specify the organization.
* </dd>
*
* </dl>
*
*
* <h3>Parameter automatically managed:</h3>
* <dl>
*
* <dt>author (string)</dt>
* <dd>the name of the items author (the owner of the gcube-token);</dd>
*
* <dt style="margin-top: 5px;">author_email (string)</dt>
* <dd>the email address of the items author (the email of the owner of gcube-token);</dd>
*
* </dl>
*
*
* <h3>Geo-Indexing your datasets:</h3>
* <p>
* In order to make an Item searchable by location, it must have a special extra, with its key named spatial.
* The value must be a valid GeoJSON geometry, for example:
* </p>
* <pre>
* {
* "type":"Polygon",
* "coordinates":[[[2.05827, 49.8625],[2.05827, 55.7447], [-6.41736, 55.7447], [-6.41736, 49.8625], [2.05827, 49.8625]]]
* }
* </pre>
*
* or
*
* <pre>
* {
* "type": "Point",
* "coordinates": [-3.145,53.078]
* }
* </pre>
*
*
* <h3>Profile</h3>
* <p>
* If at least one profile has been defined within this context, then you need to specify the profile's
* type when creating the item.
* You need to insert, among the extras of the JSON object describing the item, a <code>system:type</code>
* property with one of the available profile, see <a href="resource_Profile.html#resource_Profile_listOrCount_countOnly_GET">List Profiles</a> API.
* The validation of the submitted request will be performed against the profile whose type has been specified.
* The profile's properties need to be specified within the extras field as well.
* </p>
* <p>
* If no profile has been defined, then no validation will be performed.
* Thus you do not need to set any <code>system:type</code> property.
* </p>
*
* <h3>Social Post</h3>
* <p>
* The user is going to crreate an item can indicate if he/she desires the creation of a social post
* to inform all the users of the VRE that he/she has created the item.</br>
* To request the social post he/she must indicate <code>social_post=true</code> query parameter.<br/>
* The <code>social_post</code> query parameter is optional and the default value is <code>false</code>.<br/>
* Please note that even the user indicates <code>social_post=true</code> the social post
* is create only and only if the Catalogue-Manager enabled this feature, see <code>socialPostEnabled</code> property in
* <a href="resource_Configuration.html#resource_Configuration_read_context_GET">Read Configuration</a>.
* When the social post is created the a notification to the VRe user is sent if the property
* <code>notificationToUsersEnabled</code> is true in the above mentioned configuration.
* If false <code>notificationToUsersEnabled=false</code> the social post will not produce a notification
* to the VRE user which will be only informed about the item pubblication by reading the generated
* social post in the VRE.
* </p>
*
*
* @param json containing the item to be created
* @return <code>201 Created</code> HTTP Status to indicate that the item has been created.
* Some operation could continue in background such as the social post creation.
*
* @pathExample /items?social_post=true
* @requestExample application/json;charset=UTF-8 classpath:/api-docs-examples/item/create-item-request.json
* @responseExample application/json;charset=UTF-8 classpath:/api-docs-examples/item/create-item-response.json
*
*/
@POST
@Consumes(GCatConstants.APPLICATION_JSON_CHARSET_UTF_8)
@Produces(GCatConstants.APPLICATION_JSON_CHARSET_UTF_8)
@StatusCodes ({
@ResponseCode ( code = 201, condition = "The item has been created successfully.")
})
@Override
// @AuthorizationControl(allowedRoles={Role.CATALOGUE_EDITOR, Role.CATALOGUE_ADMIN, Role.CATALOGUE_MANAGER}, exception=NotAuthorizedException.class)
public Response create(String json) {
return super.create(json);
}
/**
* @pathExample /items/my_test_item
* @responseExample application/json;charset=UTF-8 classpath:/api-docs-examples/item/read-item-response.json
*/
@GET
@Path("/{" + ITEM_ID_PARAMETER + "}")
@Produces(GCatConstants.APPLICATION_JSON_CHARSET_UTF_8)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "The item exists.")
})
@Override
/* Catalogue-Member is not added to VRE members and is assumed as the default role in the catalogue for the VRE members. So we can't enforce
* @AuthorizationControl(allowedRoles={Role.CATALOGUE_MEMBER, Role.CATALOGUE_EDITOR, Role.CATALOGUE_ADMIN, Role.CATALOGUE_MANAGER}, exception=NotAuthorizedException.class)
*/
public String read(@PathParam(ITEM_ID_PARAMETER) String id) {
return super.read(id);
}
/**
* Any Catalogue-Admins or above is capable of modifying the authorship of the item.<br/>
* The service does not perform any check on author information provided by the user.
*
* @pathExample /items/my_test_item
* @requestExample application/json;charset=UTF-8 classpath:/api-docs-examples/item/update-item-request.json
* @responseExample application/json;charset=UTF-8 classpath:/api-docs-examples/item/update-item-response.json
*/
@PUT
@Path("/{" + ITEM_ID_PARAMETER + "}")
@Consumes(GCatConstants.APPLICATION_JSON_CHARSET_UTF_8)
@Produces(GCatConstants.APPLICATION_JSON_CHARSET_UTF_8)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "The item has been updated successfully.")
})
@Override
// @AuthorizationControl(allowedRoles={Role.CATALOGUE_EDITOR, Role.CATALOGUE_ADMIN, Role.CATALOGUE_MANAGER}, exception=NotAuthorizedException.class)
public String update(@PathParam(ITEM_ID_PARAMETER) String id, String json) {
return super.update(id, json);
}
/**
* @pathExample /items/my_test_item
* @requestExample application/json;charset=UTF-8 classpath:/api-docs-examples/item/patch-item-request.json
* @responseExample application/json;charset=UTF-8 classpath:/api-docs-examples/item/patch-item-response.json
*/
@PATCH
@Path("/{" + ITEM_ID_PARAMETER + "}")
@Consumes(GCatConstants.APPLICATION_JSON_CHARSET_UTF_8)
@Produces(GCatConstants.APPLICATION_JSON_CHARSET_UTF_8)
@StatusCodes ({
@ResponseCode ( code = 200, condition = "The item has been patched successfully.")
})
@Override
// @AuthorizationControl(allowedRoles={Role.CATALOGUE_EDITOR, Role.CATALOGUE_ADMIN, Role.CATALOGUE_MANAGER}, exception=NotAuthorizedException.class)
public String patch(@PathParam(ITEM_ID_PARAMETER) String id, String json) {
return super.patch(id, json);
}
/**
* @pathExample /items/my_test_item
*/
@DELETE
@Path("/{" + ITEM_ID_PARAMETER + "}")
@StatusCodes ({
@ResponseCode ( code = 204, condition = "The item has been deleted successfully."),
@ResponseCode ( code = 404, condition = "The item was not found.")
})
@Override
// @AuthorizationControl(allowedRoles={Role.CATALOGUE_EDITOR, Role.CATALOGUE_ADMIN, Role.CATALOGUE_MANAGER}, exception=NotAuthorizedException.class)
public Response delete(@PathParam(ITEM_ID_PARAMETER) String id,
@QueryParam(GCatConstants.PURGE_QUERY_PARAMETER) @DefaultValue("false") Boolean purge) {
return super.delete(id, purge);
}
/**
* @pathExample /items/my_test_item
*/
@PURGE
@Path("/{" + ITEM_ID_PARAMETER + "}")
@StatusCodes ({
@ResponseCode ( code = 204, condition = "The item has been purged successfully."),
@ResponseCode ( code = 404, condition = "The item was not found.")
})
@Override
// @AuthorizationControl(allowedRoles={Role.CATALOGUE_EDITOR, Role.CATALOGUE_ADMIN, Role.CATALOGUE_MANAGER}, exception=NotAuthorizedException.class)
public Response purge(@PathParam(ITEM_ID_PARAMETER) String id) {
return super.purge(id);
}
@Override
public Response delete(String name, boolean purge) throws WebServiceException {
return delete(name, new Boolean(purge));
}
protected void deleteAll(boolean purge) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
CKANPackage ckan = getInstance();
String ret = ckan.deleteAll(purge);
logger.info("Result of delete all is {}", ret);
}
});
thread.start();
}
/**
* <p>
* The bulk delete API provides a way to delete all the items matching certain criteria
* (see Filtering Listing options).
* The operation returns immediately to the client and continues in background.
* There is no way to monitor or stop the running operation.
* </p>
*
* <p>
* When invoked with no arguments, it deletes all the items of the invoking user in the default
* CKAN organization for the current context.
* </p>
*
* <p>
* If a <em>Catalogue-Admin</em> or above specifies the query parameter <em>own_only=false</em>
* it deletes all the items of all users for the CKAN organization for the current context.
* The service ignores the query parameter <em>own_only=false</em> if the requesting user is not
* Catalogue-Admin or above.
* </p>
*
* <p style="font-weight:bold;">
* Please check the result using the items listing APIs to verify what you will delete.
* </p>
*
* <p>
* The deleted items are moved to the thrash by default.
* To completely remove the items (i.e. purge) the user can use the query parameter <em>purge=true</em>.
* <span style="font-weight:bold;">Please note that the purge action is not reversible.</span>
* </p>
*
* <p>
* By indicating the query parameter <em>purge=true</em> has the same result of using the bulk
* purge API using the <code>PURGE</code> HTTP Method.
* </p>
*
* @param purge <em>(Default:false)</em> it completely removes all the items in the default CKAN organization.
* @return <code>202 Accepted</code> HTTP Status to indicate that the request has been properly take in charge.
* The operation will continue in background.
* @throws WebServiceException if an error occurs.
*
* @pathExample /items?purge=false
*
*/
@DELETE
@Produces(GCatConstants.APPLICATION_JSON_CHARSET_UTF_8)
@StatusCodes ({
@ResponseCode ( code = 202, condition = "The bulk delete/purge has been accepted successfully.")
})
@Override
// @AuthorizationControl(allowedRoles={Role.CATALOGUE_EDITOR, Role.CATALOGUE_ADMIN, Role.CATALOGUE_MANAGER}, exception=NotAuthorizedException.class)
public Response bulkDelete(@QueryParam(GCatConstants.PURGE_QUERY_PARAMETER) @DefaultValue("false") boolean purge) {
deleteAll(purge);
return Response.status(Status.ACCEPTED).build();
}
/**
* <p>
* The bulk purge API provides a way to completely remove all the items matching certain criteria
* (see Filtering Listing options). Please note that this action is not reversible.
* The operation returns immediately to the client and continues in background.
* There is no way to monitor or stop the running operation.
* </p>
*
* <p>
* When invoked with no arguments, it purges all the items of the invoking user in the default
* CKAN organization for the current context.
* </p>
*
* <p>
* If a Catalogue-Admin or above specifies the query parameter <em>own_only=false</em>,
* it purges all the items of all users for the CKAN organization for the current context.
* The service ignores the query parameter <em>own_only=false</em> if the requesting user is not
* Catalogue-Admin or above.
* </p>
*
* <p style="font-weight:bold;">
* Please check the result using the items listing APIs to verify what you will purge.
* </p>
*
* <p>
* Invoking this API has the same result of using the bulk delete API using the <code>DELETE</code> HTTP Method
* with the query parameters <em>purge=true</em>.
* </p>
*
* @return <code>202 Accepted</code> HTTP Status to indicate that the request has been
* properly taken in charge.<br />
* The operation will continue in background.
*
* @throws WebServiceException if an error occurs.
*
* @pathExample /items
*/
@PURGE
@Produces(GCatConstants.APPLICATION_JSON_CHARSET_UTF_8)
@StatusCodes ({
@ResponseCode ( code = 202, condition = "The bulk purge has been accepted successfully.")
})
@Override
// @AuthorizationControl(allowedRoles={Role.CATALOGUE_EDITOR, Role.CATALOGUE_ADMIN, Role.CATALOGUE_MANAGER}, exception=NotAuthorizedException.class)
public Response bulkPurge() {
return bulkDelete(true);
}
/**
*
* @param id the name of the item to moderate
* @param json It contains the moderation action to perform on the item.
*
* <p>The format is the following</p>
*
* <pre>
* {
* "system:cm_item_status":"approved",
* "message": "..."
* }
* </pre>
*
* <p>
* The field <code>system:cm_item_status</code> can have
* the following values: <code>approved</code> or <code>rejected</code>, indicating the
* item's new status.<br />
* It is possible to send an optional message together with the new status by adding
* the field <code>message</code>.<br />
* This operation is available for Catalogue-Moderator only.
* </p>
*
* <p>
* Catalogue-Moderator and item author can send just a message to discuss
* the approval of the item by indicating the field <code>message</code> only.
* </p>
*
* @return <code>202 Accepted</code> HTTP Status to indicate that the request has been
* properly taken in charge.<br />
* The operation will continue in background.
*
* @pathExample /items/my_test_item
* @requestExample application/json;charset=UTF-8 classpath:/api-docs-examples/item/reject.json
*/
@POST
@Path("/{" + ITEM_ID_PARAMETER + "}")
@Consumes(GCatConstants.APPLICATION_JSON_CHARSET_UTF_8)
@Produces(GCatConstants.APPLICATION_JSON_CHARSET_UTF_8)
@StatusCodes ({
@ResponseCode ( code = 202, condition = "The moderation operation has been accepted successfully.")
})
// @AuthorizationControl(allowedRoles={Role.CATALOGUE_EDITOR, Role.CATALOGUE_ADMIN, Role.CATALOGUE_MANAGER, Moderated.CATALOGUE_MODERATOR}, exception=NotAuthorizedException.class)
public Response moderate(@PathParam(ITEM_ID_PARAMETER) String id, String json) {
setCalledMethod("POST /" + COLLECTION_PARAMETER + "/{" + ID_PARAMETER + "}");
CKANPackage ckanPackage = getInstance();
ckanPackage.setName(id);
String ret = ckanPackage.moderate(json);
ResponseBuilder responseBuilder = Response.status(Status.ACCEPTED);
if(ret!=null) {
responseBuilder.entity(ret).type(GCatConstants.APPLICATION_JSON_CHARSET_UTF_8);
}
return responseBuilder.build();
}
}