diff --git a/.classpath b/.classpath index a775623..7458d2d 100644 --- a/.classpath +++ b/.classpath @@ -11,13 +11,6 @@ - - - - - - - @@ -34,5 +27,12 @@ + + + + + + + diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index d0ac04b..b823efe 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -1,13 +1,26 @@ + + + + + + + + uses + + + + + diff --git a/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml b/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml new file mode 100644 index 0000000..cc81385 --- /dev/null +++ b/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml index 4045d87..fffd28a 100644 --- a/.settings/org.eclipse.wst.common.project.facet.core.xml +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -4,4 +4,5 @@ + diff --git a/CHANGELOG.md b/CHANGELOG.md index 3470142..aa39649 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v1.6.0-SNAPSHOT] - 2022-05-25 + +#### Bug fixes + +- [#23408] GRSF Manage widget is buggy + +#### Enhancements + +- [#23407] Social Post: replace the BR tags with new lines + ## [v1.5.0] - 2021-04-12 [#21153] Upgrade the maven-portal-bom to 3.6.1 version diff --git a/pom.xml b/pom.xml index 63b5938..9f9dc21 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ org.gcube.portlets.widgets grsf-manage-widget - 1.5.0 + 1.6.0-SNAPSHOT gCube GRSF Manage widget diff --git a/src/main/java/org/gcube/datacatalogue/grsf_manage_widget/server/manage/GRSFNotificationService.java b/src/main/java/org/gcube/datacatalogue/grsf_manage_widget/server/manage/GRSFNotificationService.java index 97b63a4..af36d93 100644 --- a/src/main/java/org/gcube/datacatalogue/grsf_manage_widget/server/manage/GRSFNotificationService.java +++ b/src/main/java/org/gcube/datacatalogue/grsf_manage_widget/server/manage/GRSFNotificationService.java @@ -44,29 +44,34 @@ import com.liferay.portal.kernel.log.LogFactoryUtil; /** * 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{ +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 Logger logger = LoggerFactory.getLogger(GRSFNotificationService.class); + // private static final Logger logger = + // LoggerFactory.getLogger(GRSFNotificationService.class); /** - * 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 + * 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 DataCatalogue object * @throws Exception */ - public DataCatalogue getCatalogue(String discoverScope) throws Exception{ + public DataCatalogue getCatalogue(String discoverScope) throws Exception { String currentScope = Utils.getCurrentContext(getThreadLocalRequest(), true); DataCatalogue instance = null; - try{ - String scopeInWhichDiscover = discoverScope != null && !discoverScope.isEmpty() ? discoverScope : currentScope; + try { + String scopeInWhichDiscover = discoverScope != null && !discoverScope.isEmpty() ? discoverScope + : currentScope; logger.debug("Discovering ckan utils library into scope " + scopeInWhichDiscover); instance = DataCatalogueFactory.getFactory().getUtilsPerScope(scopeInWhichDiscover); - }catch(Exception e){ + } catch (Exception e) { logger.error("Unable to retrieve ckan utils. Error was ", e); throw e; } @@ -74,241 +79,258 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS } @Override - public ManageProductBean getProductBeanById(String productIdentifier, boolean requestForRevertingMerge) throws Exception { + public ManageProductBean getProductBeanById(String productIdentifier, boolean requestForRevertingMerge) + throws Exception { ManageProductBean toReturn = null; // check into user's session first HttpSession httpSession = getThreadLocalRequest().getSession(); - // testing case... - if(!Utils.isIntoPortal()){ +// // testing case... +// if(!Utils.isIntoPortal()){ +// +// Thread.sleep(2000); +// +// toReturn = new ManageProductBean(); +// toReturn.setCatalogueIdentifier(UUID.randomUUID().toString()); +// List connectTo = new ArrayList<>(); +// // these are the records alread connected +// connectTo.add(new ConnectedBean( +// "uuid-of-a-connected-bean", +// "Random description", +// "Random shortName", +// "Random Title", +// "http://data.d4science.org/ctlg/GRSF_Admin/uuid-of-a-connected-bean", +// "semantic identifier of the record", +// "Fishery" +// )); +// toReturn.setCurrentConnections(connectTo); +// +// // these are the "suggested connections" +// List suggestionsForConnections = new ArrayList<>(); +// suggestionsForConnections.add(new ConnectedBean( +// "uuid-of-a-connected-bean-suggested", +// "Random description", +// "Random shortName", +// "Random Title", +// "http://data.d4science.org/ctlg/GRSF_Admin/uuid-of-a-connected-bean-suggested", +// "semantic identifier of the record suggested for connection", +// "Fishery" +// )); +// toReturn.setSuggestedByKnowledgeBaseConnections(suggestionsForConnections); +// toReturn.setDomain("Stock"); +// toReturn.setCurrentGrsfType("Assessment Unit"); +// toReturn.setKnowledgeBaseId("91f1e413-dc9f-3b4e-b1c5-0e8560177253"); +// toReturn.setShortName("Widow rockfish - US West Coast"); +// toReturn.setShortNameUpdated("Widow rockfish - US West Coast"); +// toReturn.setTitle("sebastes entomelas FAO 77 FAO 67"); +// toReturn.setTraceabilityFlag(true); +// toReturn.setCurrentStatus(Status.Pending); +// toReturn.setSemanticIdentifier("asfis:WRO+fao:67;FAO"); +// ArrayList sources = new ArrayList(); +// sources.add(new SourceRecord("RAM", "http://www.google.it")); +// sources.add(new SourceRecord("FIRMS", "http://www.google.it")); +// sources.add(new SourceRecord("FishSource", "http://www.google.it")); +// toReturn.setSources(sources); +// List similarGrsfRecords = new ArrayList(); +// similarGrsfRecords.add(new SimilarGRSFRecord( +// "uuid-similar-record-1", +// "description similar record", +// "short name similar record 1", +// "title similar record 1", +// "http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-1", +// "semantic identifier record 1", +// "Stock 1" +// )); +// similarGrsfRecords.add(new SimilarGRSFRecord( +// "uuid-similar-record-2", +// "description similar record", +// "short name similar record 2", +// "title similar record 2", +// "http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-2", +// "semantic identifier record 2", +// "Stock 2" +// )); +// similarGrsfRecords.add(new SimilarGRSFRecord( +// "uuid-similar-record-3", +// "description similar record", +// "short name similar record 3", +// "title similar record 3", +// "http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-3", +// "semantic identifier record 3", +// "Stock 3" +// )); +// similarGrsfRecords.add(new SimilarGRSFRecord( +// "uuid-similar-record-4", +// "description similar record", +// "short name similar record 4", +// "title similar record 4", +// "http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-4", +// "semantic identifier record 4", +// "Stock 4" +// )); +// similarGrsfRecords.add(new SimilarGRSFRecord( +// "uuid-similar-record-5", +// "description similar record", +// "short name similar record 5", +// "title similar record 5", +// "http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-5", +// "semantic identifier record 5", +// "Stock 5" +// )); +// similarGrsfRecords.add(new SimilarGRSFRecord( +// "uuid-similar-record-6", +// "description similar record", +// "short name similar record 6", +// "title similar record 6", +// "http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-6", +// "semantic identifier record 6", +// "Stock 6" +// )); +// toReturn.setSimilarGrsfRecords(similarGrsfRecords); +// +// }else{ - Thread.sleep(2000); + String scopePerCurrentUrl = Utils.getScopeFromClientUrl(getThreadLocalRequest()); + DataCatalogue catalogue = getCatalogue(scopePerCurrentUrl); + String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername(); + CkanDataset record = catalogue.getDataset(productIdentifier, username); - toReturn = new ManageProductBean(); - toReturn.setCatalogueIdentifier(UUID.randomUUID().toString()); - List connectTo = new ArrayList<>(); - // these are the records alread connected - connectTo.add(new ConnectedBean( - "uuid-of-a-connected-bean", - "Random description", - "Random shortName", - "Random Title", - "http://data.d4science.org/ctlg/GRSF_Admin/uuid-of-a-connected-bean", - "semantic identifier of the record", - "Fishery" - )); - toReturn.setCurrentConnections(connectTo); + // it cannot be enabled in this case ... + if (record == null) + throw new Exception("Unable to retrieve information for the selected record, sorry"); + else { - // these are the "suggested connections" - List suggestionsForConnections = new ArrayList<>(); - suggestionsForConnections.add(new ConnectedBean( - "uuid-of-a-connected-bean-suggested", - "Random description", - "Random shortName", - "Random Title", - "http://data.d4science.org/ctlg/GRSF_Admin/uuid-of-a-connected-bean-suggested", - "semantic identifier of the record suggested for connection", - "Fishery" - )); - toReturn.setSuggestedByKnowledgeBaseConnections(suggestionsForConnections); - toReturn.setDomain("Stock"); - toReturn.setCurrentGrsfType("Assessment Unit"); - toReturn.setKnowledgeBaseId("91f1e413-dc9f-3b4e-b1c5-0e8560177253"); - toReturn.setShortName("Widow rockfish - US West Coast"); - toReturn.setShortNameUpdated("Widow rockfish - US West Coast"); - toReturn.setTitle("sebastes entomelas FAO 77 FAO 67"); - toReturn.setTraceabilityFlag(true); - toReturn.setCurrentStatus(Status.Pending); - toReturn.setSemanticIdentifier("asfis:WRO+fao:67;FAO"); - ArrayList sources = new ArrayList(); - sources.add(new SourceRecord("RAM", "http://www.google.it")); - sources.add(new SourceRecord("FIRMS", "http://www.google.it")); - sources.add(new SourceRecord("FishSource", "http://www.google.it")); - toReturn.setSources(sources); - List similarGrsfRecords = new ArrayList(); - similarGrsfRecords.add(new SimilarGRSFRecord( - "uuid-similar-record-1", - "description similar record", - "short name similar record 1", - "title similar record 1", - "http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-1", - "semantic identifier record 1", - "Stock 1" - )); - similarGrsfRecords.add(new SimilarGRSFRecord( - "uuid-similar-record-2", - "description similar record", - "short name similar record 2", - "title similar record 2", - "http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-2", - "semantic identifier record 2", - "Stock 2" - )); - similarGrsfRecords.add(new SimilarGRSFRecord( - "uuid-similar-record-3", - "description similar record", - "short name similar record 3", - "title similar record 3", - "http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-3", - "semantic identifier record 3", - "Stock 3" - )); - similarGrsfRecords.add(new SimilarGRSFRecord( - "uuid-similar-record-4", - "description similar record", - "short name similar record 4", - "title similar record 4", - "http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-4", - "semantic identifier record 4", - "Stock 4" - )); - similarGrsfRecords.add(new SimilarGRSFRecord( - "uuid-similar-record-5", - "description similar record", - "short name similar record 5", - "title similar record 5", - "http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-5", - "semantic identifier record 5", - "Stock 5" - )); - similarGrsfRecords.add(new SimilarGRSFRecord( - "uuid-similar-record-6", - "description similar record", - "short name similar record 6", - "title similar record 6", - "http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-6", - "semantic identifier record 6", - "Stock 6" - )); - toReturn.setSimilarGrsfRecords(similarGrsfRecords); + logger.debug("Trying to fetch the record...."); - }else{ + // check it is a grsf record (Source records have a different System Type) + Map extrasAsMap = record.getExtrasAsHashMap(); - String scopePerCurrentUrl = Utils.getScopeFromClientUrl(getThreadLocalRequest()); - DataCatalogue catalogue = getCatalogue(scopePerCurrentUrl); - String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername(); - CkanDataset record = catalogue.getDataset(productIdentifier,username); + String systemType = extrasAsMap.get(Constants.SYSTEM_TYPE_CUSTOM_KEY); + if (systemType == null || systemType.isEmpty() || systemType.equals(Constants.SYSTEM_TYPE_LEGACY_RECORD)) + throw new NoGRSFRecordException("This is not a GRSF Record"); - // it cannot be enabled in this case ... - if(record == null) - throw new Exception("Unable to retrieve information for the selected record, sorry"); - else{ + boolean isStock = record.getExtrasAsHashMap().get(Constants.DOMAIN_CUSTOM_KEY) + .contains(Product_Type.STOCK.getOrigName()); - logger.debug("Trying to fetch the record...."); + // fetch map for namespaces + Map fieldsNamespacesMap = Utils.getFieldToFieldNameSpaceMapping(httpSession, + isStock ? Constants.GENERIC_RESOURCE_NAME_MAP_KEY_NAMESPACES_STOCK + : Constants.GENERIC_RESOURCE_NAME_MAP_KEY_NAMESPACES_FISHERY); - // check it is a grsf record (Source records have a different System Type) - Map extrasAsMap = record.getExtrasAsHashMap(); + // get extras as pairs + List extrasAsPairs = record.getExtras(); + Map> extrasWithoutNamespaces = Utils.replaceFieldsKey(extrasAsPairs, + fieldsNamespacesMap); + String catalogueIdentifier = record.getId(); + String description = record.getNotes(); + Status status = Status + .fromString(extrasWithoutNamespaces.get(Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY).get(0)); - String systemType = extrasAsMap.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 Record"); + if (status.equals(Status.To_be_Merged) && !requestForRevertingMerge) + throw new GRSFRecordAlreadyManagedStatusException(Status.To_be_Merged, + "The record is locked due to a merge request in progress!"); - boolean isStock = record.getExtrasAsHashMap().get(Constants.DOMAIN_CUSTOM_KEY).contains(Product_Type.STOCK.getOrigName()); + String uuidKB = extrasWithoutNamespaces.get(Constants.UUID_KB_CUSTOM_KEY).get(0); + String grsfDomain = extrasWithoutNamespaces.get(Constants.DOMAIN_CUSTOM_KEY).get(0); + 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 recordUrl = extrasWithoutNamespaces.get(Constants.ITEM_URL_FIELD).get(0); + String grsfName = extrasWithoutNamespaces + .get(grsfDomain.contains(Product_Type.STOCK.getOrigName()) ? Constants.STOCK_NAME_CUSTOM_KEY + : Constants.FISHERY_NAME_CUSTOM_KEY) + .get(0); + boolean traceabilityFlag = false; + try { + traceabilityFlag = extrasWithoutNamespaces.get(Constants.TRACEABILITY_FLAG_CUSTOM_KEY).get(0) + .equalsIgnoreCase("true"); + } catch (Exception e) { + logger.warn("Unable to fetch traceability flag. Setting it to false", e); + } - // fetch map for namespaces - Map fieldsNamespacesMap = - Utils.getFieldToFieldNameSpaceMapping(httpSession, isStock ? - Constants.GENERIC_RESOURCE_NAME_MAP_KEY_NAMESPACES_STOCK : Constants.GENERIC_RESOURCE_NAME_MAP_KEY_NAMESPACES_FISHERY); + boolean sdgFlag = false; + try { + sdgFlag = extrasWithoutNamespaces.get(Constants.SDG_FLAG_CUSTOM_KEY).get(0).equalsIgnoreCase("true"); + } catch (Exception e) { + logger.warn("Unable to fetch sdg flag. Setting it to false", e); + } - // get extras as pairs - List extrasAsPairs = record.getExtras(); - Map> extrasWithoutNamespaces = Utils.replaceFieldsKey(extrasAsPairs, fieldsNamespacesMap); - String catalogueIdentifier = record.getId(); - String description = record.getNotes(); - Status status = Status.fromString(extrasWithoutNamespaces.get(Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY).get(0)); + // Get similar GRSF records, if any (each of which should have name, + // description, url and id(i.e semantic identifier)) + List similarGrsfRecordsAsStrings = extrasWithoutNamespaces + .containsKey(Constants.SIMILAR_GRSF_RECORDS_CUSTOM_KEY) + ? extrasWithoutNamespaces.get(Constants.SIMILAR_GRSF_RECORDS_CUSTOM_KEY) + : null; - if(status.equals(Status.To_be_Merged) && !requestForRevertingMerge) - throw new GRSFRecordAlreadyManagedStatusException(Status.To_be_Merged, "The record is locked due to a merge request in progress!"); - - String uuidKB = extrasWithoutNamespaces.get(Constants.UUID_KB_CUSTOM_KEY).get(0); - String grsfDomain = extrasWithoutNamespaces.get(Constants.DOMAIN_CUSTOM_KEY).get(0); - 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 recordUrl = extrasWithoutNamespaces.get(Constants.ITEM_URL_FIELD).get(0); - String grsfName = extrasWithoutNamespaces.get(grsfDomain.contains(Product_Type.STOCK.getOrigName()) ? Constants.STOCK_NAME_CUSTOM_KEY : Constants.FISHERY_NAME_CUSTOM_KEY).get(0); - boolean traceabilityFlag = false; - try{ - traceabilityFlag = extrasWithoutNamespaces.get(Constants.TRACEABILITY_FLAG_CUSTOM_KEY).get(0).equalsIgnoreCase("true"); - }catch(Exception e){ - logger.warn("Unable to fetch traceability flag. Setting it to false", e); - } - - boolean sdgFlag = false; - try{ - sdgFlag = extrasWithoutNamespaces.get(Constants.SDG_FLAG_CUSTOM_KEY).get(0).equalsIgnoreCase("true"); - }catch(Exception e){ - logger.warn("Unable to fetch sdg flag. Setting it to false", e); - } - - // Get similar GRSF records, if any (each of which should have name, description, url and id(i.e semantic identifier)) - List similarGrsfRecordsAsStrings = extrasWithoutNamespaces.containsKey(Constants.SIMILAR_GRSF_RECORDS_CUSTOM_KEY) ? extrasWithoutNamespaces.get(Constants.SIMILAR_GRSF_RECORDS_CUSTOM_KEY): null; - - List similarRecords = new ArrayList(0); - if(similarGrsfRecordsAsStrings != null && !similarGrsfRecordsAsStrings.isEmpty()){ - if(!similarGrsfRecordsAsStrings.get(0).equals(Constants.NO_SIMILAR_GRSF_RECORDS)){ - for (String similarGRSFRecord : similarGrsfRecordsAsStrings) { - similarRecords.add(Utils.similarGRSFRecordFromJson(similarGRSFRecord, catalogue, username, httpSession)); - } + List similarRecords = new ArrayList(0); + if (similarGrsfRecordsAsStrings != null && !similarGrsfRecordsAsStrings.isEmpty()) { + if (!similarGrsfRecordsAsStrings.get(0).equals(Constants.NO_SIMILAR_GRSF_RECORDS)) { + for (String similarGRSFRecord : similarGrsfRecordsAsStrings) { + similarRecords.add( + Utils.similarGRSFRecordFromJson(similarGRSFRecord, catalogue, username, httpSession)); } } - - logger.debug("SimilarGRSFRecords are " + similarRecords); - - // get connected records (and the proposed ones) - List connectedBeanUrls = - extrasWithoutNamespaces.containsKey(Constants.CONNECTED_CUSTOM_KEY) ? extrasWithoutNamespaces.get(Constants.CONNECTED_CUSTOM_KEY): null; - - List connectedBeans = new ArrayList(0); - if(connectedBeanUrls != null && !connectedBeanUrls.isEmpty()){ - if(!connectedBeanUrls.get(0).equals(Constants.NO_CONNECTED_RECORDS)){ - for (String connectedBean : connectedBeanUrls) { - ConnectedBean builtBean = Utils.connectedBeanRecordFromUrl(connectedBean, catalogue, username, httpSession); - if(builtBean != null) - connectedBeans.add(builtBean); - } - } - } - - logger.debug("Already connected records are " + connectedBeans); - - // get the connections the knowledge base suggests - List suggestedConnectionsByKnowledgeBase = new ArrayList(0); - List exploitedResourcesUrls = isStock ? - extrasWithoutNamespaces.containsKey(Constants.EXPLOITING_FISHERY_CUSTOM_KEY) ? - extrasWithoutNamespaces.get(Constants.EXPLOITING_FISHERY_CUSTOM_KEY) : null: - extrasWithoutNamespaces.containsKey(Constants.RESOURCES_EXPLOITED_CUSTOM_KEY) ? - extrasWithoutNamespaces.get(Constants.RESOURCES_EXPLOITED_CUSTOM_KEY) : null; - - if(exploitedResourcesUrls != null && !exploitedResourcesUrls.isEmpty()){ - for (String exploited : exploitedResourcesUrls) { - ConnectedBean builtBean = Utils.connectedBeanRecordFromUrl(exploited, catalogue, username, httpSession); - if(builtBean != null) - suggestedConnectionsByKnowledgeBase.add(builtBean); - } - } - - logger.debug("Knowledge base suggests " + suggestedConnectionsByKnowledgeBase); - - // Get sources - List resources = record.getResources(); - List sources = new ArrayList(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, shortName, description, grsfName,traceabilityFlag, sdgFlag, - status, recordUrl, sources, similarRecords, - connectedBeans, suggestedConnectionsByKnowledgeBase); - } + + logger.debug("SimilarGRSFRecords are " + similarRecords); + + // get connected records (and the proposed ones) + List connectedBeanUrls = extrasWithoutNamespaces.containsKey(Constants.CONNECTED_CUSTOM_KEY) + ? extrasWithoutNamespaces.get(Constants.CONNECTED_CUSTOM_KEY) + : null; + + List connectedBeans = new ArrayList(0); + if (connectedBeanUrls != null && !connectedBeanUrls.isEmpty()) { + if (!connectedBeanUrls.get(0).equals(Constants.NO_CONNECTED_RECORDS)) { + for (String connectedBean : connectedBeanUrls) { + ConnectedBean builtBean = Utils.connectedBeanRecordFromUrl(connectedBean, catalogue, username, + httpSession); + if (builtBean != null) + connectedBeans.add(builtBean); + } + } + } + + logger.debug("Already connected records are " + connectedBeans); + + // get the connections the knowledge base suggests + List suggestedConnectionsByKnowledgeBase = new ArrayList(0); + List exploitedResourcesUrls = isStock + ? extrasWithoutNamespaces.containsKey(Constants.EXPLOITING_FISHERY_CUSTOM_KEY) + ? extrasWithoutNamespaces.get(Constants.EXPLOITING_FISHERY_CUSTOM_KEY) + : null + : extrasWithoutNamespaces.containsKey(Constants.RESOURCES_EXPLOITED_CUSTOM_KEY) + ? extrasWithoutNamespaces.get(Constants.RESOURCES_EXPLOITED_CUSTOM_KEY) + : null; + + if (exploitedResourcesUrls != null && !exploitedResourcesUrls.isEmpty()) { + for (String exploited : exploitedResourcesUrls) { + ConnectedBean builtBean = Utils.connectedBeanRecordFromUrl(exploited, catalogue, username, + httpSession); + if (builtBean != null) + suggestedConnectionsByKnowledgeBase.add(builtBean); + } + } + + logger.debug("Knowledge base suggests " + suggestedConnectionsByKnowledgeBase); + + // Get sources + List resources = record.getResources(); + List sources = new ArrayList(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, shortName, + description, grsfName, traceabilityFlag, sdgFlag, status, recordUrl, sources, similarRecords, + connectedBeans, suggestedConnectionsByKnowledgeBase); + } +// } logger.debug("Returning item bean " + toReturn); return toReturn; @@ -316,19 +338,20 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS @Override public boolean isAdminUser() { - try{ - Boolean inSession = (Boolean)getThreadLocalRequest().getSession().getAttribute(Constants.GRSF_ADMIN_SESSION_KEY); - if(inSession != null) + try { + Boolean inSession = (Boolean) getThreadLocalRequest().getSession() + .getAttribute(Constants.GRSF_ADMIN_SESSION_KEY); + if (inSession != null) return inSession; - else{ + else { boolean toSetInSession = false; - if(!Utils.isIntoPortal()){ + if (!Utils.isIntoPortal()) { toSetInSession = true; - }else{ + } else { PortalContext pContext = PortalContext.getConfiguration(); RoleManager roleManager = new LiferayRoleManager(); - String username = pContext.getCurrentUser(getThreadLocalRequest()).getUsername(); + String username = pContext.getCurrentUser(getThreadLocalRequest()).getUsername(); long userId = pContext.getCurrentUser(getThreadLocalRequest()).getUserId(); long groupId = pContext.getCurrentGroupId(getThreadLocalRequest()); List teamRolesByUser = roleManager.listTeamsByUserAndGroup(userId, groupId); @@ -337,21 +360,22 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS getThreadLocalRequest().getSession().setAttribute(Constants.GRSF_ADMIN_SESSION_KEY, toSetInSession); return toSetInSession; } - }catch(Exception e){ - logger.error("Failed to check if the user belongs to team " + Constants.GRSF_CATALOGUE_EDITOR_ROLE + " or " + Constants.GRSF_CATALOGUE_REVIEWER_ROLE +"!", e); + } catch (Exception e) { + logger.error("Failed to check if the user belongs to team " + Constants.GRSF_CATALOGUE_EDITOR_ROLE + " or " + + Constants.GRSF_CATALOGUE_REVIEWER_ROLE + "!", e); } return false; } @Override - public void notifyProductUpdate(ManageProductBean bean) throws Exception{ + public void notifyProductUpdate(ManageProductBean bean) throws Exception { logger.info("Creating notification for the bean " + bean + " to send to the knowledge base"); - if(!Utils.isIntoPortal()){ + if (!Utils.isIntoPortal()) { Thread.sleep(2500); return; } - try{ + try { String context = Utils.getScopeFromClientUrl(getThreadLocalRequest()); String token = SecurityTokenProvider.instance.get(); @@ -360,10 +384,11 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername(); // check if the base url of the service is in session - String keyPerContext = CatalogueUtilMethods.concatenateSessionKeyScope(Constants.GRSF_UPDATER_SERVICE, context); + String keyPerContext = CatalogueUtilMethods.concatenateSessionKeyScope(Constants.GRSF_UPDATER_SERVICE, + context); HttpServletRequest threadRequest = getThreadLocalRequest(); - String baseUrl = (String)threadRequest.getSession().getAttribute(keyPerContext); - if(baseUrl == null || baseUrl.isEmpty()){ + String baseUrl = (String) threadRequest.getSession().getAttribute(keyPerContext); + if (baseUrl == null || baseUrl.isEmpty()) { baseUrl = GRSFUpdaterServiceClient.discoverEndPoint(context); threadRequest.getSession().setAttribute(keyPerContext, baseUrl); } @@ -375,7 +400,7 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS Utils.updateRecord(baseUrl, bean, catalogue, username, administratorFullName, threadRequest, PortalContext.getConfiguration().getCurrentGroupId(threadRequest), context, token); - }catch(Exception e){ + } catch (Exception e) { logger.error("Unable to update the product", e); throw e; } @@ -384,13 +409,13 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS @Override public RevertableOperationInfo validateRevertOperation(String encryptedUrl) throws Exception { - if(!Utils.isIntoPortal()){ + if (!Utils.isIntoPortal()) { Thread.sleep(2000); // random result boolean throwException = Math.random() > 0.5; - if(throwException) + if (throwException) throw new Exception("Unable to parse the inserted url"); String baseUrl = "url of the record here"; @@ -399,15 +424,15 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS String uuid = UUID.randomUUID().toString(); String adminInUrl = "costantino.perciante"; String adminInUrlFullName = "Costantino Perciante"; - long timestamp = System.currentTimeMillis() - 1000 * (long)(Math.random() * 10 * 60 * 60); - return new RevertableOperationInfo( - baseUrl, fullName, usernameCurrent, uuid, adminInUrlFullName, adminInUrl, timestamp, RevertableOperations.MERGE); + long timestamp = System.currentTimeMillis() - 1000 * (long) (Math.random() * 10 * 60 * 60); + return new RevertableOperationInfo(baseUrl, fullName, usernameCurrent, uuid, adminInUrlFullName, adminInUrl, + timestamp, RevertableOperations.MERGE); } PortalContext pContext = PortalContext.getConfiguration(); String context = Utils.getScopeFromClientUrl(getThreadLocalRequest()); RoleManager roleManager = new LiferayRoleManager(); - GCubeUser user = pContext.getCurrentUser(getThreadLocalRequest()); + GCubeUser user = pContext.getCurrentUser(getThreadLocalRequest()); String username = user.getUsername(); String fullName = user.getFullname(); long userId = pContext.getCurrentUser(getThreadLocalRequest()).getUserId(); @@ -417,21 +442,25 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS boolean isEditor = isEditor(username, teamRolesByUser); boolean isReviewer = isReviewer(username, teamRolesByUser); - if(!(isEditor | isReviewer)) + if (!(isEditor | isReviewer)) throw new Exception("You are not allowed to perform this operation. You must be an editor or a reviewer!"); // decrypt the url RevertOperationUrl decryptedUrl = new RevertOperationUrl(encryptedUrl); String userNameadminInUrl = decryptedUrl.getAdmin(); // this is the username - String fullNameadminInUrl = new LiferayUserManager().getUserByUsername(userNameadminInUrl).getFullname(); // this is the fullname + String fullNameadminInUrl = new LiferayUserManager().getUserByUsername(userNameadminInUrl).getFullname(); // this + // is + // the + // fullname String uuid = decryptedUrl.getUuid(); - logger.info("User " + username + " has requested to invert an operation on record with id " + uuid + " and admin in url is " + userNameadminInUrl); + logger.info("User " + username + " has requested to invert an operation on record with id " + uuid + + " and admin in url is " + userNameadminInUrl); // we need to check the timestamp (it has 24h validity) boolean isValidTimestamp = decryptedUrl.isTimestampValid(); - if(!isValidTimestamp) + if (!isValidTimestamp) throw new Exception("This operation can no longer be reverted (link expired)!"); DataCatalogue catalogue = getCatalogue(context); @@ -441,36 +470,36 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS String currentStatus = extras.get(Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY); // check current record status - if(!currentStatus.equals(Status.To_be_Merged.getOrigName())) - throw new Exception("Record '" + dataset.getTitle() + "' (" + recordUrl + ") is no longer involved in a merge operation!"); + if (!currentStatus.equals(Status.To_be_Merged.getOrigName())) + throw new Exception("Record '" + dataset.getTitle() + "' (" + recordUrl + + ") is no longer involved in a merge operation!"); // check if it is a reviewer, than he can do what he wants (no matter the admin) - if(isReviewer){ - return new RevertableOperationInfo(recordUrl, - fullName, username, uuid, fullNameadminInUrl, userNameadminInUrl, decryptedUrl.getTimestamp(), decryptedUrl.getOperation()); - }else{ + if (isReviewer) { + return new RevertableOperationInfo(recordUrl, fullName, username, uuid, fullNameadminInUrl, + userNameadminInUrl, decryptedUrl.getTimestamp(), decryptedUrl.getOperation()); + } else { - if(!username.equals(userNameadminInUrl)) + if (!username.equals(userNameadminInUrl)) throw new Exception("You are not the editor allowed to perform this operation!"); else - return new RevertableOperationInfo(recordUrl, - fullName, username, uuid, fullNameadminInUrl, userNameadminInUrl, decryptedUrl.getTimestamp(), decryptedUrl.getOperation()); + return new RevertableOperationInfo(recordUrl, fullName, username, uuid, fullNameadminInUrl, + userNameadminInUrl, decryptedUrl.getTimestamp(), decryptedUrl.getOperation()); } } @Override - public Boolean performRevertOperation(RevertableOperationInfo rInfo) - throws Exception { + public Boolean performRevertOperation(RevertableOperationInfo rInfo) throws Exception { - if(!Utils.isIntoPortal()){ + if (!Utils.isIntoPortal()) { // random result boolean toReturn = Math.random() > 0.5; - if(toReturn){ + if (toReturn) { boolean throwException = Math.random() > 0.5; - if(throwException) + if (throwException) throw new Exception("Unable to execute request for XYZ"); } @@ -481,23 +510,23 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS String context = Utils.getScopeFromClientUrl(threadRequest); String token = SecurityTokenProvider.instance.get(); - try(CloseableHttpClient httpClient = HttpClientBuilder.create().build();){ + try (CloseableHttpClient httpClient = HttpClientBuilder.create().build();) { - String keyPerContext = CatalogueUtilMethods.concatenateSessionKeyScope(Constants.GRSF_UPDATER_SERVICE, context); - String baseUrl = (String)getThreadLocalRequest().getSession().getAttribute(keyPerContext); - if(baseUrl == null || baseUrl.isEmpty()){ + String keyPerContext = CatalogueUtilMethods.concatenateSessionKeyScope(Constants.GRSF_UPDATER_SERVICE, + context); + String baseUrl = (String) getThreadLocalRequest().getSession().getAttribute(keyPerContext); + if (baseUrl == null || baseUrl.isEmpty()) { baseUrl = GRSFUpdaterServiceClient.discoverEndPoint(context); getThreadLocalRequest().getSession().setAttribute(keyPerContext, baseUrl); } - if(baseUrl == null || baseUrl.isEmpty()) + if (baseUrl == null || baseUrl.isEmpty()) throw new Exception("Unable to discover grsf-updater service!"); Utils.revertOperation(httpClient, baseUrl, threadRequest, rInfo, token, context, PortalContext.getConfiguration().getCurrentGroupId(threadRequest)); - } - catch(Exception e){ + } catch (Exception e) { logger.error("Unable to revert operation ", e); throw e; } @@ -506,14 +535,15 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS /** * Check if the current user is an editor + * * @param username * @param teamRoles * @return true if he/she is an editor, false otherwise */ - private boolean isEditor(String username, List teamRolesByUser){ + private boolean isEditor(String username, List teamRolesByUser) { for (GCubeTeam team : teamRolesByUser) { - if(team.getTeamName().equals(Constants.GRSF_CATALOGUE_EDITOR_ROLE)){ + if (team.getTeamName().equals(Constants.GRSF_CATALOGUE_EDITOR_ROLE)) { logger.info("User " + username + " is allowed to modify GRSF records as editor"); return true; } @@ -523,14 +553,15 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS /** * Check if the current user is a reviewer + * * @param username * @param teamRoles * @return true if he/she is an reviewer, false otherwise */ - private boolean isReviewer(String username, List teamRolesByUser){ + private boolean isReviewer(String username, List teamRolesByUser) { for (GCubeTeam team : teamRolesByUser) { - if(team.getTeamName().equals(Constants.GRSF_CATALOGUE_REVIEWER_ROLE)){ + if (team.getTeamName().equals(Constants.GRSF_CATALOGUE_REVIEWER_ROLE)) { logger.info("User " + username + " is allowed to modify GRSF records as reviewer"); return true; } @@ -539,32 +570,30 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS } @Override - public String checkIdentifierExists(String id) - throws Exception { + public String checkIdentifierExists(String id) throws Exception { String scopePerCurrentUrl = Utils.getScopeFromClientUrl(getThreadLocalRequest()); DataCatalogue catalogue = getCatalogue(scopePerCurrentUrl); String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername(); - CkanDataset dataset = catalogue.getDataset(id,username); - if(dataset == null) - throw new Exception("A GRSF record with id " + id + " doesn't exist"); + CkanDataset dataset = catalogue.getDataset(id, username); + if (dataset == null) + throw new Exception("A GRSF record with id " + id + " doesn't exist"); - if(!dataset.getOrganization().getName().equals(Constants.GRSF_ADMIN_ORGANIZATION_NAME)) + if (!dataset.getOrganization().getName().equals(Constants.GRSF_ADMIN_ORGANIZATION_NAME)) throw new Exception("The suggested record is not a GRSF record"); return dataset.getExtrasAsHashMap().get(Constants.ITEM_URL_FIELD); } @Override - public String checkIdentifierExistsInDomain(String id, - String acceptedDomain) throws Exception { + public String checkIdentifierExistsInDomain(String id, String acceptedDomain) throws Exception { - if(!Utils.isIntoPortal()){ + if (!Utils.isIntoPortal()) { boolean throwException = Math.random() > 0.5; // simulate some delay... Thread.sleep(2500); - if(throwException) + if (throwException) throw new Exception("The suggested record is not a GRSF record"); return "http://data.d4science.org/catalogue/grsf_admin/" + id; @@ -575,19 +604,20 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername(); CkanDataset dataset = catalogue.getDataset(id, username); - if(dataset == null) - throw new Exception("A record with id " + id + " doesn't exist"); + if (dataset == null) + throw new Exception("A record with id " + id + " doesn't exist"); Map extras = dataset.getExtrasAsHashMap(); String systemType = extras.get(Constants.SYSTEM_TYPE_CUSTOM_KEY); String domain = extras.get(Constants.DOMAIN_CUSTOM_KEY); String url = extras.get(Constants.ITEM_URL_FIELD); - if(systemType.equals(Constants.SYSTEM_TYPE_FOR_SOURCES_VALUE)) + if (systemType.equals(Constants.SYSTEM_TYPE_LEGACY_RECORD)) throw new Exception("This record is not a GRSF record!"); - if(!acceptedDomain.equalsIgnoreCase(domain)) - throw new Exception("You are suggesting a " + domain + " record instead of a " + acceptedDomain + " record!"); + if (!acceptedDomain.equalsIgnoreCase(domain)) + throw new Exception( + "You are suggesting a " + domain + " record instead of a " + acceptedDomain + " record!"); return url; }