Merged changes made in branch

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-catalogue/grsf-publisher-ws@171271 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Luca Frosini 2018-09-03 09:07:06 +00:00
parent 163710176a
commit 9774bcd2ef
7 changed files with 316 additions and 246 deletions

View File

@ -9,6 +9,10 @@
<Change>Added 'Connected'-'Not Connected' tag to GRSF Records #11766</Change>
<Change>Added group for SDG flag #11767</Change>
<Change>Added citation field #11811</Change>
<Change>Added sub-groups support for available time series related to GRSF Type "Assessment Unit" #11832</Change>
<Change>Added Biomass group #11967</Change>
<Change>Changed 'State and trend of Marine Resource' to 'State and Trend' #11968</Change>
<Change>Changed 'Scientific advice' to 'Scientific Advice' #11969</Change>
</Changeset>
<Changeset component="org.gcube.data-catalogue.grsf-publisher-ws.1-5-0"
date="2017-01-10">

View File

@ -11,7 +11,7 @@
<groupId>org.gcube.data-catalogue</groupId>
<artifactId>grsf-publisher-ws</artifactId>
<version>1.6.0-SNAPSHOT</version>
<version>1.7.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>grsf-publisher-ws</name>

View File

@ -7,7 +7,8 @@ import java.lang.annotation.Target;
/**
* Group annotation
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
* @author Costantino Perciante (ISTI - CNR)
* @author Luca Frosini (ISTI - CNR)
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@ -26,4 +27,11 @@ public @interface Group {
*/
String groupNameOverValue() default "";
/**
* When the group is created the source is prepended to the group name.
* Set to false to avoid source prepending
* @return
*/
boolean prependSourceToGroupName() default true;
}

View File

