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:
parent
84cc92c4fa
commit
c21a7b1fbc
|
@ -22,7 +22,7 @@
|
||||||
<attribute name="maven.pomderived" value="true"/>
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</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>
|
<attributes>
|
||||||
<attribute name="maven.pomderived" value="true"/>
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
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.compliance=1.7
|
||||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
|
|
|
@ -10,9 +10,10 @@ import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
|
||||||
public interface GRSFManageWidgetService extends RemoteService {
|
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
|
* Get the product bean from the product identifier
|
||||||
|
@ -21,9 +22,10 @@ public interface GRSFManageWidgetService extends RemoteService {
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
ManageProductBean getProductBeanById(String identifier) 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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
||||||
*/
|
*/
|
||||||
public class HideManagementPanelEvent extends GwtEvent<HideManagementPanelEventHandler> {
|
public class HideManagementPanelEvent extends GwtEvent<HideManagementPanelEventHandler> {
|
||||||
public static Type<HideManagementPanelEventHandler> TYPE = new Type<HideManagementPanelEventHandler>();
|
public static Type<HideManagementPanelEventHandler> TYPE = new Type<HideManagementPanelEventHandler>();
|
||||||
|
|
||||||
/**
|
|
||||||
* Instantiates a new hide event.
|
|
||||||
*/
|
|
||||||
public HideManagementPanelEvent() {
|
public HideManagementPanelEvent() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see com.google.gwt.event.shared.GwtEvent#getAssociatedType()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Type<HideManagementPanelEventHandler> getAssociatedType() {
|
public Type<HideManagementPanelEventHandler> getAssociatedType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see com.google.gwt.event.shared.GwtEvent#dispatch(com.google.gwt.event.shared.EventHandler)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected void dispatch(HideManagementPanelEventHandler handler) {
|
protected void dispatch(HideManagementPanelEventHandler handler) {
|
||||||
handler.onEvent(this);
|
handler.onEvent(this);
|
||||||
|
|
|
@ -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)
|
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
||||||
*/
|
*/
|
||||||
public interface HideManagementPanelEventHandler extends EventHandler {
|
public interface HideManagementPanelEventHandler extends EventHandler {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import java.util.Map.Entry;
|
||||||
import org.gcube.datacatalogue.common.enums.Status;
|
import org.gcube.datacatalogue.common.enums.Status;
|
||||||
import org.gcube.datacatalogue.grsf_manage_widget.client.GRSFManageWidgetService;
|
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.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.ManageProductBean;
|
||||||
import org.gcube.datacatalogue.grsf_manage_widget.shared.ex.NoGRSFRecordException;
|
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.core.client.GWT;
|
||||||
import com.google.gwt.dom.client.SelectElement;
|
import com.google.gwt.dom.client.SelectElement;
|
||||||
import com.google.gwt.event.dom.client.ClickEvent;
|
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.UiBinder;
|
||||||
import com.google.gwt.uibinder.client.UiField;
|
import com.google.gwt.uibinder.client.UiField;
|
||||||
import com.google.gwt.uibinder.client.UiHandler;
|
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";
|
+ " You are suggested to contact the VRE Manager if something is wrong with this";
|
||||||
private ManageProductBean bean;
|
private ManageProductBean bean;
|
||||||
|
|
||||||
public ManageProductWidget(String productIdentifier) {
|
private HandlerManager eventBus = null;
|
||||||
|
|
||||||
|
public ManageProductWidget(String productIdentifier, HandlerManager eventBus) {
|
||||||
initWidget(uiBinder.createAndBindUi(this));
|
initWidget(uiBinder.createAndBindUi(this));
|
||||||
|
this.eventBus = eventBus;
|
||||||
|
|
||||||
if(productIdentifier == null || productIdentifier.isEmpty()){
|
if(productIdentifier == null || productIdentifier.isEmpty()){
|
||||||
GWT.log("The received item identifier is null..");
|
GWT.log("The received item identifier is null..");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GWT.log("item identifier is " + productIdentifier);
|
GWT.log("item identifier is " + productIdentifier);
|
||||||
|
|
||||||
// start loader service
|
// start loader service
|
||||||
|
@ -152,6 +157,9 @@ public class ManageProductWidget extends Composite{
|
||||||
formUpdate.setVisible(false);
|
formUpdate.setVisible(false);
|
||||||
confirmButton.setEnabled(false);
|
confirmButton.setEnabled(false);
|
||||||
loadingImage.setVisible(false);
|
loadingImage.setVisible(false);
|
||||||
|
|
||||||
|
// ask to hide management panel
|
||||||
|
eventBus.fireEvent(new HideManagementPanelEvent());
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
service.getProductBeanById(productIdentifier, new AsyncCallback<ManageProductBean>() {
|
service.getProductBeanById(productIdentifier, new AsyncCallback<ManageProductBean>() {
|
||||||
|
|
|
@ -1,74 +1,53 @@
|
||||||
package org.gcube.datacatalogue.grsf_manage_widget.server.manage;
|
package org.gcube.datacatalogue.grsf_manage_widget.server.manage;
|
||||||
|
|
||||||
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
|
import java.util.ArrayList;
|
||||||
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
|
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpSession;
|
|
||||||
|
|
||||||
import org.gcube.common.portal.PortalContext;
|
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.DataCatalogue;
|
||||||
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueFactory;
|
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueFactory;
|
||||||
import org.gcube.datacatalogue.ckanutillibrary.server.utils.UtilMethods;
|
import org.gcube.datacatalogue.ckanutillibrary.server.utils.UtilMethods;
|
||||||
import org.gcube.datacatalogue.common.Constants;
|
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.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.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.datacatalogue.grsf_manage_widget.shared.ex.NoGRSFRecordException;
|
||||||
import org.gcube.resources.discovery.client.api.DiscoveryClient;
|
import org.gcube.vomanagement.usermanagement.RoleManager;
|
||||||
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
|
|
||||||
import org.gcube.vomanagement.usermanagement.impl.LiferayRoleManager;
|
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.GCubeTeam;
|
||||||
import org.gcube.vomanagement.usermanagement.model.GCubeUser;
|
import org.gcube.vomanagement.usermanagement.model.GatewayRolesNames;
|
||||||
import org.json.simple.JSONArray;
|
|
||||||
import org.json.simple.JSONObject;
|
|
||||||
import org.json.simple.parser.JSONParser;
|
|
||||||
|
|
||||||
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
|
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
|
||||||
import com.liferay.portal.kernel.log.Log;
|
import com.liferay.portal.kernel.log.Log;
|
||||||
import com.liferay.portal.kernel.log.LogFactoryUtil;
|
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.CkanDataset;
|
||||||
import eu.trentorise.opendata.jackan.model.CkanGroup;
|
|
||||||
import eu.trentorise.opendata.jackan.model.CkanPair;
|
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)
|
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
||||||
*/
|
*/
|
||||||
public class GRSFNotificationService extends RemoteServiceServlet implements GRSFManageWidgetService{
|
public class GRSFNotificationService extends RemoteServiceServlet implements GRSFManageWidgetService{
|
||||||
|
|
||||||
private static final long serialVersionUID = -4534905087994875893L;
|
private static final long serialVersionUID = -4534905087994875893L;
|
||||||
private static final Log logger = LogFactoryUtil.getLog(GRSFNotificationService.class);
|
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.
|
* Instanciate the ckan util library.
|
||||||
* Since it needs the scope, we need to check if it is null or not
|
* 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
|
* @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){
|
public DataCatalogue getCatalogue(String discoverScope) throws Exception{
|
||||||
String currentScope = getCurrentContext(getThreadLocalRequest(), false);
|
String currentScope = Utils.getCurrentContext(getThreadLocalRequest(), false);
|
||||||
DataCatalogue instance = null;
|
DataCatalogue instance = null;
|
||||||
try{
|
try{
|
||||||
String scopeInWhichDiscover = discoverScope != null && !discoverScope.isEmpty() ? discoverScope : currentScope;
|
String scopeInWhichDiscover = discoverScope != null && !discoverScope.isEmpty() ? discoverScope : currentScope;
|
||||||
|
@ -76,6 +55,7 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
instance = DataCatalogueFactory.getFactory().getUtilsPerScope(scopeInWhichDiscover);
|
instance = DataCatalogueFactory.getFactory().getUtilsPerScope(scopeInWhichDiscover);
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
logger.error("Unable to retrieve ckan utils. Error was " + e.toString());
|
logger.error("Unable to retrieve ckan utils. Error was " + e.toString());
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
return instance;
|
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");
|
logger.info("Creating notification for the bean " + bean + " to send to the knowledge base");
|
||||||
try{
|
try{
|
||||||
|
|
||||||
String context = getScopeFromClientUrl(getThreadLocalRequest());
|
String context = Utils.getScopeFromClientUrl(getThreadLocalRequest());
|
||||||
DataCatalogue catalogue = getCatalogue(context);
|
DataCatalogue catalogue = getCatalogue(context);
|
||||||
|
|
||||||
// check if the base url of the service is in session
|
// check if the base url of the service is in session
|
||||||
String keyPerContext = UtilMethods.concatenateSessionKeyScope(Constants.GRSF_UPDATER_SERVICE, context);
|
String keyPerContext = UtilMethods.concatenateSessionKeyScope(Constants.GRSF_UPDATER_SERVICE, context);
|
||||||
String baseUrl = (String)getThreadLocalRequest().getSession().getAttribute(keyPerContext);
|
String baseUrl = (String)getThreadLocalRequest().getSession().getAttribute(keyPerContext);
|
||||||
if(baseUrl == null || baseUrl.isEmpty()){
|
if(baseUrl == null || baseUrl.isEmpty()){
|
||||||
baseUrl = GRSFNotificationService.discoverEndPoint(context);
|
baseUrl = Utils.discoverEndPoint(context);
|
||||||
getThreadLocalRequest().getSession().setAttribute(keyPerContext, baseUrl);
|
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){
|
}catch(Exception e){
|
||||||
logger.error("Unable to update the product.." + e.getMessage());
|
logger.error("Unable to update the product.." + e.getMessage());
|
||||||
|
@ -110,373 +90,79 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
ManageProductBean toReturn = null;
|
ManageProductBean toReturn = null;
|
||||||
|
|
||||||
// retrieve scope per current portlet url
|
// retrieve scope per current portlet url
|
||||||
String scopePerCurrentUrl = getScopeFromClientUrl(getThreadLocalRequest());
|
String scopePerCurrentUrl = Utils.getScopeFromClientUrl(getThreadLocalRequest());
|
||||||
DataCatalogue catalogue = getCatalogue(scopePerCurrentUrl);
|
DataCatalogue catalogue = getCatalogue(scopePerCurrentUrl);
|
||||||
String username = getCurrentUser(getThreadLocalRequest()).getUsername();
|
String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername();
|
||||||
CkanDataset record = catalogue.getDataset(productIdentifier, catalogue.getApiKeyFromUsername(username));
|
CkanDataset record = catalogue.getDataset(productIdentifier, catalogue.getApiKeyFromUsername(username));
|
||||||
|
|
||||||
// it cannot be enabled in this case ...
|
// it cannot be enabled in this case ...
|
||||||
if(record == null)
|
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{
|
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);
|
String systemType = record.getExtrasAsHashMap().get(Constants.SYSTEM_TYPE_CUSTOM_KEY);
|
||||||
if(systemType == null || systemType.isEmpty() || systemType.equals(Constants.SYSTEM_TYPE_FOR_SOURCES_VALUE))
|
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
|
// fetch map for namespaces
|
||||||
Map<String, String> fieldsNamespacesMap = Utils.getFieldToFieldNameSpaceMapping(getThreadLocalRequest().getSession(),
|
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);
|
: 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
|
// get extras fields (wrt the mandatory ones) to show in the management panel TODO
|
||||||
// Set<String> extrasToShow = Utils.getLookedUpExtrasKeys();
|
// Utils.getExtrasToShow();
|
||||||
// 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);
|
|
||||||
|
|
||||||
|
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)
|
if(status == null || uuidKB == null)
|
||||||
throw new Exception("Some information is missing in this record: Status = " + status + ", knowledge base uuid = " + uuidKB +
|
throw new Exception("Some information is missing in this record: Status = " + status + ", knowledge base uuid = " + uuidKB +
|
||||||
", and grsf domain is = " + grsfDomain);
|
", 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
|
@Override
|
||||||
public boolean isAdminUser() {
|
public boolean isAdminUser() {
|
||||||
try{
|
try{
|
||||||
|
@ -487,20 +173,38 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
return inSession;
|
return inSession;
|
||||||
else{
|
else{
|
||||||
PortalContext pContext = PortalContext.getConfiguration();
|
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;
|
boolean toSetInSession = false;
|
||||||
for (GCubeTeam team : teamRoles) {
|
for (GCubeTeam team : teamRoles) {
|
||||||
if(team.getTeamName().equals(Constants.GRSF_CATALOGUE_MANAGER_ROLE)){
|
if(team.getTeamName().equals(Constants.GRSF_CATALOGUE_MANAGER_ROLE)){
|
||||||
|
logger.info("User " + username + " is " + Constants.GRSF_CATALOGUE_MANAGER_ROLE);
|
||||||
toSetInSession = true;
|
toSetInSession = true;
|
||||||
break;
|
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);
|
getThreadLocalRequest().getSession().setAttribute(Constants.GRSF_ADMIN_SESSION_KEY, toSetInSession);
|
||||||
return toSetInSession;
|
return toSetInSession;
|
||||||
}
|
}
|
||||||
}catch(Exception e){
|
}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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,65 @@
|
||||||
package org.gcube.datacatalogue.grsf_manage_widget.server.manage;
|
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.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.io.StringReader;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
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.servlet.http.HttpSession;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
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.resources.gcore.utils.XPathHelper;
|
||||||
import org.gcube.common.scope.api.ScopeProvider;
|
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.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.api.DiscoveryClient;
|
||||||
import org.gcube.resources.discovery.client.queries.api.Query;
|
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.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.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
import org.xml.sax.InputSource;
|
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)
|
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
|
||||||
*/
|
*/
|
||||||
public class Utils {
|
public class Utils {
|
||||||
|
@ -36,7 +67,14 @@ public class Utils {
|
||||||
private static final String GENERIC_RESOURCE_NAME = "GRSFManageEntries";
|
private static final String GENERIC_RESOURCE_NAME = "GRSFManageEntries";
|
||||||
private static final String GENERIC_RESOURCE_SECONDARY_TYPE = "ApplicationProfile";
|
private static final String GENERIC_RESOURCE_SECONDARY_TYPE = "ApplicationProfile";
|
||||||
private static final Logger logger = LoggerFactory.getLogger(Utils.class);
|
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() {
|
public static Set<String> getLookedUpExtrasKeys() {
|
||||||
Set<String> lookedUpExtrasKeys = new HashSet<String>();
|
Set<String> lookedUpExtrasKeys = new HashSet<String>();
|
||||||
String scope = ScopeProvider.instance.get();
|
String scope = ScopeProvider.instance.get();
|
||||||
|
@ -89,13 +127,14 @@ public class Utils {
|
||||||
* @param httpSession
|
* @param httpSession
|
||||||
* @return a map
|
* @return a map
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public static Map<String, String> getFieldToFieldNameSpaceMapping(HttpSession httpSession, String resourceName){
|
public static Map<String, String> getFieldToFieldNameSpaceMapping(HttpSession httpSession, String resourceName){
|
||||||
|
|
||||||
// check if this information is available in session
|
// check if this information is available in session
|
||||||
String sessionKey = ScopeProvider.instance.get() + resourceName;
|
String sessionKey = ScopeProvider.instance.get() + resourceName;
|
||||||
if(httpSession.getAttribute(sessionKey) != null)
|
if(httpSession.getAttribute(sessionKey) != null)
|
||||||
return (Map<String, String>) httpSession.getAttribute(sessionKey);
|
return (Map<String, String>) httpSession.getAttribute(sessionKey);
|
||||||
|
|
||||||
Map<String, String> namespacesMap = new HashMap<String, String>(); // e.g. fishery_identity:Short Title -> Short Title
|
Map<String, String> namespacesMap = new HashMap<String, String>(); // e.g. fishery_identity:Short Title -> Short Title
|
||||||
try {
|
try {
|
||||||
Query q = new QueryBox("for $profile in collection('/db/Profiles/GenericResource')//Resource " +
|
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
|
* Replace the extras' keys if needed, e.g. fishery_identity:Short Title -> Short Title
|
||||||
* @param customFields
|
* @param extrasAsPairs
|
||||||
* @param namespaces
|
* @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> 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()) {
|
List<String> values = null;
|
||||||
Map.Entry<java.lang.String, java.lang.String> entry = (Map.Entry<java.lang.String, java.lang.String>) iterator
|
if(toReturn.containsKey(replacedKey))
|
||||||
.next();
|
values = toReturn.get(replacedKey);
|
||||||
if(namespaces.containsKey(entry.getKey()))
|
|
||||||
toReturn.put(namespaces.get(entry.getKey()), entry.getValue());
|
|
||||||
else
|
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;
|
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);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.gcube.datacatalogue.grsf_manage_widget.shared;
|
package org.gcube.datacatalogue.grsf_manage_widget.shared;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.gcube.datacatalogue.common.enums.Status;
|
import org.gcube.datacatalogue.common.enums.Status;
|
||||||
|
@ -12,68 +13,75 @@ import org.gcube.datacatalogue.common.enums.Status;
|
||||||
public class ManageProductBean implements Serializable{
|
public class ManageProductBean implements Serializable{
|
||||||
|
|
||||||
private static final long serialVersionUID = -4882608487467259326L;
|
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 catalogueIdentifier; // catalogue id
|
||||||
private String knowledgeBaseIdentifier; // GRSF UUID
|
private String knowledgeBaseIdentifier; // GRSF UUID
|
||||||
private String grsfType; // Fishery or Stock type (e.g., Assessment_Unit, Marine Resource and so on)
|
private String grsfType; // Fishery or Stock type (e.g., Assessment_Unit, Marine Resource and so on)
|
||||||
private String grsfDomain; // fishery/stock
|
private String grsfDomain; // fishery/stock
|
||||||
private String sources; // sources for this record
|
|
||||||
private String grsfName; // Fishery name or stock name
|
private String grsfName; // Fishery name or stock name
|
||||||
|
private String shortName;
|
||||||
private boolean traceabilityFlag; //from false to true etc
|
private boolean traceabilityFlag; //from false to true etc
|
||||||
private Status currentStatus;
|
private Status currentStatus;
|
||||||
private Status newStatus;
|
private Status newStatus;
|
||||||
private String annotation; // added by the administrator
|
private String annotation; // added by the administrator
|
||||||
private String shortName;
|
|
||||||
private Map<String, String> extrasIfAvailable; // read from GRSFManageEntries resource
|
private Map<String, String> extrasIfAvailable; // read from GRSFManageEntries resource
|
||||||
|
private List<SourceRecord> sources; // sources for this record
|
||||||
|
private List<SimilarGRSFRecord> similarGrsfRecords;
|
||||||
|
|
||||||
public ManageProductBean() {
|
public ManageProductBean() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public ManageProductBean(String semanticIdentifier,
|
||||||
* @param semanticId
|
String catalogueIdentifier, String knowledgeBaseIdentifier,
|
||||||
* @param catalogueIdentifier
|
String grsfType, String grsfDomain, String grsfName,
|
||||||
* @param knowledgeBaseIdentifier
|
String shortName, boolean traceabilityFlag, Status currentStatus,
|
||||||
* @param grsfType
|
Status newStatus, String annotation,
|
||||||
* @param grsfDomain
|
Map<String, String> extrasIfAvailable, List<SourceRecord> sources,
|
||||||
* @param sources
|
List<SimilarGRSFRecord> similarGrsfRecords) {
|
||||||
* @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) {
|
|
||||||
super();
|
super();
|
||||||
this.semanticId = semanticId;
|
this.semanticIdentifier = semanticIdentifier;
|
||||||
this.catalogueIdentifier = catalogueIdentifier;
|
this.catalogueIdentifier = catalogueIdentifier;
|
||||||
this.knowledgeBaseIdentifier = knowledgeBaseIdentifier;
|
this.knowledgeBaseIdentifier = knowledgeBaseIdentifier;
|
||||||
this.grsfType = grsfType;
|
this.grsfType = grsfType;
|
||||||
this.grsfDomain = grsfDomain;
|
this.grsfDomain = grsfDomain;
|
||||||
this.sources = sources;
|
|
||||||
this.grsfName = grsfName;
|
this.grsfName = grsfName;
|
||||||
|
this.shortName = shortName;
|
||||||
this.traceabilityFlag = traceabilityFlag;
|
this.traceabilityFlag = traceabilityFlag;
|
||||||
this.currentStatus = currentStatus;
|
this.currentStatus = currentStatus;
|
||||||
this.newStatus = newStatus;
|
this.newStatus = newStatus;
|
||||||
this.annotation = annotation;
|
this.annotation = annotation;
|
||||||
this.shortName = shortName;
|
|
||||||
this.extrasIfAvailable = extrasIfAvailable;
|
this.extrasIfAvailable = extrasIfAvailable;
|
||||||
|
this.sources = sources;
|
||||||
|
this.similarGrsfRecords = similarGrsfRecords;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSemanticId() {
|
public String getSemanticIdentifier() {
|
||||||
return semanticId;
|
return semanticIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSemanticId(String semanticId) {
|
public void setSemanticIdentifier(String semanticIdentifier) {
|
||||||
this.semanticId = semanticId;
|
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() {
|
public String getCatalogueIdentifier() {
|
||||||
return catalogueIdentifier;
|
return catalogueIdentifier;
|
||||||
}
|
}
|
||||||
|
@ -106,14 +114,6 @@ public class ManageProductBean implements Serializable{
|
||||||
this.grsfDomain = grsfDomain;
|
this.grsfDomain = grsfDomain;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSources() {
|
|
||||||
return sources;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSources(String sources) {
|
|
||||||
this.sources = sources;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getGrsfName() {
|
public String getGrsfName() {
|
||||||
return grsfName;
|
return grsfName;
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ public class ManageProductBean implements Serializable{
|
||||||
public void setAnnotation(String annotation) {
|
public void setAnnotation(String annotation) {
|
||||||
this.annotation = annotation;
|
this.annotation = annotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTraceabilityFlag() {
|
public boolean isTraceabilityFlag() {
|
||||||
return traceabilityFlag;
|
return traceabilityFlag;
|
||||||
}
|
}
|
||||||
|
@ -172,15 +172,16 @@ public class ManageProductBean implements Serializable{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ManageProductBean [semanticId=" + semanticId
|
return "ManageProductBean [semanticIdentifier=" + semanticIdentifier
|
||||||
+ ", catalogueIdentifier=" + catalogueIdentifier
|
+ ", catalogueIdentifier=" + catalogueIdentifier
|
||||||
+ ", knowledgeBaseIdentifier=" + knowledgeBaseIdentifier
|
+ ", knowledgeBaseIdentifier=" + knowledgeBaseIdentifier
|
||||||
+ ", grsfType=" + grsfType + ", grsfDomain=" + grsfDomain
|
+ ", grsfType=" + grsfType + ", grsfDomain=" + grsfDomain
|
||||||
+ ", sources=" + sources + ", grsfName=" + grsfName
|
+ ", grsfName=" + grsfName + ", shortName=" + shortName
|
||||||
+ ", traceabilityFlag=" + traceabilityFlag + ", currentStatus="
|
+ ", traceabilityFlag=" + traceabilityFlag + ", currentStatus="
|
||||||
+ currentStatus + ", newStatus=" + newStatus + ", annotation="
|
+ currentStatus + ", newStatus=" + newStatus + ", annotation="
|
||||||
+ annotation + ", shortName=" + shortName
|
+ annotation + ", extrasIfAvailable=" + extrasIfAvailable
|
||||||
+ ", extrasIfAvailable=" + extrasIfAvailable + "]";
|
+ ", sources=" + sources + ", similarGrsfRecords="
|
||||||
|
+ similarGrsfRecords + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,11 @@ package org.gcube.datacatalogue.grsf_manage_widget.shared;
|
||||||
|
|
||||||
import java.io.Serializable;
|
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
|
* A similar grsf record
|
||||||
|
@ -64,5 +69,28 @@ public class SimilarGRSFRecord implements Serializable{
|
||||||
+ ", semanticIdentifier=" + semanticIdentifier + ", shortName="
|
+ ", semanticIdentifier=" + semanticIdentifier + ", shortName="
|
||||||
+ shortName + ", url=" + url + "]";
|
+ 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)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue