426 lines
14 KiB
Java
426 lines
14 KiB
Java
package org.gcube.data_catalogue.grsf_publish_ws.utils;
|
|
|
|
import java.beans.PropertyDescriptor;
|
|
import java.io.BufferedReader;
|
|
import java.io.InputStreamReader;
|
|
import java.lang.reflect.Field;
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
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.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.utils.groups.Source;
|
|
import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Status;
|
|
import org.gcube.datacatalogue.ckanutillibrary.DataCatalogue;
|
|
import org.gcube.datacatalogue.ckanutillibrary.DataCatalogueFactory;
|
|
import org.gcube.datacatalogue.ckanutillibrary.DataCatalogueImpl;
|
|
import org.gcube.datacatalogue.ckanutillibrary.models.ResourceBean;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import eu.trentorise.opendata.jackan.internal.org.apache.http.HttpResponse;
|
|
import eu.trentorise.opendata.jackan.internal.org.apache.http.client.methods.HttpGet;
|
|
import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.CloseableHttpClient;
|
|
import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.HttpClientBuilder;
|
|
import eu.trentorise.opendata.jackan.model.CkanLicense;
|
|
|
|
|
|
/**
|
|
* Helper methods
|
|
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
|
*/
|
|
public abstract class HelperMethods {
|
|
|
|
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(HelperMethods.class);
|
|
|
|
// to be retrieved from the web.xml
|
|
private static final String PENDING_CONTEX_KEY = "PendingContext";
|
|
private static final String CONFIRMED_CONTEX_KEY = "ConfirmedContext";
|
|
public static final String PRODUCT_TYPE = "Product type";
|
|
|
|
/**
|
|
* Convert a group name to its id on ckan
|
|
* @param origName
|
|
* @return
|
|
*/
|
|
public static String getGroupNameOnCkan(String origName){
|
|
|
|
if(origName == null)
|
|
throw new IllegalArgumentException("origName cannot be null");
|
|
|
|
String modified = origName.trim().toLowerCase().replaceAll("[^A-Za-z0-9-]", "-");
|
|
if(modified.startsWith("-"))
|
|
modified = modified.substring(1);
|
|
if(modified.endsWith("-"))
|
|
modified = modified.substring(0, modified.length() -1);
|
|
|
|
return modified;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the running instance of the data catalogue for this scope
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public static DataCatalogue getDataCatalogueRunningInstance(String scope) throws Exception{
|
|
|
|
try{
|
|
DataCatalogueImpl instance = DataCatalogueFactory.getFactory().getUtilsPerScope(scope);
|
|
return instance;
|
|
}catch(Exception e){
|
|
logger.error("Failed to instanciate data catalogue lib", e);
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
/**
|
|
* Retrieve the list of tags for this object
|
|
*/
|
|
public static void getTags(List<String> tags, Common record){
|
|
|
|
Class<?> current = record.getClass();
|
|
do{
|
|
Field[] fields = current.getDeclaredFields();
|
|
for (Field field : fields) {
|
|
if(field.isAnnotationPresent(Tag.class)){
|
|
try{
|
|
Object f = new PropertyDescriptor(field.getName(), current).getReadMethod().invoke(record);
|
|
if(f != null){
|
|
|
|
tags.add(f.toString().trim());
|
|
|
|
}
|
|
}catch(Exception e){
|
|
logger.error("Failed ot read value for field " + field.getName() + " skipping", e);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
while((current = current.getSuperclass())!=null);
|
|
|
|
// now parse also the Database Sources field
|
|
List<DatabaseSource> sources = record.getDatabaseSources();
|
|
for (DatabaseSource databaseSource : sources) {
|
|
logger.debug("Database source is " + databaseSource);
|
|
String nameAsTag = databaseSource.getName().toString();
|
|
if(!tags.contains(nameAsTag))
|
|
tags.add(nameAsTag);
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieve the list of groups' names for this object
|
|
*/
|
|
public static void getGroups(List<String> groups, Common record){
|
|
|
|
Class<?> current = record.getClass();
|
|
do{
|
|
Field[] fields = current.getDeclaredFields();
|
|
for (Field field : fields) {
|
|
if(field.isAnnotationPresent(Group.class)){
|
|
try{
|
|
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);
|
|
|
|
}
|
|
}catch(Exception e){
|
|
logger.error("Failed ot read value for field " + field.getName() + " skipping", e);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
while((current = current.getSuperclass())!=null);
|
|
|
|
logger.debug("Groups is " + groups);
|
|
|
|
// now parse also the Database Sources field
|
|
List<DatabaseSource> sources = record.getDatabaseSources();
|
|
for (DatabaseSource databaseSource : sources) {
|
|
|
|
logger.debug("Database source is " + databaseSource);
|
|
Source name = databaseSource.getName();
|
|
String groupName = getGroupNameOnCkan(name.toString().trim());
|
|
if(!groups.contains(groupName))
|
|
groups.add(groupName);
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieve the list of extras for this object
|
|
*/
|
|
public static void getExtras(Map<String, String> extras, Common record){
|
|
|
|
Class<?> current = record.getClass();
|
|
do{
|
|
Field[] fields = current.getDeclaredFields();
|
|
for (Field field : fields) {
|
|
if(field.isAnnotationPresent(CustomField.class)){
|
|
try{
|
|
Object f = new PropertyDescriptor(field.getName(), current).getReadMethod().invoke(record);
|
|
if(f != null){
|
|
|
|
// get the key to put into the map first
|
|
extras.put(field.getAnnotation(CustomField.class).key(), f.toString().trim());
|
|
|
|
}
|
|
}catch(Exception e){
|
|
logger.error("Failed ot read value for field " + field.getName() + " skipping", e);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
while((current = current.getSuperclass())!=null);
|
|
}
|
|
|
|
/**
|
|
* Retrieve the organization name in which the user wants to publish starting from the scope
|
|
* @param contextInWhichPublish
|
|
* @return
|
|
*/
|
|
public static String retrieveOrgNameFromScope(String scope) {
|
|
|
|
String[] splittedScope = scope.split("/");
|
|
return splittedScope[splittedScope.length - 1].toLowerCase();
|
|
|
|
}
|
|
|
|
/**
|
|
* Return the context in which the user wants to publish by the status information
|
|
* @param status
|
|
* @param contextServlet
|
|
* @return
|
|
*/
|
|
public static String getContextFromStatus(Status status, ServletContext contextServlet) {
|
|
|
|
String toReturn = null;
|
|
switch(status){
|
|
case Confirmed :
|
|
toReturn = (String)contextServlet.getInitParameter(CONFIRMED_CONTEX_KEY);
|
|
break;
|
|
case Pending:
|
|
toReturn = (String)contextServlet.getInitParameter(PENDING_CONTEX_KEY);
|
|
break;
|
|
default: break;
|
|
|
|
}
|
|
logger.debug("Context evaluated is " + toReturn);
|
|
return toReturn;
|
|
}
|
|
|
|
/**
|
|
* Validate the name the product will have
|
|
* @param futureName
|
|
* @return
|
|
*/
|
|
public static boolean isValid(String futureName) {
|
|
|
|
if(futureName == null || futureName.isEmpty())
|
|
return false;
|
|
else{
|
|
return futureName.matches("[\\sA-Za-z0-9_.-]+");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieve the user's email given his/her username
|
|
* @param context
|
|
* @param token
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public static String getUserEmail(String context, String token){
|
|
|
|
try(CloseableHttpClient client = HttpClientBuilder.create().build();){
|
|
|
|
String baseUrl = new ServiceEndPointReaderSocial(context).getBasePath();
|
|
String url = baseUrl.replace("http", "https") + "/users/getUserEmail?gcube-token=" + token;
|
|
logger.debug("Request url is " + baseUrl);
|
|
HttpGet getRequest = new HttpGet(url);
|
|
|
|
HttpResponse response = client.execute(getRequest);
|
|
|
|
if (response.getStatusLine().getStatusCode() != 200) {
|
|
throw new RuntimeException("Failed : HTTP error code : "
|
|
+ response.getStatusLine().getStatusCode());
|
|
}
|
|
|
|
BufferedReader br = new BufferedReader(
|
|
new InputStreamReader((response.getEntity().getContent())));
|
|
|
|
String email = "";
|
|
String temp = null;
|
|
|
|
while ((temp = br.readLine()) != null) {
|
|
email+= temp;
|
|
}
|
|
|
|
return email;
|
|
}catch(Exception e){
|
|
logger.error("error while performing post method " + e.toString());
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the user's fullname given his/her username
|
|
* @param context
|
|
* @param token
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public static String getUserFullname(String context, String token){
|
|
|
|
try(CloseableHttpClient client = HttpClientBuilder.create().build();){
|
|
|
|
String baseUrl = new ServiceEndPointReaderSocial(context).getBasePath();
|
|
String url = baseUrl.replace("http", "https") + "/users/getUserEmail?gcube-token=" + token;
|
|
logger.debug("Request url is " + url);
|
|
HttpGet getRequest = new HttpGet(url);
|
|
HttpResponse response = client.execute(getRequest);
|
|
|
|
if (response.getStatusLine().getStatusCode() != 200) {
|
|
throw new RuntimeException("Failed : HTTP error code : "
|
|
+ response.getStatusLine().getStatusCode());
|
|
}
|
|
|
|
BufferedReader br = new BufferedReader(
|
|
new InputStreamReader((response.getEntity().getContent())));
|
|
|
|
String fullName = "";
|
|
String temp = null;
|
|
|
|
while ((temp = br.readLine()) != null) {
|
|
fullName+= temp;
|
|
}
|
|
|
|
return fullName;
|
|
}catch(Exception e){
|
|
logger.error("error while performing post method " + e.toString());
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the list of ckan licenses and build up a map <license_id, license_title>
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public static Map<String, String> getLicenses() throws Exception {
|
|
|
|
Map<String, String> toReturn = new HashMap<String, String>();
|
|
String scope = ScopeProvider.instance.get();
|
|
DataCatalogue catalogue = getDataCatalogueRunningInstance(scope);
|
|
List<CkanLicense> licenses = catalogue.getLicenses();
|
|
|
|
for (CkanLicense ckanLicense : licenses) {
|
|
toReturn.put(ckanLicense.getId(), ckanLicense.getTitle());
|
|
}
|
|
|
|
return toReturn;
|
|
}
|
|
|
|
/**
|
|
* Check that the given license id is in CKAN
|
|
* @param license id to check
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public static boolean existsLicenseId(String license) throws Exception {
|
|
|
|
Map<String, String> licenses = getLicenses();
|
|
return licenses.containsKey(license);
|
|
|
|
}
|
|
|
|
// /**
|
|
// * 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)
|
|
* @param record
|
|
* @return
|
|
*/
|
|
public static List<ResourceBean> getResourcesFromBean(Common record, String username) {
|
|
List<ResourceBean> toReturn = new ArrayList<ResourceBean>();
|
|
|
|
List<DatabaseSource> databaseSources = record.getDatabaseSources();
|
|
List<Resource> databaseOfInformation = record.getSourceOfInformation();
|
|
|
|
// transform database sources
|
|
for (DatabaseSource res : databaseSources) {
|
|
logger.debug("Adding resource " + res);
|
|
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));
|
|
}
|
|
|
|
logger.debug("Returning resources " + toReturn);
|
|
return toReturn;
|
|
}
|
|
|
|
}
|