server side almost finished

git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/widgets/grsf-manage-widget@158328 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Costantino Perciante 2017-11-09 13:49:07 +00:00
parent 84cc92c4fa
commit c21a7b1fbc
10 changed files with 632 additions and 462 deletions

View File

@ -22,7 +22,7 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>

View File

@ -1,6 +1,6 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error

View File

@ -10,9 +10,10 @@ import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
public interface GRSFManageWidgetService extends RemoteService {
/**
* Notify product update
* check if the user has the rights to manage the item
*/
String notifyProductUpdate(ManageProductBean bean);
boolean isAdminUser();
/**
* Get the product bean from the product identifier
@ -21,9 +22,10 @@ public interface GRSFManageWidgetService extends RemoteService {
* @throws Exception
*/
ManageProductBean getProductBeanById(String identifier) throws Exception;
/**
* check if the user has the rights to manage the item
* Notify product update
*/
boolean isAdminUser();
String notifyProductUpdate(ManageProductBean bean);
}

View File

@ -4,29 +4,20 @@ import com.google.gwt.event.shared.GwtEvent;
/**
* Hide management panel
* Hide management panel event.
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/
public class HideManagementPanelEvent extends GwtEvent<HideManagementPanelEventHandler> {
public static Type<HideManagementPanelEventHandler> TYPE = new Type<HideManagementPanelEventHandler>();
/**
* Instantiates a new hide event.
*/
public HideManagementPanelEvent() {
}
/* (non-Javadoc)
* @see com.google.gwt.event.shared.GwtEvent#getAssociatedType()
*/
@Override
public Type<HideManagementPanelEventHandler> getAssociatedType() {
return TYPE;
}
/* (non-Javadoc)
* @see com.google.gwt.event.shared.GwtEvent#dispatch(com.google.gwt.event.shared.EventHandler)
*/
@Override
protected void dispatch(HideManagementPanelEventHandler handler) {
handler.onEvent(this);

View File

@ -4,7 +4,7 @@ import com.google.gwt.event.shared.EventHandler;
/**
* Hide management panel event handler
* Hide management panel event handler.
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/
public interface HideManagementPanelEventHandler extends EventHandler {

View File

@ -10,6 +10,7 @@ import java.util.Map.Entry;
import org.gcube.datacatalogue.common.enums.Status;
import org.gcube.datacatalogue.grsf_manage_widget.client.GRSFManageWidgetService;
import org.gcube.datacatalogue.grsf_manage_widget.client.GRSFManageWidgetServiceAsync;
import org.gcube.datacatalogue.grsf_manage_widget.client.events.HideManagementPanelEvent;
import org.gcube.datacatalogue.grsf_manage_widget.shared.ManageProductBean;
import org.gcube.datacatalogue.grsf_manage_widget.shared.ex.NoGRSFRecordException;
@ -29,6 +30,7 @@ import com.github.gwtbootstrap.client.ui.constants.ControlGroupType;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.SelectElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
@ -116,14 +118,17 @@ public class ManageProductWidget extends Composite{
+ " You are suggested to contact the VRE Manager if something is wrong with this";
private ManageProductBean bean;
public ManageProductWidget(String productIdentifier) {
private HandlerManager eventBus = null;
public ManageProductWidget(String productIdentifier, HandlerManager eventBus) {
initWidget(uiBinder.createAndBindUi(this));
this.eventBus = eventBus;
if(productIdentifier == null || productIdentifier.isEmpty()){
GWT.log("The received item identifier is null..");
return;
}
GWT.log("item identifier is " + productIdentifier);
// start loader service
@ -152,6 +157,9 @@ public class ManageProductWidget extends Composite{
formUpdate.setVisible(false);
confirmButton.setEnabled(false);
loadingImage.setVisible(false);
// ask to hide management panel
eventBus.fireEvent(new HideManagementPanelEvent());
}else{
service.getProductBeanById(productIdentifier, new AsyncCallback<ManageProductBean>() {

View File

@ -1,74 +1,53 @@
package org.gcube.datacatalogue.grsf_manage_widget.server.manage;
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.gcube.common.portal.PortalContext;
import org.gcube.common.resources.gcore.ServiceEndpoint;
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.datacatalogue.ckanutillibrary.server.ApplicationProfileScopePerUrlReader;
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue;
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueFactory;
import org.gcube.datacatalogue.ckanutillibrary.server.utils.UtilMethods;
import org.gcube.datacatalogue.common.Constants;
import org.gcube.datacatalogue.grsf_manage_widget.client.GRSFManageWidgetService;
import org.gcube.datacatalogue.common.enums.Sources;
import org.gcube.datacatalogue.common.enums.Status;
import org.gcube.datacatalogue.grsf_manage_widget.client.GRSFManageWidgetService;
import org.gcube.datacatalogue.grsf_manage_widget.shared.ManageProductBean;
import org.gcube.datacatalogue.grsf_manage_widget.shared.SimilarGRSFRecord;
import org.gcube.datacatalogue.grsf_manage_widget.shared.SourceRecord;
import org.gcube.datacatalogue.grsf_manage_widget.shared.ex.NoGRSFRecordException;
import org.gcube.resources.discovery.client.api.DiscoveryClient;
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
import org.gcube.vomanagement.usermanagement.RoleManager;
import org.gcube.vomanagement.usermanagement.impl.LiferayRoleManager;
import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager;
import org.gcube.vomanagement.usermanagement.model.GCubeRole;
import org.gcube.vomanagement.usermanagement.model.GCubeTeam;
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.gcube.vomanagement.usermanagement.model.GatewayRolesNames;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import eu.trentorise.opendata.jackan.internal.org.apache.http.HttpResponse;
import eu.trentorise.opendata.jackan.internal.org.apache.http.client.methods.HttpPost;
import eu.trentorise.opendata.jackan.internal.org.apache.http.entity.StringEntity;
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.internal.org.apache.http.util.EntityUtils;
import eu.trentorise.opendata.jackan.model.CkanDataset;
import eu.trentorise.opendata.jackan.model.CkanGroup;
import eu.trentorise.opendata.jackan.model.CkanPair;
import eu.trentorise.opendata.jackan.model.CkanTag;
import eu.trentorise.opendata.jackan.model.CkanResource;
/**
* Endpoint for sending update records information to GRSF KB
* Endpoint for sending update records information to GRSF KnowledgeBase.
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/
public class GRSFNotificationService extends RemoteServiceServlet implements GRSFManageWidgetService{
private static final long serialVersionUID = -4534905087994875893L;
private static final Log logger = LogFactoryUtil.getLog(GRSFNotificationService.class);
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static final int MAX_TRIAL = 5;
/**
* Instanciate the ckan util library.
* Since it needs the scope, we need to check if it is null or not
* @param discoverScope if you want to the discover the utils library in this specified scope
* @return
* @return DataCatalogue object
* @throws Exception
*/
public DataCatalogue getCatalogue(String discoverScope){
String currentScope = getCurrentContext(getThreadLocalRequest(), false);
public DataCatalogue getCatalogue(String discoverScope) throws Exception{
String currentScope = Utils.getCurrentContext(getThreadLocalRequest(), false);
DataCatalogue instance = null;
try{
String scopeInWhichDiscover = discoverScope != null && !discoverScope.isEmpty() ? discoverScope : currentScope;
@ -76,6 +55,7 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
instance = DataCatalogueFactory.getFactory().getUtilsPerScope(scopeInWhichDiscover);
}catch(Exception e){
logger.error("Unable to retrieve ckan utils. Error was " + e.toString());
throw e;
}
return instance;
}
@ -86,17 +66,17 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
logger.info("Creating notification for the bean " + bean + " to send to the knowledge base");
try{
String context = getScopeFromClientUrl(getThreadLocalRequest());
String context = Utils.getScopeFromClientUrl(getThreadLocalRequest());
DataCatalogue catalogue = getCatalogue(context);
// check if the base url of the service is in session
String keyPerContext = UtilMethods.concatenateSessionKeyScope(Constants.GRSF_UPDATER_SERVICE, context);
String baseUrl = (String)getThreadLocalRequest().getSession().getAttribute(keyPerContext);
if(baseUrl == null || baseUrl.isEmpty()){
baseUrl = GRSFNotificationService.discoverEndPoint(context);
baseUrl = Utils.discoverEndPoint(context);
getThreadLocalRequest().getSession().setAttribute(keyPerContext, baseUrl);
}
return GRSFNotificationService.updateCatalogueRecord(baseUrl, bean, catalogue, getCurrentUser(getThreadLocalRequest()).getUsername());
return Utils.updateCatalogueRecord(baseUrl, bean, catalogue, Utils.getCurrentUser(getThreadLocalRequest()).getUsername());
}catch(Exception e){
logger.error("Unable to update the product.." + e.getMessage());
@ -110,373 +90,79 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
ManageProductBean toReturn = null;
// retrieve scope per current portlet url
String scopePerCurrentUrl = getScopeFromClientUrl(getThreadLocalRequest());
String scopePerCurrentUrl = Utils.getScopeFromClientUrl(getThreadLocalRequest());
DataCatalogue catalogue = getCatalogue(scopePerCurrentUrl);
String username = getCurrentUser(getThreadLocalRequest()).getUsername();
String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
CkanDataset record = catalogue.getDataset(productIdentifier, catalogue.getApiKeyFromUsername(username));
// it cannot be enabled in this case ...
if(record == null)
throw new Exception("Unable to retrieve information for the selected item, sorry");
throw new Exception("Unable to retrieve information for the selected record, sorry");
else{
// check it is a grsf record
// check it is a grsf record (Source records have a different System Type)
String systemType = record.getExtrasAsHashMap().get(Constants.SYSTEM_TYPE_CUSTOM_KEY);
if(systemType == null || systemType.isEmpty() || systemType.equals(Constants.SYSTEM_TYPE_FOR_SOURCES_VALUE))
throw new NoGRSFRecordException("This is not a GRSF Item");
throw new NoGRSFRecordException("This is not a GRSF Record");
Map<String, String> extrasAsHashMap = record.getExtrasAsHashMap();
// get extras as hashmap and pairs
List<CkanPair> extrasAsPairs = record.getExtras();
// fetch map for namespaces
Map<String, String> fieldsNamespacesMap = Utils.getFieldToFieldNameSpaceMapping(getThreadLocalRequest().getSession(),
extrasAsHashMap.get(Constants.DOMAIN_CUSTOM_KEY).equals(Constants.STOCK_NAME_CUSTOM_KEY) ? Constants.GENERIC_RESOURCE_NAME_MAP_KEY_NAMESPACES_STOCK
record.getExtrasAsHashMap().get(Constants.DOMAIN_CUSTOM_KEY).equals(Constants.STOCK_NAME_CUSTOM_KEY) ? Constants.GENERIC_RESOURCE_NAME_MAP_KEY_NAMESPACES_STOCK
: Constants.GENERIC_RESOURCE_NAME_MAP_KEY_NAMESPACES_FISHERY);
Map<String, String> extrasWithoutNamespaces = Utils.replaceFieldsKey(extrasAsHashMap, fieldsNamespacesMap);
Map<String, List<String>> extrasWithoutNamespaces = Utils.replaceFieldsKey(extrasAsPairs, fieldsNamespacesMap);
//// other info to show TODO
// Set<String> extrasToShow = Utils.getLookedUpExtrasKeys();
// if(extrasToShow != null && !extrasToShow.isEmpty()){
// Map<String, String> extrasKeyValuePair = new HashMap<String, String>();
// List<CkanPair> extrasAsPairs = product.getExtras();
// for (CkanPair ckanPair : extrasAsPairs) {
// String key = ckanPair.getKey();
// String value = ckanPair.getValue();
//
// if(extrasToShow.contains(key)){
// String currentValueInMap = extrasKeyValuePair.get(key);
// if(currentValueInMap == null)
// currentValueInMap = value;
// else
// currentValueInMap += ", " + value;
// extrasKeyValuePair.put(key, currentValueInMap);
// }
// }
// toReturn.setExtrasIfAvailable(extrasKeyValuePair);
// }
String status = extrasWithoutNamespaces.get(Constants.STATUS_CUSTOM_FIELD_KEY);
String uuidKB = extrasWithoutNamespaces.get(Constants.KB_UUID_FIELD_KEY);
String semanticId = extrasWithoutNamespaces.get(Constants.SEMANTIC_IDENTIFIER);
String shortName = extrasWithoutNamespaces.get(Constants.SHORT_NAME_FIELD_KEY);
String grsfType = extrasWithoutNamespaces.get(Constants.GRSF_TYPE_FIELD_KEY);
String grsfDomain = extrasWithoutNamespaces.get(Constants.GRSF_DOMAIN);
String grsfName = extrasWithoutNamespaces.get(grsfDomain.equals(Constants.STOCK) ? Constants.STOCK_GRSF_NAME : Constants.FISHERY_GRSF_NAME);
String traceabilityFlag = extrasWithoutNamespaces.get(Constants.TRACEABILITY_FLAG);
String sources = extrasWithoutNamespaces.get(Constants.GRSF_DATABASE_SOURCE);
// get extras fields (wrt the mandatory ones) to show in the management panel TODO
// Utils.getExtrasToShow();
String catalogueIdentifier = record.getId();
String status = extrasWithoutNamespaces.get(Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY).get(0);
String uuidKB = extrasWithoutNamespaces.get(Constants.UUID_KB_CUSTOM_KEY).get(0);
String grsfDomain = extrasWithoutNamespaces.get(Constants.DOMAIN_CUSTOM_KEY).get(0);
if(status == null || uuidKB == null)
throw new Exception("Some information is missing in this record: Status = " + status + ", knowledge base uuid = " + uuidKB +
", and grsf domain is = " + grsfDomain);
// set the values
toReturn = new ManageProductBean(semanticId, productIdentifier, uuidKB,
grsfType, grsfDomain, sources, grsfName, traceabilityFlag.equalsIgnoreCase("true"), Status.fromString(status), null, null, shortName, null);
logger.info("Returning item bean " + toReturn);
String semanticId = extrasWithoutNamespaces.get(Constants.GRSF_SEMANTIC_IDENTIFIER_CUSTOM_KEY).get(0);
String shortName = extrasWithoutNamespaces.get(Constants.SHORT_NAME_CUSTOM_KEY).get(0);
String grsfType = extrasWithoutNamespaces.get(Constants.GRSF_TYPE_CUSTOM_KEY).get(0);
String grsfName = extrasWithoutNamespaces.get(grsfDomain.equals(Constants.STOCK_NAME_CUSTOM_KEY) ?
Constants.STOCK_NAME_CUSTOM_KEY : Constants.FISHERY_NAME_CUSTOM_KEY).get(0);
boolean traceabilityFlag = extrasWithoutNamespaces.get(Constants.TRACEABILITY_FLAG_CUSTOM_KEY).get(0).equalsIgnoreCase("true");
return toReturn;
// Get similar GRSF records, if any (each of which should have name, description, url and id(i.e semantic identifier))
List<String> similarGrsfRecordsAsStrings =
extrasWithoutNamespaces.containsKey(Constants.SIMILAR_GRSF_RECORDS_CUSTOM_KEY) ?
extrasWithoutNamespaces.get(Constants.SIMILAR_GRSF_RECORDS_CUSTOM_KEY): null;
List<SimilarGRSFRecord> similarRecords = new ArrayList<SimilarGRSFRecord>(0);
if(similarGrsfRecordsAsStrings != null)
for (String similarGRSFRecord : similarGrsfRecordsAsStrings) {
similarRecords.add(SimilarGRSFRecord.fromJson(similarGRSFRecord));
}
// Get sources
List<CkanResource> resources = record.getResources();
List<SourceRecord> sources = new ArrayList<SourceRecord>(3);
for (CkanResource ckanResource : resources) {
if(Sources.getListNames().contains(ckanResource.getName()))
sources.add(new SourceRecord(ckanResource.getName(), ckanResource.getUrl()));
}
// set the values
toReturn = new ManageProductBean(semanticId, catalogueIdentifier, uuidKB, grsfType,
grsfDomain, grsfName, shortName, traceabilityFlag, Status.fromString(status), null,
null, null, sources, similarRecords);
logger.info("Returning item bean " + toReturn);
return toReturn;
}
}
/**
* Discover the service endpoint and return its url
* @param context
* @return the url of the service on success, null otherwise
*/
public static String discoverEndPoint(String context){
String oldContext = ScopeProvider.instance.get();
ScopeProvider.instance.set(context);
String toReturn = null;
try{
SimpleQuery query = queryFor(ServiceEndpoint.class);
query.addCondition("$resource/Profile/Name/text() eq '"+ Constants.SERVICE_NAME +"'");
query.addCondition("$resource/Profile/Category/text() eq '"+ Constants.SERVICE_CATEGORY +"'");
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
List<ServiceEndpoint> resources = client.submit(query);
if (resources.size() == 0){
logger.error("There is no Runtime Resource having name " + Constants.SERVICE_NAME +" and Category " + Constants.SERVICE_CATEGORY + " in this scope.");
throw new Exception("There is no Runtime Resource having name " + Constants.SERVICE_NAME +" and Category " + Constants.SERVICE_CATEGORY + " in this scope.");
}
else {
for (ServiceEndpoint res : resources) {
Iterator<AccessPoint> accessPointIterator = res.profile().accessPoints().iterator();
while (accessPointIterator.hasNext()) {
ServiceEndpoint.AccessPoint accessPoint = (ServiceEndpoint.AccessPoint) accessPointIterator
.next();
// return the path
toReturn = accessPoint.address();
}
}
}
}catch(Exception e){
logger.error("Unable to retrieve such service endpoint information!", e);
}finally{
if(oldContext != null && !oldContext.equals(context))
ScopeProvider.instance.set(oldContext);
}
return toReturn;
}
/**
* Send an update for this bean
* @param baseUrl
* @param bean
* @param username
* @param catalogue
* @return true on success, false otherwise
*/
@SuppressWarnings("unchecked")
public static String updateCatalogueRecord(String serviceUrl, ManageProductBean bean, DataCatalogue catalogue, String username){
if(serviceUrl == null)
throw new IllegalArgumentException("GRSF Updater service url cannot be null");
if(bean == null)
throw new IllegalArgumentException("Item bean to manage cannot be null");
try(CloseableHttpClient httpClient = HttpClientBuilder.create().build();){
JSONObject obj = new JSONObject();
obj.put(Constants.CATALOGUE_ID, bean.getCatalogueIdentifier());
obj.put(Constants.KB_ID, bean.getKnowledgeBaseIdentifier());
obj.put(Constants.PRODUCT_TYPE, bean.getGrsfDomain().toLowerCase());
obj.put(Constants.STATUS, bean.getNewStatus().toString().toLowerCase());
String annotation = bean.getAnnotation();
if(annotation != null)
obj.put(Constants.ANNOTATION, annotation.replaceAll("\"", ""));
logger.debug("Update request looks like " + obj.toJSONString());
HttpPost request = new HttpPost(serviceUrl + Constants.SERVICE_POST_METHOD);
request.setHeader("Accept", "application/json");
request.setHeader("Content-type", "application/json");
StringEntity params = new StringEntity(obj.toJSONString());
request.setEntity(params);
HttpResponse response = httpClient.execute(request);
logger.debug("Response code is " + response.getStatusLine().getStatusCode() + " and response message is " + response.getStatusLine().getReasonPhrase());
String result = EntityUtils.toString(response.getEntity());
JSONParser parser = new JSONParser();
JSONObject parsedJSON = (JSONObject)parser.parse(result);
if(response.getStatusLine().getStatusCode() != Constants.STATUS_SUCCESS)
throw new IllegalArgumentException(
"Error while performing the update request: " + response.getStatusLine().getReasonPhrase() +
"and error in the result bean is " + parsedJSON.get(Constants.ERROR));
// patch the catalogue product
return patchProduct(catalogue, bean, username);
}catch(Exception e){
logger.error("Unable to update this Item " + e.getMessage());
return e.getMessage();
}
}
/**
* Patch the product
* @param catalogue
* @param bean
* @param username
*/
@SuppressWarnings("unchecked")
private static String patchProduct(DataCatalogue catalogue,
ManageProductBean bean, String username) {
logger.info("Going to patch record in the catalogue with identifier " + bean.getCatalogueIdentifier() +
" from user " + username);
String apiKey = catalogue.getApiKeyFromUsername(username);
CkanDataset dataset = catalogue.getDataset(bean.getCatalogueIdentifier(), apiKey);
String errorMessage = null;
for (int i = 0; i < MAX_TRIAL; i++) {
try(CloseableHttpClient httpClient = HttpClientBuilder.create().build();){
JSONObject jsonRequest = new JSONObject();
JSONArray tagsAsJson = new JSONArray();
JSONArray groupsAsJson = new JSONArray();
JSONArray customFieldsAsJson = new JSONArray();
// manage the custom fields
List<CkanPair> extras = dataset.getExtras();
for (CkanPair ckanPair : extras) {
if(ckanPair.getKey().equals(Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY) && ckanPair.getValue().equals(bean.getCurrentStatus().toString()))
continue;
JSONObject obj = new JSONObject();
obj.put("key", ckanPair.getKey());
obj.put("value", ckanPair.getValue());
customFieldsAsJson.add(obj);
}
// add the new one and the annotation message
JSONObject newStatus = new JSONObject();
newStatus.put("key", Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY);
newStatus.put("value", bean.getNewStatus().toString());
customFieldsAsJson.add(newStatus);
JSONObject newAnnotation = new JSONObject();
newAnnotation.put("key", Constants.ANNOTATION_CUSTOM_KEY);
newAnnotation.put("value", "date: " + DATE_FORMAT.format(new Date())
+ ", admin: " + new LiferayUserManager().getUserByUsername(username).getFullname()
+ ", message: " + (bean.getAnnotation() != null ? bean.getAnnotation().replaceAll("\"", "") : "none")
+ ", old status: " + bean.getCurrentStatus().toString()
+ ", new status: " + bean.getNewStatus().toString()
);
customFieldsAsJson.add(newAnnotation);
// manage the tags
List<CkanTag> tags = dataset.getTags();
for(CkanTag ckanTag : tags){
if(!ckanTag.getName().equals(bean.getCurrentStatus().toString())){
JSONObject obj = new JSONObject();
obj.put("vocabulary_id", ckanTag.getVocabularyId());
obj.put("state", ckanTag.getState().toString());
obj.put("display_name", ckanTag.getDisplayName());
obj.put("id", ckanTag.getId());
obj.put("name", ckanTag.getName());
tagsAsJson.add(obj);
}
}
// add the new one
JSONObject newTag = new JSONObject();
newTag.put("name", bean.getNewStatus().toString());
newTag.put("display_name", bean.getNewStatus().toString());
tagsAsJson.add(newTag);
// manage the groups
List<CkanGroup> groups = dataset.getGroups();
for (CkanGroup ckanGroup : groups) {
if(!ckanGroup.getName().equals("grsf" + "-" + bean.getCurrentStatus().toString().toLowerCase())){
JSONObject obj = new JSONObject();
obj.put("name", ckanGroup.getName());
groupsAsJson.add(obj);
}
}
JSONObject newGroup = new JSONObject();
newGroup.put("name", "grsf" + "-" + bean.getNewStatus().toString().toLowerCase());
groupsAsJson.add(newGroup);
// perform the request
jsonRequest.put("id", bean.getCatalogueIdentifier());
jsonRequest.put("tags", tagsAsJson);
jsonRequest.put("extras", customFieldsAsJson);
jsonRequest.put("groups", groupsAsJson);
logger.debug("Request param is going to be " + jsonRequest);
if((errorMessage = catalogue.patchProductWithJSON(bean.getCatalogueIdentifier(), jsonRequest, apiKey)) == null){
logger.info("Record patched ...");
break;
}else
continue; // retry
}catch(Exception e){
logger.error("Error while trying to patch grsf record (iteration " + i + " of " + MAX_TRIAL + ")" + e.getMessage());
errorMessage = e.getMessage();
}
}
return errorMessage;
}
/**
* Get the scope in which ckan information needs to be discovered from the url
* @param httpServletRequest
* @return
*/
public static String getScopeFromClientUrl(HttpServletRequest httpServletRequest){
if(httpServletRequest == null)
throw new IllegalArgumentException("HttpServletRequest is null!");
String scopeToReturn = null;
try{
String clientUrl = getCurrentClientUrl(httpServletRequest).split("\\?")[0];
logger.debug("Client url is " + clientUrl);
// check if this information is in session, otherwise set it and return
HttpSession session = httpServletRequest.getSession();
if((scopeToReturn = (String) session.getAttribute(clientUrl)) != null){
logger.debug("Scope to return is " + scopeToReturn);
}else{
// ask to the ckan library and set it
scopeToReturn = ApplicationProfileScopePerUrlReader.getScopePerUrl(clientUrl);
logger.debug("Scope to return is " + scopeToReturn);
session.setAttribute(clientUrl, scopeToReturn);
}
}catch(Exception e){
scopeToReturn = getCurrentContext(httpServletRequest, false);
logger.warn("Failed to determine the scope from the client url, returning the current one: " + scopeToReturn);
}
return scopeToReturn;
}
/**
* Needed to get the url of the client
* @param httpServletRequest the httpServletRequest object
* @return the instance of the user
* @see the url at client side
*/
public static String getCurrentClientUrl(HttpServletRequest httpServletRequest) {
if(httpServletRequest == null)
throw new IllegalArgumentException("HttpServletRequest is null!");
return httpServletRequest.getHeader(Constants.GCUBE_REQUEST_URL);
}
/**
* Retrieve the current scope by using the portal manager
* @param b
* @return a GcubeUser object
*/
public static String getCurrentContext(HttpServletRequest request, boolean setInThread){
if(request == null)
throw new IllegalArgumentException("HttpServletRequest is null!");
PortalContext pContext = PortalContext.getConfiguration();
String context = pContext.getCurrentScope(request);
logger.debug("Returning context " + context);
if(context != null && setInThread)
ScopeProvider.instance.set(context);
return context;
}
/**
* Retrieve the current user by using the portal manager
* @return a GcubeUser object
*/
public static GCubeUser getCurrentUser(HttpServletRequest request){
if(request == null)
throw new IllegalArgumentException("HttpServletRequest is null!");
PortalContext pContext = PortalContext.getConfiguration();
GCubeUser user = pContext.getCurrentUser(request);
logger.debug("Returning user " + user);
return user;
}
@Override
public boolean isAdminUser() {
try{
@ -487,20 +173,38 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
return inSession;
else{
PortalContext pContext = PortalContext.getConfiguration();
List<GCubeTeam> teamRoles = new LiferayRoleManager().listTeamsByUserAndGroup(pContext.getCurrentUser(getThreadLocalRequest()).getUserId(), pContext.getCurrentGroupId(getThreadLocalRequest()));
RoleManager roleManager = new LiferayRoleManager();
String username = pContext.getCurrentUser(getThreadLocalRequest()).getUsername();
long userId = pContext.getCurrentUser(getThreadLocalRequest()).getUserId();
long groupId = pContext.getCurrentGroupId(getThreadLocalRequest());
List<GCubeRole> vreRoles = roleManager.listRolesByUserAndGroup(userId, groupId);
List<GCubeTeam> teamRoles = new LiferayRoleManager().listTeamsByUserAndGroup(userId, groupId);
boolean toSetInSession = false;
for (GCubeTeam team : teamRoles) {
if(team.getTeamName().equals(Constants.GRSF_CATALOGUE_MANAGER_ROLE)){
logger.info("User " + username + " is " + Constants.GRSF_CATALOGUE_MANAGER_ROLE);
toSetInSession = true;
break;
}
}
if(!toSetInSession)
for (GCubeRole gCubeTeam : vreRoles) {
if(gCubeTeam.getRoleName().equals(GatewayRolesNames.VRE_MANAGER.getRoleName())){
logger.info("User " + username + " is " + GatewayRolesNames.VRE_MANAGER.getRoleName());
toSetInSession = true;
break;
}
}
getThreadLocalRequest().getSession().setAttribute(Constants.GRSF_ADMIN_SESSION_KEY, toSetInSession);
return toSetInSession;
}
}catch(Exception e){
logger.error("Failed to check if the user has team " + Constants.GRSF_CATALOGUE_MANAGER_ROLE, e);
logger.error("Failed to check if the user has team " + Constants.GRSF_CATALOGUE_MANAGER_ROLE
+ " or " + GatewayRolesNames.VRE_MANAGER.getRoleName() +"!", e);
}
return false;
}
}

View File

@ -1,34 +1,65 @@
package org.gcube.datacatalogue.grsf_manage_widget.server.manage;
import static org.gcube.resources.discovery.icclient.ICFactory.client;
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
import java.io.StringReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.gcube.common.portal.PortalContext;
import org.gcube.common.resources.gcore.ServiceEndpoint;
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
import org.gcube.common.resources.gcore.utils.XPathHelper;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.datacatalogue.ckanutillibrary.server.ApplicationProfileScopePerUrlReader;
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue;
import org.gcube.datacatalogue.ckanutillibrary.shared.ex.ApplicationProfileNotFoundException;
import org.gcube.datacatalogue.common.Constants;
import org.gcube.datacatalogue.grsf_manage_widget.shared.ManageProductBean;
import org.gcube.resources.discovery.client.api.DiscoveryClient;
import org.gcube.resources.discovery.client.queries.api.Query;
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
import org.gcube.resources.discovery.client.queries.impl.QueryBox;
import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager;
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import eu.trentorise.opendata.jackan.internal.org.apache.http.HttpResponse;
import eu.trentorise.opendata.jackan.internal.org.apache.http.client.methods.HttpPost;
import eu.trentorise.opendata.jackan.internal.org.apache.http.entity.StringEntity;
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.internal.org.apache.http.util.EntityUtils;
import eu.trentorise.opendata.jackan.model.CkanDataset;
import eu.trentorise.opendata.jackan.model.CkanGroup;
import eu.trentorise.opendata.jackan.model.CkanPair;
import eu.trentorise.opendata.jackan.model.CkanTag;
/**
* Look up from the IS other information that the widget should show
* Utility methods for GRSF Management panel widget.
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/
public class Utils {
@ -36,7 +67,14 @@ public class Utils {
private static final String GENERIC_RESOURCE_NAME = "GRSFManageEntries";
private static final String GENERIC_RESOURCE_SECONDARY_TYPE = "ApplicationProfile";
private static final Logger logger = LoggerFactory.getLogger(Utils.class);
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static final String REGEX_UUID = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
private static final int MAX_TRIAL = 5;
/**
* Look up from the IS other information that can be potentially displayed in read only mode in the management panel.
* @return a list of extra keys to show.
*/
public static Set<String> getLookedUpExtrasKeys() {
Set<String> lookedUpExtrasKeys = new HashSet<String>();
String scope = ScopeProvider.instance.get();
@ -89,13 +127,14 @@ public class Utils {
* @param httpSession
* @return a map
*/
@SuppressWarnings("unchecked")
public static Map<String, String> getFieldToFieldNameSpaceMapping(HttpSession httpSession, String resourceName){
// check if this information is available in session
String sessionKey = ScopeProvider.instance.get() + resourceName;
if(httpSession.getAttribute(sessionKey) != null)
return (Map<String, String>) httpSession.getAttribute(sessionKey);
Map<String, String> namespacesMap = new HashMap<String, String>(); // e.g. fishery_identity:Short Title -> Short Title
try {
Query q = new QueryBox("for $profile in collection('/db/Profiles/GenericResource')//Resource " +
@ -136,28 +175,425 @@ public class Utils {
}
/**
* Replace the extras' keys if needed
* @param customFields
* Replace the extras' keys if needed, e.g. fishery_identity:Short Title -> Short Title
* @param extrasAsPairs
* @param namespaces
* @return
* @return a map with replaced key value pairs
*/
public static Map<String, String> replaceFieldsKey(Map<String, String> customFields,
public static Map<String, List<String>> replaceFieldsKey(List<CkanPair> extrasAsPairs,
Map<String, String> namespaces) {
Map<String, String> toReturn = new HashMap<String, String>();
Map<String, List<String>> toReturn = new HashMap<String, List<String>>();
Iterator<Entry<String, String>> iterator = customFields.entrySet().iterator();
for (CkanPair ckanPair : extrasAsPairs) {
String pairKey = ckanPair.getKey();
String pairValue = ckanPair.getValue();
String replacedKey = namespaces.containsKey(pairKey) ? namespaces.get(pairKey) : pairKey;
while (iterator.hasNext()) {
Map.Entry<java.lang.String, java.lang.String> entry = (Map.Entry<java.lang.String, java.lang.String>) iterator
.next();
if(namespaces.containsKey(entry.getKey()))
toReturn.put(namespaces.get(entry.getKey()), entry.getValue());
List<String> values = null;
if(toReturn.containsKey(replacedKey))
values = toReturn.get(replacedKey);
else
toReturn.put(entry.getKey(), entry.getValue());
values = new ArrayList<String>(1);
values.add(pairValue);
toReturn.put(replacedKey, values);
}
return toReturn;
}
/**
* Discover the service endpoint and return its url
* @param context
* @return the url of the service on success, null otherwise
*/
public static String discoverEndPoint(String context){
String oldContext = ScopeProvider.instance.get();
ScopeProvider.instance.set(context);
String toReturn = null;
try{
SimpleQuery query = queryFor(ServiceEndpoint.class);
query.addCondition("$resource/Profile/Name/text() eq '"+ Constants.SERVICE_NAME +"'");
query.addCondition("$resource/Profile/Category/text() eq '"+ Constants.SERVICE_CATEGORY +"'");
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
List<ServiceEndpoint> resources = client.submit(query);
if (resources.size() == 0){
logger.error("There is no Runtime Resource having name " + Constants.SERVICE_NAME +" and Category " + Constants.SERVICE_CATEGORY + " in this scope.");
throw new Exception("There is no Runtime Resource having name " + Constants.SERVICE_NAME +" and Category " + Constants.SERVICE_CATEGORY + " in this scope.");
}
else {
for (ServiceEndpoint res : resources) {
Iterator<AccessPoint> accessPointIterator = res.profile().accessPoints().iterator();
while (accessPointIterator.hasNext()) {
ServiceEndpoint.AccessPoint accessPoint = (ServiceEndpoint.AccessPoint) accessPointIterator
.next();
// return the path
toReturn = accessPoint.address();
}
}
}
}catch(Exception e){
logger.error("Unable to retrieve such service endpoint information!", e);
}finally{
if(oldContext != null && !oldContext.equals(context))
ScopeProvider.instance.set(oldContext);
}
return toReturn;
}
/**
* Send an update for this bean
* @param baseUrl
* @param bean
* @param username
* @param catalogue
* @return true on success, false otherwise
*/
@SuppressWarnings("unchecked")
public static String updateCatalogueRecord(String serviceUrl, ManageProductBean bean, DataCatalogue catalogue, String username){
if(serviceUrl == null)
throw new IllegalArgumentException("GRSF Updater service url cannot be null");
if(bean == null)
throw new IllegalArgumentException("Item bean to manage cannot be null");
try(CloseableHttpClient httpClient = HttpClientBuilder.create().build();){
JSONObject obj = new JSONObject();
obj.put(Constants.CATALOGUE_ID, bean.getCatalogueIdentifier());
obj.put(Constants.KB_ID, bean.getKnowledgeBaseIdentifier());
obj.put(Constants.PRODUCT_TYPE, bean.getGrsfDomain().toLowerCase());
obj.put(Constants.STATUS, bean.getNewStatus().toString().toLowerCase());
String annotation = bean.getAnnotation();
if(annotation != null)
obj.put(Constants.ANNOTATION, annotation.replaceAll("\"", ""));
logger.debug("Update request looks like " + obj.toJSONString());
HttpPost request = new HttpPost(serviceUrl + Constants.SERVICE_POST_METHOD);
request.setHeader("Accept", "application/json");
request.setHeader("Content-type", "application/json");
StringEntity params = new StringEntity(obj.toJSONString());
request.setEntity(params);
HttpResponse response = httpClient.execute(request);
logger.debug("Response code is " + response.getStatusLine().getStatusCode() + " and response message is " + response.getStatusLine().getReasonPhrase());
String result = EntityUtils.toString(response.getEntity());
JSONParser parser = new JSONParser();
JSONObject parsedJSON = (JSONObject)parser.parse(result);
if(response.getStatusLine().getStatusCode() != Constants.STATUS_SUCCESS)
throw new IllegalArgumentException(
"Error while performing the update request: " + response.getStatusLine().getReasonPhrase() +
"and error in the result bean is " + parsedJSON.get(Constants.ERROR));
// patch the catalogue product
return patchProduct(catalogue, bean, username);
}catch(Exception e){
logger.error("Unable to update this Item " + e.getMessage());
return e.getMessage();
}
}
/**
* Patch the product
* @param catalogue
* @param bean
* @param username
*/
@SuppressWarnings("unchecked")
private static String patchProduct(DataCatalogue catalogue,
ManageProductBean bean, String username) {
logger.info("Going to patch record in the catalogue with identifier " + bean.getCatalogueIdentifier() +
" from user " + username);
String apiKey = catalogue.getApiKeyFromUsername(username);
CkanDataset dataset = catalogue.getDataset(bean.getCatalogueIdentifier(), apiKey);
String errorMessage = null;
for (int i = 0; i < MAX_TRIAL; i++) {
try(CloseableHttpClient httpClient = HttpClientBuilder.create().build();){
JSONObject jsonRequest = new JSONObject();
JSONArray tagsAsJson = new JSONArray();
JSONArray groupsAsJson = new JSONArray();
JSONArray customFieldsAsJson = new JSONArray();
// manage the custom fields
List<CkanPair> extras = dataset.getExtras();
for (CkanPair ckanPair : extras) {
if(ckanPair.getKey().equals(Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY) && ckanPair.getValue().equals(bean.getCurrentStatus().toString()))
continue;
JSONObject obj = new JSONObject();
obj.put("key", ckanPair.getKey());
obj.put("value", ckanPair.getValue());
customFieldsAsJson.add(obj);
}
// add the new one and the annotation message
JSONObject newStatus = new JSONObject();
newStatus.put("key", Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY);
newStatus.put("value", bean.getNewStatus().toString());
customFieldsAsJson.add(newStatus);
JSONObject newAnnotation = new JSONObject();
newAnnotation.put("key", Constants.ANNOTATION_CUSTOM_KEY);
newAnnotation.put("value", "date: " + DATE_FORMAT.format(new Date())
+ ", admin: " + new LiferayUserManager().getUserByUsername(username).getFullname()
+ ", message: " + (bean.getAnnotation() != null ? bean.getAnnotation().replaceAll("\"", "") : "none")
+ ", old status: " + bean.getCurrentStatus().toString()
+ ", new status: " + bean.getNewStatus().toString()
);
customFieldsAsJson.add(newAnnotation);
// manage the tags
List<CkanTag> tags = dataset.getTags();
for(CkanTag ckanTag : tags){
if(!ckanTag.getName().equals(bean.getCurrentStatus().toString())){
JSONObject obj = new JSONObject();
obj.put("vocabulary_id", ckanTag.getVocabularyId());
obj.put("state", ckanTag.getState().toString());
obj.put("display_name", ckanTag.getDisplayName());
obj.put("id", ckanTag.getId());
obj.put("name", ckanTag.getName());
tagsAsJson.add(obj);
}
}
// add the new one
JSONObject newTag = new JSONObject();
newTag.put("name", bean.getNewStatus().toString());
newTag.put("display_name", bean.getNewStatus().toString());
tagsAsJson.add(newTag);
// manage the groups
List<CkanGroup> groups = dataset.getGroups();
for (CkanGroup ckanGroup : groups) {
if(!ckanGroup.getName().equals("grsf" + "-" + bean.getCurrentStatus().toString().toLowerCase())){
JSONObject obj = new JSONObject();
obj.put("name", ckanGroup.getName());
groupsAsJson.add(obj);
}
}
JSONObject newGroup = new JSONObject();
newGroup.put("name", "grsf" + "-" + bean.getNewStatus().toString().toLowerCase());
groupsAsJson.add(newGroup);
// perform the request
jsonRequest.put("id", bean.getCatalogueIdentifier());
jsonRequest.put("tags", tagsAsJson);
jsonRequest.put("extras", customFieldsAsJson);
jsonRequest.put("groups", groupsAsJson);
logger.debug("Request param is going to be " + jsonRequest);
if((errorMessage = catalogue.patchProductWithJSON(bean.getCatalogueIdentifier(), jsonRequest, apiKey)) == null){
logger.info("Record patched ...");
break;
}else
continue; // retry
}catch(Exception e){
logger.error("Error while trying to patch grsf record (iteration " + i + " of " + MAX_TRIAL + ")" + e.getMessage());
errorMessage = e.getMessage();
}
}
return errorMessage;
}
/**
* Get the scope in which ckan information needs to be discovered from the url
* @param httpServletRequest
* @return
*/
public static String getScopeFromClientUrl(HttpServletRequest httpServletRequest){
if(httpServletRequest == null)
throw new IllegalArgumentException("HttpServletRequest is null!");
String scopeToReturn = null;
try{
String clientUrl = getCurrentClientUrl(httpServletRequest).split("\\?")[0];
logger.debug("Client url is " + clientUrl);
// check if this information is in session, otherwise set it and return
HttpSession session = httpServletRequest.getSession();
if((scopeToReturn = (String) session.getAttribute(clientUrl)) != null){
logger.debug("Scope to return is " + scopeToReturn);
}else{
// ask to the ckan library and set it
scopeToReturn = ApplicationProfileScopePerUrlReader.getScopePerUrl(clientUrl);
logger.debug("Scope to return is " + scopeToReturn);
session.setAttribute(clientUrl, scopeToReturn);
}
}catch(Exception e){
scopeToReturn = getCurrentContext(httpServletRequest, false);
logger.warn("Failed to determine the scope from the client url, returning the current one: " + scopeToReturn);
}
return scopeToReturn;
}
/**
* Needed to get the url of the client
* @param httpServletRequest the httpServletRequest object
* @return the instance of the user
* @see the url at client side
*/
public static String getCurrentClientUrl(HttpServletRequest httpServletRequest) {
if(httpServletRequest == null)
throw new IllegalArgumentException("HttpServletRequest is null!");
return httpServletRequest.getHeader(Constants.GCUBE_REQUEST_URL);
}
/**
* Retrieve the current scope by using the portal manager
* @param b
* @return a GcubeUser object
*/
public static String getCurrentContext(HttpServletRequest request, boolean setInThread){
if(request == null)
throw new IllegalArgumentException("HttpServletRequest is null!");
PortalContext pContext = PortalContext.getConfiguration();
String context = pContext.getCurrentScope(request);
logger.debug("Returning context " + context);
if(context != null && setInThread)
ScopeProvider.instance.set(context);
return context;
}
/**
* Retrieve the current user by using the portal manager
* @return a GcubeUser object
*/
public static GCubeUser getCurrentUser(HttpServletRequest request){
if(request == null)
throw new IllegalArgumentException("HttpServletRequest is null!");
PortalContext pContext = PortalContext.getConfiguration();
GCubeUser user = pContext.getCurrentUser(request);
logger.debug("Returning user " + user);
return user;
}
/**
* Given a semantic identifier, check if a record exists and return it
* @param suggestedRecordSemanticIdentifier
* @param catalogue
* @return CkanDataset
* @throws Exception in case no record matches the semantic identifier
*/
public static CkanDataset getRecordBySemanticIdentifier(
String suggestedRecordSemanticIdentifier, DataCatalogue catalogue,
String apiKey) throws Exception {
if(suggestedRecordSemanticIdentifier == null || suggestedRecordSemanticIdentifier.isEmpty())
throw new Exception(Constants.GRSF_SEMANTIC_IDENTIFIER_CUSTOM_KEY + " cannot be null or emtpy");
String query = Constants.GRSF_SEMANTIC_IDENTIFIER_CUSTOM_KEY + "\"" + suggestedRecordSemanticIdentifier+ "\"";
List<CkanDataset> datasets = catalogue.searchForPackageInOrganization(apiKey, query, 0, 10, Constants.GRSF_ADMIN_ORGANIZATION_NAME);
if(datasets == null || datasets.isEmpty()){
String message = "Unable to find dataset with such " + Constants.GRSF_SEMANTIC_IDENTIFIER_CUSTOM_KEY;
logger.warn(message);
throw new Exception(message);
}
if(datasets.size() == 1)
return datasets.get(0);
else{
// worst situation.. we need to check for the right one
for(CkanDataset dataset: datasets)
for(CkanPair extra : dataset.getExtras())
if(extra.getKey().contains(Constants.GRSF_SEMANTIC_IDENTIFIER_CUSTOM_KEY) && extra.getValue().equals(suggestedRecordSemanticIdentifier))
return dataset;
}
// in the end ....
throw new Exception("Unable to find record with " + Constants.GRSF_SEMANTIC_IDENTIFIER_CUSTOM_KEY + " equals to " + suggestedRecordSemanticIdentifier);
}
/**
* Exploits the fact that in GRSF the url of a record contains the name (which is unique) of the record itself
* @param url
* @param clg
* @return
*/
public static CkanDataset getDatasetFromUrl(String url, DataCatalogue clg, String apiKey){
if(url == null || url.isEmpty())
return null;
// Parse url
// Create a Pattern object
Pattern r = Pattern.compile(REGEX_UUID);
// Now create matcher object.
Matcher m = r.matcher(url);
if (m.find()) {
String uuidFound = m.group();
logger.debug("Found match for uuid " + uuidFound);
return clg.getDataset(uuidFound, apiKey);
}
return null;
}
// /**
// * Get extra information to show in the management panel, if any
// * @param extrasAsPairs
// */
// public static void getExtrasToShow(List<CkanPair> extrasAsPairs, ){
//
// Set<String> extrasToShow = getLookedUpExtrasKeys();
// if(extrasToShow != null && !extrasToShow.isEmpty()){
// Map<String, String> extrasKeyValuePair = new HashMap<String, String>();
// = product.getExtras();
// for (CkanPair ckanPair : extrasAsPairs) {
// String key = ckanPair.getKey();
// String value = ckanPair.getValue();
//
// if(extrasToShow.contains(key)){
// String currentValueInMap = extrasKeyValuePair.get(key);
// if(currentValueInMap == null)
// currentValueInMap = value;
// else
// currentValueInMap += ", " + value;
// extrasKeyValuePair.put(key, currentValueInMap);
// }
// }
// toReturn.setExtrasIfAvailable(extrasKeyValuePair);
// }
//
// }
}

View File

@ -1,6 +1,7 @@
package org.gcube.datacatalogue.grsf_manage_widget.shared;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.gcube.datacatalogue.common.enums.Status;
@ -12,68 +13,75 @@ import org.gcube.datacatalogue.common.enums.Status;
public class ManageProductBean implements Serializable{
private static final long serialVersionUID = -4882608487467259326L;
private String semanticId; // Stock id or Fishery id
private String semanticIdentifier; // Stock id or Fishery id
private String catalogueIdentifier; // catalogue id
private String knowledgeBaseIdentifier; // GRSF UUID
private String grsfType; // Fishery or Stock type (e.g., Assessment_Unit, Marine Resource and so on)
private String grsfDomain; // fishery/stock
private String sources; // sources for this record
private String grsfName; // Fishery name or stock name
private String shortName;
private boolean traceabilityFlag; //from false to true etc
private Status currentStatus;
private Status newStatus;
private String annotation; // added by the administrator
private String shortName;
private Map<String, String> extrasIfAvailable; // read from GRSFManageEntries resource
private List<SourceRecord> sources; // sources for this record
private List<SimilarGRSFRecord> similarGrsfRecords;
public ManageProductBean() {
super();
}
/**
* @param semanticId
* @param catalogueIdentifier
* @param knowledgeBaseIdentifier
* @param grsfType
* @param grsfDomain
* @param sources
* @param grsfName
* @param traceabilityFlag
* @param currentStatus
* @param newStatus
* @param annotation
* @param shortName
* @param extrasIfAvailable
*/
public ManageProductBean(String semanticId, String catalogueIdentifier,
String knowledgeBaseIdentifier, String grsfType, String grsfDomain,
String sources, String grsfName, boolean traceabilityFlag,
Status currentStatus, Status newStatus, String annotation,
String shortName, Map<String, String> extrasIfAvailable) {
public ManageProductBean(String semanticIdentifier,
String catalogueIdentifier, String knowledgeBaseIdentifier,
String grsfType, String grsfDomain, String grsfName,
String shortName, boolean traceabilityFlag, Status currentStatus,
Status newStatus, String annotation,
Map<String, String> extrasIfAvailable, List<SourceRecord> sources,
List<SimilarGRSFRecord> similarGrsfRecords) {
super();
this.semanticId = semanticId;
this.semanticIdentifier = semanticIdentifier;
this.catalogueIdentifier = catalogueIdentifier;
this.knowledgeBaseIdentifier = knowledgeBaseIdentifier;
this.grsfType = grsfType;
this.grsfDomain = grsfDomain;
this.sources = sources;
this.grsfName = grsfName;
this.shortName = shortName;
this.traceabilityFlag = traceabilityFlag;
this.currentStatus = currentStatus;
this.newStatus = newStatus;
this.annotation = annotation;
this.shortName = shortName;
this.extrasIfAvailable = extrasIfAvailable;
this.sources = sources;
this.similarGrsfRecords = similarGrsfRecords;
}
public String getSemanticId() {
return semanticId;
public String getSemanticIdentifier() {
return semanticIdentifier;
}
public void setSemanticId(String semanticId) {
this.semanticId = semanticId;
public void setSemanticIdentifier(String semanticIdentifier) {
this.semanticIdentifier = semanticIdentifier;
}
public List<SourceRecord> getSources() {
return sources;
}
public void setSources(List<SourceRecord> sources) {
this.sources = sources;
}
public List<SimilarGRSFRecord> getSimilarGrsfRecords() {
return similarGrsfRecords;
}
public void setSimilarGrsfRecords(List<SimilarGRSFRecord> similarGrsfRecords) {
this.similarGrsfRecords = similarGrsfRecords;
}
public String getCatalogueIdentifier() {
return catalogueIdentifier;
}
@ -106,14 +114,6 @@ public class ManageProductBean implements Serializable{
this.grsfDomain = grsfDomain;
}
public String getSources() {
return sources;
}
public void setSources(String sources) {
this.sources = sources;
}
public String getGrsfName() {
return grsfName;
}
@ -153,7 +153,7 @@ public class ManageProductBean implements Serializable{
public void setAnnotation(String annotation) {
this.annotation = annotation;
}
public boolean isTraceabilityFlag() {
return traceabilityFlag;
}
@ -172,15 +172,16 @@ public class ManageProductBean implements Serializable{
@Override
public String toString() {
return "ManageProductBean [semanticId=" + semanticId
return "ManageProductBean [semanticIdentifier=" + semanticIdentifier
+ ", catalogueIdentifier=" + catalogueIdentifier
+ ", knowledgeBaseIdentifier=" + knowledgeBaseIdentifier
+ ", grsfType=" + grsfType + ", grsfDomain=" + grsfDomain
+ ", sources=" + sources + ", grsfName=" + grsfName
+ ", grsfName=" + grsfName + ", shortName=" + shortName
+ ", traceabilityFlag=" + traceabilityFlag + ", currentStatus="
+ currentStatus + ", newStatus=" + newStatus + ", annotation="
+ annotation + ", shortName=" + shortName
+ ", extrasIfAvailable=" + extrasIfAvailable + "]";
+ annotation + ", extrasIfAvailable=" + extrasIfAvailable
+ ", sources=" + sources + ", similarGrsfRecords="
+ similarGrsfRecords + "]";
}
}

View File

@ -2,6 +2,11 @@ package org.gcube.datacatalogue.grsf_manage_widget.shared;
import java.io.Serializable;
import org.gcube.datacatalogue.common.Constants;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
/**
* A similar grsf record
@ -64,5 +69,28 @@ public class SimilarGRSFRecord implements Serializable{
+ ", semanticIdentifier=" + semanticIdentifier + ", shortName="
+ shortName + ", url=" + url + "]";
}
/**
* Get a {@link SimilarGRSFRecord} from a json string
* @param json
* @return {@link SimilarGRSFRecord}
* @throws ParseException
*/
public static SimilarGRSFRecord fromJson(String json) throws ParseException{
if(json == null)
return null;
JSONParser parser = new JSONParser();
JSONObject object = (JSONObject)parser.parse(json);
return new SimilarGRSFRecord(
(String)object.get(Constants.SIMILAR_RECORDS_BEAN_FIELD_DESCRIPTION),
(String)object.get(Constants.SIMILAR_RECORDS_BEAN_FIELD_IDENTIFIER),
(String)object.get(Constants.SIMILAR_RECORDS_BEAN_FIELD_NAME),
(String)object.get(Constants.SIMILAR_RECORDS_BEAN_FIELD_URL)
);
}
}