diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/custom_annotations/CkanField.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/custom_annotations/CkanField.java deleted file mode 100644 index 21d26f4..0000000 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/custom_annotations/CkanField.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.gcube.data_catalogue.grsf_publish_ws.custom_annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotate a field of the json input representing a future CKAN field (key, value) - * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface CkanField { - -} diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/custom_annotations/CkanResource.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/custom_annotations/CkanResource.java index 7fd10fb..ee0963f 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/custom_annotations/CkanResource.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/custom_annotations/CkanResource.java @@ -13,4 +13,6 @@ import java.lang.annotation.Target; @Target(ElementType.FIELD) public @interface CkanResource { + boolean inspect() default false; + } 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 97504f4..f711573 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 @@ -8,6 +8,7 @@ import javax.validation.Valid; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; +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; @@ -48,8 +49,9 @@ public class Common { private String maintainerContact; @JsonProperty("catches_or_landings") - @CustomField(key="Catches or landings") - private String catchesOrLandings; + @Valid + @CkanResource + private Resource catchesOrLandings; @JsonProperty("database_sources") @NotNull(message="database_source cannot be null") @@ -60,6 +62,7 @@ public class Common { @JsonProperty("source_of_information") @NotNull(message="source_of_information cannot be null") @Size(min=1, message="source_of_information cannot be empty") + @CkanResource @Valid private List sourceOfInformation; @@ -72,26 +75,26 @@ public class Common { @Group @CustomField(key="Type") private Type type; - + @JsonProperty("short_title") @CustomField(key="Short Title") @NotNull private String shortTitle; - + @JsonProperty("uuid_knowledge_base") @CustomField(key="UUID Knowledge Base") @NotNull @Size(min=1, message="uuid_knowledge_base cannot be empty") private String uuid; - + @JsonProperty("traceability_flag") @CustomField(key="Traceability Flag") @NotNull private boolean traceabilityFlag; - + @JsonProperty("extras") private Map> extras = new HashMap<>(); - + @JsonProperty("status") @CustomField(key="Status") @Group @@ -123,7 +126,7 @@ public class Common { */ public Common(String description, String license, String author, Long version, String authorContact, String maintainer, - String maintainerContact, String catchesOrLandings, + String maintainerContact, Resource catchesOrLandings, List databaseSources, List sourceOfInformation, String dataOwner, Type type, String shortTitle, String uuid, boolean traceabilityFlag, @@ -203,11 +206,11 @@ public class Common { this.maintainerContact = maintainerContact; } - public String getCatchesOrLandings() { + public Resource getCatchesOrLandings() { return catchesOrLandings; } - public void setCatchesOrLandings(String catchesOrLandings) { + public void setCatchesOrLandings(Resource catchesOrLandings) { this.catchesOrLandings = catchesOrLandings; } @@ -274,7 +277,7 @@ public class Common { public void setTraceabilityFlag(boolean traceabilityFlag) { this.traceabilityFlag = traceabilityFlag; } - + public Status getStatus() { return status; } 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 127f8fa..5f650cf 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 @@ -2,14 +2,14 @@ package org.gcube.data_catalogue.grsf_publish_ws.json.input; import java.util.List; +import javax.validation.Valid; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; +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.groups.Abundance_Level; -import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Exploitation_Rate; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; @@ -61,16 +61,18 @@ public class StockRecord extends Common{ private String stateOfMarineResource; @JsonProperty("exploitation_rate") - @CustomField(key="Exploitation rate") @Group @Tag - private Exploitation_Rate exploitationRate; + @CkanResource(inspect=true) + @Valid + private Resource exploitationRate; @JsonProperty("abundance_level") - @CustomField(key="Abundance level") @Group @Tag - private Abundance_Level abundanceLevel; + @CkanResource(inspect=true) + @Valid + private Resource abundanceLevel; @JsonProperty("narrative_state_and_trend") @CustomField(key="Narrative state and trend") @@ -96,9 +98,7 @@ public class StockRecord extends Common{ @CustomField(key="Water Area") private List waterArea;// TODO check that multiple values are mapped to ckan - /** - * - */ + public StockRecord() { super(); } @@ -126,7 +126,7 @@ public class StockRecord extends Common{ String speciesScientificName, String area, String exploitingFishery, String managementEntity, String assessmentMethods, String stateOfMarineResource, - Exploitation_Rate exploitationRate, Abundance_Level abundanceLevel, + Resource exploitationRate, Resource abundanceLevel, String narrativeStateAndTrend, String scientificAdvice, String reportingEntity, Long reportingYear, String stockUri, List waterArea) { @@ -229,19 +229,19 @@ public class StockRecord extends Common{ this.stateOfMarineResource = stateOfMarineResource; } - public Exploitation_Rate getExploitationRate() { + public Resource getExploitationRate() { return exploitationRate; } - public void setExploitationRate(Exploitation_Rate exploitationRate) { + public void setExploitationRate(Resource exploitationRate) { this.exploitationRate = exploitationRate; } - public Abundance_Level getAbundanceLevel() { + public Resource getAbundanceLevel() { return abundanceLevel; } - public void setAbundanceLevel(Abundance_Level abundanceLevel) { + public void setAbundanceLevel(Resource abundanceLevel) { this.abundanceLevel = abundanceLevel; } diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/output/ResponseCreationBean.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/output/ResponseCreationBean.java index 9612caf..3e8e2a8 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/output/ResponseCreationBean.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/output/ResponseCreationBean.java @@ -13,7 +13,7 @@ public class ResponseCreationBean { private String id; @JsonProperty("product_url") - String datasetUrl; + String productUrl; @JsonProperty("error") private String error; // in case of error @@ -24,13 +24,13 @@ public class ResponseCreationBean { /** * @param id - * @param datasetUrl + * @param productUrl * @param error */ - public ResponseCreationBean(String id, String datasetUrl, String error) { + public ResponseCreationBean(String id, String productUrl, String error) { super(); this.id = id; - this.datasetUrl = datasetUrl; + this.productUrl = productUrl; this.error = error; } @@ -42,12 +42,12 @@ public class ResponseCreationBean { this.id = id; } - public String getDatasetUrl() { - return datasetUrl; + public String getProducttUrl() { + return productUrl; } - public void setDatasetUrl(String datasetUrl) { - this.datasetUrl = datasetUrl; + public void setProductUrl(String productUrl) { + this.productUrl = productUrl; } public String getError() { @@ -60,7 +60,7 @@ public class ResponseCreationBean { @Override public String toString() { - return "ResponseCreationBean [id=" + id + ", datasetUrl=" + datasetUrl + return "ResponseCreationBean [id=" + id + ", productUrl=" + productUrl + ", error=" + error + "]"; } 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 1f97187..8e1cb16 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 @@ -200,7 +200,7 @@ public class GrsfPublisherFisheryService { }else{ // evaluate the resources - List resources = HelperMethods.getResourcesFromBean(record, username); + List resources = HelperMethods.getResourcesFromBean(record, username, tags, groups); // if confirmed, set to visible TODO anyway if it is confirmed we should another method boolean setPublic = false; @@ -239,7 +239,7 @@ public class GrsfPublisherFisheryService { responseBean.setId(id); status = Status.CREATED; responseBean.setError(null); - responseBean.setDatasetUrl(catalogue.getPortletUrl() + "?path=/dataset/" + futureName); + responseBean.setProductUrl(catalogue.getPortletUrl() + "?path=/dataset/" + futureName); if(!groups.isEmpty()){ logger.info("Launching thread for association to the list of groups " + groups); 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 f099012..b011a30 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 @@ -143,7 +143,7 @@ public class GrsfPublisherStockService { }else{ - logger.debug("Checking if such name [" + futureTitle + "]doesn't exist yet..."); + logger.debug("Checking if such name [" + futureTitle + "] doesn't exist yet..."); String futureName = UtilMethods.fromProductTitleToName(futureTitle); logger.info("Transformed name is " + futureName); boolean alreadyExist = catalogue.existProductWithNameOrId(futureName); @@ -192,7 +192,7 @@ public class GrsfPublisherStockService { }else{ // evaluate the resources - List resources = HelperMethods.getResourcesFromBean(record, username); + List resources = HelperMethods.getResourcesFromBean(record, username, tags, groups); boolean setPublic = false; @@ -230,7 +230,7 @@ public class GrsfPublisherStockService { responseBean.setId(id); status = Status.CREATED; responseBean.setError(null); - responseBean.setDatasetUrl(catalogue.getPortletUrl() + "?path=/dataset/" + futureName); + responseBean.setProductUrl(catalogue.getPortletUrl() + "?path=/dataset/" + futureName); if(!groups.isEmpty()){ logger.info("Launching thread for association to the list of groups " + groups); 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 411cc4a..0162ee9 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 @@ -13,12 +13,14 @@ import java.util.Map; import javax.servlet.ServletContext; import org.gcube.common.scope.api.ScopeProvider; +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.json.input.Common; import org.gcube.data_catalogue.grsf_publish_ws.json.input.DatabaseSource; import org.gcube.data_catalogue.grsf_publish_ws.json.input.Resource; +import org.gcube.data_catalogue.grsf_publish_ws.json.input.StockRecord; 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.DataCatalogue; @@ -98,6 +100,7 @@ public abstract class HelperMethods { Object f = new PropertyDescriptor(field.getName(), current).getReadMethod().invoke(record); if(f != null){ + tags.add(f.toString().trim()); } @@ -366,60 +369,18 @@ public abstract class HelperMethods { } - // /** - // * Validate a record along the database_sources and the source_of_information - // * @param record - // * @return - // */ - // public static Response validateBeanAndResources(Common record){ - // - // ResponseCreationBean responseBean = new ResponseCreationBean(); - // javax.ws.rs.core.Response.Status status = javax.ws.rs.core.Response.Status.BAD_REQUEST; - // - // ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); - // Validator validator = factory.getValidator(); - // - // - // Set> violations = validator.validate(record); - // for (ConstraintViolation constraintViolation : violations) { - // logger.warn("Violation is about " + constraintViolation.getPropertyPath() + ", message error is " + constraintViolation.getMessage()); - // responseBean.setError(constraintViolation.getMessage()); - // return Response.status(status).entity(responseBean).build(); - // } - // - // // check database_sources and source_of_information (they are not null nor empty at this point) - // List databaseSources = record.getDatabaseSources(); - // for (DatabaseSource databaseSource : databaseSources) { - // Set> violationsDatabaseSourcesBean = validator.validate(databaseSource); - // for (ConstraintViolation constraintViolation : violationsDatabaseSourcesBean) { - // logger.warn("Violation is about " + constraintViolation.getPropertyPath() + ", message error is " + constraintViolation.getMessage()); - // responseBean.setError(constraintViolation.getMessage()); - // return Response.status(status).entity(responseBean).build(); - // } - // } - // - // List sourcesOfInformation = record.getSourceOfInformation(); - // for (Resource sourceOfinformation : sourcesOfInformation) { - // Set> violationsSourceOfinformationsBean = validator.validate(sourceOfinformation); - // for (ConstraintViolation constraintViolation : violationsSourceOfinformationsBean) { - // logger.warn("Violation is about " + constraintViolation.getPropertyPath() + ", message error is " + constraintViolation.getMessage()); - // responseBean.setError(constraintViolation.getMessage()); - // return Response.status(status).entity(responseBean).build(); - // } - // } - // return null; - // } - /** - * Retrieve the ResourceBean given the record (extract resources from Database Sources and Source of Information) + * Retrieve the ResourceBean given the record (extract resources from Database Sources and Source of Information and others) * @param record - * @return + * @param username + * @param tags + * @param groups + * @return */ - public static List getResourcesFromBean(Common record, String username) { + public static List getResourcesFromBean(Common record, String username, List tags, List groups){ List toReturn = new ArrayList(); List databaseSources = record.getDatabaseSources(); - List databaseOfInformation = record.getSourceOfInformation(); // transform database sources for (DatabaseSource res : databaseSources) { @@ -427,14 +388,53 @@ public abstract class HelperMethods { toReturn.add(new ResourceBean(res.getUrl(), res.getName().getOrigName(), res.getDescription(), null, username, null, null)); } - // just add source of information - for (Resource res : databaseOfInformation) { - logger.debug("Adding resource " + res); - toReturn.add(new ResourceBean(res.getUrl(), res.getName(), res.getDescription(), null, username, null, null)); + Class current = record.getClass(); + do{ + Field[] fields = current.getDeclaredFields(); + for (Field field : fields) { + if(field.isAnnotationPresent(CkanResource.class)){ + try{ + Object f = new PropertyDescriptor(field.getName(), current).getReadMethod().invoke(record); + if(f != null){ + + if(f instanceof List){ + + List listOfResources = (List)f; + + for (Resource resource : listOfResources) { + toReturn.add(new ResourceBean(resource.getUrl(), resource.getName(), resource.getDescription(), null, username, null, null)); + } + + }else{ + + Resource res = (Resource)f; + toReturn.add(new ResourceBean(res.getUrl(), res.getName(), res.getDescription(), null, username, null, null)); + + } + + // TODO handle groups/tags + + } + }catch(Exception e){ + logger.error("Failed ot read value for field " + field.getName() + " skipping", e); + } + } + } } + while((current = current.getSuperclass())!=null); + logger.debug("Returning resources " + toReturn); return toReturn; } + /** + * Inspect a resource file at this url for finding out tags/groups of the object + * @param r + */ + public static void inspectResourceFile(Resource r){ + + // TODO + + } } 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 cac794a..2285d35 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 @@ -188,8 +188,8 @@ public class JTests { //Object to JSON in String String jsonInString = mapper.writeValueAsString(record); System.out.println(jsonInString); - - + + // // // JSON back to object // StockRecord converted = mapper.readValue(jsonInString, recordStock.getClass()); @@ -237,22 +237,22 @@ public class JTests { // System.out.println(HelperMethods.retrieveOrgNameFromScope("/gcube/devNext/NextNext")); } - + //@Test public void testCustomFieldAnnotation() throws JsonProcessingException{ - + StockRecord record = new StockRecord(); record.setWaterArea(Arrays.asList("aa", "bb", "cc", "dd")); Map> extras = new HashMap>(); HelperMethods.getExtras(extras , record); System.out.println("Extras = " + extras); - + ObjectMapper mapper = new ObjectMapper(); //Object to JSON in String String jsonInString = mapper.writeValueAsString(record); System.out.println(jsonInString); - - + + } }