diff --git a/pom.xml b/pom.xml index 5c05c08..24bd7e7 100644 --- a/pom.xml +++ b/pom.xml @@ -135,6 +135,12 @@ jersey-bean-validation ${version.jersey} + + javax.servlet + servlet-api + 3.0-alpha-1 + compile + org.glassfish.jersey.test-framework.providers jersey-test-framework-provider-jetty diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/custom_annotations/Group.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/custom_annotations/Group.java index 7f4205a..508eb3e 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/custom_annotations/Group.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/custom_annotations/Group.java @@ -13,6 +13,4 @@ import java.lang.annotation.Target; @Target({ElementType.FIELD, ElementType.TYPE}) public @interface Group { - Class parentGroup() default Class.class; - } diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/Common.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/Common.java index 0e0a185..5f2d735 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/Common.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/Common.java @@ -1,5 +1,6 @@ package org.gcube.data_catalogue.grsf_publish_ws.json.input; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -12,9 +13,14 @@ import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.CkanResource; import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.CustomField; import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.Group; import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.Tag; +import org.gcube.data_catalogue.grsf_publish_ws.utils.HelperMethods; import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Source; import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Status; +import org.gcube.datacatalogue.ckanutillibrary.models.ResourceBean; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; @@ -22,11 +28,12 @@ import com.fasterxml.jackson.annotation.JsonProperty; * Information that both Stock and Fishery must contain * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) */ -@JsonIgnoreProperties(value = {"author", "author_contact", "extras", "product_type"}, ignoreUnknown = true) // ignore in serialization/deserialization +@JsonIgnoreProperties(value = {"author", "author_contact", "product_type"}) // ignore in serialization/deserialization public class Common { + private static Logger logger = LoggerFactory.getLogger(Common.class); public static final String PRODUCT_TYPE_KEY = "Product type"; - + @JsonProperty("description") private String description; @@ -58,15 +65,11 @@ public class Common { @CkanResource @NotNull(message="database_source cannot be null") @Size(min=1, message="database_source cannot be empty") - @Tag - @Group @Valid private List> databaseSources; @JsonProperty("source_of_information") @CkanResource - @NotNull(message="source_of_information cannot be null") - @Size(min=1, message="source_of_information cannot be empty") @Valid private List> sourceOfInformation; @@ -100,9 +103,16 @@ public class Common { @Tag @Group private String productType; - - @JsonProperty("extras") - private Map> extras = new HashMap<>(); + + @JsonProperty("reporting_year") + @CustomField(key="Reporting year") + private Long reportingYear; + + @JsonProperty("extras_fields") + private Map> extrasFields = new HashMap<>(); + + @JsonProperty("extras_resources") + private List extrasResources = new ArrayList(); public Common() { super(); @@ -117,26 +127,27 @@ public class Common { * @param authorContact * @param maintainer * @param maintainerContact - * @param catchesOrLandings + * @param dataOwner * @param databaseSources * @param sourceOfInformation - * @param dataOwner - * @param type * @param shortTitle * @param uuid * @param traceabilityFlag - * @param extras * @param status * @param productType + * @param reportingYear + * @param extrasFields + * @param extrasResources */ public Common(String description, String license, String author, Long version, String authorContact, String maintainer, - String maintainerContact, + String maintainerContact, String dataOwner, List> databaseSources, - List> sourceOfInformation, String dataOwner, - String shortTitle, String uuid, - boolean traceabilityFlag, Map> extras, - Status status, String productType) { + List> sourceOfInformation, String shortTitle, + String uuid, boolean traceabilityFlag, Status status, + String productType, Long reportingYear, + Map> extrasFields, + List extrasResources) { super(); this.description = description; this.license = license; @@ -145,21 +156,47 @@ public class Common { this.authorContact = authorContact; this.maintainer = maintainer; this.maintainerContact = maintainerContact; + this.dataOwner = dataOwner; this.databaseSources = databaseSources; this.sourceOfInformation = sourceOfInformation; - this.dataOwner = dataOwner; this.shortTitle = shortTitle; this.uuid = uuid; this.traceabilityFlag = traceabilityFlag; - this.extras = extras; this.status = status; this.productType = productType; + this.reportingYear = reportingYear; + this.extrasFields = extrasFields; + this.extrasResources = extrasResources; } public String getProductType() { return productType; } + public Long getReportingYear() { + return reportingYear; + } + + public void setReportingYear(Long reportingYear) { + this.reportingYear = reportingYear; + } + + public Map> getExtrasFields() { + return extrasFields; + } + + public void setExtrasFields(Map> extrasFields) { + this.extrasFields = extrasFields; + } + + public List getExtrasResources() { + return extrasResources; + } + + public void setExtrasResources(List extrasResources) { + this.extrasResources = extrasResources; + } + public void setProductType(String productType) { this.productType = productType; } @@ -244,14 +281,6 @@ public class Common { this.dataOwner = dataOwner; } - public void setExtras(Map> extras) { - this.extras = extras; - } - - public Map> getExtras() { - return extras; - } - public String getShortTitle() { return shortTitle; } @@ -283,6 +312,28 @@ public class Common { public void setStatus(Status status) { this.status = status; } + + @JsonAnySetter + /** + * Use for generics object passed into the map + * @param key + * @param value + */ + private void genericSetter(String key, Object value){ + + // found extra property + logger.info("Found extra property: [" + key + "," + value + "]"); + + // try to convert the value to a string and put into the hashmap + List values = new ArrayList(); + if(extrasFields.containsKey(key)) + values = extrasFields.get(key); + else + values = new ArrayList(); + + values.add(HelperMethods.removeHTML(value.toString())); + extrasFields.put(key, values); + } @Override public String toString() { @@ -292,9 +343,10 @@ public class Common { + maintainer + ", maintainerContact=" + maintainerContact + ", dataOwner=" + dataOwner + ", databaseSources=" + databaseSources + ", sourceOfInformation=" - + sourceOfInformation + ", shortTitle=" - + shortTitle + ", uuid=" + uuid + ", traceabilityFlag=" - + traceabilityFlag + ", extras=" + extras + ", status=" - + status + ", productType=" + productType + "]"; + + sourceOfInformation + ", shortTitle=" + shortTitle + + ", uuid=" + uuid + ", traceabilityFlag=" + traceabilityFlag + + ", status=" + status + ", productType=" + productType + + ", reportingYear=" + reportingYear + ", extrasFields=" + + extrasFields + ", extrasResources=" + extrasResources + "]"; } } diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/FisheryRecord.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/FisheryRecord.java index 210df4b..ab2e9fe 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/FisheryRecord.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/FisheryRecord.java @@ -1,6 +1,5 @@ package org.gcube.data_catalogue.grsf_publish_ws.json.input; -import java.util.Collections; import java.util.List; import javax.validation.Valid; @@ -40,11 +39,11 @@ public class FisheryRecord extends Common{ @JsonProperty("fishing_area") @CustomField(key="Fishing area") - private String fishingArea; + private List fishingArea; @JsonProperty("exploited_stocks") @CustomField(key="Exploited stocks") - private String exploitingStocks; + private List exploitingStocks; @JsonProperty("management_entity") @Tag @@ -53,7 +52,7 @@ public class FisheryRecord extends Common{ @JsonProperty("jurisdiction_area") @CustomField(key="Jurisdiction Area") - private String jurisdictionArea; + private List jurisdictionArea; @JsonProperty("production_system_type") @Group @@ -108,8 +107,9 @@ public class FisheryRecord extends Common{ * @param type */ public FisheryRecord(String fisheryName, String fisheryId, - String scientificName, String fishingArea, String exploitingStocks, - String managementEntity, String jurisdictionArea, + String scientificName, List fishingArea, + List exploitingStocks, String managementEntity, + List jurisdictionArea, Production_System_Type productionSystemType, String flagState, String fishingGear, String environment, List> catchesOrLandings, @@ -129,7 +129,7 @@ public class FisheryRecord extends Common{ this.catchesOrLandings = catchesOrLandings; this.type = type; } - + public String getFisheryName() { return fisheryName; } @@ -154,22 +154,14 @@ public class FisheryRecord extends Common{ this.scientificName = scientificName; } - public String getFishingArea() { + public List getFishingArea() { return fishingArea; } - public void setFishingArea(String fishingArea) { + public void setFishingArea(List fishingArea) { this.fishingArea = fishingArea; } - public String getExploitingStocks() { - return exploitingStocks; - } - - public void setExploitingStocks(String exploitingStocks) { - this.exploitingStocks = exploitingStocks; - } - public String getManagementEntity() { return managementEntity; } @@ -178,11 +170,11 @@ public class FisheryRecord extends Common{ this.managementEntity = managementEntity; } - public String getJurisdictionArea() { + public List getJurisdictionArea() { return jurisdictionArea; } - public void setJurisdictionArea(String jurisdictionArea) { + public void setJurisdictionArea(List jurisdictionArea) { this.jurisdictionArea = jurisdictionArea; } @@ -224,10 +216,6 @@ public class FisheryRecord extends Common{ public void setCatchesOrLandings(List> catchesOrLandings) { this.catchesOrLandings = catchesOrLandings; - - if(catchesOrLandings != null){ - Collections.sort(catchesOrLandings); - } } public Fishery_Type getType() { @@ -250,4 +238,5 @@ public class FisheryRecord extends Common{ + ", environment=" + environment + ", catchesOrLandings=" + catchesOrLandings + ", type=" + type + "]"; } + } diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/Resource.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/Resource.java index dcf181b..ccf4941 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/Resource.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/Resource.java @@ -66,7 +66,7 @@ public class Resource { @Override public String toString() { - // in case of @Tag, we check the class of the element Name + // in case of @Tag/@Group, we check the class of the element Name Class nameClass = name.getClass(); if(nameClass.equals(Source.class)) diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/StockRecord.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/StockRecord.java index d9b1f82..a380853 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/StockRecord.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/StockRecord.java @@ -1,6 +1,5 @@ package org.gcube.data_catalogue.grsf_publish_ws.json.input; -import java.util.Collections; import java.util.List; import javax.validation.Valid; @@ -23,7 +22,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; */ @JsonIgnoreProperties(ignoreUnknown = true) public class StockRecord extends Common{ - + @JsonProperty("stock_name") @NotNull(message="stock_name cannot be null") @Size(min=2, message="stock_name cannot be empty") @@ -34,22 +33,20 @@ public class StockRecord extends Common{ @CustomField(key="Stock Id") private String stockID; - @JsonProperty("species_scientific_name") - @CustomField(key="Species scientific name") + @JsonProperty("species") + @CustomField(key="Species") @Tag - @NotNull(message="species_scientific_name cannot be null") - @Size(min=1, message="species_scientific_name cannot be empty") - private String speciesScientificName; + @Size(min=1, message="species cannot be empty") + private List species; @JsonProperty("assessment_distribution_area") @CustomField(key="Assessment distribution area") - @NotNull(message="assessment distribution cannot be null") @Size(min=1, message="assessment distribution area cannot be empty") - private String area; + private List area; @JsonProperty("exploiting_fishery") @CustomField(key="Exploiting fishery") - private String exploitingFishery; + private List exploitingFishery; @JsonProperty("management_entity") @CustomField(key="Management entity") @@ -63,25 +60,27 @@ public class StockRecord extends Common{ @CustomField(key="State of marine resources") private String stateOfMarineResource; - @JsonProperty("exploitation_rate") - @CustomField(key="Exploitation Rate") + @JsonProperty("standard_exploitation_rate") + @CustomField(key="Standard Exploitation Rate") @Tag @Valid - private List> exploitationRate; + private List> exploitationRateStandard; + + @JsonProperty("exploitation_rate") + @CustomField(key="Exploitation Rate") + @Valid + private List> exploitationRate; + + @JsonProperty("standard_abundance_level") + @CustomField(key="Standard Abundance Level") + @Tag + @Valid + private List> abundanceLevelStandard; @JsonProperty("abundance_level") @CustomField(key="Abundance Level") - @Tag @Valid - private List> abundanceLevel; - - @JsonProperty("exploitation_rate_for_grouping") - @Group - private Exploitation_Rate exploitationRateForGrouping; - - @JsonProperty("abundance_level_for_grouping") - @Group - private Abundance_Level abundanceLevelForGrouping; + private List> abundanceLevel; @JsonProperty("narrative_state_and_trend") @CustomField(key="Narrative state and trend") @@ -95,10 +94,6 @@ public class StockRecord extends Common{ @CustomField(key="Reporting entity") private String reportingEntity; - @JsonProperty("reporting_year") - @CustomField(key="Reporting year") - private Long reportingYear; - @JsonProperty("stock_uri") @CustomField(key="Stock Uri") private String stockUri; @@ -106,7 +101,7 @@ public class StockRecord extends Common{ @JsonProperty("water_area") @CustomField(key="Water Area") private List waterArea; - + @JsonProperty("type") @CustomField(key="Type") @Tag @@ -121,16 +116,16 @@ public class StockRecord extends Common{ * Create a Stock element. * @param stockName * @param stockID - * @param speciesScientificName + * @param species * @param area * @param exploitingFishery * @param managementEntity * @param assessmentMethods * @param stateOfMarineResource + * @param exploitationRateStandard * @param exploitationRate + * @param abundanceLevelStandard * @param abundanceLevel - * @param exploitationRateForGrouping - * @param abundanceLevelForGrouping * @param narrativeStateAndTrend * @param scientificAdvice * @param reportingEntity @@ -139,39 +134,43 @@ public class StockRecord extends Common{ * @param waterArea * @param type */ - public StockRecord(String stockName, String stockID, - String speciesScientificName, String area, - String exploitingFishery, String managementEntity, - String assessmentMethods, String stateOfMarineResource, - List> exploitationRate, - List> abundanceLevel, - Exploitation_Rate exploitationRateForGrouping, - Abundance_Level abundanceLevelForGrouping, + public StockRecord( + String stockName, + String stockID, + List species, + List area, + List exploitingFishery, + String managementEntity, + String assessmentMethods, + String stateOfMarineResource, + List> exploitationRateStandard, + List> exploitationRate, + List> abundanceLevelStandard, + List> abundanceLevel, String narrativeStateAndTrend, String scientificAdvice, String reportingEntity, Long reportingYear, String stockUri, List waterArea, Stock_Type type) { super(); this.stockName = stockName; this.stockID = stockID; - this.speciesScientificName = speciesScientificName; + this.species = species; this.area = area; this.exploitingFishery = exploitingFishery; this.managementEntity = managementEntity; this.assessmentMethods = assessmentMethods; this.stateOfMarineResource = stateOfMarineResource; + this.exploitationRateStandard = exploitationRateStandard; this.exploitationRate = exploitationRate; + this.abundanceLevelStandard = abundanceLevelStandard; this.abundanceLevel = abundanceLevel; - this.exploitationRateForGrouping = exploitationRateForGrouping; - this.abundanceLevelForGrouping = abundanceLevelForGrouping; this.narrativeStateAndTrend = narrativeStateAndTrend; this.scientificAdvice = scientificAdvice; this.reportingEntity = reportingEntity; - this.reportingYear = reportingYear; this.stockUri = stockUri; this.waterArea = waterArea; this.type = type; } - + public Stock_Type getType() { return type; } @@ -179,24 +178,6 @@ public class StockRecord extends Common{ public void setType(Stock_Type type) { this.type = type; } - - public Exploitation_Rate getExploitationRateForGrouping() { - return exploitationRateForGrouping; - } - - public void setExploitationRateForGrouping( - Exploitation_Rate exploitationRateForGrouping) { - this.exploitationRateForGrouping = exploitationRateForGrouping; - } - - public Abundance_Level getAbundanceLevelForGrouping() { - return abundanceLevelForGrouping; - } - - public void setAbundanceLevelForGrouping( - Abundance_Level abundanceLevelForGrouping) { - this.abundanceLevelForGrouping = abundanceLevelForGrouping; - } public String getStockUri() { return stockUri; @@ -230,27 +211,27 @@ public class StockRecord extends Common{ this.stockID = stockID; } - public String getSpeciesScientificName() { - return speciesScientificName; + public List getSpecies() { + return species; } - public void setSpeciesScientificName(String speciesScientificName) { - this.speciesScientificName = speciesScientificName; + public void setSpecies(List species) { + this.species = species; } - public String getArea() { + public List getArea() { return area; } - public void setArea(String area) { + public void setArea(List area) { this.area = area; } - public String getExploitingFishery() { + public List getExploitingFishery() { return exploitingFishery; } - public void setExploitingFishery(String exploitingFishery) { + public void setExploitingFishery(List exploitingFishery) { this.exploitingFishery = exploitingFishery; } @@ -278,28 +259,31 @@ public class StockRecord extends Common{ this.stateOfMarineResource = stateOfMarineResource; } - public List> getExploitationRate() { - return exploitationRate; + public List> getExploitationRateStandard() { + return exploitationRateStandard; } - public void setExploitationRate(List> exploitationRate) { - this.exploitationRate = exploitationRate; - - if(exploitationRate != null){ - Collections.sort(exploitationRate); - } + public void setExploitationRateStandard( + List> exploitationRateStandard) { + this.exploitationRateStandard = exploitationRateStandard; } - public List> getAbundanceLevel() { + public List> getAbundanceLevelStandard() { + return abundanceLevelStandard; + } + + public void setAbundanceLevelStandard( + List> abundanceLevelStandard) { + this.abundanceLevelStandard = abundanceLevelStandard; + } + + public List> getAbundanceLevel() { return abundanceLevel; } - public void setAbundanceLevel(List> abundanceLevel) { + public void setAbundanceLevel( + List> abundanceLevel) { this.abundanceLevel = abundanceLevel; - - if(abundanceLevel != null){ - Collections.sort(abundanceLevel); - } } public String getNarrativeStateAndTrend() { @@ -325,32 +309,33 @@ public class StockRecord extends Common{ public void setReportingEntity(String reportingEntity) { this.reportingEntity = reportingEntity; } - - public Long getReportingYear() { - return reportingYear; + + public List> getExploitationRate() { + return exploitationRate; } - public void setReportingYear(Long reportingYear) { - this.reportingYear = reportingYear; + public void setExploitationRate( + List> exploitationRate) { + this.exploitationRate = exploitationRate; } @Override public String toString() { return "StockRecord [stockName=" + stockName + ", stockID=" + stockID - + ", speciesScientificName=" + speciesScientificName - + ", area=" + area + ", exploitingFishery=" + exploitingFishery + + ", species=" + species + ", area=" + area + + ", exploitingFishery=" + exploitingFishery + ", managementEntity=" + managementEntity + ", assessmentMethods=" + assessmentMethods + ", stateOfMarineResource=" + stateOfMarineResource + + ", exploitationRateStandard=" + exploitationRateStandard + ", exploitationRate=" + exploitationRate + + ", abundanceLevelStandard=" + abundanceLevelStandard + ", abundanceLevel=" + abundanceLevel - + ", exploitationRateForGrouping=" - + exploitationRateForGrouping + ", abundanceLevelForGrouping=" - + abundanceLevelForGrouping + ", narrativeStateAndTrend=" - + narrativeStateAndTrend + ", scientificAdvice=" - + scientificAdvice + ", reportingEntity=" + reportingEntity - + ", reportingYear=" + reportingYear + ", stockUri=" + stockUri - + ", waterArea=" + waterArea + ", type=" + type + "]"; + + ", narrativeStateAndTrend=" + narrativeStateAndTrend + + ", scientificAdvice=" + scientificAdvice + + ", reportingEntity=" + reportingEntity + ", stockUri=" + + stockUri + ", waterArea=" + waterArea + ", type=" + type + + "]"; } } diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherFisheryService.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherFisheryService.java index 126b7bd..56f43b7 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherFisheryService.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherFisheryService.java @@ -149,8 +149,8 @@ public class GrsfPublisherFisheryService { // fishing area and jurisdiction area cannot be empty at the same time String futureName = record.getUuid(); String futureTitle = record.getFisheryName(); - String fishingArea = record.getFishingArea(); - String jurisdictionArea = record.getJurisdictionArea(); + List fishingArea = record.getFishingArea(); + List jurisdictionArea = record.getJurisdictionArea(); if(!HelperMethods.isNameValid(futureName)){ status = Status.BAD_REQUEST; @@ -186,10 +186,7 @@ public class GrsfPublisherFisheryService { HelperMethods.getGroups(groups, record); // evaluate the custom fields - Map> customFields = new HashMap>(); - - if(record.getExtras() != null) - customFields = record.getExtras(); + Map> customFields = record.getExtrasFields(); // automatically retrieve the other ones HelperMethods.getExtras(customFields, record); @@ -207,7 +204,8 @@ public class GrsfPublisherFisheryService { }else{ // evaluate the resources - List resources = HelperMethods.getResourcesFromBean(record, username, tags, groups); + List resources = record.getExtrasResources(); + HelperMethods.getResourcesFromBean(record, username, tags, groups, resources); // check the license id String license = null; @@ -225,7 +223,7 @@ public class GrsfPublisherFisheryService { catalogue.getApiKeyFromUsername(username), futureTitle, futureName, - organization, + organization,//"grsf", //TO DELETE TODO authorFullname, authorMail, record.getMaintainer(), diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherStockService.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherStockService.java index 5e1d9dc..e5091f5 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherStockService.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherStockService.java @@ -175,10 +175,7 @@ public class GrsfPublisherStockService { HelperMethods.getGroups(groups, record); // evaluate the custom fields - Map> customFields = new HashMap>(); - - if(record.getExtras() != null) - customFields = record.getExtras(); + Map> customFields = record.getExtrasFields(); // automatically retrieve the other ones HelperMethods.getExtras(customFields, record); @@ -197,7 +194,8 @@ public class GrsfPublisherStockService { }else{ // evaluate the resources - List resources = HelperMethods.getResourcesFromBean(record, username, tags, groups); + List resources = record.getExtrasResources(); + HelperMethods.getResourcesFromBean(record, username, tags, groups, resources); // check the license id String license = null; @@ -215,7 +213,7 @@ public class GrsfPublisherStockService { catalogue.getApiKeyFromUsername(username), futureTitle, futureName, - organization, + organization,//"grsf", //TO DELETE TODO authorFullname, authorMail, record.getMaintainer(), diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/HelperMethods.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/HelperMethods.java index c85f7e4..5653db2 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/HelperMethods.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/HelperMethods.java @@ -74,7 +74,7 @@ public abstract class HelperMethods { modified = modified.substring(1); if(modified.endsWith("-")) modified = modified.substring(0, modified.length() -1); - + logger.info("Group name generated is " + modified); return modified; @@ -169,34 +169,43 @@ public abstract class HelperMethods { Object f = new PropertyDescriptor(field.getName(), current).getReadMethod().invoke(record); if(f != null){ - // also convert to the group name that should be on ckan - String groupName = getGroupNameOnCkan(f.toString().trim()); - if(!groups.contains(groupName)) - groups.add(groupName); + if(f instanceof List){ + List asList = ((List) f); + if(!asList.isEmpty()){ + logger.debug("The object annotated with @Tag/@Group is a list. Adding ... "); + + // else add all the available elements + for (int i = 0; i < asList.size(); i++) { + String groupName = getGroupNameOnCkan(asList.get(i).toString().trim()); + logger.debug(groupName); + if(!groups.contains(groupName)) + groups.add(groupName); + } + + } + }else{ + + // also convert to the group name that should be on ckan + String groupName = getGroupNameOnCkan(f.toString().trim()); + if(!groups.contains(groupName)) + groups.add(groupName); + } } - + // check if the field is an enumerator, and the enum class is also annotated with @Group if(field.getType().isEnum() && field.getType().isAnnotationPresent(Group.class)){ - + logger.info("Class " + field.getClass().getSimpleName() + " has annotation @Group"); - + // extract the name from the enum class and add it to the groups // also convert to the group name that should be on ckan String groupName = getGroupNameOnCkan(field.getType().getSimpleName()); if(!groups.contains(groupName)) groups.add(groupName); - - // check if this class has a father too (@Group annotation allows it) - Group groupAnnotationOnEnum = field.getType().getAnnotation(Group.class); - if(!groupAnnotationOnEnum.parentGroup().equals(Class.class)){ - String groupNameFather = getGroupNameOnCkan(groupAnnotationOnEnum.parentGroup().getSimpleName()); - if(!groups.contains(groupNameFather)) - groups.add(groupNameFather); - } - + } - + }catch(Exception e){ logger.error("Failed ot read value for field " + field.getName() + " skipping", e); } @@ -427,11 +436,11 @@ public abstract class HelperMethods { * @param username * @param tags * @param groups + * @param resources * @return */ - public static List getResourcesFromBean(Common record, String username, List tags, List groups){ + public static void getResourcesFromBean(Common record, String username, List tags, List groups, List resources){ - List toReturn = new ArrayList(); Class current = record.getClass(); do{ Field[] fields = current.getDeclaredFields(); @@ -446,13 +455,13 @@ public abstract class HelperMethods { List listOfResources = (List)f; for (Resource resource : listOfResources) { - toReturn.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; - toReturn.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)); } } @@ -464,8 +473,7 @@ public abstract class HelperMethods { } while((current = current.getSuperclass())!=null); // iterate from the inherited class up to the Object.class - logger.info("Returning resources " + toReturn); - return toReturn; + logger.info("Returning resources " + resources); } /** @@ -563,29 +571,12 @@ public abstract class HelperMethods { if(html == null || html.isEmpty()) return html; - logger.info("Incoming text is " + html); - // remove html and clean String withoutHTML = Jsoup.parse(html).text(); withoutHTML = Jsoup.clean(withoutHTML, Whitelist.basic()); - // TODO ... - // could contain non ascii chars ... try to convert them to question marks and then remove them - // try{ - // String strippedWithQuestionMarks = Normalizer.normalize(withoutHTML, Normalizer.Form.NFD); - // String regex = "[\\p{InCombiningDiacriticalMarks}\\p{IsLm}\\p{IsSk}]+"; - // strippedWithQuestionMarks = new String(strippedWithQuestionMarks.replaceAll(regex, "").getBytes("ascii"), "ascii"); - // strippedWithQuestionMarks = strippedWithQuestionMarks.replaceAll("[?]+", " "); - // withoutHTML = strippedWithQuestionMarks; - // }catch(UnsupportedEncodingException e){ - // logger.warn("Unable to convert to question marks non ascii chars..", e); - // // remove non ascii directly - // withoutHTML = withoutHTML.replaceAll("[^\\x00-\\x7F]", " "); - // } - // remove non ascii chars ... withoutHTML = withoutHTML.replaceAll("[^\\p{ASCII}]", " "); - logger.info("Without html is " + withoutHTML); return withoutHTML; } } diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/groups/Abundance_Level.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/groups/Abundance_Level.java index 28f2d5b..2cced6b 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/groups/Abundance_Level.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/groups/Abundance_Level.java @@ -9,7 +9,7 @@ import com.fasterxml.jackson.annotation.JsonValue; * Abundance_Level for Stock records * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) */ -@Group(parentGroup=Indicator.class) +@Group public enum Abundance_Level { Intermediate_Abundance("Intermediate abundance"), diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/groups/Exploitation_Rate.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/groups/Exploitation_Rate.java index 876af4c..b452176 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/groups/Exploitation_Rate.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/groups/Exploitation_Rate.java @@ -8,7 +8,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; * Exploitation_Rate for Stock records * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) */ -@Group(parentGroup=Indicator.class) +@Group public enum Exploitation_Rate { Moderate_Fishing_Mortality("Moderate fishing mortality"), diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/groups/Indicator.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/groups/Indicator.java deleted file mode 100644 index 63797a1..0000000 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/groups/Indicator.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.gcube.data_catalogue.grsf_publish_ws.utils.groups; - -import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.Group; - -/** - * Indicator group: father of Abundance level and Exploitation Rate - * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) - */ -@Group -public enum Indicator { - -} diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/threads/AssociationToGroupThread.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/threads/AssociationToGroupThread.java index a8700c3..39081eb 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/threads/AssociationToGroupThread.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/threads/AssociationToGroupThread.java @@ -1,12 +1,19 @@ package org.gcube.data_catalogue.grsf_publish_ws.utils.threads; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.ListIterator; +import java.util.Set; import org.gcube.datacatalogue.ckanutillibrary.DataCatalogue; import org.gcube.datacatalogue.ckanutillibrary.models.RolesCkanGroupOrOrg; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import eu.trentorise.opendata.jackan.model.CkanGroup; + /** * Associate the dataset to a group. * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) @@ -40,31 +47,76 @@ public class AssociationToGroupThread extends Thread { @Override public void run() { - logger.info("Association thread started to put the dataset with id="+ datasetId + " into group with title(s) " + groupsTitles + " for user " + username); + try{ - String userApiKey = catalogue.getApiKeyFromUsername(username); + logger.info("Association thread started to put the dataset with id="+ datasetId + " into group with title(s) " + groupsTitles + " for user " + username); - // retrieve the role to be assigned according the one the user has into the organization of the dataset - RolesCkanGroupOrOrg role = RolesCkanGroupOrOrg.valueOf(catalogue.getRoleOfUserInOrganization(username, organizationId, catalogue.getApiKeyFromUsername(username)).toUpperCase()); - - if(!role.equals(RolesCkanGroupOrOrg.ADMIN)) - role = RolesCkanGroupOrOrg.MEMBER; // decrease the role to member if it is not an admin + // find parents' groups + String userApiKey = catalogue.getApiKeyFromUsername(username); + findHierarchy(groupsTitles, catalogue, userApiKey); - for (String groupTitle : groupsTitles) { + Set uniqueGroups = new HashSet(groupsTitles); + + logger.info("Full set of groups is " + groupsTitles); + - logger.debug("Setting role " + role + " into group " + groupTitle + " to user " + username); - boolean assigned = catalogue.checkRoleIntoGroup(username, groupTitle, role); + // retrieve the role to be assigned according the one the user has into the organization of the dataset + RolesCkanGroupOrOrg role = RolesCkanGroupOrOrg.valueOf(catalogue.getRoleOfUserInOrganization(username, organizationId, userApiKey).toUpperCase()); - if(!assigned){ - logger.warn("The user " + username + " has not enough privileges to associate the dataset into group OR the group doesn't exist" + groupTitle); - continue; + if(!role.equals(RolesCkanGroupOrOrg.ADMIN)) + role = RolesCkanGroupOrOrg.MEMBER; // decrease the role to member if it is not an admin + + for (String groupTitle : uniqueGroups) { + + logger.debug("Setting role " + role + " into group " + groupTitle + " to user " + username); + boolean assigned = catalogue.checkRoleIntoGroup(username, groupTitle, role); + + if(!assigned){ + logger.warn("The user " + username + " has not enough privileges to associate the dataset into group OR the group doesn't exist" + groupTitle); + continue; + } + else{ + boolean putIntoGroup = catalogue.assignDatasetToGroup(groupTitle, datasetId, userApiKey); + logger.info("Was product put into group " + groupTitle + "? " + putIntoGroup); + } } - else{ - boolean putIntoGroup = catalogue.assignDatasetToGroup(groupTitle, datasetId, userApiKey); - logger.info("Was product put into group " + groupTitle + "? " + putIntoGroup); + logger.info("The Association Group thread ended correctly"); + }catch(Exception e){ + logger.error("Exception follows ", e); + } + } + + /** + * Find the hierarchy of trees + * @param uniqueGroups + * @param catalogue + * @param user's api key + */ + public static void findHierarchy( + List groupsTitles, + DataCatalogue catalogue, + String apiKey) { + + ListIterator iterator = groupsTitles.listIterator(); + + while (iterator.hasNext()) { + String group = (String) iterator.next(); + + List parents = catalogue.getParentGroups(group, apiKey); + + if(parents == null || parents.isEmpty()) + return; + + for (CkanGroup ckanGroup : parents) { + List parentsList = new ArrayList(Arrays.asList(ckanGroup.getName())); + findHierarchy(parentsList, catalogue, apiKey); + + for (String parent : parentsList) { + iterator.add(parent); + } } } - logger.info("The Association Group thread ended correctly"); + } } diff --git a/src/test/java/org/gcube/data_catalogue/grsf_publish_ws/JTests.java b/src/test/java/org/gcube/data_catalogue/grsf_publish_ws/JTests.java index 3752d84..28de3a5 100644 --- a/src/test/java/org/gcube/data_catalogue/grsf_publish_ws/JTests.java +++ b/src/test/java/org/gcube/data_catalogue/grsf_publish_ws/JTests.java @@ -13,8 +13,10 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.homelibrary.home.HomeLibrary; @@ -41,9 +43,9 @@ import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Abundance_Level; import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Fishery_Type; import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Source; import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Status; +import org.gcube.data_catalogue.grsf_publish_ws.utils.threads.AssociationToGroupThread; import org.gcube.datacatalogue.ckanutillibrary.DataCatalogue; import org.gcube.datacatalogue.ckanutillibrary.DataCatalogueFactory; -import org.junit.Test; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.core.JsonProcessingException; @@ -547,7 +549,7 @@ public class JTests { logger.debug("Name is " +groupName ); } - + } } } @@ -555,4 +557,27 @@ public class JTests { } + //@Test + public void testHierarchy(){ + String name = "low-abundance"; + DataCatalogue catalogue = HelperMethods.getDataCatalogueRunningInstance("/gcube/devNext/NextNext"); + List uniqueGroups = new ArrayList(); + uniqueGroups.add(name); + uniqueGroups.add(name); + AssociationToGroupThread.findHierarchy(uniqueGroups, catalogue, catalogue.getApiKeyFromUsername("costantino_perciante")); + logger.debug("Hierarchy is " + uniqueGroups); + } + + //@Test + public void testAssociationThread() throws InterruptedException{ + String name = "low-abundance"; + DataCatalogue catalogue = HelperMethods.getDataCatalogueRunningInstance("/gcube/devNext/NextNext"); + AssociationToGroupThread threadGroups = new AssociationToGroupThread(Arrays.asList(name), "another-test-test-please-ignore", "grsf", "costantino_perciante", catalogue); + threadGroups.start(); + threadGroups.join(); + logger.info("Thread stopped!"); + + + } + }