@ -26,6 +26,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
* Information that both Stock and Fishery records must contain.
* @author Costantino Perciante (ISTI - CNR)
* @author Luca Frosini (ISTI - CNR)
*
*/
public abstract class Common extends Base{
@ -72,12 +73,14 @@ public abstract class Common extends Base{
@JsonProperty(Constants.CATCHES_JSON_KEY)
@CustomField(key=Constants.CATCHES_CUSTOM_KEY)
@TimeSeries
@Group(groupNameOverValue=Constants.CATCHES_CUSTOM_KEY, prependSourceToGroupName=false)
@Valid
private List<TimeSeriesBean<String, String>> catches;
@JsonProperty(Constants.LANDINGS_JSON_KEY)
@CustomField(key=Constants.LANDINGS_CUSTOM_KEY)
@TimeSeries
@Group(groupNameOverValue=Constants.LANDINGS_CUSTOM_KEY, prependSourceToGroupName=false)
@Valid
private List<TimeSeriesBean<String, String>> landings;

View File

@ -16,10 +16,12 @@ import com.fasterxml.jackson.annotation.JsonProperty;
/**
* A fishery record bean.
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
* @author Costantino Perciante (ISTI - CNR)
* @author Luca Frosini (ISTI - CNR)
*/
public class FisheryRecord extends Common {
@JsonProperty(Constants.FISHERY_NAME_JSON_KEY)
@NotNull(message="fishery_name cannot be null")
@Size(min=1, message="fishery_name cannot be empty")

View File

@ -20,7 +20,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
/**
* A stock record bean.
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
* @author Costantino Perciante (ISTI - CNR)
* @author Luca Frosini (ISTI - CNR)
*/
public class StockRecord extends Common{
@ -50,47 +51,55 @@ public class StockRecord extends Common{
@JsonProperty(Constants.FIRMS_ABUNDANCE_LEVEL_JSON_KEY)
@CustomField(key=Constants.FIRMS_ABUNDANCE_LEVEL_CUSTOM_KEY)
@TimeSeries
@Group(groupNameOverValue=Constants.FIRMS_ABUNDANCE_LEVEL_CUSTOM_KEY, prependSourceToGroupName=false)
@Valid
private List<TimeSeriesBean<Abundance_Level, Void>> abundanceLevelStandard;
@JsonProperty(Constants.ABUNDANCE_LEVEL_JSON_KEY)
@CustomField(key=Constants.ABUNDANCE_LEVEL_CUSTOM_KEY)
@TimeSeries
@Group(groupNameOverValue=Constants.ABUNDANCE_LEVEL_CUSTOM_KEY, prependSourceToGroupName=false)
@Valid
private List<TimeSeriesBean<String, String>> abundanceLevel;
@JsonProperty(Constants.BIOMASS_JSON_KEY)
@CustomField(key=Constants.BIOMASS_CUSTOM_KEY)
@TimeSeries
@Group(groupNameOverValue=Constants.BIOMASS_CUSTOM_KEY, prependSourceToGroupName=false)
@Valid
private List<TimeSeriesBean<String, String>> biomass;
@JsonProperty(Constants.FISHING_PRESSURE_FIRMS_JSON_KEY)
@CustomField(key=Constants.FISHING_PRESSURE_FIRMS_CUSTOM_KEY)
@TimeSeries
@Group(groupNameOverValue=Constants.FISHING_PRESSURE_FIRMS_CUSTOM_KEY, prependSourceToGroupName=false)
@Valid
private List<TimeSeriesBean<Fishing_Pressure, Void>> fishingPressureStandard;
@JsonProperty(Constants.FISHING_PRESSURE_JSON_KEY)
@CustomField(key=Constants.FISHING_PRESSURE_CUSTOM_KEY)
@TimeSeries
@Group(groupNameOverValue=Constants.FISHING_PRESSURE_CUSTOM_KEY, prependSourceToGroupName=false)
@Valid
private List<TimeSeriesBean<String, String>> fishingPressure;
@JsonProperty(Constants.STATE_AND_TREND_MARINE_RESOURCE_JSON_KEY)
@CustomField(key=Constants.STATE_AND_TREND_MARINE_RESOURCE_CUSTOM_KEY)
@TimeSeries
@Group(groupNameOverValue=Constants.STATE_AND_TREND_MARINE_RESOURCE_CUSTOM_KEY, prependSourceToGroupName=false)
@Valid
private List<TimeSeriesBean<String, Void>> narrativeState;
@JsonProperty(Constants.FAO_CATEGORIES_JSON_KEY)
@CustomField(key=Constants.FAO_CATEGORIES_CUSTOM_KEY)
@TimeSeries
@Group(groupNameOverValue=Constants.FAO_CATEGORIES_CUSTOM_KEY, prependSourceToGroupName=false)
@Valid
private List<TimeSeriesBean<String, Void>> faoState;
@JsonProperty(Constants.SCIENTIFIC_ADVICE_JSON_KEY)
@CustomField(key=Constants.SCIENTIFIC_ADVICE_CUSTOM_KEY)
@Group(groupNameOverValue=Constants.SCIENTIFIC_ADVICE_CUSTOM_KEY, prependSourceToGroupName=false)
private List<String> scientificAdvice;
@JsonProperty(Constants.ASSESSOR_JSON_KEY)

View File

@ -36,6 +36,7 @@ import org.gcube.datacatalogue.common.Constants;
import org.gcube.datacatalogue.common.enums.Product_Type;
import org.gcube.datacatalogue.common.enums.Sources;
import org.gcube.datacatalogue.common.enums.Status;
import org.gcube.datacatalogue.common.enums.Stock_Type;
import org.json.simple.JSONObject;
import org.slf4j.LoggerFactory;
@ -44,7 +45,8 @@ import eu.trentorise.opendata.jackan.model.CkanLicense;
/**
* Services common utils.
* @author Costantino Perciante at ISTI-CNR
* @author Costantino Perciante (ISTI - CNR)
* @author Luca Frosini (ISTI - CNR)
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public class CommonServiceUtils {
@ -108,7 +110,8 @@ public class CommonServiceUtils {
List<String> fishingArea = fishery.getFishingArea();
List<String> jurisdictionArea = fishery.getJurisdictionArea();
if((fishingArea == null || fishingArea.isEmpty()) && (jurisdictionArea == null || jurisdictionArea.isEmpty()))
if((fishingArea == null || fishingArea.isEmpty())
&& (jurisdictionArea == null || jurisdictionArea.isEmpty()))
throw new Exception("fishing_area and jurisdiction_area cannot be null/empty at the same time!");
}
}
@ -126,17 +129,9 @@ public class CommonServiceUtils {
* @param username
* @param source
*/
public static void getTagsGroupsResourcesExtrasByRecord(
Set<String> tags,
boolean skipTags,
Set<String> groups,
boolean skipGroups,
List<ResourceBean> resources,
boolean skipResources,
Map<String, List<String>> extras,
Base record,
String username,
Sources source // it comes from the source type e.g., "grsf-", "ram-" ..
public static void getTagsGroupsResourcesExtrasByRecord(Set<String> tags, boolean skipTags, Set<String> groups,
boolean skipGroups, List<ResourceBean> resources, boolean skipResources, Map<String,List<String>> extras,
Base record, String username, Sources source // it comes from the source type e.g., "grsf-", "ram-" ..
) {
Class<?> current = record.getClass();
@ -156,8 +151,7 @@ public class CommonServiceUtils {
getResourcesByField(field, current, record, username, resources);
}
}
while((current = current.getSuperclass())!=null); // start from the inherited class up to the Object.class
} while((current = current.getSuperclass()) != null); // start from the inherited class up to the Object.class
logger.debug("Tags are " + tags);
logger.debug("Groups are " + groups);
@ -183,16 +177,19 @@ public class CommonServiceUtils {
// check if it is a time series, in this take the last X elements
if(asList.get(0).getClass().equals(TimeSeriesBean.class)) {
elementsToConsider = Math.min(elementsToConsider, Constants.TIME_SERIES_TAKE_LAST_VALUES);
elementsToConsider = Math.min(elementsToConsider,
Constants.TIME_SERIES_TAKE_LAST_VALUES);
for(int i = 0; i < elementsToConsider; i++) {
String finalTag = asList.get(i).toString().trim().replaceAll(Constants.REGEX_TAGS, "");
String finalTag = asList.get(i).toString().trim().replaceAll(Constants.REGEX_TAGS,
"");
if(finalTag.length() <= TAG_MAX_SIZE)
tags.add(finalTag);
}
} else {
// else add all the available elements
for(int i = 0; i < elementsToConsider; i++) {
String finalTag = asList.get(i).toString().trim().replaceAll(Constants.REGEX_TAGS, "");
String finalTag = asList.get(i).toString().trim().replaceAll(Constants.REGEX_TAGS,
"");
if(finalTag.length() <= TAG_MAX_SIZE)
tags.add(finalTag);
}
@ -216,10 +213,29 @@ public class CommonServiceUtils {
/**
* Retrieve the list of groups' names for this object
*/
private static void getGroupsByField(Field field, Class<?> current, Base record, Set<String> groups, Sources source){
private static void getGroupsByField(Field field, Class<?> current, Base record, Set<String> groups,
Sources source) {
if(field.isAnnotationPresent(Group.class)) {
String conditionToCheck = field.getAnnotation(Group.class).condition();
String groupNameOverValue = field.getAnnotation(Group.class).groupNameOverValue();
Group group = field.getAnnotation(Group.class);
String conditionToCheck = group.condition();
String groupNameOverValue = group.groupNameOverValue();
// See https://support.d4science.org/issues/11832
boolean assessmentUnit = false;
boolean prependSource = group.prependSourceToGroupName();
if(record instanceof StockRecord) {
StockRecord stockRecord = (StockRecord) record;
Stock_Type stock_Type = stockRecord.getType();
if(stock_Type != Stock_Type.Assessment_Unit) {
prependSource = false;
}else {
assessmentUnit = true;
}
}
// end patch for https://support.d4science.org/issues/11832
try {
Object f = new PropertyDescriptor(field.getName(), current).getReadMethod().invoke(record);
if(f != null) {
@ -231,26 +247,42 @@ public class CommonServiceUtils {
// else add all the available elements
for(int i = 0; i < asList.size(); i++) {
boolean match = conditionToCheck.isEmpty() ? true : asList.get(i).toString().trim().matches(conditionToCheck);
boolean match = conditionToCheck.isEmpty() ? true
: asList.get(i).toString().trim().matches(conditionToCheck);
if(match) {
String groupName = groupNameOverValue.isEmpty() ?
HelperMethods.getGroupNameOnCkan(source.toString().toLowerCase() + "-" + asList.get(i).toString().trim()) :
source.toString().toLowerCase() + "-" + groupNameOverValue;
String groupName = groupNameOverValue.isEmpty()
? HelperMethods.getGroupNameOnCkan(source.toString().toLowerCase() + "-"
+ asList.get(i).toString().trim())
: source.toString().toLowerCase() + "-" + groupNameOverValue;
if(assessmentUnit && !prependSource) {
groups.add(groupNameOverValue);
}else {
groups.add(groupName);
}
}
}
}
} else {
// also convert to the group name that should be on ckan
boolean match = conditionToCheck.isEmpty() ? true : f.toString().trim().matches(conditionToCheck);
boolean match = conditionToCheck.isEmpty() ? true
: f.toString().trim().matches(conditionToCheck);
if(match) {
String groupName = groupNameOverValue.isEmpty() ?
HelperMethods.getGroupNameOnCkan(source.toString().toLowerCase() + "-" + f.toString().trim()) :
source.toString().toLowerCase() + "-" + groupNameOverValue;
String groupName = groupNameOverValue.isEmpty()
? HelperMethods.getGroupNameOnCkan(
source.toString().toLowerCase() + "-" + f.toString().trim())
: source.toString().toLowerCase() + "-" + groupNameOverValue;
if(assessmentUnit && !prependSource) {
groups.add(groupNameOverValue);
}else {
groups.add(groupName);
}
}
}
@ -267,7 +299,8 @@ public class CommonServiceUtils {
* Retrieve the list of extras for this object
* @param source
*/
private static void getExtrasByField(Field field, Class<?> current, Base record, Map<String, List<String>> extras, Sources source){
private static void getExtrasByField(Field field, Class<?> current, Base record, Map<String,List<String>> extras,
Sources source) {
if(field.isAnnotationPresent(CustomField.class)) {
try {
Object f = new PropertyDescriptor(field.getName(), current).getReadMethod().invoke(record);
@ -301,7 +334,8 @@ public class CommonServiceUtils {
valuesForKey = new HashSet<String>();
if(f instanceof List<?>) {
logger.debug("The object " + field.getName() + " is a list and is annotated with @CustomField. Adding ...");
logger.debug("The object " + field.getName()
+ " is a list and is annotated with @CustomField. Adding ...");
List asList = (List) f;
if(!asList.isEmpty()) {
@ -309,14 +343,14 @@ public class CommonServiceUtils {
// check if it is a time series, in this case take the last X elements
if(asList.get(0).getClass().equals(TimeSeriesBean.class)) {
elementsToConsider = Math.min(elementsToConsider, Constants.TIME_SERIES_TAKE_LAST_VALUES);
elementsToConsider = Math.min(elementsToConsider,
Constants.TIME_SERIES_TAKE_LAST_VALUES);
for(int i = 0; i < elementsToConsider; i++) {
// trim and remove html
String clean = HelperMethods.removeHTML(asList.get(i).toString().trim());
valuesForKey.add(clean);
}
}
else
} else
for(int i = 0; i < elementsToConsider; i++) {
String clean = HelperMethods.removeHTML(asList.get(i).toString().trim());
valuesForKey.add(clean);
@ -345,7 +379,8 @@ public class CommonServiceUtils {
* @param resources
* @return
*/
private static void getResourcesByField(Field field, Class<?> current, Base record, String username, List<ResourceBean> resources){
private static void getResourcesByField(Field field, Class<?> current, Base record, String username,
List<ResourceBean> resources) {
if(field.isAnnotationPresent(CkanResource.class)) {
try {
Object f = new PropertyDescriptor(field.getName(), current).getReadMethod().invoke(record);
@ -356,13 +391,15 @@ public class CommonServiceUtils {
List<Resource> listOfResources = (List<Resource>) f;
for(Resource resource : listOfResources) {
resources.add(new ResourceBean(resource.getUrl(), resource.getName().toString(), resource.getDescription(), null, username, null, null));
resources.add(new ResourceBean(resource.getUrl(), resource.getName().toString(),
resource.getDescription(), null, username, null, null));
}
} else {
Resource res = (Resource) f;
resources.add(new ResourceBean(res.getUrl(), res.getName().toString(), res.getDescription(), null, username, null, null));
resources.add(new ResourceBean(res.getUrl(), res.getName().toString(), res.getDescription(),
null, username, null, null));
}
}
@ -376,13 +413,15 @@ public class CommonServiceUtils {
* Evaluate if the user has the admin role
* Throws exception if he/she doesn't
*/
public static void hasAdminRole(String username, DataCatalogue catalogue, String apiKey, String organization) throws Exception{
public static void hasAdminRole(String username, DataCatalogue catalogue, String apiKey, String organization)
throws Exception {
String role = catalogue.getRoleOfUserInOrganization(username, organization, apiKey);
logger.info("Role of the user " + username + " is " + role + " in " + organization);
if(role == null || role.isEmpty() || !role.equalsIgnoreCase(RolesCkanGroupOrOrg.ADMIN.toString()))
throw new Exception("You are not authorized to create a product. Please check you have the Catalogue-Administrator role!");
throw new Exception(
"You are not authorized to create a product. Please check you have the Catalogue-Administrator role!");
}
@ -395,7 +434,8 @@ public class CommonServiceUtils {
public static void checkName(String futureName, DataCatalogue catalogue) throws Exception {
if(!HelperMethods.isNameValid(futureName)) {
throw new Exception("The 'uuid_knowledge_base' must contain only alphanumeric characters, and symbols like '.' or '_', '-'");
throw new Exception(
"The 'uuid_knowledge_base' must contain only alphanumeric characters, and symbols like '.' or '_', '-'");
} else {
logger.debug("Checking if such name [" + futureName + "] doesn't exist ...");
@ -425,8 +465,9 @@ public class CommonServiceUtils {
* @throws Exception
*/
public static void validateRecordAndMapFields(String apiKey, String context, ServletContext contextServlet,
Sources sourceInPath, Common record, Product_Type productType, Set<String> tags, Map<String, List<String>> customFields,
Set<String> groups, List<ResourceBean> resources, String username, String futureTitle) throws Exception {
Sources sourceInPath, Common record, Product_Type productType, Set<String> tags,
Map<String,List<String>> customFields, Set<String> groups, List<ResourceBean> resources, String username,
String futureTitle) throws Exception {
// validate the record if it is a GRSF one and set the record type and in manage context
// Status field is needed only in the Manage context for GRSF records
@ -443,7 +484,8 @@ public class CommonServiceUtils {
// we have the id within the catalog of this record. This means that we can retrieve the record and its system:type
for(RefersToBean refersToBean : refersTo) {
String sourceOrganization = getRecordOrganization(refersToBean.getId(), apiKey, context);
resources.add(new ResourceBean(refersToBean.getUrl(), sourceOrganization , "", null, username, null, null));
resources.add(new ResourceBean(refersToBean.getUrl(), sourceOrganization, "", null, username, null,
null));
sourcesList.add(sourceOrganization.toLowerCase());
databaseSource += sourceOrganization + " ";
}
@ -463,8 +505,10 @@ public class CommonServiceUtils {
record.setDomain(productType.getOrigName());
// set system type (it is equal to the GRSF Type for GRSF records, "Legacy" for source records)
record.setSystemType(sourceInPath.equals(Sources.GRSF) ?
productType.equals(Product_Type.FISHERY) ? ((FisheryRecord)record).getType().getOrigName() : ((StockRecord)record).getType().getOrigName()
record.setSystemType(
sourceInPath.equals(Sources.GRSF)
? productType.equals(Product_Type.FISHERY) ? ((FisheryRecord) record).getType().getOrigName()
: ((StockRecord) record).getType().getOrigName()
: Constants.SYSTEM_TYPE_FOR_SOURCES_VALUE);
logger.debug("Domain is " + productType.getOrigName() + " and system type " + record.getSystemType());
@ -472,7 +516,8 @@ public class CommonServiceUtils {
// evaluate the custom fields/tags, resources and groups
groups.add(sourceInPath.getOrigName().toLowerCase() + "-" + productType.getOrigName().toLowerCase()); //e.g. grsf-fishery
boolean skipTags = !sourceInPath.equals(Sources.GRSF); // no tags for the Original records
CommonServiceUtils.getTagsGroupsResourcesExtrasByRecord(tags, skipTags, groups, false, resources, false, customFields, record, username, sourceInPath);
CommonServiceUtils.getTagsGroupsResourcesExtrasByRecord(tags, skipTags, groups, false, resources, false,
customFields, record, username, sourceInPath);
}
@ -483,8 +528,8 @@ public class CommonServiceUtils {
* @param productType
* @param sourceInPath
*/
private static void addRecordToGroupSources(Set<String> groups,
List<String> sourcesList, Product_Type productType, Sources sourceInPath) {
private static void addRecordToGroupSources(Set<String> groups, List<String> sourcesList, Product_Type productType,
Sources sourceInPath) {
Collections.sort(sourcesList); // be sure the name are sorted because the groups have been generated this way
String groupName = sourceInPath.getOrigName().toLowerCase() + "-" + productType.getOrigName().toLowerCase();
@ -539,18 +584,20 @@ public class CommonServiceUtils {
* @param partialDescription
* @throws InterruptedException
*/
public static void actionsPostCreateOrUpdate(
final String datasetId, final String futureName, final Common record, final String apiKey, final String username, final String organization, String itemUrl,
ResponseCreationBean responseBean, final DataCatalogue catalogue,
Map<String, String> namespaces, final Set<String> groups, final String context,
final String token, final String futureTitle, final String authorFullname, final ServletContext contextServlet, final boolean isUpdated,
public static void actionsPostCreateOrUpdate(final String datasetId, final String futureName, final Common record,
final String apiKey, final String username, final String organization, String itemUrl,
ResponseCreationBean responseBean, final DataCatalogue catalogue, Map<String,String> namespaces,
final Set<String> groups, final String context, final String token, final String futureTitle,
final String authorFullname, final ServletContext contextServlet, final boolean isUpdated,
String description) throws InterruptedException {
// on create, we need to add the item url... the description can be set on create and update instead
if(!isUpdated) {
itemUrl = catalogue.getUnencryptedUrlFromDatasetIdOrName(futureName);
Map<String,List<String>> addField = new HashMap<String,List<String>>();
String modifiedUUIDKey = namespaces.containsKey(Constants.ITEM_URL_FIELD) ? namespaces.get(Constants.ITEM_URL_FIELD) : Constants.ITEM_URL_FIELD;
String modifiedUUIDKey = namespaces.containsKey(Constants.ITEM_URL_FIELD)
? namespaces.get(Constants.ITEM_URL_FIELD)
: Constants.ITEM_URL_FIELD;
addField.put(modifiedUUIDKey, Arrays.asList(itemUrl));
catalogue.patchProductCustomFields(datasetId, apiKey, addField, false);
}
@ -577,7 +624,8 @@ public class CommonServiceUtils {
// manage groups (wait thread to die: ckan doesn't support too much concurrency on same record ...)
if(!groups.isEmpty()) {
logger.info("Launching thread for association to the list of groups " + groups);
AssociationToGroupThread threadGroups = new AssociationToGroupThread(new ArrayList<String>(groups), datasetId, organization, username, catalogue, apiKey);
AssociationToGroupThread threadGroups = new AssociationToGroupThread(
new ArrayList<String>(groups), datasetId, organization, username, catalogue, apiKey);
threadGroups.start();
threadGroups.join();
}
@ -586,15 +634,10 @@ public class CommonServiceUtils {
new ManageTimeSeriesThread(record, futureName, username, catalogue, context, token).start();
// write a post if the product has been published in grsf context
if(!isUpdated && context.equals((String)contextServlet.getInitParameter(HelperMethods.PUBLIC_CONTEX_KEY))){
new WritePostCatalogueManagerThread(
context,
token,
futureTitle,
itemUrlForThread,
true,
new ArrayList<String>(),
authorFullname).start();
if(!isUpdated && context
.equals((String) contextServlet.getInitParameter(HelperMethods.PUBLIC_CONTEX_KEY))) {
new WritePostCatalogueManagerThread(context, token, futureTitle, itemUrlForThread, true,
new ArrayList<String>(), authorFullname).start();
logger.info("Thread to write a post about the new product has been launched");
}
} catch(InterruptedException e) {
@ -611,7 +654,8 @@ public class CommonServiceUtils {
* @param organization
* @param admin
*/
public static void extendRoleToOtherOrganizations(String username, DataCatalogue catalogue, String organization, RolesCkanGroupOrOrg admin) {
public static void extendRoleToOtherOrganizations(String username, DataCatalogue catalogue, String organization,
RolesCkanGroupOrOrg admin) {
logger.debug("Checking if role extension is needed here");
if(extensionsCheck.containsKey(username) && extensionsCheck.get(username))