Start adding code to handle resources and inspect them to extract groups/tags' names

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-catalogue/grsf-publisher-ws@133782 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Costantino Perciante 2016-11-01 21:35:52 +00:00
parent 08cbe4dee0
commit c5d9730ef5
9 changed files with 103 additions and 114 deletions

View File

@ -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 {
}

View File

@ -13,4 +13,6 @@ import java.lang.annotation.Target;
@Target(ElementType.FIELD)
public @interface CkanResource {
boolean inspect() default false;
}

View File

@ -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<Resource> 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<String, List<String>> 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<DatabaseSource> databaseSources,
List<Resource> 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;
}

View File

@ -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<String> 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<String> 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;
}

View File

@ -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 + "]";
}

View File

@ -200,7 +200,7 @@ public class GrsfPublisherFisheryService {
}else{
// evaluate the resources
List<ResourceBean> resources = HelperMethods.getResourcesFromBean(record, username);
List<ResourceBean> 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);

View File

@ -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<ResourceBean> resources = HelperMethods.getResourcesFromBean(record, username);
List<ResourceBean> 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);

View File

@ -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<ConstraintViolation<Common>> violations = validator.validate(record);
// for (ConstraintViolation<Common> 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<DatabaseSource> databaseSources = record.getDatabaseSources();
// for (DatabaseSource databaseSource : databaseSources) {
// Set<ConstraintViolation<DatabaseSource>> violationsDatabaseSourcesBean = validator.validate(databaseSource);
// for (ConstraintViolation<DatabaseSource> 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<Resource> sourcesOfInformation = record.getSourceOfInformation();
// for (Resource sourceOfinformation : sourcesOfInformation) {
// Set<ConstraintViolation<Resource>> violationsSourceOfinformationsBean = validator.validate(sourceOfinformation);
// for (ConstraintViolation<Resource> 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<ResourceBean> getResourcesFromBean(Common record, String username) {
public static List<ResourceBean> getResourcesFromBean(Common record, String username, List<String> tags, List<String> groups){
List<ResourceBean> toReturn = new ArrayList<ResourceBean>();
List<DatabaseSource> databaseSources = record.getDatabaseSources();
List<Resource> 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<Resource> listOfResources = (List<Resource>)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
}
}

View File

@ -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<String, List<String>> extras = new HashMap<String, List<String>>();
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);
}
}