diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 31c2b6e4986d6415f2d8d69ba701507390fd1faf..22bd3a98c2fe66599d07565a911ecfc819f669d9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -392,3 +392,36 @@ test_deploy_with_db_without_superadmin_rights: - test 200 = $(curl --write-out %{http_code} --silent --output /dev/null -c cookie.txt http://localhost:8080/minerva/api/doLogin) - test 200 = $(curl --write-out %{http_code} --silent --output /dev/null --cookie cookie.txt http://localhost:8080/minerva/api/projects/) +test_postgres_9_3_compatibility: + image: maven:3.6.0-jdk-8 + services: + - postgres:9.3 + stage: test + script: + - mkdir /etc/minerva/ + - cp test-db-ci.properties /etc/minerva/db.properties + - mvn -DskipTests=true clean install -pl persist -am + - mvn test -pl persist + +test_postgres_10_compatibility: + image: maven:3.6.0-jdk-8 + services: + - postgres:10 + stage: test + script: + - mkdir /etc/minerva/ + - cp test-db-ci.properties /etc/minerva/db.properties + - mvn -DskipTests=true clean install -pl persist -am + - mvn test -pl persist + +test_postgres_11_compatibility: + image: maven:3.6.0-jdk-8 + services: + - postgres:11 + stage: test + script: + - mkdir /etc/minerva/ + - cp test-db-ci.properties /etc/minerva/db.properties + - mvn -DskipTests=true clean install -pl persist -am + - mvn test -pl persist + diff --git a/CHANGELOG b/CHANGELOG index 091c93583ce78d5f461a679db9ed90cc3d0c5ba1..2eef00a6cea62514d0d7b9f221d56e9b25267ace 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,138 +1,45 @@ minerva (12.3.0~alpha.0) unstable; urgency=low - * Feature: annotators are more flexible - you can define set of input and + * Feature: annotators are more flexible - you can define set of input and outputs used by annotator (#617) * Small improvement: validation of the organism and disease id on map upload added (#618) - * Small improvement: added current username next to logout button in admin + * Small improvement: added current username next to logout button in admin panel (#660) - * Small improvement: New comment dialog does not contain content of previous + * Small improvement: New comment dialog does not contain content of previous comment dialog (#680) * Small improvement: Left logo is configurable (#731) * Small improvement: Plugin API provides list of overview images (#702) * Small improvement: Plugin API allows to show/hide overview images (#702) * Small improvement: Plugin API allows to trigger search on the map (#702) * Small improvement: Plugin API allows to clear search results on map (#702) - * Small improvement: edit/remove project button is disabled until project is + * Small improvement: edit/remove project button is disabled until project is uploaded (#683) - * Small improvement: warning about capslock is visible on login page when + * Small improvement: warning about capslock is visible on login page when necessary (#658) - * Small improvement: names of columns in data overlay are unified: no + * Small improvement: names of columns in data overlay are unified: no whitespace, "_" used as separator (#596) * Small improvement: list of references in drug panel contains PUBMED prefix (#666) - * Small improvement: passwords to email account and ldap are not sent over + * Small improvement: passwords to email account and ldap are not sent over API (#732) - * Small improvement: reactant/product/modifier specific colors are parsed + * Small improvement: reactant/product/modifier specific colors are parsed properly from CellDesigner file (#597) * Small improvement: Info tab contains information about disease and organism when info is provided * Small improvement: Info tab provides information about model annotations and submap tabs provide information about submaps annotations if applicable (#591) - * Bug fix: progress bar of gene genome mapping upload is refreshing properly + * Bug fix: progress bar of gene genome mapping upload is refreshing properly (#728) - * Bug fix: when editing project Disease and Organism could not be removed + * Bug fix: when editing project Disease and Organism could not be removed (#616) - * Bug fix: dashed line partially wasn't dashed in "Unknown Catalysis" and - "Unknown Inhibition" reactions (#664) - * Bug fix: "Unknown Catalysis" and "Unknown Inhibition" reaction end is + * Bug fix: dashed line partially wasn't dashed in "Unknown Catalysis" and + "Unknown Inhibition" reactions (#664) + * Bug fix: "Unknown Catalysis" and "Unknown Inhibition" reaction end is slightly separated from target phenotype (#664) -minerva (12.2.0~beta.2) unstable; urgency=medium - * Bug fix: order of the overlays is defined explicitly also for general - overlays (#684) - * Bug fix: files are saved in proper folder (#694, #670) - * Bug fix: removing comments in a project asked for confirmation twice after - edit project dialog for specific project was opened; closed and opened - again (#697) - * Bug fix: clicking on compartment border inside pathway should return - compartment, not a pathway (#324) - * Bug fix: clicking outside of the element sometimes resulted with the - invalid element highlighted (#324) - * Bug fix: parent compartment/pathway use proper type name in left panel - (#324) - * Bug fix: editing/removing project requires Map Management privilege (#681) - * Bug fix: when removeAllListeners is called list of registered listeners is - cleaned (#687) - * Bug fix: when plugin is removed the html elements associated with it are - removed as well (#686) - * Bug fix: when creating new user default privileges are set properly (#692) - * Bug fix: import from SBML issue - reaction with product and modifier being - the same element caused exception (#703) - * Bug fix: plugin can be added after plugin has been removed in admin plugin - panel (#686) - * Bug fix: too many annotations (>=100) caused misaligning in the left panel - (#708) - * Bug fix: text was outside the popup window (#711) - * Bug fix: custom semantic zooming contains multiple overlays checkbox was - disabled (#715) - * Bug fix: export to svg contains viewBox info (#716) - * Bug fix: import from sbml with layout could crash when two elements - occupied the exact same position (#717) - * Bug fix: overlays added via API couldn't be visualized after refresh (#718) - * Bug fix: Safari sometimes cached server responses and used wrong data, for - example in admin panel configuration tab (#719) - * Bug fix: description of transcription site is centered (#720) - * Bug fix: selecting too few parameters in export doesn't throw reportable - error (#721) - * Bug fix: changes in selected checkbox in add project dialog block UI (#722) - * Bug fix: providing invalid overlay id in url could break minerva (#726) - * Bug fix: removing project that doesn't exist doesn't cause 500 error (#723) - * Bug fix: Editing project with images and submaps could cause a problem - (#725) - * Bug fix: opening map with invalid id shows proper error message (#724) - * Bug fix: Fixing an issue where search panel was not properly resized on - expansion (#682) - * Small improvement: highlighting table rows in admin panel uses better - contrast color (#706) - - -- Piotr Gawron <piotr.gawron@uni.lu> Wed, 20 Feb 2019 14:00:00 +0200 - -minerva (12.2.0~beta.1) unstable; urgency=medium - * Small improvement: list of publication can be filtered by submap (#614) - * Small improvement: report bug utility shows confirmation dialog on success - (#648) - * Small improvement: size of add overlay window adjusted to show more data - without scrollbars (#657) - * Small improvement: all popup dialogs in the app have dialog specific css - class names (#665) - * Bug fix: loading icon is not overlapping input in the search panel (#404) - * Bug fix: position of transcription sites in genes are computed properly - (#553) - * Bug fix: REQUEST AN ACCOUNT was enabled when associated email was invalid - (#626) - * Bug fix: layout exported to SBML can be properly visualized by COPASI - (#654) - * Bug fix: working with too many maps within the single session could crash - connection to server (#651) - * Bug fix: invalid pubmed id could crash listing/downloading publications - (#656) - * Bug fix: icons in safari sometimes disappear (#661) - * Bug fix: downloading reference genome for the second time resulted in an - error (#670) - * Bug fix: plugin validation in admin panel improved to catch more problems - (#672) - * Bug fix: drawing corrupted heterodimer association in CellDesigner could - crash map upload (#673) - * Bug fix: custom semantic zooming didn't work with pathways imported from - CellDesigner layers (#678) - - -- Piotr Gawron <piotr.gawron@uni.lu> Thu, 7 Feb 2019 14:00:00 +0200 - -minerva (12.2.0~beta.0) unstable; urgency=medium +minerva (12.2.0) stable; urgency=medium * Feature: bug report utility - * Small improvement: JS plugin can create listener that is triggered on - search results focus change - - -- Piotr Gawron <piotr.gawron@uni.lu> Wed, 23 Jan 2019 15:00:00 +0200 - -minerva (12.2.0~alpha.1) unstable; urgency=medium - * Bug fix: problems with SBML-CellDesigner translation fixed - * Bug fix: gitlab CI tests fixed - - -- Piotr Gawron <piotr.gawron@uni.lu> Thu, 17 Jan 2019 15:00:00 +0200 - -minerva (12.2.0~alpha.0) unstable; urgency=medium * Feature: url GET parameters support all kind of search and selected overlays highlight * Feature: user can create custom logging configuration in file @@ -144,6 +51,15 @@ minerva (12.2.0~alpha.0) unstable; urgency=medium file formats * Feature: current state of the browsed map is reflected in the url (position, zoom, overlays, search queries, etc.) + * Small improvement: highlighting table rows in admin panel uses better + contrast color (#706) + * Small improvement: list of publication can be filtered by submap (#614) + * Small improvement: size of add overlay window adjusted to show more data + without scrollbars (#657) + * Small improvement: all popup dialogs in the application have dialog + specific css class names (#665) + * Small improvement: JS plugin can create listener that is triggered on + search results focus change * Small improvement: export to SBML includes unit factors * Small improvement: mesh identifiers are resolved to meshb.nlm.nih.gov urls * Small improvement: genetics information allows to provide information about @@ -178,6 +94,47 @@ minerva (12.2.0~alpha.0) unstable; urgency=medium * Small improvement: 'REQUEST AN ACCOUNT' link is available only the contact email account is provided * Small improvement: Plugin API allows to show/hide data overlays + * Bug fix: Icons were sometimes not properly loaded on Safari (#661) + * Bug fix: migration scripts are compatibile with postgres 9.3 version that + is default on Ubuntu 14 (#762) + * Bug fix: update/remove button is disabled when user has no privileges for + managing overlays (#742) + * Bug fix: when user cannot manage users information in overlays and users + tab in edit project dialog is provided instead of hiding tabs (#756) + * Bug fix: removing comments in a project asked for confirmation twice after + edit project dialog for specific project was opened; closed and opened + again (#697) + * Bug fix: editing/removing project requires Map Management privilege (#681) + * Bug fix: when removeAllListeners is called list of registered listeners is + cleaned (#687) + * Bug fix: when plugin is removed the html elements associated with it are + removed as well (#686) + * Bug fix: when creating new user default privileges are set properly (#692) + * Bug fix: plugin can be added after plugin has been removed in admin plugin + panel (#686) + * Bug fix: too many annotations (>=100) caused misaligning in the left panel + (#708) + * Bug fix: export to svg contains viewBox info (#716) + * Bug fix: overlays added via API couldn't be visualized after refresh (#718) + * Bug fix: Safari sometimes cached server responses and used wrong data, for + example in admin panel configuration tab (#719) + * Bug fix: description of transcription site is centered (#720) + * Bug fix: selecting too few parameters in export doesn't throw reportable + error (#721) + * Bug fix: providing invalid overlay id in url could break minerva (#726) + * Bug fix: removing project that doesn't exist doesn't cause 500 error (#723) + * Bug fix: opening map with invalid id shows proper error message (#724) + * Bug fix: Fixing an issue where search panel was not properly resized on + expansion (#682) + * Bug fix: loading icon is not overlapping input in the search panel (#404) + * Bug fix: position of transcription sites in genes are computed properly + (#553) + * Bug fix: REQUEST AN ACCOUNT was enabled when associated email was invalid + (#626) + * Bug fix: working with too many maps within the single session could crash + connection to server (#651) + * Bug fix: drawing corrupted heterodimer association in CellDesigner could + crash map upload (#673) * Bug fix: export to CellDesigner align inhibition reaction properly * Bug fix: export/import to/from SBML handles Heterodimer Association reaction properly @@ -193,9 +150,9 @@ minerva (12.2.0~alpha.0) unstable; urgency=medium * Bug fix: type of the data overlay can be defined in the file content (useful when uploading genetic variants) * Bug fix: CLEAR button clears comment checkbox if necessary - * Bug fix: minerva install problem on ubuntu 16 fixed + * Bug fix: minerva install problem on ubuntu 18 fixed - -- Piotr Gawron <piotr.gawron@uni.lu> Fri, 11 Jan 2019 12:00:00 +0200 + -- Piotr Gawron <piotr.gawron@uni.lu> Mon, 25 Mar 2019 17:00:00 +0200 minerva (12.1.8) stable; urgency=medium * Bug fix: add a project reset users custom overlays limit to default (#679) diff --git a/frontend-js/src/main/css/global.css b/frontend-js/src/main/css/global.css index 416421e54fbafe1ce757c904c24d632326a0d771..a99d1a4ac0775f5de79591abac9c2e8ab5a6e819 100644 --- a/frontend-js/src/main/css/global.css +++ b/frontend-js/src/main/css/global.css @@ -616,7 +616,7 @@ Plugin tabs float: left; } -.minerva-top-checkbox-div input { +.minerva-top-checkbox-div input[type=checkbox] { margin-top: 12px; display: inline; float: left; diff --git a/frontend-js/src/main/js/gui/admin/AddProjectDialog.js b/frontend-js/src/main/js/gui/admin/AddProjectDialog.js index 8390cbf4bd3d74d9d5d97f5f9201dcefe42a853d..049db1560a4e506ac9579738afca1d778efee4cf 100644 --- a/frontend-js/src/main/js/gui/admin/AddProjectDialog.js +++ b/frontend-js/src/main/js/gui/admin/AddProjectDialog.js @@ -788,10 +788,10 @@ AddProjectDialog.prototype.bindProjectUploadPreferences = function (user, type, var value = user.getPreferences().getProjectUpload()[type]; element.prop('checked', value); - GuiConnector.showProcessing(); element.change(function () { var data = new UserPreferences(); data.getProjectUpload()[type] = element.is(":checked"); + GuiConnector.showProcessing(); return ServerConnector.updateUserPreferences({ user: user, preferences: data diff --git a/frontend-js/src/main/js/gui/admin/EditProjectDialog.js b/frontend-js/src/main/js/gui/admin/EditProjectDialog.js index 80548ba60b8aac9ca0387eee13b2f437a444029d..0b3073e53bc609711965a6d6c22ebbd7d3b8553e 100644 --- a/frontend-js/src/main/js/gui/admin/EditProjectDialog.js +++ b/frontend-js/src/main/js/gui/admin/EditProjectDialog.js @@ -641,7 +641,7 @@ EditProjectDialog.prototype.refreshOverlays = function () { return self.setOverlays(overlays); }); } else { - guiUtils.hideTab(self, $(".minerva-project-overlays-tab", self.getElement())[0]); + guiUtils.disableTab($(".minerva-project-overlays-tab", self.getElement())[0], "You have no privileges to manage users data"); } }); }; @@ -671,7 +671,7 @@ EditProjectDialog.prototype.refreshUsers = function () { return self.setUsers(users); }); } else { - guiUtils.hideTab(self, $(".minerva-project-users-tab", self.getElement())[0]); + guiUtils.disableTab($(".minerva-project-users-tab", self.getElement())[0], "You have no privileges to manage users data"); } }); }; @@ -774,9 +774,13 @@ EditProjectDialog.prototype.userToTableRow = function (user, columns) { * @returns {Array} */ EditProjectDialog.prototype.overlayToTableRow = function (overlay, users) { + var self = this; var row = []; var id = overlay.getId(); var creatorSelect; + + var loggedUser = null; + if (overlay.getCreator() === "") { creatorSelect = "<select name='creator-" + id + "' value=''>"; } else { @@ -795,6 +799,10 @@ EditProjectDialog.prototype.overlayToTableRow = function (overlay, users) { creatorSelect += "<option value='" + user.getLogin() + "' " + selected + ">" + user.getLogin() + "(" + user.getName() + " " + user.getSurname() + ")</option>"; + + if (user.getLogin() === self.getServerConnector().getSessionData().getLogin()) { + loggedUser = user; + } } creatorSelect += "</select>"; @@ -825,8 +833,15 @@ EditProjectDialog.prototype.overlayToTableRow = function (overlay, users) { row[4] = defaultOverlayCheckbox; row[5] = creatorSelect; row[6] = downloadSourceButton; - row[7] = "<button name='saveOverlay' data='" + id + "'><i class=\"fa fa-save\" style=\"font-size:17px\"></i></button>"; - row[8] = "<button name='removeOverlay' data='" + id + "'><i class='fa fa-trash-o' style='font-size:17px'></button>"; + + var disabled = " disabled "; + if (loggedUser.hasPrivilege(self.getConfiguration().getPrivilegeType(PrivilegeType.LAYOUT_MANAGEMENT), self.getProject().getId())) { + disabled = ""; + } + + + row[7] = "<button name='saveOverlay' data='" + id + "'" + disabled + "><i class=\"fa fa-save\" style=\"font-size:17px\"></i></button>"; + row[8] = "<button name='removeOverlay' data='" + id + "'" + disabled + "><i class='fa fa-trash-o' style='font-size:17px'></button>"; return row; }; @@ -1053,7 +1068,7 @@ EditProjectDialog.prototype.openAddOverlayDialog = function () { }); return self._addOverlayDialog.init().then(function () { return self._addOverlayDialog.open(); - }).then(function(){ + }).then(function () { return self._addOverlayDialog; }); }; diff --git a/frontend-js/src/main/js/gui/admin/MapsAdminPanel.js b/frontend-js/src/main/js/gui/admin/MapsAdminPanel.js index e4addc6aff9b3d8cdfd8235ca57c7dc048efd752..aa5e8e492d8f4c2a799181150d19971c62de980f 100644 --- a/frontend-js/src/main/js/gui/admin/MapsAdminPanel.js +++ b/frontend-js/src/main/js/gui/admin/MapsAdminPanel.js @@ -346,9 +346,9 @@ MapsAdminPanel.prototype.onAddClicked = function () { return dialog.open(); }); } else { - dialog.clear(); - dialog.open(); - return Promise.resolve(); + return dialog.clear().then(function () { + return dialog.open(); + }) } }; @@ -480,12 +480,9 @@ MapsAdminPanel.prototype.showEditDialog = function (id) { return ServerConnector.getProject(id).then(function (project) { return self.getDialog(project); }).then(function (dialog) { - dialog.open(); + }).finally(function () { GuiConnector.hideProcessing(); - }).then(null, function (error) { - GuiConnector.hideProcessing(); - return Promise.reject(error); }); }; @@ -500,11 +497,8 @@ MapsAdminPanel.prototype.showLogs = function (id, level) { GuiConnector.showProcessing(); return self.getLogDialog(id, level).then(function (dialog) { return dialog.open(); - }).then(function () { - GuiConnector.hideProcessing(); - }, function (error) { + }).finally(function () { GuiConnector.hideProcessing(); - return Promise.reject(error); }); }; diff --git a/frontend-js/src/main/js/gui/leftPanel/GuiUtils.js b/frontend-js/src/main/js/gui/leftPanel/GuiUtils.js index 3ae1d5a4d8f41b3a1192f4433c47fdf2453589b7..2e3f3e6b30009722acb4ff6c8ed1c840475a702b 100644 --- a/frontend-js/src/main/js/gui/leftPanel/GuiUtils.js +++ b/frontend-js/src/main/js/gui/leftPanel/GuiUtils.js @@ -1142,6 +1142,26 @@ GuiUtils.prototype.hideTab = function (abstractGuiElement, panel) { } }; +/** + * + * @param {HTMLElement} element + * @param {string} message + */ +GuiUtils.prototype.disableTab = function (element, message) { + $(element).children().css("visibility", "hidden"); + $("[class='minerva-help-button']", element).children().css("visibility", "visible"); + var hideReasonDiv = document.createElement("div"); + hideReasonDiv.className = "searchPanel"; + + var center = document.createElement("center"); + var messageDiv = document.createElement("h4"); + messageDiv.innerHTML = message; + center.appendChild(messageDiv); + hideReasonDiv.appendChild(center); + + $(element).prepend(hideReasonDiv); +}; + /** * * @param {AbstractGuiElement} abstractGuiElement diff --git a/frontend-js/src/main/js/gui/leftPanel/PublicationListDialog.js b/frontend-js/src/main/js/gui/leftPanel/PublicationListDialog.js index b9868ad2234bc07938ef15ba0e1b449ec6990254..585b2e2f18e2c9448ab139cd19ba5fc3a8c57afc 100644 --- a/frontend-js/src/main/js/gui/leftPanel/PublicationListDialog.js +++ b/frontend-js/src/main/js/gui/leftPanel/PublicationListDialog.js @@ -108,7 +108,7 @@ PublicationListDialog.prototype._dataTableAjaxCall = function (data, callback) { row[3] = article.journal; row[4] = article.year; } else { - row[0] = publicationList.data[i].publication.id; + row[0] = publicationList.data[i].publication.resource; row[1] = "N/A"; row[2] = "N/A"; row[3] = "N/A"; @@ -304,7 +304,7 @@ PublicationListDialog.prototype.publicationListToArray = function (publicationLi row[3] = article.journal; row[4] = article.year; } else { - row[0] = entry.publication.id; + row[0] = entry.publication.resource; row[1] = "N/A"; row[2] = "N/A"; row[3] = "N/A"; diff --git a/frontend-js/src/main/js/map/data/PrivilegeType.js b/frontend-js/src/main/js/map/data/PrivilegeType.js index a708574bab7adc6ade238472a3e6c1e28ed51f01..ba6e5ff2a42565baf75e568c55a58df43040089d 100644 --- a/frontend-js/src/main/js/map/data/PrivilegeType.js +++ b/frontend-js/src/main/js/map/data/PrivilegeType.js @@ -36,6 +36,7 @@ PrivilegeType.MANAGE_PLUGINS = 'MANAGE_PLUGINS'; PrivilegeType.PROJECT_MANAGEMENT = 'PROJECT_MANAGEMENT'; PrivilegeType.ADD_MAP = 'ADD_MAP'; PrivilegeType.USER_MANAGEMENT = 'USER_MANAGEMENT'; +PrivilegeType.LAYOUT_MANAGEMENT = 'LAYOUT_MANAGEMENT'; /** * diff --git a/frontend-js/src/test/js/gui/admin/EditProjectDialog-test.js b/frontend-js/src/test/js/gui/admin/EditProjectDialog-test.js index ec175e302dc7859ea7096e54cfaf37e1e7ea60d4..840128d97362b0e219442dc14fa165cca275e666 100644 --- a/frontend-js/src/test/js/gui/admin/EditProjectDialog-test.js +++ b/frontend-js/src/test/js/gui/admin/EditProjectDialog-test.js @@ -6,7 +6,8 @@ var EditProjectDialog = require('../../../../main/js/gui/admin/EditProjectDialog var ServerConnector = require('../../ServerConnector-mock'); var logger = require('../../logger'); -var assert = require('assert'); +var chai = require('chai'); +var assert = chai.assert; var Promise = require('bluebird'); describe('EditProjectDialog', function () { @@ -130,4 +131,37 @@ describe('EditProjectDialog', function () { }); }); + describe('overlayToTableRow', function () { + it('as not admin', function () { + var dialog; + helper.loginAsAdmin(); + return createDialog().then(function (result) { + dialog = result; + return ServerConnector.getUsers(); + }).then(function (users) { + helper.loginWithoutAccess(); + var overlay = helper.createOverlay(); + var data = dialog.overlayToTableRow(overlay, users); + assert.ok(data[7].indexOf("disabled") >= 0) + }).then(function () { + return dialog.destroy(); + }); + }); + it('as admin', function () { + var dialog; + helper.loginAsAdmin(); + return createDialog().then(function (result) { + dialog = result; + return ServerConnector.getUsers(); + }).then(function (users) { + var overlay = helper.createOverlay(); + var data = dialog.overlayToTableRow(overlay, users); + assert.equal(data[7].indexOf("disabled"), -1) + }).then(function () { + return dialog.destroy(); + }); + }); + }); + + }); diff --git a/frontend-js/src/test/js/gui/admin/MapsAdminPanel-test.js b/frontend-js/src/test/js/gui/admin/MapsAdminPanel-test.js index bb98eef61d4e8cb994e1b8d7e184b66035dc36f3..37dc06d61f4493f407e2f6fc608b77a7105a4b77 100644 --- a/frontend-js/src/test/js/gui/admin/MapsAdminPanel-test.js +++ b/frontend-js/src/test/js/gui/admin/MapsAdminPanel-test.js @@ -7,6 +7,7 @@ var ServerConnector = require('../../ServerConnector-mock'); var logger = require('../../logger'); var assert = require('assert'); +var Promise = require('bluebird'); function createMapsAdminPanel() { return new MapsAdminPanel({ diff --git a/model-command/src/main/java/lcsb/mapviewer/commands/layout/ApplySimpleLayoutModelCommand.java b/model-command/src/main/java/lcsb/mapviewer/commands/layout/ApplySimpleLayoutModelCommand.java index 36b05a8d4c20e84205612a4c9ca291d20a08b5a8..7d06c068c228d8125d35c359e01d065d36be4cd2 100644 --- a/model-command/src/main/java/lcsb/mapviewer/commands/layout/ApplySimpleLayoutModelCommand.java +++ b/model-command/src/main/java/lcsb/mapviewer/commands/layout/ApplySimpleLayoutModelCommand.java @@ -219,7 +219,7 @@ public class ApplySimpleLayoutModelCommand extends ApplyLayoutModelCommand { minPoint.getY() + COMPARTMENT_BORDER, dimension.getWidth() - COMPARTMENT_BORDER * 2, dimension.getHeight() - COMPARTMENT_BORDER * 2); for (Element element : compartment.getElements()) { - if (!elements.contains(element) && element.getBorder()!=null) { + if (!elements.contains(element) && element.getBorder() != null && element.getX() != 0 && element.getY() != 0) { border.add(element.getBorder()); } } diff --git a/model/src/main/java/lcsb/mapviewer/model/map/model/Model.java b/model/src/main/java/lcsb/mapviewer/model/map/model/Model.java index 213a598b666218d20e79b42bdd847d8a22b6d8fe..ad86777a623847e843ab021e5838554406828a88 100644 --- a/model/src/main/java/lcsb/mapviewer/model/map/model/Model.java +++ b/model/src/main/java/lcsb/mapviewer/model/map/model/Model.java @@ -151,7 +151,7 @@ public interface Model { * @param elements * list of elements */ - void addElements(List<? extends Element> elements); + void addElements(Collection<? extends Element> elements); /** * Sets new short description of the model. diff --git a/model/src/main/java/lcsb/mapviewer/model/map/model/ModelFullIndexed.java b/model/src/main/java/lcsb/mapviewer/model/map/model/ModelFullIndexed.java index b0bae9102df897f2000370b9f8349511a17a0d01..067648d9e8530634e4ee7f61f3d7327c346326ee 100644 --- a/model/src/main/java/lcsb/mapviewer/model/map/model/ModelFullIndexed.java +++ b/model/src/main/java/lcsb/mapviewer/model/map/model/ModelFullIndexed.java @@ -198,7 +198,7 @@ public class ModelFullIndexed implements Model { } @Override - public void addElements(List<? extends Element> elements) { + public void addElements(Collection<? extends Element> elements) { for (Element element : elements) { addElement(element); } diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/Element.java b/model/src/main/java/lcsb/mapviewer/model/map/species/Element.java index 23f9e1802e56b00e13e442fe9e69befc0ad3f2ad..9245aee4c29e1a95dfa1efda8921442fb420b9ff 100644 --- a/model/src/main/java/lcsb/mapviewer/model/map/species/Element.java +++ b/model/src/main/java/lcsb/mapviewer/model/map/species/Element.java @@ -322,7 +322,7 @@ public abstract class Element implements BioEntity, Serializable, SbmlArgument { * @see x */ public void setX(String string) { - this.x = Double.parseDouble(string); + setX(Double.parseDouble(string)); } /** @@ -483,7 +483,7 @@ public abstract class Element implements BioEntity, Serializable, SbmlArgument { * @return rectangle border */ public Rectangle2D getBorder() { - if (x == null || y == null || width == null || height == null) { + if (x == null || y == null || width == null || height == null || width == 0.0 || height == 0.0) { return null; } return new Rectangle2D.Double(x, y, width, height); diff --git a/persist/src/main/resources/db/migration/V1__base.sql b/persist/src/main/resources/db/migration/V1__base.sql index 0e8f1b24a5d754258f6963b7349ccfb252d5bd42..2315f11629ebf4eb4383f323ca55c04c11b3e78d 100644 --- a/persist/src/main/resources/db/migration/V1__base.sql +++ b/persist/src/main/resources/db/migration/V1__base.sql @@ -13,7 +13,6 @@ SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SET check_function_bodies = false; SET client_min_messages = warning; -SET row_security = off; -- -- TOC entry 1 (class 3079 OID 12355) diff --git a/reactome/src/main/java/lcsb/mapviewer/reactome/utils/ReactomeConnector.java b/reactome/src/main/java/lcsb/mapviewer/reactome/utils/ReactomeConnector.java index f41b6ae6261905346b8845af1fe16a21fa5c64fc..0b4304a7fd86aafe051e23aa96016239185580bb 100644 --- a/reactome/src/main/java/lcsb/mapviewer/reactome/utils/ReactomeConnector.java +++ b/reactome/src/main/java/lcsb/mapviewer/reactome/utils/ReactomeConnector.java @@ -139,7 +139,7 @@ public class ReactomeConnector extends CachableInterface implements DataSourceUp /** * Url used for accessing Reactome RestFULL API. */ - private static final String REACTOME_URL = "http://reactome.org/ReactomeRESTfulAPI/RESTfulWS/"; + public static final String REACTOME_URL = "http://reactomews.oicr.on.ca:8080/ReactomeRESTfulAPI/RESTfulWS/"; @Override public List<ReactomePhysicalEntity> getEntitiesForName(String name) throws IOException { diff --git a/reactome/src/test/java/lcsb/mapviewer/reactome/utils/ReactomeConnectorTest.java b/reactome/src/test/java/lcsb/mapviewer/reactome/utils/ReactomeConnectorTest.java index cfc792e5f612d0caad2fad0009e871be3fb2ccb6..6dc740d05a21fc8e810c6670e6b9c47bfa2f98ad 100644 --- a/reactome/src/test/java/lcsb/mapviewer/reactome/utils/ReactomeConnectorTest.java +++ b/reactome/src/test/java/lcsb/mapviewer/reactome/utils/ReactomeConnectorTest.java @@ -173,7 +173,7 @@ public class ReactomeConnectorTest extends ReactomeTestFunctions { @Test(timeout = 15000) public void testCachableInterfaceByParams() throws Exception { - String url = "http://reactome.org/ReactomeRESTfulAPI/RESTfulWS/listByQuery/DatabaseObjects"; + String url = ReactomeConnector.REACTOME_URL + "listByQuery/DatabaseObjects"; String query = "identifier=2562550\n" + url; String newRes = "hello"; try { diff --git a/reactome/src/test/java/lcsb/mapviewer/reactome/xml/ReactomeReferenceGeneProductParserTest.java b/reactome/src/test/java/lcsb/mapviewer/reactome/xml/ReactomeReferenceGeneProductParserTest.java index 5412d92cafa5ca788bd8e42436993a411517d073..2c51193790a348d9229da562ba4b1413212b49dc 100644 --- a/reactome/src/test/java/lcsb/mapviewer/reactome/xml/ReactomeReferenceGeneProductParserTest.java +++ b/reactome/src/test/java/lcsb/mapviewer/reactome/xml/ReactomeReferenceGeneProductParserTest.java @@ -53,7 +53,7 @@ public class ReactomeReferenceGeneProductParserTest extends ReactomeTestFunction assertEquals((Integer) 2, res.getReferenceDatabase().getDbId()); assertEquals((Integer) 48895, res.getSpecies().getDbId()); - assertEquals((Integer) 11373937, res.getReferenceGenes().get(0).getDbId()); + assertEquals((Integer) 10586616, res.getReferenceGenes().get(0).getDbId()); } catch (Exception e) { e.printStackTrace(); diff --git a/reactome/src/test/java/lcsb/mapviewer/reactome/xml/ReactomeReferenceIsoformParserTest.java b/reactome/src/test/java/lcsb/mapviewer/reactome/xml/ReactomeReferenceIsoformParserTest.java index 1cfb460fdd0e475b183fc36a0f44ef9cf4880bc6..fc18b30ee840e7c8a35747f728832f10c14a76e2 100644 --- a/reactome/src/test/java/lcsb/mapviewer/reactome/xml/ReactomeReferenceIsoformParserTest.java +++ b/reactome/src/test/java/lcsb/mapviewer/reactome/xml/ReactomeReferenceIsoformParserTest.java @@ -39,7 +39,7 @@ public class ReactomeReferenceIsoformParserTest extends ReactomeTestFunctions { assertEquals((Integer) 2, res.getReferenceDatabase().getDbId()); assertEquals("false", res.getIsSequenceChanged()); assertEquals((Integer) 48887, res.getSpecies().getDbId()); - assertEquals((Integer) 11373937, res.getReferenceGenes().get(0).getDbId()); + assertEquals((Integer) 10586616, res.getReferenceGenes().get(0).getDbId()); assertEquals((Integer) 192971, res.getReferenceTranscripts().get(0).getDbId()); assertEquals((Integer) 402286, res.getIsoformParents().get(0).getDbId()); assertEquals("UniProt:P02545-1 LMNA", res.getDisplayName()); diff --git a/reactome/testFiles/reactome/referenceGeneProduct.xml b/reactome/testFiles/reactome/referenceGeneProduct.xml index 502894eef6af22255c140af50ca417422668445a..a3458d75e34352146a9dd6b4d329e5c4dae5bddc 100644 --- a/reactome/testFiles/reactome/referenceGeneProduct.xml +++ b/reactome/testFiles/reactome/referenceGeneProduct.xml @@ -20,7 +20,7 @@ <schemaClass>Species</schemaClass> </species> <referenceGene> - <dbId>11373937</dbId> + <dbId>10586616</dbId> <displayName>BioGPS Gene:1 A1BG</displayName> <schemaClass>ReferenceDNASequence</schemaClass> </referenceGene> diff --git a/reactome/testFiles/reactome/referenceIsoform.xml b/reactome/testFiles/reactome/referenceIsoform.xml index 8d08e978b194355ce6d27192a52b759c8a67989c..415b1bba7b619d406c2a81d0a8f83a290cf441d1 100644 --- a/reactome/testFiles/reactome/referenceIsoform.xml +++ b/reactome/testFiles/reactome/referenceIsoform.xml @@ -382,7 +382,7 @@ <schemaClass>Species</schemaClass> </species> <referenceGene> - <dbId>11373937</dbId> + <dbId>10586616</dbId> <displayName>BioGPS Gene:1 A1BG</displayName> <schemaClass>ReferenceDNASequence</schemaClass> </referenceGene> diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/publications/PublicationsRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/publications/PublicationsRestImpl.java index 7aa17f4e66616f91a793de617f2e3541d369440b..6fa4406ef870369fff71405de599215cbd5874b1 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/publications/PublicationsRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/publications/PublicationsRestImpl.java @@ -11,6 +11,7 @@ import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; +import org.apache.commons.lang3.math.NumberUtils; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -21,6 +22,7 @@ import lcsb.mapviewer.annotation.services.PubmedParser; import lcsb.mapviewer.annotation.services.PubmedSearchException; import lcsb.mapviewer.api.BaseRestImpl; import lcsb.mapviewer.api.QueryException; +import lcsb.mapviewer.common.comparator.IntegerComparator; import lcsb.mapviewer.common.exception.InvalidArgumentException; import lcsb.mapviewer.model.map.BioEntity; import lcsb.mapviewer.model.map.MiriamData; @@ -89,7 +91,7 @@ public class PublicationsRestImpl extends BaseRestImpl { this.searchService = searchService; } - private enum SortColumn { + enum SortColumn { PUBMED_ID("pubmedId"), YEAR("year"), JOURNAL("journal"), @@ -159,7 +161,7 @@ public class PublicationsRestImpl extends BaseRestImpl { return result; } - private Comparator<Entry<MiriamData, List<BioEntity>>> getComparatorForColumn(SortColumn sortColumnEnum, + Comparator<Entry<MiriamData, List<BioEntity>>> getComparatorForColumn(SortColumn sortColumnEnum, String sortOrder) { final int orderFactor; if (sortOrder.toLowerCase().equals("desc")) { @@ -171,13 +173,16 @@ public class PublicationsRestImpl extends BaseRestImpl { return null; } else if (sortColumnEnum.equals(SortColumn.PUBMED_ID)) { return new Comparator<Map.Entry<MiriamData, List<BioEntity>>>() { + IntegerComparator integerComparator = new IntegerComparator(); + @Override public int compare(Entry<MiriamData, List<BioEntity>> o1, Entry<MiriamData, List<BioEntity>> o2) { - Integer id1 = Integer.valueOf(o1.getKey().getResource()); - Integer id2 = Integer.valueOf(o2.getKey().getResource()); - return id1.compareTo(id2) * orderFactor; + Integer id1 = extractPubmedId(o1.getKey()); + Integer id2 = extractPubmedId(o2.getKey()); + return integerComparator.compare(id1, id2) * orderFactor; } + }; } else if (sortColumnEnum.equals(SortColumn.YEAR)) { return new Comparator<Map.Entry<MiriamData, List<BioEntity>>>() { @@ -310,4 +315,13 @@ public class PublicationsRestImpl extends BaseRestImpl { return pubmedParser.getPubmedArticleById(Integer.valueOf(resource)); } + private Integer extractPubmedId(MiriamData md) { + if (NumberUtils.isDigits(md.getResource())) { + return Integer.valueOf(md.getResource()); + } else { + return null; + } + + } + } diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/publications/PublicationsRestImplTest.java b/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/publications/PublicationsRestImplTest.java index 0cfca04523e45e92496b967c467e4f3a10a6169a..ee528a95c08a5c9b5191931731e219f29f5162ba 100644 --- a/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/publications/PublicationsRestImplTest.java +++ b/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/publications/PublicationsRestImplTest.java @@ -1,13 +1,18 @@ package lcsb.mapviewer.api.projects.models.publications; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import java.util.ArrayList; +import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.TreeMap; +import java.util.Map.Entry; import org.apache.log4j.Logger; import org.junit.After; @@ -19,6 +24,10 @@ import org.springframework.beans.factory.annotation.Autowired; import lcsb.mapviewer.api.QueryException; import lcsb.mapviewer.api.RestTestFunctions; +import lcsb.mapviewer.api.projects.models.publications.PublicationsRestImpl.SortColumn; +import lcsb.mapviewer.model.map.BioEntity; +import lcsb.mapviewer.model.map.MiriamData; +import lcsb.mapviewer.model.map.MiriamType; import lcsb.mapviewer.model.map.model.Model; import lcsb.mapviewer.services.interfaces.IModelService; @@ -124,4 +133,48 @@ public class PublicationsRestImplTest extends RestTestFunctions { return _projectRestImpl; } + @Test + public void testComparatorForColumnWithInvalidData() { + Entry<MiriamData, List<BioEntity>> valid = new Entry<MiriamData, List<BioEntity>>() { + + @Override + public List<BioEntity> setValue(List<BioEntity> value) { + return null; + } + + @Override + public List<BioEntity> getValue() { + return new ArrayList<>(); + } + + @Override + public MiriamData getKey() { + return new MiriamData(MiriamType.PUBMED, "12345"); + } + }; + Entry<MiriamData, List<BioEntity>> invalid = new Entry<MiriamData, List<BioEntity>>() { + + @Override + public List<BioEntity> setValue(List<BioEntity> value) { + return null; + } + + @Override + public List<BioEntity> getValue() { + return new ArrayList<>(); + } + + @Override + public MiriamData getKey() { + return new MiriamData(MiriamType.PUBMED, ""); + } + }; + for (SortColumn sortColumn : SortColumn.values()) { + Comparator<Entry<MiriamData, List<BioEntity>>> comparator = _projectRestImpl.getComparatorForColumn(sortColumn, + "desc"); + assertNotNull(comparator.compare(valid, invalid)); + + } + } + } diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/ProjectService.java b/service/src/main/java/lcsb/mapviewer/services/impl/ProjectService.java index 50acecfe1e036ca58799145fb5bdc73749163921..31aad6fe6743e53fc1146d45e4a31ae53ac6d216 100644 --- a/service/src/main/java/lcsb/mapviewer/services/impl/ProjectService.java +++ b/service/src/main/java/lcsb/mapviewer/services/impl/ProjectService.java @@ -1202,15 +1202,6 @@ public class ProjectService implements IProjectService { @Override public void updateProject(Project project, String token) throws SecurityException { projectDao.update(project); - if (token != null) { - Model model = modelService.getLastModelByProjectId(project.getProjectId(), token); - if (model != null) { - // TODO it's a hack to prevent lazy initialization of the project - project.getLayouts(); - project.getOverviewImages(); - model.setProject(project); - } - } } /** diff --git a/web/src/main/webapp/index.xhtml b/web/src/main/webapp/index.xhtml index 59e7efe6cbb829e6908fd879050ae326dc88eada..f745a7959fd0b6aaf43ed338012b9c06510b9267 100644 --- a/web/src/main/webapp/index.xhtml +++ b/web/src/main/webapp/index.xhtml @@ -35,6 +35,17 @@ var btn = $.fn.button.noConflict(); // reverts $.fn.button to jqueryui btn $.fn.btn = btn; // assigns bootstrap button functionality to $.fn.btn + /** + * Safari has some issue with the jquery css or the way JSF presents the CSS resources. + * This is a hack that fixes this issue by forcing the icon sprite png to be loaded once the document is ready. + */ + $('document').ready(function() { + var style = document.createElement("style"); + var styleText = document.createTextNode(".ui-icon { background-image: url(/minerva/javax.faces.resource/images/ui-icons_616161_256x240.png.xhtml?ln=primefaces-aristo&m_version=Unknown) !important; }"); + style.appendChild(styleText); + document.head.appendChild(style); + }); + function initMap(){ var element = document.getElementById('minervaAppDiv'); return minerva.create({